From 6f0a22d53d997438721655573f9b9e31923f64ca Mon Sep 17 00:00:00 2001 From: calderwoodra Date: Fri, 27 Apr 2018 15:58:27 -0700 Subject: Implemented remove starred contact from speed dial fragment. This is triggered by long pressing a SpeedDialUiItem and selecting remove in the resulting menu. This will remove it's assocaited entry from the SpeedDialEntry database and if the contact associated with the SpeedDialUiItem being removed only has one speed dial entry, additionally we will unstar the contact as well. Bug: 77761023 Test: WIP PiperOrigin-RevId: 194606709 Change-Id: I4d6fb104a388c39c77796f7626cd63e991303a51 --- .../dialer/speeddial/SpeedDialFragment.java | 41 +++++++++-- .../speeddial/loader/SpeedDialUiItemMutator.java | 80 ++++++++++++++++++++++ 2 files changed, 114 insertions(+), 7 deletions(-) (limited to 'java') diff --git a/java/com/android/dialer/speeddial/SpeedDialFragment.java b/java/com/android/dialer/speeddial/SpeedDialFragment.java index 018f97888..54709e491 100644 --- a/java/com/android/dialer/speeddial/SpeedDialFragment.java +++ b/java/com/android/dialer/speeddial/SpeedDialFragment.java @@ -105,6 +105,10 @@ public class SpeedDialFragment extends Fragment { LogUtil.enterBlock("SpeedDialFragment.onCreateView"); View rootLayout = inflater.inflate(R.layout.fragment_speed_dial, container, false); + speedDialLoaderListener = + DialerExecutorComponent.get(getContext()) + .createUiListener(getChildFragmentManager(), "speed_dial_loader_listener"); + // Setup favorite contact context menu contextMenu = rootLayout.findViewById(R.id.favorite_contact_context_menu); contextMenuBackground = rootLayout.findViewById(R.id.context_menu_background); @@ -124,7 +128,11 @@ public class SpeedDialFragment extends Fragment { rootLayout, contextMenu, contextMenuBackground, - new SpeedDialContextMenuItemListener(getActivity(), getChildFragmentManager()), + new SpeedDialContextMenuItemListener( + getActivity(), + getChildFragmentManager(), + new UpdateSpeedDialAdapterListener(), + speedDialLoaderListener), layoutManager); adapter = new SpeedDialAdapter(getContext(), favoritesListener, suggestedListener, headerListener); @@ -138,10 +146,6 @@ public class SpeedDialFragment extends Fragment { ItemTouchHelper touchHelper = new ItemTouchHelper(callback); touchHelper.attachToRecyclerView(recyclerView); adapter.setItemTouchHelper(touchHelper); - - speedDialLoaderListener = - DialerExecutorComponent.get(getContext()) - .createUiListener(getChildFragmentManager(), "speed_dial_loader_listener"); return rootLayout; } @@ -437,11 +441,18 @@ public class SpeedDialFragment extends Fragment { private final FragmentActivity activity; private final FragmentManager childFragmentManager; + private final SupportUiListener> speedDialLoaderListener; + private final UpdateSpeedDialAdapterListener updateAdapterListener; SpeedDialContextMenuItemListener( - FragmentActivity activity, FragmentManager childFragmentManager) { + FragmentActivity activity, + FragmentManager childFragmentManager, + UpdateSpeedDialAdapterListener updateAdapterListener, + SupportUiListener> speedDialLoaderListener) { this.activity = activity; this.childFragmentManager = childFragmentManager; + this.updateAdapterListener = updateAdapterListener; + this.speedDialLoaderListener = speedDialLoaderListener; } @Override @@ -472,7 +483,15 @@ public class SpeedDialFragment extends Fragment { @Override public void removeFavoriteContact(SpeedDialUiItem speedDialUiItem) { - // TODO(calderwoodra): implement remove + speedDialLoaderListener.listen( + activity, + UiItemLoaderComponent.get(activity) + .speedDialUiItemMutator() + .removeSpeedDialUiItem(speedDialUiItem), + updateAdapterListener::updateAdapter, + throwable -> { + throw new RuntimeException(throwable); + }); } @Override @@ -485,6 +504,14 @@ public class SpeedDialFragment extends Fragment { } } + /** Listener for when a SpeedDialUiItem is updated. */ + private class UpdateSpeedDialAdapterListener { + + void updateAdapter(ImmutableList speedDialUiItems) { + onSpeedDialUiItemListLoaded(speedDialUiItems); + } + } + /** Interface for {@link SpeedDialFragment} to communicate with its host/parent. */ public interface HostInterface { diff --git a/java/com/android/dialer/speeddial/loader/SpeedDialUiItemMutator.java b/java/com/android/dialer/speeddial/loader/SpeedDialUiItemMutator.java index 5dae2efab..e8892c431 100644 --- a/java/com/android/dialer/speeddial/loader/SpeedDialUiItemMutator.java +++ b/java/com/android/dialer/speeddial/loader/SpeedDialUiItemMutator.java @@ -54,6 +54,7 @@ import com.google.common.util.concurrent.ListeningExecutorService; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import javax.inject.Inject; import javax.inject.Singleton; @@ -108,6 +109,85 @@ public final class SpeedDialUiItemMutator { return dialerFutureSerializer.submit(this::loadSpeedDialUiItemsInternal, backgroundExecutor); } + /** + * Delete the SpeedDialUiItem. + * + *

