diff options
author | calderwoodra <calderwoodra@google.com> | 2018-04-25 17:21:03 -0700 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-04-25 17:23:09 -0700 |
commit | aa9d670a4f076e52418cd5e404435c524713278e (patch) | |
tree | 35906c59b5daccce7f7dacd2ca8a01aaa3dcec5c /java/com/android/dialer/speeddial/loader | |
parent | a0c49f63111f672d91e812370baa0249b69929cd (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/loader')
-rw-r--r-- | java/com/android/dialer/speeddial/loader/SpeedDialUiItem.java | 11 | ||||
-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.java | 2 |
3 files changed, 94 insertions, 10 deletions
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) |