Merge changes I220cb741,I471b2d19

* changes:
  Add "Set up" and "Invite" for video to call log entry actions
  Fix voicemail populator bug and change emergency call to emergency call back.
diff --git a/java/com/android/dialer/app/calllog/CallLogAdapter.java b/java/com/android/dialer/app/calllog/CallLogAdapter.java
index 4f78bc9..f456555 100644
--- a/java/com/android/dialer/app/calllog/CallLogAdapter.java
+++ b/java/com/android/dialer/app/calllog/CallLogAdapter.java
@@ -828,65 +828,65 @@
   }
 
   private void loadAndRender(
-      final CallLogListItemViewHolder views,
+      final CallLogListItemViewHolder viewHolder,
       final long rowId,
       final PhoneCallDetails details,
       final CallDetailsEntries callDetailsEntries) {
-    LogUtil.d("CallLogAdapter.loadAndRender", "position: %d", views.getAdapterPosition());
+    LogUtil.d("CallLogAdapter.loadAndRender", "position: %d", viewHolder.getAdapterPosition());
     // Reset block and spam information since this view could be reused which may contain
     // outdated data.
-    views.isSpam = false;
-    views.blockId = null;
-    views.isSpamFeatureEnabled = false;
+    viewHolder.isSpam = false;
+    viewHolder.blockId = null;
+    viewHolder.isSpamFeatureEnabled = false;
 
     // Attempt to set the isCallComposerCapable field. If capabilities are unknown for this number,
     // the value will be false while capabilities are requested. mExpandCollapseListener will
     // attempt to set the field properly in that case
-    views.isCallComposerCapable = isCallComposerCapable(views.number);
-    views.setDetailedPhoneDetails(callDetailsEntries);
-    views.duoReady = getDuo().isReachable(mActivity, views.number);
+    viewHolder.isCallComposerCapable = isCallComposerCapable(viewHolder.number);
+    viewHolder.setDetailedPhoneDetails(callDetailsEntries);
+    viewHolder.duo = getDuo();
     final AsyncTask<Void, Void, Boolean> loadDataTask =
         new AsyncTask<Void, Void, Boolean>() {
           @Override
           protected Boolean doInBackground(Void... params) {
-            views.blockId =
+            viewHolder.blockId =
                 mFilteredNumberAsyncQueryHandler.getBlockedIdSynchronous(
-                    views.number, views.countryIso);
-            details.isBlocked = views.blockId != null;
+                    viewHolder.number, viewHolder.countryIso);
+            details.isBlocked = viewHolder.blockId != null;
             if (isCancelled()) {
               return false;
             }
             if (mIsSpamEnabled) {
-              views.isSpamFeatureEnabled = true;
+              viewHolder.isSpamFeatureEnabled = true;
               // Only display the call as a spam call if there are incoming calls in the list.
               // Call log cards with only outgoing calls should never be displayed as spam.
-              views.isSpam =
+              viewHolder.isSpam =
                   details.hasIncomingCalls()
                       && Spam.get(mActivity)
-                          .checkSpamStatusSynchronous(views.number, views.countryIso);
-              details.isSpam = views.isSpam;
+                          .checkSpamStatusSynchronous(viewHolder.number, viewHolder.countryIso);
+              details.isSpam = viewHolder.isSpam;
             }
-            return !isCancelled() && loadData(views, rowId, details);
+            return !isCancelled() && loadData(viewHolder, rowId, details);
           }
 
           @Override
           protected void onPostExecute(Boolean success) {
-            views.isLoaded = true;
+            viewHolder.isLoaded = true;
             if (success) {
-              views.callbackAction = getCallbackAction(views.rowId);
-              int currentDayGroup = getDayGroup(views.rowId);
+              viewHolder.callbackAction = getCallbackAction(viewHolder.rowId);
+              int currentDayGroup = getDayGroup(viewHolder.rowId);
               if (currentDayGroup != details.previousGroup) {
-                views.dayGroupHeaderVisibility = View.VISIBLE;
-                views.dayGroupHeaderText = getGroupDescription(currentDayGroup);
+                viewHolder.dayGroupHeaderVisibility = View.VISIBLE;
+                viewHolder.dayGroupHeaderText = getGroupDescription(currentDayGroup);
               } else {
-                views.dayGroupHeaderVisibility = View.GONE;
+                viewHolder.dayGroupHeaderVisibility = View.GONE;
               }
-              render(views, details, rowId);
+              render(viewHolder, details, rowId);
             }
           }
         };
 
-    views.asyncTask = loadDataTask;
+    viewHolder.asyncTask = loadDataTask;
     mAsyncTaskExecutor.submit(LOAD_DATA_TASK_IDENTIFIER, loadDataTask);
   }
 
