Implement SIM swapping

When the call is still ringing, a new button is added to allow to user to call with the other SIM. A background worker will be created to hang up the phone and redial with the other SIM. The in call UI will be prevented from ending during the process.

 Video: https://drive.google.com/a/google.com/file/d/0B2eYBUUznfyTSl9MdXQ0V1ZzQkE/view?usp=sharing

 UX has not been finalized, the icon and position are just placeholder.

Bug: 64215256
Test: SwapSimWorkerTest
PiperOrigin-RevId: 171715715
Change-Id: Idb3f486e9fc9a45d4c5e244af2d7d91b075bf0f2
diff --git a/java/com/android/incallui/CallButtonPresenter.java b/java/com/android/incallui/CallButtonPresenter.java
index bd5bb78..b3fb97f 100644
--- a/java/com/android/incallui/CallButtonPresenter.java
+++ b/java/com/android/incallui/CallButtonPresenter.java
@@ -22,11 +22,14 @@
 import android.support.v4.app.Fragment;
 import android.support.v4.os.UserManagerCompat;
 import android.telecom.CallAudioState;
+import android.telecom.PhoneAccountHandle;
 import com.android.contacts.common.compat.CallCompat;
 import com.android.dialer.common.Assert;
 import com.android.dialer.common.LogUtil;
+import com.android.dialer.common.concurrent.DialerExecutorComponent;
 import com.android.dialer.logging.DialerImpression;
 import com.android.dialer.logging.Logger;
+import com.android.dialer.telecom.TelecomUtil;
 import com.android.incallui.InCallCameraManager.Listener;
 import com.android.incallui.InCallPresenter.CanAddCallListener;
 import com.android.incallui.InCallPresenter.InCallDetailsListener;
@@ -42,6 +45,7 @@
 import com.android.incallui.incall.protocol.InCallButtonIds;
 import com.android.incallui.incall.protocol.InCallButtonUi;
 import com.android.incallui.incall.protocol.InCallButtonUiDelegate;
+import com.android.incallui.multisim.SwapSimWorker;
 import com.android.incallui.videotech.utils.VideoUtils;
 
 /** Logic for call buttons. */
@@ -63,6 +67,7 @@
   private boolean mAutomaticallyMuted = false;
   private boolean mPreviousMuteState = false;
   private boolean isInCallButtonUiReady;
+  private PhoneAccountHandle mOtherAccount;
 
   public CallButtonPresenter(Context context) {
     mContext = context.getApplicationContext();
@@ -310,6 +315,23 @@
     mInCallButtonUi.showAudioRouteSelector();
   }
 
+  @Override
+  public void swapSimClicked() {
+    LogUtil.enterBlock("CallButtonPresenter.swapSimClicked");
+    SwapSimWorker worker =
+        new SwapSimWorker(
+            getContext(),
+            mCall,
+            InCallPresenter.getInstance().getCallList(),
+            mOtherAccount,
+            InCallPresenter.getInstance().acquireInCallUiLock("swapSim"));
+    DialerExecutorComponent.get(getContext())
+        .dialerExecutorFactory()
+        .createNonUiTaskBuilder(worker)
+        .build()
+        .executeParallel(null);
+  }
+
   /**
    * Switches the camera between the front-facing and back-facing camera.
    *
@@ -409,6 +431,7 @@
    *
    * @param call The active call.
    */
+  @SuppressWarnings("MissingPermission")
   private void updateButtonsState(DialerCall call) {
     LogUtil.v("CallButtonPresenter.updateButtonsState", "");
     final boolean isVideo = call.isVideoCall();
@@ -439,11 +462,15 @@
             && call.getState() != DialerCall.State.DIALING
             && call.getState() != DialerCall.State.CONNECTING;
 
+    mOtherAccount = TelecomUtil.getOtherAccount(getContext(), call.getAccountHandle());
+    boolean showSwapSim = mOtherAccount != null && DialerCall.State.isDialing(call.getState());
+
     mInCallButtonUi.showButton(InCallButtonIds.BUTTON_AUDIO, true);
     mInCallButtonUi.showButton(InCallButtonIds.BUTTON_SWAP, showSwap);
     mInCallButtonUi.showButton(InCallButtonIds.BUTTON_HOLD, showHold);
     mInCallButtonUi.setHold(isCallOnHold);
     mInCallButtonUi.showButton(InCallButtonIds.BUTTON_MUTE, showMute);
+    mInCallButtonUi.showButton(InCallButtonIds.BUTTON_SWAP_SIM, showSwapSim);
     mInCallButtonUi.showButton(InCallButtonIds.BUTTON_ADD_CALL, true);
     mInCallButtonUi.enableButton(InCallButtonIds.BUTTON_ADD_CALL, showAddCall);
     mInCallButtonUi.showButton(InCallButtonIds.BUTTON_UPGRADE_TO_VIDEO, showUpgradeToVideo);
@@ -532,4 +559,5 @@
     }
     return null;
   }
+
 }