Merge changes I2c82e950,Ibb386e20

* changes:
  Use Dagger to get Duo instance in CallLogListItemViewHolder
  Add input dialog for simulator to use customized number.
diff --git a/java/com/android/dialer/app/DialtactsActivity.java b/java/com/android/dialer/app/DialtactsActivity.java
index cc3f81b..1a549ab 100644
--- a/java/com/android/dialer/app/DialtactsActivity.java
+++ b/java/com/android/dialer/app/DialtactsActivity.java
@@ -1737,7 +1737,7 @@
       Simulator simulator = SimulatorComponent.get(context).getSimulator();
       if (simulator.shouldShow()) {
         simulatorMenuItem.setVisible(true);
-        simulatorMenuItem.setActionProvider(simulator.getActionProvider(context));
+        simulatorMenuItem.setActionProvider(simulator.getActionProvider(DialtactsActivity.this));
       } else {
         simulatorMenuItem.setVisible(false);
       }
diff --git a/java/com/android/dialer/app/calllog/CallLogAdapter.java b/java/com/android/dialer/app/calllog/CallLogAdapter.java
index 0459519..f3d04d9 100644
--- a/java/com/android/dialer/app/calllog/CallLogAdapter.java
+++ b/java/com/android/dialer/app/calllog/CallLogAdapter.java
@@ -844,7 +844,6 @@
     // attempt to set the field properly in that case
     viewHolder.isCallComposerCapable = isCallComposerCapable(viewHolder.number);
     viewHolder.setDetailedPhoneDetails(callDetailsEntries);
