Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5ccde90a authored by calderwoodra's avatar calderwoodra Committed by Copybara-Service
Browse files

Added duo channels to favorite contacts and duo suggestions.

Bug: 36841782,77724710,77760800
Test: SpeedDialUiItemLoaderTest
PiperOrigin-RevId: 193432314
Change-Id: If9e0aa05b1aeb266960281ac13218091882ff4c3
parent 136a888e
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -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;
  }
}
+15 −1
Original line number Diff line number Diff line
@@ -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)
+31 −5
Original line number Diff line number Diff line
@@ -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()));
    }
  }

+9 −6
Original line number Diff line number Diff line
@@ -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);
  }
}
+72 −0
Original line number Diff line number Diff line
@@ -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<SpeedDialUiItem> insertDuoChannels(
      Context context, ImmutableList<SpeedDialUiItem> speedDialUiItems) {
    Assert.isMainThread();

    Duo duo = DuoComponent.get(context).getDuo();
    int maxDuoSuggestions = MAX_DUO_SUGGESTIONS;

    ImmutableList.Builder<SpeedDialUiItem> 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<Channel> 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();
  }
}