Merge "Add upgrade to RTT call button."
diff --git a/java/com/android/dialer/telecom/TelecomUtil.java b/java/com/android/dialer/telecom/TelecomUtil.java
index 2608cb2..f05ec20 100644
--- a/java/com/android/dialer/telecom/TelecomUtil.java
+++ b/java/com/android/dialer/telecom/TelecomUtil.java
@@ -26,6 +26,7 @@
 import android.os.Build.VERSION;
 import android.os.Build.VERSION_CODES;
 import android.provider.CallLog.Calls;
+import android.provider.Settings;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.annotation.RequiresPermission;
@@ -299,6 +300,11 @@
     return instance.isDefaultDialer(context);
   }
 
+  public static boolean isRttEnabled(Context context) {
+    return Settings.System.getInt(context.getContentResolver(), Settings.System.RTT_CALLING_MODE, 0)
+        != 0;
+  }
+
   /** @return the other SIM based PhoneAccountHandle that is not {@code currentAccount} */
   @Nullable
   @RequiresPermission(permission.READ_PHONE_STATE)
diff --git a/java/com/android/incallui/CallButtonPresenter.java b/java/com/android/incallui/CallButtonPresenter.java
index 3854642..38c8da8 100644
--- a/java/com/android/incallui/CallButtonPresenter.java
+++ b/java/com/android/incallui/CallButtonPresenter.java
@@ -304,6 +304,12 @@
   }
 
   @Override
