diff options
author | calderwoodra <calderwoodra@google.com> | 2018-04-19 11:50:09 -0700 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-04-19 12:25:11 -0700 |
commit | 7c6d4125661f20e9ba57c30b8c6873f4ed4038ba (patch) | |
tree | 80f66b588998c2d6e73c6098d1ac5439c9be2f68 | |
parent | 455f0efd3c2c8ee682c5781fd4f13738f30d034e (diff) |
Implement remember this choice in SpeedDialEntry database.
In order to connect SpeedDialUiItems to the correct SpeedDialEntry in the
database, we need to pipe the entry ID throgh to the UI item. So this
change includes the logic to pipe the id as well.
Bug: 36841782,77760800
Test: DisambigDialogTest
PiperOrigin-RevId: 193550938
Change-Id: I6ec64d0aec7f85d36555707a54953bfdff938bb5
6 files changed, 109 insertions, 12 deletions
diff --git a/java/com/android/dialer/speeddial/DisambigDialog.java b/java/com/android/dialer/speeddial/DisambigDialog.java index 6f7403a21..0d29a9c84 100644 --- a/java/com/android/dialer/speeddial/DisambigDialog.java +++ b/java/com/android/dialer/speeddial/DisambigDialog.java @@ -17,42 +17,59 @@ package com.android.dialer.speeddial; import android.app.Dialog; +import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.support.annotation.VisibleForTesting; +import android.support.annotation.WorkerThread; import android.support.v4.app.DialogFragment; import android.support.v4.app.FragmentManager; import android.support.v7.app.AlertDialog; import android.util.ArraySet; import android.view.LayoutInflater; import android.view.View; +import android.widget.CheckBox; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import com.android.dialer.callintent.CallInitiationType; import com.android.dialer.callintent.CallIntentBuilder; +import com.android.dialer.common.Assert; +import com.android.dialer.common.LogUtil; +import com.android.dialer.common.concurrent.DefaultFutureCallback; +import com.android.dialer.common.concurrent.DialerExecutorComponent; import com.android.dialer.constants.ActivityRequestCodes; import com.android.dialer.duo.DuoComponent; import com.android.dialer.logging.DialerImpression; import com.android.dialer.logging.Logger; import com.android.dialer.precall.PreCall; +import com.android.dialer.speeddial.database.SpeedDialEntry; import com.android.dialer.speeddial.database.SpeedDialEntry.Channel; +import com.android.dialer.speeddial.database.SpeedDialEntryDatabaseHelper; +import com.android.dialer.speeddial.loader.SpeedDialUiItem; +import com.google.common.collect.ImmutableList; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; import java.util.List; import java.util.Set; /** Disambiguation dialog for favorite contacts in {@link SpeedDialFragment}. */ public class DisambigDialog extends DialogFragment { + @VisibleForTesting public static final String FRAGMENT_TAG = "disambig_dialog"; private final Set<String> phoneNumbers = new ArraySet<>(); + private SpeedDialUiItem speedDialUiItem; @VisibleForTesting public List<Channel> channels; @VisibleForTesting public LinearLayout container; + private CheckBox rememberThisChoice; /** Show a disambiguation dialog for a starred contact without a favorite communication avenue. */ - public static DisambigDialog show(List<Channel> channels, FragmentManager manager) { + public static DisambigDialog show(SpeedDialUiItem speedDialUiItem, FragmentManager manager) { DisambigDialog dialog = new DisambigDialog(); - dialog.channels = channels; - dialog.show(manager, null); + dialog.speedDialUiItem = speedDialUiItem; + dialog.channels = speedDialUiItem.channels(); + dialog.show(manager, FRAGMENT_TAG); return dialog; } @@ -62,6 +79,7 @@ public class DisambigDialog extends DialogFragment { // TODO(calderwoodra): set max height of the scrollview. Might need to override onMeasure. View view = inflater.inflate(R.layout.disambig_dialog_layout, null, false); container = view.findViewById(R.id.communication_avenue_container); + rememberThisChoice = view.findViewById(R.id.remember_this_choice_checkbox); insertOptions(container.findViewById(R.id.communication_avenue_container), channels); return new AlertDialog.Builder(getActivity()).setView(view).create(); } @@ -132,7 +150,10 @@ public class DisambigDialog extends DialogFragment { } private void onVideoOptionClicked(Channel channel) { - // TODO(calderwoodra): save this option if remember is checked + if (rememberThisChoice.isChecked()) { + setDefaultChannel(getContext().getApplicationContext(), speedDialUiItem, channel); + } + if (channel.technology() == Channel.DUO) { Logger.get(getContext()) .logImpression( @@ -151,9 +172,42 @@ public class DisambigDialog extends DialogFragment { } private void onVoiceOptionClicked(Channel channel) { - // TODO(calderwoodra): save this option if remember is checked + if (rememberThisChoice.isChecked()) { + setDefaultChannel(getContext().getApplicationContext(), speedDialUiItem, channel); + } + PreCall.start( getContext(), new CallIntentBuilder(channel.number(), CallInitiationType.Type.SPEED_DIAL)); dismiss(); } + + private static void setDefaultChannel(Context appContext, SpeedDialUiItem item, Channel channel) { + LogUtil.enterBlock("DisambigDialog.setDefaultChannel"); + ListenableFuture<Void> future = + DialerExecutorComponent.get(appContext) + .backgroundExecutor() + .submit( + () -> { + updateDatabaseEntry(appContext, item, channel); + return null; + }); + Futures.addCallback( + future, + new DefaultFutureCallback<>(), + DialerExecutorComponent.get(appContext).backgroundExecutor()); + } + + @WorkerThread + private static void updateDatabaseEntry( + Context appContext, SpeedDialUiItem item, Channel channel) { + Assert.isWorkerThread(); + SpeedDialEntry entry = + SpeedDialEntry.builder() + .setId(item.speedDialEntryId()) + .setContactId(item.contactId()) + .setLookupKey(item.lookupKey()) + .setDefaultChannel(channel) + .build(); + new SpeedDialEntryDatabaseHelper(appContext).update(ImmutableList.of(entry)); + } } diff --git a/java/com/android/dialer/speeddial/FavoritesViewHolder.java b/java/com/android/dialer/speeddial/FavoritesViewHolder.java index 56d9f36d9..474516ef2 100644 --- a/java/com/android/dialer/speeddial/FavoritesViewHolder.java +++ b/java/com/android/dialer/speeddial/FavoritesViewHolder.java @@ -34,7 +34,6 @@ import com.android.dialer.speeddial.database.SpeedDialEntry.Channel; import com.android.dialer.speeddial.draghelper.SpeedDialFavoritesViewHolderOnTouchListener; import com.android.dialer.speeddial.draghelper.SpeedDialFavoritesViewHolderOnTouchListener.OnTouchFinishCallback; import com.android.dialer.speeddial.loader.SpeedDialUiItem; -import java.util.List; /** ViewHolder for starred/favorite contacts in {@link SpeedDialFragment}. */ public class FavoritesViewHolder extends RecyclerView.ViewHolder @@ -97,7 +96,7 @@ public class FavoritesViewHolder extends RecyclerView.ViewHolder if (speedDialUiItem.defaultChannel() != null) { listener.onClick(speedDialUiItem.defaultChannel()); } else { - listener.onAmbiguousContactClicked(speedDialUiItem.channels()); + listener.onAmbiguousContactClicked(speedDialUiItem); } } @@ -117,7 +116,7 @@ public class FavoritesViewHolder extends RecyclerView.ViewHolder public interface FavoriteContactsListener { /** Called when the user clicks on a favorite contact that doesn't have a default number. */ - void onAmbiguousContactClicked(List<Channel> channels); + void onAmbiguousContactClicked(SpeedDialUiItem speedDialUiItem); /** Called when the user clicks on a favorite contact. */ void onClick(Channel channel); diff --git a/java/com/android/dialer/speeddial/SpeedDialFragment.java b/java/com/android/dialer/speeddial/SpeedDialFragment.java index 52d7b7fc9..c45ec5856 100644 --- a/java/com/android/dialer/speeddial/SpeedDialFragment.java +++ b/java/com/android/dialer/speeddial/SpeedDialFragment.java @@ -48,7 +48,6 @@ import com.android.dialer.speeddial.draghelper.SpeedDialLayoutManager; import com.android.dialer.speeddial.loader.SpeedDialUiItem; import com.android.dialer.speeddial.loader.UiItemLoaderComponent; import com.google.common.collect.ImmutableList; -import java.util.List; /** * Fragment for displaying: @@ -185,8 +184,8 @@ public class SpeedDialFragment extends Fragment { private final class SpeedDialFavoritesListener implements FavoriteContactsListener { @Override - public void onAmbiguousContactClicked(List<Channel> channels) { - DisambigDialog.show(channels, getChildFragmentManager()); + public void onAmbiguousContactClicked(SpeedDialUiItem speedDialUiItem) { + DisambigDialog.show(speedDialUiItem, getChildFragmentManager()); } @Override diff --git a/java/com/android/dialer/speeddial/loader/SpeedDialUiItem.java b/java/com/android/dialer/speeddial/loader/SpeedDialUiItem.java index 28c22747e..65aa297f0 100644 --- a/java/com/android/dialer/speeddial/loader/SpeedDialUiItem.java +++ b/java/com/android/dialer/speeddial/loader/SpeedDialUiItem.java @@ -118,6 +118,15 @@ public abstract class SpeedDialUiItem { return builder.build(); } + /** + * The id of the corresponding SpeedDialEntry. Null if the UI item does not have an entry, for + * example suggested contacts (isStarred() will also be false) + * + * @see SpeedDialEntry#id() + */ + @Nullable + public abstract Long speedDialEntryId(); + /** @see android.provider.ContactsContract.Contacts#DISPLAY_NAME */ public abstract String name(); @@ -158,6 +167,9 @@ public abstract class SpeedDialUiItem { @AutoValue.Builder public abstract static class Builder { + /** Set to null if {@link #isStarred()} is false. */ + public abstract Builder setSpeedDialEntryId(@Nullable Long id); + 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/SpeedDialUiItemLoader.java index 9ea84eca2..955793d72 100644 --- a/java/com/android/dialer/speeddial/loader/SpeedDialUiItemLoader.java +++ b/java/com/android/dialer/speeddial/loader/SpeedDialUiItemLoader.java @@ -303,11 +303,24 @@ 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. + SpeedDialUiItem.Builder entrySpeedDialItem = + item.toBuilder().setSpeedDialEntryId(entry.id()); + + // Preserve the default channel if it didn't change/still exists + Channel defaultChannel = entry.defaultChannel(); + if (defaultChannel != null) { + if (item.channels().contains(defaultChannel) + || isValidDuoDefaultChannel(item.channels(), defaultChannel)) { + entrySpeedDialItem.setDefaultChannel(defaultChannel); + } + } + // It's impossible for two contacts to exist with the same contact id, so if this entry // was previously matched to a SpeedDialUiItem and is being matched again, something // went horribly wrong. Assert.checkArgument( - map.put(entry, item) == null, + map.put(entry, entrySpeedDialItem.build()) == null, "Each SpeedDialEntry only has one correct SpeedDialUiItem"); } } @@ -321,6 +334,25 @@ public final class SpeedDialUiItemLoader { } } + /** + * Since we can't check duo reachabliity on background threads, we have to assume the contact is + * still duo reachable. So we just check it is and return true if the Duo number is still + * associated with the contact. + */ + private static boolean isValidDuoDefaultChannel( + ImmutableList<Channel> channels, Channel defaultChannel) { + if (defaultChannel.technology() != Channel.DUO) { + return false; + } + + for (Channel channel : channels) { + if (channel.number().equals(defaultChannel.number())) { + return true; + } + } + return false; + } + @WorkerThread private List<SpeedDialUiItem> getStrequentContacts() { Assert.isWorkerThread(); diff --git a/java/com/android/dialer/speeddial/res/layout/disambig_dialog_layout.xml b/java/com/android/dialer/speeddial/res/layout/disambig_dialog_layout.xml index 356205805..ba7b8052e 100644 --- a/java/com/android/dialer/speeddial/res/layout/disambig_dialog_layout.xml +++ b/java/com/android/dialer/speeddial/res/layout/disambig_dialog_layout.xml @@ -61,6 +61,7 @@ android:id="@+id/remember_this_choice_checkbox" android:layout_width="match_parent" android:layout_height="wrap_content" + android:minHeight="48dp" android:text="@string/speed_dial_remember_this_choice"/> </FrameLayout> </LinearLayout>
\ No newline at end of file |