From 5ccde90a5bb1d5bebc97de2baa9c72fff7cb1342 Mon Sep 17 00:00:00 2001 From: calderwoodra Date: Wed, 18 Apr 2018 16:00:07 -0700 Subject: Added duo channels to favorite contacts and duo suggestions. Bug: 36841782,77724710,77760800 Test: SpeedDialUiItemLoaderTest PiperOrigin-RevId: 193432314 Change-Id: If9e0aa05b1aeb266960281ac13218091882ff4c3 --- .../android/dialer/logging/dialer_impression.proto | 7 ++- .../android/dialer/speeddial/DisambigDialog.java | 16 ++++- .../dialer/speeddial/SpeedDialFragment.java | 36 +++++++++-- .../dialer/speeddial/SuggestionViewHolder.java | 15 +++-- .../speeddial/loader/SpeedDialUiItemLoader.java | 72 ++++++++++++++++++++++ 5 files changed, 133 insertions(+), 13 deletions(-) diff --git a/java/com/android/dialer/logging/dialer_impression.proto b/java/com/android/dialer/logging/dialer_impression.proto index a0e36f35e..cc65bf9ed 100644 --- a/java/com/android/dialer/logging/dialer_impression.proto +++ b/java/com/android/dialer/logging/dialer_impression.proto @@ -12,7 +12,7 @@ message DialerImpression { // Event enums to be used for Impression Logging in Dialer. // It's perfectly acceptable for this enum to be large // Values should be from 1000 to 100000. - // Next Tag: 1376 + // Next Tag: 1379 enum Type { UNKNOWN_AOSP_EVENT_TYPE = 1000; @@ -741,5 +741,10 @@ message DialerImpression { TOKEN_FETCHER_CLEAR_EXCEPTION = 1374; PEOPLE_API_LOOKUP_FAILED = 1375; + + // New Speed Dial impressions + LIGHTBRINGER_VIDEO_REQUESTED_FOR_FAVORITE_CONTACT = 1376; + LIGHTBRINGER_VIDEO_REQUESTED_FOR_SUGGESTED_CONTACT = 1377; + LIGHTBRINGER_VIDEO_REQUESTED_FOR_FAVORITE_CONTACT_DISAMBIG = 1378; } } diff --git a/java/com/android/dialer/speeddial/DisambigDialog.java b/java/com/android/dialer/speeddial/DisambigDialog.java index 2a8200274..6f7403a21 100644 --- a/java/com/android/dialer/speeddial/DisambigDialog.java +++ b/java/com/android/dialer/speeddial/DisambigDialog.java @@ -17,6 +17,7 @@ package com.android.dialer.speeddial; import android.app.Dialog; +import android.content.Intent; import android.os.Bundle; import android.support.annotation.VisibleForTesting; import android.support.v4.app.DialogFragment; @@ -30,6 +31,10 @@ import android.widget.LinearLayout; import android.widget.TextView; import com.android.dialer.callintent.CallInitiationType; import com.android.dialer.callintent.CallIntentBuilder; +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.Channel; import java.util.List; @@ -128,7 +133,16 @@ public class DisambigDialog extends DialogFragment { private void onVideoOptionClicked(Channel channel) { // TODO(calderwoodra): save this option if remember is checked - // TODO(calderwoodra): place a duo call if possible + if (channel.technology() == Channel.DUO) { + Logger.get(getContext()) + .logImpression( + DialerImpression.Type.LIGHTBRINGER_VIDEO_REQUESTED_FOR_FAVORITE_CONTACT_DISAMBIG); + Intent intent = + DuoComponent.get(getContext()).getDuo().getIntent(getContext(), channel.number()); + getActivity().startActivityForResult(intent, ActivityRequestCodes.DIALTACTS_DUO); + return; + } + PreCall.start( getContext(), new CallIntentBuilder(channel.number(), CallInitiationType.Type.SPEED_DIAL) diff --git a/java/com/android/dialer/speeddial/SpeedDialFragment.java b/java/com/android/dialer/speeddial/SpeedDialFragment.java index b58d4abf4..004588ef4 100644 --- a/java/com/android/dialer/speeddial/SpeedDialFragment.java +++ b/java/com/android/dialer/speeddial/SpeedDialFragment.java @@ -31,6 +31,10 @@ import com.android.dialer.callintent.CallIntentBuilder; import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.DialerExecutorComponent; import com.android.dialer.common.concurrent.SupportUiListener; +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.ContextMenu.ContextMenuItemListener; import com.android.dialer.speeddial.FavoritesViewHolder.FavoriteContactsListener; @@ -123,7 +127,10 @@ public class SpeedDialFragment extends Fragment { getContext(), UiItemLoaderComponent.get(getContext()).speedDialUiItemLoader().loadSpeedDialUiItems(), speedDialUiItems -> { - adapter.setSpeedDialUiItems(speedDialUiItems); + adapter.setSpeedDialUiItems( + UiItemLoaderComponent.get(getContext()) + .speedDialUiItemLoader() + .insertDuoChannels(getContext(), speedDialUiItems)); adapter.notifyDataSetChanged(); }, throwable -> { @@ -148,7 +155,15 @@ public class SpeedDialFragment extends Fragment { @Override public void onClick(Channel channel) { - // TODO(calderwoodra): add logic for duo video calls + if (channel.technology() == Channel.DUO) { + Logger.get(getContext()) + .logImpression(DialerImpression.Type.LIGHTBRINGER_VIDEO_REQUESTED_FOR_FAVORITE_CONTACT); + Intent intent = + DuoComponent.get(getContext()).getDuo().getIntent(getContext(), channel.number()); + getActivity().startActivityForResult(intent, ActivityRequestCodes.DIALTACTS_DUO); + return; + } + PreCall.start( getContext(), new CallIntentBuilder(channel.number(), CallInitiationType.Type.SPEED_DIAL) @@ -181,14 +196,25 @@ public class SpeedDialFragment extends Fragment { private final class SpeedDialSuggestedListener implements SuggestedContactsListener { @Override - public void onOverFlowMenuClicked(String number) { + public void onOverFlowMenuClicked(SpeedDialUiItem speedDialUiItem) { // TODO(calderwoodra) show overflow menu for suggested contacts } @Override - public void onRowClicked(String number) { + public void onRowClicked(Channel channel) { + if (channel.technology() == Channel.DUO) { + Logger.get(getContext()) + .logImpression( + DialerImpression.Type.LIGHTBRINGER_VIDEO_REQUESTED_FOR_SUGGESTED_CONTACT); + Intent intent = + DuoComponent.get(getContext()).getDuo().getIntent(getContext(), channel.number()); + getActivity().startActivityForResult(intent, ActivityRequestCodes.DIALTACTS_DUO); + return; + } PreCall.start( - getContext(), new CallIntentBuilder(number, CallInitiationType.Type.SPEED_DIAL)); + getContext(), + new CallIntentBuilder(channel.number(), CallInitiationType.Type.SPEED_DIAL) + .setIsVideoCall(channel.isVideoTechnology())); } } diff --git a/java/com/android/dialer/speeddial/SuggestionViewHolder.java b/java/com/android/dialer/speeddial/SuggestionViewHolder.java index 9e4c81de8..546ffbdff 100644 --- a/java/com/android/dialer/speeddial/SuggestionViewHolder.java +++ b/java/com/android/dialer/speeddial/SuggestionViewHolder.java @@ -29,6 +29,7 @@ import com.android.dialer.glidephotomanager.GlidePhotoManagerComponent; import com.android.dialer.glidephotomanager.PhotoInfo; import com.android.dialer.location.GeoUtil; import com.android.dialer.phonenumberutil.PhoneNumberHelper; +import com.android.dialer.speeddial.database.SpeedDialEntry.Channel; import com.android.dialer.speeddial.loader.SpeedDialUiItem; /** ViewHolder for displaying suggested contacts in {@link SpeedDialFragment}. */ @@ -40,7 +41,7 @@ public class SuggestionViewHolder extends RecyclerView.ViewHolder implements OnC private final TextView nameOrNumberView; private final TextView numberView; - private String number; + private SpeedDialUiItem speedDialUiItem; SuggestionViewHolder(View view, SuggestedContactsListener listener) { super(view); @@ -54,7 +55,8 @@ public class SuggestionViewHolder extends RecyclerView.ViewHolder implements OnC public void bind(Context context, SpeedDialUiItem speedDialUiItem) { Assert.isNotNull(speedDialUiItem.defaultChannel()); - number = + this.speedDialUiItem = speedDialUiItem; + String number = PhoneNumberHelper.formatNumber( context, speedDialUiItem.defaultChannel().number(), @@ -77,6 +79,7 @@ public class SuggestionViewHolder extends RecyclerView.ViewHolder implements OnC .setPhotoId(speedDialUiItem.photoId()) .setPhotoUri(speedDialUiItem.photoUri()) .setName(speedDialUiItem.name()) + .setIsVideo(speedDialUiItem.defaultChannel().isVideoTechnology()) .setLookupUri( Contacts.getLookupUri(speedDialUiItem.contactId(), speedDialUiItem.lookupKey()) .toString()) @@ -86,18 +89,18 @@ public class SuggestionViewHolder extends RecyclerView.ViewHolder implements OnC @Override public void onClick(View v) { if (v.getId() == R.id.overflow) { - listener.onOverFlowMenuClicked(number); + listener.onOverFlowMenuClicked(speedDialUiItem); } else { - listener.onRowClicked(number); + listener.onRowClicked(speedDialUiItem.defaultChannel()); } } /** Listener/Callback for {@link SuggestionViewHolder} parents. */ public interface SuggestedContactsListener { - void onOverFlowMenuClicked(String number); + void onOverFlowMenuClicked(SpeedDialUiItem speedDialUiItem); /** Called when a suggested contact is clicked. */ - void onRowClicked(String number); + void onRowClicked(Channel channel); } } diff --git a/java/com/android/dialer/speeddial/loader/SpeedDialUiItemLoader.java b/java/com/android/dialer/speeddial/loader/SpeedDialUiItemLoader.java index 31494805f..9a027de71 100644 --- a/java/com/android/dialer/speeddial/loader/SpeedDialUiItemLoader.java +++ b/java/com/android/dialer/speeddial/loader/SpeedDialUiItemLoader.java @@ -24,6 +24,7 @@ import android.os.Build.VERSION_CODES; import android.provider.ContactsContract; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract.Contacts; +import android.support.annotation.MainThread; import android.support.annotation.WorkerThread; import android.util.ArrayMap; import android.util.ArraySet; @@ -33,8 +34,11 @@ import com.android.dialer.common.concurrent.Annotations.BackgroundExecutor; import com.android.dialer.common.concurrent.DialerExecutor.SuccessListener; import com.android.dialer.common.concurrent.DialerFutureSerializer; import com.android.dialer.common.database.Selection; +import com.android.dialer.duo.Duo; +import com.android.dialer.duo.DuoComponent; import com.android.dialer.inject.ApplicationContext; 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.collect.ImmutableList; @@ -72,6 +76,8 @@ import javax.inject.Singleton; @Singleton public final class SpeedDialUiItemLoader { + private static final int MAX_DUO_SUGGESTIONS = 3; + private final Context appContext; private final ListeningExecutorService backgroundExecutor; // Used to ensure that only one refresh flow runs at a time. @@ -320,4 +326,70 @@ public final class SpeedDialUiItemLoader { return contacts; } } + + /** + * Returns a new list with duo reachable channels inserted. Duo channels won't replace ViLTE + * channels. + */ + @MainThread + public ImmutableList insertDuoChannels( + Context context, ImmutableList speedDialUiItems) { + Assert.isMainThread(); + + Duo duo = DuoComponent.get(context).getDuo(); + int maxDuoSuggestions = MAX_DUO_SUGGESTIONS; + + ImmutableList.Builder newSpeedDialItemList = ImmutableList.builder(); + // for each existing item + for (SpeedDialUiItem item : speedDialUiItems) { + // If the item is a suggestion + if (!item.isStarred()) { + // And duo reachable, insert a duo suggestion + if (maxDuoSuggestions > 0 && duo.isReachable(context, item.defaultChannel().number())) { + maxDuoSuggestions--; + Channel defaultChannel = + item.defaultChannel().toBuilder().setTechnology(Channel.DUO).build(); + newSpeedDialItemList.add(item.toBuilder().setDefaultChannel(defaultChannel).build()); + } + // Insert the voice suggestion too + newSpeedDialItemList.add(item); + } else if (item.defaultChannel() == null) { + // If the contact is starred and doesn't have a default channel, insert duo channels + newSpeedDialItemList.add(insertDuoChannelsToStarredContact(context, item)); + } // if starred and has a default channel, leave it as is, the user knows what they want. + } + return newSpeedDialItemList.build(); + } + + @MainThread + private SpeedDialUiItem insertDuoChannelsToStarredContact(Context context, SpeedDialUiItem item) { + Assert.isMainThread(); + Assert.checkArgument(item.isStarred()); + + // build a new list of channels + ImmutableList.Builder newChannelsList = ImmutableList.builder(); + Channel previousChannel = item.channels().get(0); + newChannelsList.add(previousChannel); + + for (int i = 1; i < item.channels().size(); i++) { + Channel currentChannel = item.channels().get(i); + // If the previous and current channel are voice channels, that means the previous number + // didn't have a video channel. + // If the previous number is duo reachable, insert a duo channel. + if (!previousChannel.isVideoTechnology() + && !currentChannel.isVideoTechnology() + && DuoComponent.get(context).getDuo().isReachable(context, previousChannel.number())) { + newChannelsList.add(previousChannel.toBuilder().setTechnology(Channel.DUO).build()); + } + newChannelsList.add(currentChannel); + previousChannel = currentChannel; + } + + // Check the last channel + if (!previousChannel.isVideoTechnology() + && DuoComponent.get(context).getDuo().isReachable(context, previousChannel.number())) { + newChannelsList.add(previousChannel.toBuilder().setTechnology(Channel.DUO).build()); + } + return item.toBuilder().setChannels(newChannelsList.build()).build(); + } } -- cgit v1.2.3