+  public void changeToRttClicked() {
+    LogUtil.enterBlock("CallButtonPresenter.changeToRttClicked");
+    call.sendRttUpgradeRequest();
+  }
+
+  @Override
   public void onEndCallClicked() {
     LogUtil.i("CallButtonPresenter.onEndCallClicked", "call: " + call);
     if (call != null) {
@@ -473,6 +479,8 @@
             // Most devices cannot make calls on 2 SIMs at the same time.
             && InCallPresenter.getInstance().getCallList().getAllCalls().size() == 1;
 
+    boolean showUpgradeToRtt = TelecomUtil.isRttEnabled(context) && call.canUpgradeToRttCall();
+
     inCallButtonUi.showButton(InCallButtonIds.BUTTON_AUDIO, true);
     inCallButtonUi.showButton(InCallButtonIds.BUTTON_SWAP, showSwap);
     inCallButtonUi.showButton(InCallButtonIds.BUTTON_HOLD, showHold);
@@ -482,6 +490,7 @@
     inCallButtonUi.showButton(InCallButtonIds.BUTTON_ADD_CALL, true);
     inCallButtonUi.enableButton(InCallButtonIds.BUTTON_ADD_CALL, showAddCall);
     inCallButtonUi.showButton(InCallButtonIds.BUTTON_UPGRADE_TO_VIDEO, showUpgradeToVideo);
+    inCallButtonUi.showButton(InCallButtonIds.BUTTON_UPGRADE_TO_RTT, showUpgradeToRtt);
     inCallButtonUi.showButton(InCallButtonIds.BUTTON_DOWNGRADE_TO_AUDIO, showDowngradeToAudio);
     inCallButtonUi.showButton(
         InCallButtonIds.BUTTON_SWITCH_CAMERA,
diff --git a/java/com/android/incallui/InCallActivity.java b/java/com/android/incallui/InCallActivity.java
index 9d08dc4..1ba3683 100644
--- a/java/com/android/incallui/InCallActivity.java
+++ b/java/com/android/incallui/InCallActivity.java
@@ -1468,7 +1468,7 @@
       return new ShouldShowUiResult(false, null);
     }
 
-    if (call.isRttCall()) {
+    if (call.isActiveRttCall()) {
       LogUtil.i("InCallActivity.getShouldShowRttUi", "found rtt call");
       return new ShouldShowUiResult(true, call);
     }
@@ -1520,7 +1520,7 @@
     AnswerScreen answerScreen =
         AnswerBindings.createAnswerScreen(
             call.getId(),
-            call.isRttCall(),
+            call.isActiveRttCall(),
             call.isVideoCall(),
             isVideoUpgradeRequest,
             call.getVideoTech().isSelfManagedCamera(),
diff --git a/java/com/android/incallui/ProximitySensor.java b/java/com/android/incallui/ProximitySensor.java
index 4b03344..9719e5d 100644
--- a/java/com/android/incallui/ProximitySensor.java
+++ b/java/com/android/incallui/ProximitySensor.java
@@ -113,7 +113,7 @@
 
     DialerCall activeCall = callList.getActiveCall();
     boolean isVideoCall = activeCall != null && activeCall.isVideoCall();
-    boolean isRttCall = activeCall != null && activeCall.isRttCall();
+    boolean isRttCall = activeCall != null && activeCall.isActiveRttCall();
 
     if (isOffhook != isPhoneOffhook
         || this.isVideoCall != isVideoCall
diff --git a/java/com/android/incallui/call/CallList.java b/java/com/android/incallui/call/CallList.java
index f639e5b..01f3b9d 100644
--- a/java/com/android/incallui/call/CallList.java
+++ b/java/com/android/incallui/call/CallList.java
@@ -514,6 +514,15 @@
     return call != null && call != getDisconnectingCall() && call != getDisconnectedCall();
   }
 
+  boolean hasActiveRttCall() {
+    for (DialerCall call : getAllCalls()) {
+      if (call.isActiveRttCall()) {
+        return true;
+      }
+    }
+    return false;
+  }
+
   /**
    * Returns the first call found in the call map with the upgrade to video modification state.
    *
diff --git a/java/com/android/incallui/call/DialerCall.java b/java/com/android/incallui/call/DialerCall.java
index 4815a6e..e08c926 100644
--- a/java/com/android/incallui/call/DialerCall.java
+++ b/java/com/android/incallui/call/DialerCall.java
@@ -988,7 +988,7 @@
   }
 
   @TargetApi(28)
-  public boolean isRttCall() {
+  public boolean isActiveRttCall() {
     if (BuildCompat.isAtLeastP()) {
       return getTelecomCall().isRttActive();
     } else {
@@ -998,12 +998,41 @@
 
   @TargetApi(28)
   public RttCall getRttCall() {
-    if (!isRttCall()) {
+    if (!isActiveRttCall()) {
       return null;
     }
     return getTelecomCall().getRttCall();
   }
 
+  @TargetApi(28)
+  public boolean canUpgradeToRttCall() {
+    PhoneAccount phoneAccount = getPhoneAccount();
+    if (phoneAccount == null) {
+      return false;
+    }
+    if (!phoneAccount.hasCapabilities(PhoneAccount.CAPABILITY_RTT)) {
+      return false;
+    }
+    if (isActiveRttCall()) {
+      return false;
+    }
+    if (isVideoCall()) {
+      return false;
+    }
+    if (isConferenceCall()) {
+      return false;
+    }
+    if (CallList.getInstance().hasActiveRttCall()) {
+      return false;
+    }
+    return true;
+  }
+
+  @TargetApi(28)
+  public void sendRttUpgradeRequest() {
+    getTelecomCall().sendRttRequest();
+  }
+
   public boolean hasReceivedVideoUpgradeRequest() {
     return VideoUtils.hasReceivedVideoUpgradeRequest(getVideoTech().getSessionModificationState());
   }
diff --git a/java/com/android/incallui/callpending/CallPendingActivity.java b/java/com/android/incallui/callpending/CallPendingActivity.java
index c7ce2b1..831ebbd 100644
--- a/java/com/android/incallui/callpending/CallPendingActivity.java
+++ b/java/com/android/incallui/callpending/CallPendingActivity.java
@@ -255,6 +255,9 @@
           public void changeToVideoClicked() {}
 
           @Override
+          public void changeToRttClicked() {}
+
+          @Override
           public void switchCameraClicked(boolean useFrontFacingCamera) {}
 
           @Override
diff --git a/java/com/android/incallui/incall/impl/ButtonChooserFactory.java b/java/com/android/incallui/incall/impl/ButtonChooserFactory.java
index 2a08940..757d813 100644
--- a/java/com/android/incallui/incall/impl/ButtonChooserFactory.java
+++ b/java/com/android/incallui/incall/impl/ButtonChooserFactory.java
@@ -57,6 +57,9 @@
     mapping.put(
         InCallButtonIds.BUTTON_MANAGE_VOICE_CONFERENCE,
         MappingInfo.builder(4).setSlotOrder(0).build());
+    // RTT call is only supported on IMS and WiFi.
+    mapping.put(
+        InCallButtonIds.BUTTON_UPGRADE_TO_RTT, MappingInfo.builder(3).setSlotOrder(0).build());
     mapping.put(
         InCallButtonIds.BUTTON_UPGRADE_TO_VIDEO, MappingInfo.builder(4).setSlotOrder(10).build());
     mapping.put(
@@ -114,7 +117,7 @@
     mapping.put(InCallButtonIds.BUTTON_MUTE, MappingInfo.builder(0).build());
     mapping.put(InCallButtonIds.BUTTON_DIALPAD, MappingInfo.builder(1).build());
     mapping.put(InCallButtonIds.BUTTON_AUDIO, MappingInfo.builder(2).build());
-    mapping.put(InCallButtonIds.BUTTON_MERGE, MappingInfo.builder(3).setSlotOrder(0).build());
+    mapping.put(InCallButtonIds.BUTTON_MERGE, MappingInfo.builder(3).setSlotOrder(5).build());
     mapping.put(InCallButtonIds.BUTTON_ADD_CALL, MappingInfo.builder(3).build());
     mapping.put(InCallButtonIds.BUTTON_SWAP_SIM, MappingInfo.builder(4).build());
     return mapping;
diff --git a/java/com/android/incallui/incall/impl/ButtonController.java b/java/com/android/incallui/incall/impl/ButtonController.java
index 98460c7..9106dab 100644
--- a/java/com/android/incallui/incall/impl/ButtonController.java
+++ b/java/com/android/incallui/incall/impl/ButtonController.java
@@ -519,6 +519,24 @@
     }
   }
 
+  class UpgradeToRttButtonController extends SimpleNonCheckableButtonController {
+
+    public UpgradeToRttButtonController(@NonNull InCallButtonUiDelegate delegate) {
+      super(
+          delegate,
+          InCallButtonIds.BUTTON_UPGRADE_TO_RTT,
+          0,
+          R.string.incall_label_rttcall,
+          R.drawable.quantum_ic_rtt_vd_theme_24);
+      Assert.isNotNull(delegate);
+    }
+
+    @Override
+    public void onClick(View view) {
+      delegate.changeToRttClicked();
+    }
+  }
+
   class ManageConferenceButtonController extends SimpleNonCheckableButtonController {
 
     private final InCallScreenDelegate inCallScreenDelegate;
diff --git a/java/com/android/incallui/incall/impl/InCallFragment.java b/java/com/android/incallui/incall/impl/InCallFragment.java
index fb8c2c4..6f0ba60 100644
--- a/java/com/android/incallui/incall/impl/InCallFragment.java
+++ b/java/com/android/incallui/incall/impl/InCallFragment.java
@@ -54,6 +54,7 @@
 import com.android.incallui.contactgrid.ContactGridManager;
 import com.android.incallui.hold.OnHoldFragment;
 import com.android.incallui.incall.impl.ButtonController.SpeakerButtonController;
+import com.android.incallui.incall.impl.ButtonController.UpgradeToRttButtonController;
 import com.android.incallui.incall.impl.InCallButtonGridFragment.OnButtonGridCreatedListener;
 import com.android.incallui.incall.protocol.InCallButtonIds;
 import com.android.incallui.incall.protocol.InCallButtonIdsExtension;
@@ -114,7 +115,8 @@
         || id == InCallButtonIds.BUTTON_ADD_CALL
         || id == InCallButtonIds.BUTTON_MERGE
         || id == InCallButtonIds.BUTTON_MANAGE_VOICE_CONFERENCE
-        || id == InCallButtonIds.BUTTON_SWAP_SIM;
+        || id == InCallButtonIds.BUTTON_SWAP_SIM
+        || id == InCallButtonIds.BUTTON_UPGRADE_TO_RTT;
   }
 
   @Override
@@ -226,6 +228,7 @@
     buttonControllers.add(new ButtonController.SwapSimButtonController(inCallButtonUiDelegate));
     buttonControllers.add(
         new ButtonController.UpgradeToVideoButtonController(inCallButtonUiDelegate));
+    buttonControllers.add(new UpgradeToRttButtonController(inCallButtonUiDelegate));
     buttonControllers.add(
         new ButtonController.ManageConferenceButtonController(inCallScreenDelegate));
     buttonControllers.add(
diff --git a/java/com/android/incallui/incall/impl/res/values/strings.xml b/java/com/android/incallui/incall/impl/res/values/strings.xml
index d021756..c4c40a1 100644
--- a/java/com/android/incallui/incall/impl/res/values/strings.xml
+++ b/java/com/android/incallui/incall/impl/res/values/strings.xml
@@ -20,6 +20,10 @@
      [CHAR LIMIT=12] -->
   <string name="incall_label_videocall">Video call</string>
 
+  <!-- Button shown during a phone call to upgrade to Real-time Text.
+     [CHAR LIMIT=12] -->
+  <string name="incall_label_rttcall">RTT</string>
+
   <!-- Button shown during a phone call to put the call on hold.
      [CHAR LIMIT=12] -->
   <string name="incall_label_hold">Hold</string>
diff --git a/java/com/android/incallui/incall/protocol/InCallButtonIds.java b/java/com/android/incallui/incall/protocol/InCallButtonIds.java
index 3de5335..80ea75e 100644
--- a/java/com/android/incallui/incall/protocol/InCallButtonIds.java
+++ b/java/com/android/incallui/incall/protocol/InCallButtonIds.java
@@ -39,6 +39,7 @@
   InCallButtonIds.BUTTON_SWITCH_TO_SECONDARY,
   InCallButtonIds.BUTTON_SWAP_SIM,
   InCallButtonIds.BUTTON_COUNT,
+  InCallButtonIds.BUTTON_UPGRADE_TO_RTT
 })
 public @interface InCallButtonIds {
 
@@ -58,4 +59,5 @@
   int BUTTON_SWITCH_TO_SECONDARY = 13;
   int BUTTON_SWAP_SIM = 14;
   int BUTTON_COUNT = 15;
+  int BUTTON_UPGRADE_TO_RTT = 16;
 }
diff --git a/java/com/android/incallui/incall/protocol/InCallButtonIdsExtension.java b/java/com/android/incallui/incall/protocol/InCallButtonIdsExtension.java
index db6e900..5239d9d 100644
--- a/java/com/android/incallui/incall/protocol/InCallButtonIdsExtension.java
+++ b/java/com/android/incallui/incall/protocol/InCallButtonIdsExtension.java
@@ -56,6 +56,8 @@
       return "SWITCH_TO_SECONDARY";
     } else if (id == InCallButtonIds.BUTTON_SWAP_SIM) {
       return "SWAP_SIM";
+    } else if (id == InCallButtonIds.BUTTON_UPGRADE_TO_RTT) {
+      return "UPGRADE_TO_RTT";
     } else {
       return "INVALID_BUTTON: " + id;
     }
diff --git a/java/com/android/incallui/incall/protocol/InCallButtonUiDelegate.java b/java/com/android/incallui/incall/protocol/InCallButtonUiDelegate.java
index 9f9c5fb..b0e23ef 100644
--- a/java/com/android/incallui/incall/protocol/InCallButtonUiDelegate.java
+++ b/java/com/android/incallui/incall/protocol/InCallButtonUiDelegate.java
@@ -47,6 +47,8 @@
 
   void changeToVideoClicked();
 
+  void changeToRttClicked();
+
   void switchCameraClicked(boolean useFrontFacingCamera);
 
   void toggleCameraClicked();