diff --git a/java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java b/java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java
index 26ca5bd..a5a0cff 100644
--- a/java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java
+++ b/java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java
@@ -78,6 +78,7 @@
 import com.android.dialer.contactphoto.ContactPhotoManager;
 import com.android.dialer.dialercontact.DialerContact;
 import com.android.dialer.dialercontact.SimDetails;
+import com.android.dialer.duo.Duo;
 import com.android.dialer.duo.DuoConstants;
 import com.android.dialer.lettertile.LetterTileDrawable;
 import com.android.dialer.lettertile.LetterTileDrawable.ContactType;
@@ -147,6 +148,8 @@
 
   public View callButtonView;
   public View videoCallButtonView;
+  public View setUpVideoButtonView;
+  public View inviteVideoButtonView;
   public View createNewContactButtonView;
   public View addToExistingContactButtonView;
   public View sendMessageView;
@@ -228,7 +231,7 @@
   public boolean isSpam;
 
   public boolean isCallComposerCapable;
-  public boolean duoReady;
+  public Duo duo;
 
   private View.OnClickListener mExpandCollapseListener;
   private final OnActionModeStateChangedListener onActionModeStateChangedListener;
@@ -466,6 +469,12 @@
       videoCallButtonView = actionsView.findViewById(R.id.video_call_action);
       videoCallButtonView.setOnClickListener(this);
 
+      setUpVideoButtonView = actionsView.findViewById(R.id.set_up_video_action);
+      setUpVideoButtonView.setOnClickListener(this);
+
+      inviteVideoButtonView = actionsView.findViewById(R.id.invite_video_action);
+      inviteVideoButtonView.setOnClickListener(this);
+
       createNewContactButtonView = actionsView.findViewById(R.id.create_new_contact_action);
       createNewContactButtonView.setOnClickListener(this);
 
@@ -593,6 +602,8 @@
     // This saves us having to remember to set it to GONE in multiple places.
     callButtonView.setVisibility(View.GONE);
     videoCallButtonView.setVisibility(View.GONE);
+    setUpVideoButtonView.setVisibility(View.GONE);
+    inviteVideoButtonView.setVisibility(View.GONE);
 
     if (isFullyUndialableVoicemail()) {
       // Sometimes the voicemail server will report the message is from some non phone number
@@ -665,9 +676,15 @@
             && (hasPlacedCarrierVideoCall() || canSupportCarrierVideoCall())) {
           videoCallButtonView.setTag(IntentProvider.getReturnVideoCallIntentProvider(number));
           videoCallButtonView.setVisibility(View.VISIBLE);
-        } else if (duoReady) {
+        } else if (duo.isReachable(mContext, number)) {
           videoCallButtonView.setTag(IntentProvider.getDuoVideoIntentProvider(number));
           videoCallButtonView.setVisibility(View.VISIBLE);
+        } else if (duo.isActivated(mContext)) {
+          inviteVideoButtonView.setTag(IntentProvider.getDuoInviteIntentProvider(number));
+          inviteVideoButtonView.setVisibility(View.VISIBLE);
+        } else if (duo.isEnabled(mContext)) {
+          setUpVideoButtonView.setTag(IntentProvider.getSetUpDuoIntentProvider());
+          setUpVideoButtonView.setVisibility(View.VISIBLE);
         }
         break;
       default:
@@ -755,7 +772,7 @@
   private boolean showDuoPrimaryButton() {
     return accountHandle != null
         && accountHandle.getComponentName().equals(DuoConstants.PHONE_ACCOUNT_COMPONENT_NAME)
-        && duoReady;
+        && duo.isReachable(mContext, number);
   }
 
   private static boolean hasDialableChar(CharSequence number) {
diff --git a/java/com/android/dialer/app/calllog/IntentProvider.java b/java/com/android/dialer/app/calllog/IntentProvider.java
index 0835d89..996bca0 100644
--- a/java/com/android/dialer/app/calllog/IntentProvider.java
+++ b/java/com/android/dialer/app/calllog/IntentProvider.java
@@ -22,6 +22,7 @@
 import android.net.Uri;
 import android.provider.ContactsContract;
 import android.support.annotation.Nullable;
+import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telephony.TelephonyManager;
 import com.android.contacts.common.model.Contact;
@@ -32,6 +33,7 @@
 import com.android.dialer.callintent.CallIntentBuilder;
 import com.android.dialer.dialercontact.DialerContact;
 import com.android.dialer.duo.DuoComponent;
+import com.android.dialer.duo.DuoConstants;
 import com.android.dialer.precall.PreCall;
 import com.android.dialer.util.IntentUtil;
 import java.util.ArrayList;
@@ -102,6 +104,29 @@
     };
   }
 