-    viewHolder.duo = getDuo();
     final AsyncTask<Void, Void, Boolean> loadDataTask =
         new AsyncTask<Void, Void, Boolean>() {
           @Override
diff --git a/java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java b/java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java
index 922a086..0aa46c5 100644
--- a/java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java
+++ b/java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java
@@ -79,6 +79,7 @@
 import com.android.dialer.dialercontact.DialerContact;
 import com.android.dialer.dialercontact.SimDetails;
 import com.android.dialer.duo.Duo;
+import com.android.dialer.duo.DuoComponent;
 import com.android.dialer.duo.DuoConstants;
 import com.android.dialer.lettertile.LetterTileDrawable;
 import com.android.dialer.lettertile.LetterTileDrawable.ContactType;
@@ -231,7 +232,6 @@
   public boolean isSpam;
 
   public boolean isCallComposerCapable;
-  public Duo duo;
 
   private View.OnClickListener mExpandCollapseListener;
   private final OnActionModeStateChangedListener onActionModeStateChangedListener;
@@ -670,6 +670,7 @@
         videoCallButtonView.setVisibility(View.GONE);
         break;
       case CallbackAction.VOICE:
+        Duo duo = DuoComponent.get(mContext).getDuo();
         // For a voice call, set the secondary callback action to be an IMS video call if it is
         // available. Otherwise try to set it as a Duo call.
         if (CallUtil.isVideoEnabled(mContext)
@@ -776,7 +777,7 @@
   private boolean showDuoPrimaryButton() {
     return accountHandle != null
         && accountHandle.getComponentName().equals(DuoConstants.PHONE_ACCOUNT_COMPONENT_NAME)
-        && duo.isReachable(mContext, number);
+        && DuoComponent.get(mContext).getDuo().isReachable(mContext, number);
   }
 
   private static boolean hasDialableChar(CharSequence number) {
diff --git a/java/com/android/dialer/simulator/Simulator.java b/java/com/android/dialer/simulator/Simulator.java
index d75d10e..3931ae4 100644
--- a/java/com/android/dialer/simulator/Simulator.java
+++ b/java/com/android/dialer/simulator/Simulator.java
@@ -16,9 +16,10 @@
 
 package com.android.dialer.simulator;
 
-import android.content.Context;
 import android.support.annotation.IntDef;
 import android.support.annotation.Nullable;
+import android.support.annotation.StringDef;
+import android.support.v7.app.AppCompatActivity;
 import android.view.ActionProvider;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -28,7 +29,7 @@
 public interface Simulator {
   boolean shouldShow();
 
-  ActionProvider getActionProvider(Context context);
+  ActionProvider getActionProvider(AppCompatActivity activity);
 
   /** The type of conference to emulate. */
   // TODO(a bug): add VoLTE and CDMA conference call
@@ -55,6 +56,19 @@
   static final int ON_NEW_INCOMING_CONNECTION = 2;
   static final int ON_CONFERENCE = 3;
 
+  static final String CALLER_ID_PRESENTATION_TYPE = "caller_id_";
+
+  /** Bundle keys that are used in making fake call. */
+  @Retention(RetentionPolicy.SOURCE)
+  @StringDef({
+    IS_VOLTE,
+    PRESENTATION_CHOICE,
+  })
+  @interface BundleKey {}
+
+  public final String IS_VOLTE = "ISVOLTE";
+  public final String PRESENTATION_CHOICE = "PRESENTATIONCHOICE";
+
   /** Information about a connection event. */
   public static class Event {
     /** The type of connection event. */
diff --git a/java/com/android/dialer/simulator/impl/SimulatorConferenceCreator.java b/java/com/android/dialer/simulator/impl/SimulatorConferenceCreator.java
index 36c1995..2bfa982 100644
--- a/java/com/android/dialer/simulator/impl/SimulatorConferenceCreator.java
+++ b/java/com/android/dialer/simulator/impl/SimulatorConferenceCreator.java
@@ -92,7 +92,7 @@
   private void addConferenceCall(String number, Bundle extras) {
     switch (conferenceType) {
       case Simulator.CONFERENCE_TYPE_VOLTE:
-        extras.putBoolean("ISVOLTE", true);
+        extras.putBoolean(Simulator.IS_VOLTE, true);
         break;
       default:
         break;
diff --git a/java/com/android/dialer/simulator/impl/SimulatorConnection.java b/java/com/android/dialer/simulator/impl/SimulatorConnection.java
index 2a24d8f..d7427dd 100644
--- a/java/com/android/dialer/simulator/impl/SimulatorConnection.java
+++ b/java/com/android/dialer/simulator/impl/SimulatorConnection.java
@@ -23,6 +23,7 @@
 import android.telecom.VideoProfile;
 import com.android.dialer.common.Assert;
 import com.android.dialer.common.LogUtil;
+import com.android.dialer.simulator.Simulator;
 import com.android.dialer.simulator.Simulator.Event;
 import com.android.dialer.simulator.SimulatorComponent;
 import com.android.dialer.simulator.SimulatorConnectionsBank;
@@ -46,8 +47,12 @@
             | CAPABILITY_HOLD
             | CAPABILITY_CAN_UPGRADE_TO_VIDEO
             | CAPABILITY_DISCONNECT_FROM_CONFERENCE);
-    if (request.getExtras() != null && !request.getExtras().getBoolean("ISVOLTE")) {
-      setConnectionCapabilities(getConnectionCapabilities() | CAPABILITY_SEPARATE_FROM_CONFERENCE);
+
+    if (request.getExtras() != null) {
+      if (!request.getExtras().getBoolean(Simulator.IS_VOLTE)) {
+        setConnectionCapabilities(
+            getConnectionCapabilities() | CAPABILITY_SEPARATE_FROM_CONFERENCE);
+      }
     }
     setVideoProvider(new SimulatorVideoProvider(context, this));
     simulatorConnectionsBank = SimulatorComponent.get(context).getSimulatorConnectionsBank();
@@ -136,4 +141,6 @@
   public interface Listener {
     void onEvent(@NonNull SimulatorConnection connection, @NonNull Event event);
   }
+
+
 }
diff --git a/java/com/android/dialer/simulator/impl/SimulatorConnectionService.java b/java/com/android/dialer/simulator/impl/SimulatorConnectionService.java
index e6bf99f..a5fb20b 100644
--- a/java/com/android/dialer/simulator/impl/SimulatorConnectionService.java
+++ b/java/com/android/dialer/simulator/impl/SimulatorConnectionService.java
@@ -29,6 +29,7 @@
 import com.android.dialer.common.Assert;
 import com.android.dialer.common.LogUtil;
 import com.android.dialer.common.concurrent.ThreadUtil;
+import com.android.dialer.simulator.Simulator;
 import com.android.dialer.simulator.SimulatorComponent;
 import com.android.dialer.simulator.SimulatorConnectionsBank;
 import java.util.ArrayList;
@@ -80,10 +81,13 @@
       SimulatorSimCallManager.unregister(this);
       return null;
     }
-
     SimulatorConnection connection = new SimulatorConnection(this, request);
+    connection.setAddress(
+        request.getAddress(),
+        request
+            .getExtras()
+            .getInt(Simulator.PRESENTATION_CHOICE, TelecomManager.PRESENTATION_ALLOWED));
     connection.setDialing();
-    connection.setAddress(request.getAddress(), TelecomManager.PRESENTATION_ALLOWED);
     simulatorConnectionsBank.add(connection);
     ThreadUtil.postOnUiThread(
         () ->
@@ -109,10 +113,13 @@
       SimulatorSimCallManager.unregister(this);
       return null;
     }
-
     SimulatorConnection connection = new SimulatorConnection(this, request);
+    connection.setAddress(
+        getPhoneNumber(request),
+        request
+            .getExtras()
+            .getInt(Simulator.PRESENTATION_CHOICE, TelecomManager.PRESENTATION_ALLOWED));
     connection.setRinging();
-    connection.setAddress(getPhoneNumber(request), TelecomManager.PRESENTATION_ALLOWED);
     simulatorConnectionsBank.add(connection);
     ThreadUtil.postOnUiThread(
         () ->
@@ -138,11 +145,6 @@
     }
   }
 
-  private static Uri getPhoneNumber(ConnectionRequest request) {
-    String phoneNumber = request.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
-    return Uri.fromParts(PhoneAccount.SCHEME_TEL, phoneNumber, null);
-  }
-
   /** Callback used to notify listeners when a new connection has been added. */
   public interface Listener {
     void onNewOutgoingConnection(@NonNull SimulatorConnection connection);
@@ -152,4 +154,9 @@
     void onConference(
         @NonNull SimulatorConnection connection1, @NonNull SimulatorConnection connection2);
   }
+
+  private static Uri getPhoneNumber(ConnectionRequest request) {
+    String phoneNumber = request.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
+    return Uri.fromParts(PhoneAccount.SCHEME_TEL, phoneNumber, null);
+  }
 }
diff --git a/java/com/android/dialer/simulator/impl/SimulatorDialogFragment.java b/java/com/android/dialer/simulator/impl/SimulatorDialogFragment.java
new file mode 100644
index 0000000..f8403c7
--- /dev/null
+++ b/java/com/android/dialer/simulator/impl/SimulatorDialogFragment.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.dialer.simulator.impl;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.os.Bundle;
+import android.support.v4.app.DialogFragment;
+import android.telecom.TelecomManager;
+import android.widget.EditText;
+
+/** Holds dialog logic for creating different types of voice calls. */
+public final class SimulatorDialogFragment extends DialogFragment {
+
+  private final String[] callerIdPresentationItems = {
+    "ALLOWED", "PAYPHONE", "RESTRICTED", "UNKNOWN"
+  };
+  private int callerIdPresentationChoice;
+
+  private DialogCallback dialogCallback;
+
+  static SimulatorDialogFragment newInstance(DialogCallback dialogCallback) {
+    SimulatorDialogFragment fragment = new SimulatorDialogFragment();
+    fragment.setCallBack(dialogCallback);
+    return fragment;
+  }
+
+  public void setCallBack(DialogCallback dialogCallback) {
+    this.dialogCallback = dialogCallback;
+  }
+
+  @Override
+  public Dialog onCreateDialog(Bundle bundle) {
+    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+    final EditText input = new EditText(getActivity());
+    builder
+        .setTitle("Phone Number:")
+        .setView(input)
+        .setSingleChoiceItems(
+            callerIdPresentationItems,
+            0,
+            (dialog, id) -> {
+              switch (id) {
+                case 0:
+                  callerIdPresentationChoice = TelecomManager.PRESENTATION_ALLOWED;
+                  break;
+                case 1:
+                  callerIdPresentationChoice = TelecomManager.PRESENTATION_PAYPHONE;
+                  break;
+                case 2:
+                  callerIdPresentationChoice = TelecomManager.PRESENTATION_RESTRICTED;
+                  break;
+                case 3:
+                  callerIdPresentationChoice = TelecomManager.PRESENTATION_UNKNOWN;
+                  break;
+                default:
+                  throw new IllegalStateException("Unknown presentation choice selected!");
+              }
+            })
+        .setPositiveButton(
+            R.string.call,
+            (dialog, id) -> {
+              dialogCallback.createCustomizedCall(
+                  input.getText().toString(), callerIdPresentationChoice);
+              dialog.cancel();
+              SimulatorDialogFragment.this.dismiss();
+            });
+    AlertDialog dialog = builder.create();
+    dialog.show();
+    return dialog;
+  }
+
+  /** Callback for after clicking enter button on dialog. */
+  public interface DialogCallback {
+    void createCustomizedCall(String callerId, int callerIdPresentation);
+  }
+}
diff --git a/java/com/android/dialer/simulator/impl/SimulatorImpl.java b/java/com/android/dialer/simulator/impl/SimulatorImpl.java
index d6ee5ef..41c234b 100644
--- a/java/com/android/dialer/simulator/impl/SimulatorImpl.java
+++ b/java/com/android/dialer/simulator/impl/SimulatorImpl.java
@@ -16,7 +16,7 @@
 
 package com.android.dialer.simulator.impl;
 
-import android.content.Context;
+import android.support.v7.app.AppCompatActivity;
 import android.view.ActionProvider;
 import com.android.dialer.buildtype.BuildType;
 import com.android.dialer.common.LogUtil;
@@ -34,7 +34,7 @@
   }
 
   @Override
-  public ActionProvider getActionProvider(Context context) {
-    return SimulatorMainMenu.getActionProvider(context);
+  public ActionProvider getActionProvider(AppCompatActivity activity) {
+    return SimulatorMainMenu.getActionProvider(activity);
   }
 }
diff --git a/java/com/android/dialer/simulator/impl/SimulatorMainMenu.java b/java/com/android/dialer/simulator/impl/SimulatorMainMenu.java
index 6053a0d..6ec30f6 100644
--- a/java/com/android/dialer/simulator/impl/SimulatorMainMenu.java
+++ b/java/com/android/dialer/simulator/impl/SimulatorMainMenu.java
@@ -21,6 +21,7 @@
 import android.provider.VoicemailContract;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.v7.app.AppCompatActivity;
 import android.view.ActionProvider;
 import com.android.dialer.common.concurrent.DialerExecutor.Worker;
 import com.android.dialer.common.concurrent.DialerExecutorComponent;
@@ -34,20 +35,26 @@
 /** Implements the top level simulator menu. */
 final class SimulatorMainMenu {
 
-  static ActionProvider getActionProvider(@NonNull Context context) {
-    return new SimulatorSubMenu(context)
-        .addItem("Voice call", SimulatorVoiceCall.getActionProvider(context))
-        .addItem("IMS video", SimulatorVideoCall.getActionProvider(context))
-        .addItem("Notifications", SimulatorNotifications.getActionProvider(context))
-        .addItem("Populate database", () -> populateDatabase(context))
-        .addItem("Fast populate database", () -> fastPopulateDatabase(context))
-        .addItem("Clean database", () -> cleanDatabase(context))
-        .addItem("clear preferred SIM", () -> clearPreferredSim(context))
-        .addItem("Sync voicemail", () -> syncVoicemail(context))
-        .addItem("Share persistent log", () -> sharePersistentLog(context))
+  static ActionProvider getActionProvider(@NonNull AppCompatActivity activity) {
+    return new SimulatorSubMenu(activity.getApplicationContext())
+        .addItem("Voice call", SimulatorVoiceCall.getActionProvider(activity))
+        .addItem(
+            "IMS video", SimulatorVideoCall.getActionProvider(activity.getApplicationContext()))
+        .addItem(
+            "Notifications",
+            SimulatorNotifications.getActionProvider(activity.getApplicationContext()))
+        .addItem("Populate database", () -> populateDatabase(activity.getApplicationContext()))
+        .addItem(
+            "Fast populate database", () -> fastPopulateDatabase(activity.getApplicationContext()))
+        .addItem("Clean database", () -> cleanDatabase(activity.getApplicationContext()))
+        .addItem("clear preferred SIM", () -> clearPreferredSim(activity.getApplicationContext()))
+        .addItem("Sync voicemail", () -> syncVoicemail(activity.getApplicationContext()))
+        .addItem("Share persistent log", () -> sharePersistentLog(activity.getApplicationContext()))
         .addItem(
             "Enriched call simulator",
-            () -> context.startActivity(EnrichedCallSimulatorActivity.newIntent(context)));
+            () ->
+                activity.startActivity(
+                    EnrichedCallSimulatorActivity.newIntent(activity.getApplicationContext())));
   }
 
   private static void populateDatabase(@NonNull Context context) {
diff --git a/java/com/android/dialer/simulator/impl/SimulatorVoiceCall.java b/java/com/android/dialer/simulator/impl/SimulatorVoiceCall.java
index 9ffcfc8..89c5d2f 100644
--- a/java/com/android/dialer/simulator/impl/SimulatorVoiceCall.java
+++ b/java/com/android/dialer/simulator/impl/SimulatorVoiceCall.java
@@ -17,8 +17,10 @@
 package com.android.dialer.simulator.impl;
 
 import android.content.Context;
+import android.os.Bundle;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.v7.app.AppCompatActivity;
 import android.telecom.Connection;
 import android.telecom.DisconnectCause;
 import android.view.ActionProvider;
@@ -34,20 +36,43 @@
   @NonNull private final Context context;
   @Nullable private String connectionTag;
 
-  static ActionProvider getActionProvider(@NonNull Context context) {
-    return new SimulatorSubMenu(context)
-        .addItem("Incoming call", () -> new SimulatorVoiceCall(context).addNewIncomingCall(false))
-        .addItem("Outgoing call", () -> new SimulatorVoiceCall(context).addNewOutgoingCall())
-        .addItem("Spam call", () -> new SimulatorVoiceCall(context).addNewIncomingCall(true))
+  static ActionProvider getActionProvider(@NonNull AppCompatActivity activity) {
+    return new SimulatorSubMenu(activity.getApplicationContext())
         .addItem(
-            "Emergency call back", () -> new SimulatorVoiceCall(context).addNewEmergencyCallBack())
+            "Incoming call",
+            () -> new SimulatorVoiceCall(activity.getApplicationContext()).addNewIncomingCall())
+        .addItem(
+            "Outgoing call",
+            () -> new SimulatorVoiceCall(activity.getApplicationContext()).addNewOutgoingCall())
+        .addItem(
+            "Customized incoming call",
+            () ->
+                new SimulatorVoiceCall(activity.getApplicationContext())
+                    .addNewIncomingCall(activity))
+        .addItem(
+            "Customized outgoing call",
+            () ->
+                new SimulatorVoiceCall(activity.getApplicationContext())
+                    .addNewOutgoingCall(activity))
+        .addItem(
+            "Spam incoming call",
+            () -> new SimulatorVoiceCall(activity.getApplicationContext()).addSpamIncomingCall())
+        .addItem(
+            "Emergency call back",
+            () ->
+                new SimulatorVoiceCall(activity.getApplicationContext()).addNewEmergencyCallBack())
         .addItem(
             "GSM conference",
-            () -> new SimulatorConferenceCreator(context, Simulator.CONFERENCE_TYPE_GSM).start(5))
+            () ->
+                new SimulatorConferenceCreator(
+                        activity.getApplicationContext(), Simulator.CONFERENCE_TYPE_GSM)
+                    .start(5))
         .addItem(
             "VoLTE conference",
             () ->
-                new SimulatorConferenceCreator(context, Simulator.CONFERENCE_TYPE_VOLTE).start(5));
+                new SimulatorConferenceCreator(
+                        activity.getApplicationContext(), Simulator.CONFERENCE_TYPE_VOLTE)
+                    .start(5));
   }
 
   private SimulatorVoiceCall(@NonNull Context context) {
@@ -57,11 +82,8 @@
         new SimulatorConferenceCreator(context, Simulator.CONFERENCE_TYPE_GSM));
   }
 
-  private void addNewIncomingCall(boolean isSpam) {
-    String callerId =
-        isSpam
-            ? "+1-661-778-3020" /* Blacklisted custom spam number */
-            : "+44 (0) 20 7031 3000" /* Google London office */;
+  private void addNewIncomingCall() {
+    String callerId = "+44 (0) 20 7031 3000" /* Google London office */;
     connectionTag =
         SimulatorSimCallManager.addNewIncomingCall(context, callerId, false /* isVideo */);
   }
@@ -72,6 +94,35 @@
         SimulatorSimCallManager.addNewOutgoingCall(context, callerId, false /* isVideo */);
   }
 
+  private void addNewIncomingCall(AppCompatActivity activity) {
+    SimulatorDialogFragment.newInstance(
+            (callerId, callerIdPresentation) -> {
+              Bundle extras = new Bundle();
+              extras.putInt(Simulator.PRESENTATION_CHOICE, callerIdPresentation);
+              connectionTag =
+                  SimulatorSimCallManager.addNewIncomingCall(
+                      context, callerId, false /* isVideo */, extras);
+            })
+        .show(activity.getSupportFragmentManager(), "SimulatorDialog");
+  }
+
+  private void addNewOutgoingCall(AppCompatActivity activity) {
+    SimulatorDialogFragment.newInstance(
+            (callerId, callerIdPresentation) -> {
+              Bundle extras = new Bundle();
+              extras.putInt(Simulator.PRESENTATION_CHOICE, callerIdPresentation);
+              connectionTag =
+                  SimulatorSimCallManager.addNewOutgoingCall(
+                      context, callerId, false /* isVideo */, extras);
+            })
+        .show(activity.getSupportFragmentManager(), "SimulatorDialog");
+  }
+
+  private void addSpamIncomingCall() {
+    String callerId = "+1-661-778-3020"; /* Blacklisted custom spam number */
+    SimulatorSimCallManager.addNewIncomingCall(context, callerId, false /* isVideo */);
+  }
+
   private void addNewEmergencyCallBack() {
     String callerId = "911";
     connectionTag = SimulatorSimCallManager.addNewIncomingCall(context, callerId, false);
@@ -141,4 +192,8 @@
         break;
     }
   }
+
+  private interface DialogCallback {
+    void callback(String callerId, int callerIdPresentation);
+  }
 }