If the item is starred, it's entry will be removed from the SpeedDialEntry database. + * Additionally, if the contact only has one entry in the database, it will be unstarred. + * + *

If the item isn't starred, it's usage data will be deleted but the suggestion can come back + * if the user calls that contact again. + * + * @return the updated list of SpeedDialUiItems. + */ + public ListenableFuture> removeSpeedDialUiItem( + SpeedDialUiItem speedDialUiItem) { + return dialerFutureSerializer.submit( + () -> removeSpeedDialUiItemInternal(speedDialUiItem), backgroundExecutor); + } + + @WorkerThread + private ImmutableList removeSpeedDialUiItemInternal( + SpeedDialUiItem speedDialUiItem) { + Assert.isWorkerThread(); + if (speedDialUiItem.isStarred()) { + removeStarredSpeedDialUiItem(speedDialUiItem); + } else { + removeSuggestedSpeedDialUiItem(speedDialUiItem); + } + return loadSpeedDialUiItemsInternal(); + } + + /** + * Delete the SpeedDialEntry associated with the passed in SpeedDialUiItem. Additionally, if the + * entry being deleted is the only entry for that contact, unstar it in the cp2. + */ + @WorkerThread + private void removeStarredSpeedDialUiItem(SpeedDialUiItem speedDialUiItem) { + Assert.isWorkerThread(); + Assert.checkArgument(speedDialUiItem.isStarred()); + SpeedDialEntryDao db = getSpeedDialEntryDao(); + ImmutableList entries = db.getAllEntries(); + + SpeedDialEntry entryToDelete = null; + int entriesForTheSameContact = 0; + for (SpeedDialEntry entry : entries) { + if (entry.contactId() == speedDialUiItem.contactId()) { + entriesForTheSameContact++; + } + + if (Objects.equals(entry.id(), speedDialUiItem.speedDialEntryId())) { + Assert.checkArgument(entryToDelete == null); + entryToDelete = entry; + } + } + db.delete(ImmutableList.of(entryToDelete.id())); + if (entriesForTheSameContact == 1) { + unstarContact(speedDialUiItem); + } + } + + @WorkerThread + private void unstarContact(SpeedDialUiItem speedDialUiItem) { + Assert.isWorkerThread(); + ContentValues contentValues = new ContentValues(); + contentValues.put(Phone.STARRED, 0); + appContext + .getContentResolver() + .update( + Phone.CONTENT_URI, + contentValues, + Phone.CONTACT_ID + " = ?", + new String[] {Long.toString(speedDialUiItem.contactId())}); + } + + @WorkerThread + @SuppressWarnings("unused") + private void removeSuggestedSpeedDialUiItem(SpeedDialUiItem speedDialUiItem) { + Assert.isWorkerThread(); + // TODO(calderwoodra): remove strequent contact + } + /** * Takes a contact uri from {@link Phone#CONTENT_URI} and updates {@link Phone#STARRED} to be * true, if it isn't already or Inserts the contact into the {@link SpeedDialEntryDatabaseHelper} -- cgit v1.2.3