+  public static IntentProvider getSetUpDuoIntentProvider() {
+    return new IntentProvider() {
+      @Override
+      public Intent getIntent(Context context) {
+        return new Intent("com.google.android.apps.tachyon.action.REGISTER")
+            .setPackage(DuoConstants.PACKAGE_NAME);
+      }
+    };
+  }
+
+  public static IntentProvider getDuoInviteIntentProvider(String number) {
+    return new IntentProvider() {
+      @Override
+      public Intent getIntent(Context context) {
+        Intent intent =
+            new Intent("com.google.android.apps.tachyon.action.INVITE")
+                .setPackage(DuoConstants.PACKAGE_NAME)
+                .setData(Uri.fromParts(PhoneAccount.SCHEME_TEL, number, null /* fragment */));
+        return intent;
+      }
+    };
+  }
+
   public static IntentProvider getReturnVoicemailCallIntentProvider(
       @Nullable PhoneAccountHandle phoneAccountHandle) {
     return new IntentProvider() {
diff --git a/java/com/android/dialer/app/res/layout/call_log_list_item_actions.xml b/java/com/android/dialer/app/res/layout/call_log_list_item_actions.xml
index ec9e5a0..7df0d15 100644
--- a/java/com/android/dialer/app/res/layout/call_log_list_item_actions.xml
+++ b/java/com/android/dialer/app/res/layout/call_log_list_item_actions.xml
@@ -73,6 +73,34 @@
   </LinearLayout>
 
   <LinearLayout
+      android:id="@+id/set_up_video_action"
+      style="@style/CallLogActionStyle">
+
+    <ImageView
+        style="@style/CallLogActionIconStyle"
+        android:src="@drawable/quantum_ic_videocam_white_24"/>
+
+    <TextView
+        style="@style/CallLogActionTextStyle"
+        android:text="@string/call_log_action_set_up_video"/>
+
+  </LinearLayout>
+
+  <LinearLayout
+      android:id="@+id/invite_video_action"
+      style="@style/CallLogActionStyle">
+
+    <ImageView
+        style="@style/CallLogActionIconStyle"
+        android:src="@drawable/quantum_ic_videocam_white_24"/>
+
+    <TextView
+        style="@style/CallLogActionTextStyle"
+        android:text="@string/call_log_action_invite_video"/>
+
+  </LinearLayout>
+
+  <LinearLayout
     android:id="@+id/create_new_contact_action"
     style="@style/CallLogActionStyle">
 
diff --git a/java/com/android/dialer/app/res/values/strings.xml b/java/com/android/dialer/app/res/values/strings.xml
index 01c4776..99720c2 100644
--- a/java/com/android/dialer/app/res/values/strings.xml
+++ b/java/com/android/dialer/app/res/values/strings.xml
@@ -348,6 +348,16 @@
        [CHAR LIMIT=30] -->
   <string name="call_log_action_video_call">Video call</string>
 
+  <!-- Button text for the "Set up" video calling option displayed underneath an entry in the call log.
+       Tapping causes a the user to be taken to set up video calling.
+       [CHAR LIMIT=30] -->
+  <string name="call_log_action_set_up_video">Set up</string>
+
+  <!-- Button text for the "Invite" option displayed underneath an entry in the call log.
+       Tapping causes a the user to be taken to the messaging app with a message ready to invite them to set up video calling.
+       [CHAR LIMIT=30] -->
+  <string name="call_log_action_invite_video">Invite</string>
+
   <!-- Button text for a button displayed underneath an entry in the call log, which opens up a
        messaging app to send a SMS to the number represented by the call log entry.
        [CHAR LIMIT=30] -->
diff --git a/java/com/android/dialer/databasepopulator/VoicemailPopulator.java b/java/com/android/dialer/databasepopulator/VoicemailPopulator.java
index b1f8d1f..97f6b0a 100644
--- a/java/com/android/dialer/databasepopulator/VoicemailPopulator.java
+++ b/java/com/android/dialer/databasepopulator/VoicemailPopulator.java
@@ -38,7 +38,7 @@
 /** Populates the device database with voicemail entries. */
 public final class VoicemailPopulator {
   private static final String ACCOUNT_ID = "ACCOUNT_ID";
-
+  private static String componentName = "";
   private static final Voicemail.Builder[] SIMPLE_VOICEMAILS = {
     // Long transcription with an embedded phone number.
     Voicemail.builder()
@@ -48,6 +48,7 @@
                 + "I hope you listen to all of it. This is very important. "
                 + "Hi, this is a very long voicemail. "
                 + "I hope you listen to all of it. It's very important.")
+        .setPhoneAccountComponentName(componentName)
         .setDurationSeconds(10)
         .setIsRead(false),
     // RTL transcription.
@@ -55,24 +56,28 @@
         .setPhoneNumber("+1-302-6365454")
         .setTranscription("هزاران دوست کم اند و یک دشمن زیاد")
         .setDurationSeconds(60)
+        .setPhoneAccountComponentName(componentName)
         .setIsRead(true),
     // Empty number.
     Voicemail.builder()
         .setPhoneNumber("")
         .setTranscription("")
         .setDurationSeconds(60)
+        .setPhoneAccountComponentName(componentName)
         .setIsRead(true),
     // No duration.
     Voicemail.builder()
         .setPhoneNumber("+1-302-6365454")
         .setTranscription("")
         .setDurationSeconds(0)
+        .setPhoneAccountComponentName(componentName)
         .setIsRead(true),
     // Short number.
     Voicemail.builder()
         .setPhoneNumber("711")
         .setTranscription("This is a short voicemail.")
         .setDurationSeconds(12)
+        .setPhoneAccountComponentName(componentName)
         .setIsRead(true),
   };
 
@@ -118,7 +123,7 @@
   public static void enableVoicemail(@NonNull Context context) {
     PhoneAccountHandle handle =
         new PhoneAccountHandle(new ComponentName(context, VoicemailPopulator.class), ACCOUNT_ID);
-
+    componentName = handle.getComponentName().toString();
     ContentValues values = new ContentValues();
     values.put(Status.SOURCE_PACKAGE, handle.getComponentName().getPackageName());
     if (VERSION.SDK_INT >= VERSION_CODES.N_MR1) {
@@ -147,6 +152,8 @@
 
     public abstract boolean getIsRead();
 
+    public abstract String getPhoneAccountComponentName();
+
     public static Builder builder() {
       return new AutoValue_VoicemailPopulator_Voicemail.Builder();
     }
@@ -159,6 +166,7 @@
       values.put(Voicemails.SOURCE_PACKAGE, context.getPackageName());
       values.put(Voicemails.IS_READ, getIsRead() ? 1 : 0);
       values.put(Voicemails.TRANSCRIPTION, getTranscription());
+      values.put(Voicemails.PHONE_ACCOUNT_COMPONENT_NAME, getPhoneAccountComponentName());
       return values;
     }
 
@@ -175,6 +183,8 @@
 
       public abstract Builder setIsRead(boolean isRead);
 
+      public abstract Builder setPhoneAccountComponentName(String phoneAccountComponentName);
+
       public abstract Voicemail build();
     }
   }
diff --git a/java/com/android/dialer/simulator/impl/SimulatorNotifications.java b/java/com/android/dialer/simulator/impl/SimulatorNotifications.java
index 4ed7c9b..a243c34 100644
--- a/java/com/android/dialer/simulator/impl/SimulatorNotifications.java
+++ b/java/com/android/dialer/simulator/impl/SimulatorNotifications.java
@@ -56,6 +56,7 @@
               .setTranscription(String.format("Short transcript %d", i))
               .setDurationSeconds(60)
               .setIsRead(false)
+              .setPhoneAccountComponentName("")
               .setTimeMillis(System.currentTimeMillis() - TimeUnit.HOURS.toMillis(i))
               .build();
       voicemails.add(voicemail.getAsContentValues(context));
diff --git a/java/com/android/dialer/simulator/impl/SimulatorVoiceCall.java b/java/com/android/dialer/simulator/impl/SimulatorVoiceCall.java
index 451896b..9ffcfc8 100644
--- a/java/com/android/dialer/simulator/impl/SimulatorVoiceCall.java
+++ b/java/com/android/dialer/simulator/impl/SimulatorVoiceCall.java
@@ -39,7 +39,8 @@
         .addItem("Incoming call", () -> new SimulatorVoiceCall(context).addNewIncomingCall(false))
         .addItem("Outgoing call", () -> new SimulatorVoiceCall(context).addNewOutgoingCall())
         .addItem("Spam call", () -> new SimulatorVoiceCall(context).addNewIncomingCall(true))
-        .addItem("Emergency call", () -> new SimulatorVoiceCall(context).addNewEmergencyCall())
+        .addItem(
+            "Emergency call back", () -> new SimulatorVoiceCall(context).addNewEmergencyCallBack())
         .addItem(
             "GSM conference",
             () -> new SimulatorConferenceCreator(context, Simulator.CONFERENCE_TYPE_GSM).start(5))
@@ -71,7 +72,7 @@
         SimulatorSimCallManager.addNewOutgoingCall(context, callerId, false /* isVideo */);
   }
 
-  private void addNewEmergencyCall() {
+  private void addNewEmergencyCallBack() {
     String callerId = "911";
     connectionTag = SimulatorSimCallManager.addNewIncomingCall(context, callerId, false);
   }