summaryrefslogtreecommitdiff
path: root/java/com/android/dialer/speeddial
diff options
context:
space:
mode:
authorcalderwoodra <calderwoodra@google.com>2018-04-25 17:21:03 -0700
committerCopybara-Service <copybara-piper@google.com>2018-04-25 17:23:09 -0700
commitaa9d670a4f076e52418cd5e404435c524713278e (patch)
tree35906c59b5daccce7f7dacd2ca8a01aaa3dcec5c /java/com/android/dialer/speeddial
parenta0c49f63111f672d91e812370baa0249b69929cd (diff)
Persist contacts pinned positions in speed dial.
Bug: 78491298 Test: WIP PiperOrigin-RevId: 194323952 Change-Id: I6883ce1506684c93cb5538ebbc0e14aecc300a00
Diffstat (limited to 'java/com/android/dialer/speeddial')
-rw-r--r--java/com/android/dialer/speeddial/SpeedDialAdapter.java30
-rw-r--r--java/com/android/dialer/speeddial/SpeedDialFragment.java20
-rw-r--r--java/com/android/dialer/speeddial/database/SpeedDialEntry.java8
-rw-r--r--java/com/android/dialer/speeddial/database/SpeedDialEntryDatabaseHelper.java30
-rw-r--r--java/com/android/dialer/speeddial/loader/SpeedDialUiItem.java11
-rw-r--r--java/com/android/dialer/speeddial/loader/SpeedDialUiItemMutator.java (renamed from java/com/android/dialer/speeddial/loader/SpeedDialUiItemLoader.java)91
-rw-r--r--java/com/android/dialer/speeddial/loader/UiItemLoaderComponent.java2
7 files changed, 160 insertions, 32 deletions
diff --git a/java/com/android/dialer/speeddial/SpeedDialAdapter.java b/java/com/android/dialer/speeddial/SpeedDialAdapter.java
index 8a37e97dd..a382b1a6b 100644
--- a/java/com/android/dialer/speeddial/SpeedDialAdapter.java
+++ b/java/com/android/dialer/speeddial/SpeedDialAdapter.java
@@ -34,10 +34,10 @@ import com.android.dialer.speeddial.HeaderViewHolder.SpeedDialHeaderListener;
import com.android.dialer.speeddial.SuggestionViewHolder.SuggestedContactsListener;
import com.android.dialer.speeddial.draghelper.SpeedDialItemTouchHelperCallback.ItemTouchHelperAdapter;
import com.android.dialer.speeddial.loader.SpeedDialUiItem;
+import com.google.common.collect.ImmutableList;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -146,7 +146,13 @@ public final class SpeedDialAdapter extends RecyclerView.Adapter<RecyclerView.Vi
public void setSpeedDialUiItems(List<SpeedDialUiItem> immutableSpeedDialUiItems) {
speedDialUiItems = new ArrayList<>();
speedDialUiItems.addAll(immutableSpeedDialUiItems);
- speedDialUiItems.sort((o1, o2) -> Boolean.compare(o2.isStarred(), o1.isStarred()));
+ speedDialUiItems.sort(
+ (o1, o2) -> {
+ if (o1.isStarred() && o2.isStarred()) {
+ return Integer.compare(o1.pinnedPosition().or(-1), o2.pinnedPosition().or(-1));
+ }
+ return Boolean.compare(o2.isStarred(), o1.isStarred());
+ });
positionToRowTypeMap.clear();
if (speedDialUiItems.isEmpty()) {
return;
@@ -168,6 +174,13 @@ public final class SpeedDialAdapter extends RecyclerView.Adapter<RecyclerView.Vi
}
}
+ public ImmutableList<SpeedDialUiItem> getSpeedDialUiItems() {
+ if (speedDialUiItems == null || speedDialUiItems.isEmpty()) {
+ return ImmutableList.of();
+ }
+ return ImmutableList.copyOf(speedDialUiItems);
+ }
+
public SpanSizeLookup getSpanSizeLookup() {
return new SpanSizeLookup() {
@Override
@@ -189,16 +202,9 @@ public final class SpeedDialAdapter extends RecyclerView.Adapter<RecyclerView.Vi
@Override
public void onItemMove(int fromPosition, int toPosition) {
- if (fromPosition < toPosition) {
- for (int i = fromPosition; i < toPosition && i < speedDialUiItems.size() - 1; i++) {
- Collections.swap(speedDialUiItems, i, i + 1);
- }
- } else {
- for (int i = fromPosition - 1; i > toPosition; i--) {
- Collections.swap(speedDialUiItems, i, i - 1);
- }
- }
- // TODO(calderwoodra): store pinned positions
+ // fromPosition/toPosition correspond to adapter position, which is off by 1 from the list
+ // position b/c of the favorites header. So subtract 1 here.
+ speedDialUiItems.add(toPosition - 1, speedDialUiItems.remove(fromPosition - 1));
notifyItemMoved(fromPosition, toPosition);
}
diff --git a/java/com/android/dialer/speeddial/SpeedDialFragment.java b/java/com/android/dialer/speeddial/SpeedDialFragment.java
index b74c06239..b76db1cf3 100644
--- a/java/com/android/dialer/speeddial/SpeedDialFragment.java
+++ b/java/com/android/dialer/speeddial/SpeedDialFragment.java
@@ -36,6 +36,7 @@ import com.android.dialer.callintent.CallInitiationType;
import com.android.dialer.callintent.CallIntentBuilder;
import com.android.dialer.common.FragmentUtils;
import com.android.dialer.common.LogUtil;
+import com.android.dialer.common.concurrent.DefaultFutureCallback;
import com.android.dialer.common.concurrent.DialerExecutorComponent;
import com.android.dialer.common.concurrent.SupportUiListener;
import com.android.dialer.constants.ActivityRequestCodes;
@@ -54,6 +55,7 @@ import com.android.dialer.speeddial.loader.SpeedDialUiItem;
import com.android.dialer.speeddial.loader.UiItemLoaderComponent;
import com.android.dialer.util.IntentUtil;
import com.google.common.collect.ImmutableList;
+import com.google.common.util.concurrent.Futures;
/**
* Fragment for displaying:
@@ -143,7 +145,7 @@ public class SpeedDialFragment extends Fragment {
speedDialLoaderListener.listen(
getContext(),
- UiItemLoaderComponent.get(getContext()).speedDialUiItemLoader().loadSpeedDialUiItems(),
+ UiItemLoaderComponent.get(getContext()).speedDialUiItemMutator().loadSpeedDialUiItems(),
this::onSpeedDialUiItemListLoaded,
throwable -> {
throw new RuntimeException(throwable);
@@ -158,7 +160,7 @@ public class SpeedDialFragment extends Fragment {
speedDialLoaderListener.listen(
getContext(),
UiItemLoaderComponent.get(getContext())
- .speedDialUiItemLoader()
+ .speedDialUiItemMutator()
.starContact(data.getData()),
this::onSpeedDialUiItemListLoaded,
throwable -> {
@@ -173,7 +175,7 @@ public class SpeedDialFragment extends Fragment {
// TODO(calderwoodra): Use DiffUtil to properly update and animate the change
adapter.setSpeedDialUiItems(
UiItemLoaderComponent.get(getContext())
- .speedDialUiItemLoader()
+ .speedDialUiItemMutator()
.insertDuoChannels(getContext(), speedDialUiItems));
adapter.notifyDataSetChanged();
if (getActivity() != null) {
@@ -187,6 +189,18 @@ public class SpeedDialFragment extends Fragment {
super.onPause();
contextMenu.hideMenu();
contextMenuBackground.setVisibility(View.GONE);
+ Futures.addCallback(
+ DialerExecutorComponent.get(getContext())
+ .backgroundExecutor()
+ .submit(
+ () -> {
+ UiItemLoaderComponent.get(getContext())
+ .speedDialUiItemMutator()
+ .updatePinnedPosition(adapter.getSpeedDialUiItems());
+ return null;
+ }),
+ new DefaultFutureCallback<>(),
+ DialerExecutorComponent.get(getContext()).backgroundExecutor());
}
@Override
diff --git a/java/com/android/dialer/speeddial/database/SpeedDialEntry.java b/java/com/android/dialer/speeddial/database/SpeedDialEntry.java
index 89aed8f37..181f9eca7 100644
--- a/java/com/android/dialer/speeddial/database/SpeedDialEntry.java
+++ b/java/com/android/dialer/speeddial/database/SpeedDialEntry.java
@@ -20,6 +20,7 @@ import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
import com.google.auto.value.AutoValue;
+import com.google.common.base.Optional;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -35,6 +36,9 @@ public abstract class SpeedDialEntry {
@Nullable
public abstract Long id();
+ /** Position the contact is pinned to in the UI. Will be absent if it hasn't be set yet. */
+ public abstract Optional<Integer> pinnedPosition();
+
/** @see {@link Contacts#_ID} */
public abstract long contactId();
@@ -53,7 +57,7 @@ public abstract class SpeedDialEntry {
public abstract Builder toBuilder();
public static Builder builder() {
- return new AutoValue_SpeedDialEntry.Builder();
+ return new AutoValue_SpeedDialEntry.Builder().setPinnedPosition(Optional.absent());
}
/** Builder class for speed dial entry. */
@@ -62,6 +66,8 @@ public abstract class SpeedDialEntry {
public abstract Builder setId(Long id);
+ public abstract Builder setPinnedPosition(Optional<Integer> pinnedPosition);
+
public abstract Builder setContactId(long contactId);
public abstract Builder setLookupKey(String lookupKey);
diff --git a/java/com/android/dialer/speeddial/database/SpeedDialEntryDatabaseHelper.java b/java/com/android/dialer/speeddial/database/SpeedDialEntryDatabaseHelper.java
index 544bb3613..1416a203d 100644
--- a/java/com/android/dialer/speeddial/database/SpeedDialEntryDatabaseHelper.java
+++ b/java/com/android/dialer/speeddial/database/SpeedDialEntryDatabaseHelper.java
@@ -25,6 +25,7 @@ import android.text.TextUtils;
import com.android.dialer.common.Assert;
import com.android.dialer.common.database.Selection;
import com.android.dialer.speeddial.database.SpeedDialEntry.Channel;
+import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.util.ArrayList;
@@ -38,12 +39,20 @@ import java.util.List;
public final class SpeedDialEntryDatabaseHelper extends SQLiteOpenHelper
implements SpeedDialEntryDao {
+ /**
+ * If the pinned position is absent, then we need to write an impossible value in the table like
+ * -1 so that it doesn't default to 0. When we read this value from the table, we'll translate it
+ * to Optional.absent() in the resulting {@link SpeedDialEntry}.
+ */
+ private static final int PINNED_POSITION_ABSENT = -1;
+
private static final int DATABASE_VERSION = 2;
private static final String DATABASE_NAME = "CPSpeedDialEntry";
// Column names
private static final String TABLE_NAME = "speed_dial_entries";
private static final String ID = "id";
+ private static final String PINNED_POSITION = "pinned_position";
private static final String CONTACT_ID = "contact_id";
private static final String LOOKUP_KEY = "lookup_key";
private static final String PHONE_NUMBER = "phone_number";
@@ -53,12 +62,13 @@ public final class SpeedDialEntryDatabaseHelper extends SQLiteOpenHelper
// Column positions
private static final int POSITION_ID = 0;
- private static final int POSITION_CONTACT_ID = 1;
- private static final int POSITION_LOOKUP_KEY = 2;
- private static final int POSITION_PHONE_NUMBER = 3;
- private static final int POSITION_PHONE_TYPE = 4;
- private static final int POSITION_PHONE_LABEL = 5;
- private static final int POSITION_PHONE_TECHNOLOGY = 6;
+ private static final int POSITION_PINNED_POSITION = 1;
+ private static final int POSITION_CONTACT_ID = 2;
+ private static final int POSITION_LOOKUP_KEY = 3;
+ private static final int POSITION_PHONE_NUMBER = 4;
+ private static final int POSITION_PHONE_TYPE = 5;
+ private static final int POSITION_PHONE_LABEL = 6;
+ private static final int POSITION_PHONE_TECHNOLOGY = 7;
// Create Table Query
private static final String CREATE_TABLE_SQL =
@@ -66,6 +76,7 @@ public final class SpeedDialEntryDatabaseHelper extends SQLiteOpenHelper
+ TABLE_NAME
+ " ("
+ (ID + " integer primary key, ")
+ + (PINNED_POSITION + " integer, ")
+ (CONTACT_ID + " integer, ")
+ (LOOKUP_KEY + " text, ")
+ (PHONE_NUMBER + " text, ")
@@ -119,11 +130,17 @@ public final class SpeedDialEntryDatabaseHelper extends SQLiteOpenHelper
.build();
}
+ Optional<Integer> pinnedPosition = Optional.of(cursor.getInt(POSITION_PINNED_POSITION));
+ if (pinnedPosition.or(PINNED_POSITION_ABSENT) == PINNED_POSITION_ABSENT) {
+ pinnedPosition = Optional.absent();
+ }
+
SpeedDialEntry entry =
SpeedDialEntry.builder()
.setDefaultChannel(channel)
.setContactId(cursor.getLong(POSITION_CONTACT_ID))
.setLookupKey(cursor.getString(POSITION_LOOKUP_KEY))
+ .setPinnedPosition(pinnedPosition)
.setId(cursor.getLong(POSITION_ID))
.build();
entries.add(entry);
@@ -226,6 +243,7 @@ public final class SpeedDialEntryDatabaseHelper extends SQLiteOpenHelper
if (includeId) {
values.put(ID, entry.id());
}
+ values.put(PINNED_POSITION, entry.pinnedPosition().or(PINNED_POSITION_ABSENT));
values.put(CONTACT_ID, entry.contactId());
values.put(LOOKUP_KEY, entry.lookupKey());
if (entry.defaultChannel() != null) {
diff --git a/java/com/android/dialer/speeddial/loader/SpeedDialUiItem.java b/java/com/android/dialer/speeddial/loader/SpeedDialUiItem.java
index 9bda3fb31..a2bdfb89a 100644
--- a/java/com/android/dialer/speeddial/loader/SpeedDialUiItem.java
+++ b/java/com/android/dialer/speeddial/loader/SpeedDialUiItem.java
@@ -25,6 +25,7 @@ import com.android.dialer.common.Assert;
import com.android.dialer.speeddial.database.SpeedDialEntry;
import com.android.dialer.speeddial.database.SpeedDialEntry.Channel;
import com.google.auto.value.AutoValue;
+import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.List;
@@ -83,7 +84,9 @@ public abstract class SpeedDialUiItem {
}
public static Builder builder() {
- return new AutoValue_SpeedDialUiItem.Builder().setChannels(ImmutableList.of());
+ return new AutoValue_SpeedDialUiItem.Builder()
+ .setChannels(ImmutableList.of())
+ .setPinnedPosition(Optional.absent());
}
/**
@@ -139,6 +142,7 @@ public abstract class SpeedDialUiItem {
public SpeedDialEntry buildSpeedDialEntry() {
return SpeedDialEntry.builder()
.setId(speedDialEntryId())
+ .setPinnedPosition(pinnedPosition())
.setLookupKey(lookupKey())
.setContactId(contactId())
.setDefaultChannel(defaultChannel())
@@ -212,6 +216,9 @@ public abstract class SpeedDialUiItem {
@Nullable
public abstract Long speedDialEntryId();
+ /** @see SpeedDialEntry#pinnedPosition() */
+ public abstract Optional<Integer> pinnedPosition();
+
/** @see android.provider.ContactsContract.Contacts#DISPLAY_NAME */
public abstract String name();
@@ -255,6 +262,8 @@ public abstract class SpeedDialUiItem {
/** Set to null if {@link #isStarred()} is false. */
public abstract Builder setSpeedDialEntryId(@Nullable Long id);
+ public abstract Builder setPinnedPosition(Optional<Integer> pinnedPosition);
+
public abstract Builder setName(String name);
public abstract Builder setContactId(long contactId);
diff --git a/java/com/android/dialer/speeddial/loader/SpeedDialUiItemLoader.java b/java/com/android/dialer/speeddial/loader/SpeedDialUiItemMutator.java
index 921468773..5dae2efab 100644
--- a/java/com/android/dialer/speeddial/loader/SpeedDialUiItemLoader.java
+++ b/java/com/android/dialer/speeddial/loader/SpeedDialUiItemMutator.java
@@ -17,11 +17,14 @@
package com.android.dialer.speeddial.loader;
import android.annotation.TargetApi;
+import android.content.ContentProviderOperation;
import android.content.ContentValues;
import android.content.Context;
+import android.content.OperationApplicationException;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build.VERSION_CODES;
+import android.os.RemoteException;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Contacts;
@@ -43,6 +46,7 @@ import com.android.dialer.speeddial.database.SpeedDialEntry;
import com.android.dialer.speeddial.database.SpeedDialEntry.Channel;
import com.android.dialer.speeddial.database.SpeedDialEntryDao;
import com.android.dialer.speeddial.database.SpeedDialEntryDatabaseHelper;
+import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.ListenableFuture;
@@ -76,7 +80,7 @@ import javax.inject.Singleton;
@SuppressWarnings("AndroidApiChecker")
@TargetApi(VERSION_CODES.N)
@Singleton
-public final class SpeedDialUiItemLoader {
+public final class SpeedDialUiItemMutator {
private static final int MAX_DUO_SUGGESTIONS = 3;
@@ -87,7 +91,7 @@ public final class SpeedDialUiItemLoader {
private final ContactsPreferences contactsPreferences;
@Inject
- public SpeedDialUiItemLoader(
+ public SpeedDialUiItemMutator(
@ApplicationContext Context appContext,
@BackgroundExecutor ListeningExecutorService backgroundExecutor) {
this.appContext = appContext;
@@ -127,7 +131,7 @@ public final class SpeedDialUiItemLoader {
null,
null)) {
if (cursor == null) {
- LogUtil.e("SpeedDialUiItemLoader.insertNewContactEntry", "Cursor was null");
+ LogUtil.e("SpeedDialUiItemMutator.insertNewContactEntry", "Cursor was null");
return loadSpeedDialUiItemsInternal();
}
Assert.checkArgument(cursor.moveToFirst(), "Cursor should never be empty");
@@ -285,7 +289,7 @@ public final class SpeedDialUiItemLoader {
null,
null)) {
if (cursor == null) {
- LogUtil.e("SpeedDialUiItemLoader.updateContactIdsAndLookupKeys", "null cursor");
+ LogUtil.e("SpeedDialUiItemMutator.updateContactIdsAndLookupKeys", "null cursor");
return new ArrayList<>();
}
if (cursor.getCount() == 0) {
@@ -339,9 +343,11 @@ public final class SpeedDialUiItemLoader {
SpeedDialUiItem item = SpeedDialUiItem.fromCursor(cursor);
for (SpeedDialEntry entry : entries) {
if (entry.contactId() == item.contactId()) {
- // Update the id to match it's corresponding SpeedDialEntry.
+ // Update the id and pinned position to match it's corresponding SpeedDialEntry.
SpeedDialUiItem.Builder entrySpeedDialItem =
- item.toBuilder().setSpeedDialEntryId(entry.id());
+ item.toBuilder()
+ .setSpeedDialEntryId(entry.id())
+ .setPinnedPosition(entry.pinnedPosition());
// Preserve the default channel if it didn't change/still exists
Channel defaultChannel = entry.defaultChannel();
@@ -405,7 +411,7 @@ public final class SpeedDialUiItemLoader {
.getContentResolver()
.query(strequentUri, new String[] {Phone.CONTACT_ID}, null, null, null)) {
if (cursor == null) {
- LogUtil.e("SpeedDialUiItemLoader.getStrequentContacts", "null cursor");
+ LogUtil.e("SpeedDialUiItemMutator.getStrequentContacts", "null cursor");
return new ArrayList<>();
}
if (cursor.getCount() == 0) {
@@ -430,7 +436,7 @@ public final class SpeedDialUiItemLoader {
null)) {
List<SpeedDialUiItem> contacts = new ArrayList<>();
if (cursor == null) {
- LogUtil.e("SpeedDialUiItemLoader.getStrequentContacts", "null cursor");
+ LogUtil.e("SpeedDialUiItemMutator.getStrequentContacts", "null cursor");
return new ArrayList<>();
}
if (cursor.getCount() == 0) {
@@ -444,6 +450,75 @@ public final class SpeedDialUiItemLoader {
}
/**
+ * Persists the position of the {@link SpeedDialUiItem items} as the pinned position according to
+ * the order they were passed in.
+ */
+ @WorkerThread
+ public void updatePinnedPosition(List<SpeedDialUiItem> speedDialUiItems) {
+ Assert.isWorkerThread();
+ if (speedDialUiItems == null || speedDialUiItems.isEmpty()) {
+ return;
+ }
+
+ // Update the positions in the SpeedDialEntry database
+ ImmutableList.Builder<SpeedDialEntry> entriesToUpdate = ImmutableList.builder();
+ for (int i = 0; i < speedDialUiItems.size(); i++) {
+ SpeedDialUiItem item = speedDialUiItems.get(i);
+ if (item.isStarred()) {
+ entriesToUpdate.add(
+ item.buildSpeedDialEntry().toBuilder().setPinnedPosition(Optional.of(i)).build());
+ }
+ }
+ getSpeedDialEntryDao().update(entriesToUpdate.build());
+
+ // Update the positions in CP2
+ // Build a list of SpeedDialUiItems where each contact is only represented once but the order
+ // is maintained. For example, assume you have a list of contacts with contact ids:
+ // > { 1, 1, 2, 1, 2, 3 }
+ // This list will be reduced to:
+ // > { 1, 2, 3 }
+ // and their positions in the resulting list will be written to the CP2 Contacts.PINNED column.
+ List<SpeedDialUiItem> cp2SpeedDialUiItems = new ArrayList<>();
+ Set<Long> contactIds = new ArraySet<>();
+ for (SpeedDialUiItem item : speedDialUiItems) {
+ if (contactIds.add(item.contactId())) {
+ cp2SpeedDialUiItems.add(item);
+ }
+ }
+
+ // Code copied from PhoneFavoritesTileAdapter#handleDrop
+ ArrayList<ContentProviderOperation> operations = new ArrayList<>();
+ for (int i = 0; i < cp2SpeedDialUiItems.size(); i++) {
+ SpeedDialUiItem item = cp2SpeedDialUiItems.get(i);
+ // Pinned positions in the database start from 1 instead of being zero-indexed like
+ // arrays, so offset by 1.
+ int databasePinnedPosition = i + 1;
+ if (item.pinnedPosition().isPresent()
+ && item.pinnedPosition().get() == databasePinnedPosition) {
+ continue;
+ }
+
+ Uri uri = Uri.withAppendedPath(Contacts.CONTENT_URI, String.valueOf(item.contactId()));
+ ContentValues values = new ContentValues();
+ values.put(Contacts.PINNED, databasePinnedPosition);
+ operations.add(ContentProviderOperation.newUpdate(uri).withValues(values).build());
+ }
+ if (operations.isEmpty()) {
+ // Nothing to update
+ return;
+ }
+ try {
+ appContext.getContentResolver().applyBatch(ContactsContract.AUTHORITY, operations);
+ // TODO(calderwoodra): log
+ } catch (RemoteException | OperationApplicationException e) {
+ LogUtil.e(
+ "SpeedDialUiItemMutator.updatePinnedPosition",
+ "Exception thrown when pinning contacts",
+ e);
+ }
+ }
+
+ /**
* Returns a new list with duo reachable channels inserted. Duo channels won't replace ViLTE
* channels.
*/
diff --git a/java/com/android/dialer/speeddial/loader/UiItemLoaderComponent.java b/java/com/android/dialer/speeddial/loader/UiItemLoaderComponent.java
index 7d01b4380..852908409 100644
--- a/java/com/android/dialer/speeddial/loader/UiItemLoaderComponent.java
+++ b/java/com/android/dialer/speeddial/loader/UiItemLoaderComponent.java
@@ -24,7 +24,7 @@ import dagger.Subcomponent;
@Subcomponent
public abstract class UiItemLoaderComponent {
- public abstract SpeedDialUiItemLoader speedDialUiItemLoader();
+ public abstract SpeedDialUiItemMutator speedDialUiItemMutator();
public static UiItemLoaderComponent get(Context context) {
return ((UiItemLoaderComponent.HasComponent)