Listen to IMS capability status for RTT

In TelecomAccountRegistry, disable/enable the RTT capability for a subid
depending on whether the MMTel voice capability is active for that
subid.

Test: manual
Bug: 121230208
Change-Id: Ibd8668e6430f2d702d1a420a9927dae8426b4bcf
diff --git a/src/com/android/services/telephony/TelecomAccountRegistry.java b/src/com/android/services/telephony/TelecomAccountRegistry.java
index a0e5530..7be0747 100644
--- a/src/com/android/services/telephony/TelecomAccountRegistry.java
+++ b/src/com/android/services/telephony/TelecomAccountRegistry.java
@@ -46,6 +46,9 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
 import android.telephony.TelephonyManager;
+import android.telephony.ims.ImsMmTelManager;
+import android.telephony.ims.feature.MmTelFeature;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
 import android.text.TextUtils;
 
 import com.android.ims.ImsManager;
@@ -78,7 +81,10 @@
         private final PstnIncomingCallNotifier mIncomingCallNotifier;
         private final PstnPhoneCapabilitiesNotifier mPhoneCapabilitiesNotifier;
         private boolean mIsEmergency;
-        private boolean mIsDummy;
+        private boolean mIsRttCapable;
+        private MmTelFeature.MmTelCapabilities mMmTelCapabilities;
+        private ImsMmTelManager.CapabilityCallback mMmtelCapabilityCallback;
+        private final boolean mIsDummy;
         private boolean mIsVideoCapable;
         private boolean mIsVideoPresenceSupported;
         private boolean mIsVideoPauseSupported;
@@ -99,11 +105,36 @@
             mIncomingCallNotifier = new PstnIncomingCallNotifier((Phone) mPhone);
             mPhoneCapabilitiesNotifier = new PstnPhoneCapabilitiesNotifier((Phone) mPhone,
                     this);
+
+            if (!mIsDummy) {
+                ImsMmTelManager manager;
+                try {
+                    manager = ImsMmTelManager.createForSubscriptionId(mContext, getSubId());
+                } catch (IllegalArgumentException e) {
+                    Log.i(this, "Not registering Mmtel listener because the subid is invalid");
+                    return;
+                }
+                mMmtelCapabilityCallback =
+                        new ImsMmTelManager.CapabilityCallback() {
+                            @Override
+                            public void onCapabilitiesStatusChanged(
+                                    MmTelFeature.MmTelCapabilities capabilities) {
+                                mMmTelCapabilities = capabilities;
+                                updateRttCapability();
+                            }
+                        };
+                manager.registerMmTelCapabilityCallback(mContext.getMainExecutor(),
+                                mMmtelCapabilityCallback);
+            }
         }
 
         void teardown() {
             mIncomingCallNotifier.teardown();
             mPhoneCapabilitiesNotifier.teardown();
+            if (mMmtelCapabilityCallback != null) {
+                ImsMmTelManager.createForSubscriptionId(mContext, getSubId())
+                        .unregisterMmTelCapabilityCallback(mMmtelCapabilityCallback);
+            }
         }
 
         /**
@@ -260,8 +291,10 @@
                 extras.putBoolean(PhoneAccount.EXTRA_PLAY_CALL_RECORDING_TONE, true);
             }
 
-            if (PhoneGlobals.getInstance().phoneMgr.isRttEnabled(subId)) {
+            if (PhoneGlobals.getInstance().phoneMgr.isRttEnabled(subId)
+                    && isImsVoiceCapable(this)) {
                 capabilities |= PhoneAccount.CAPABILITY_RTT;
+                mIsRttCapable = true;
             }
 
             extras.putBoolean(PhoneAccount.EXTRA_SUPPORTS_VIDEO_CALLING_FALLBACK,
@@ -525,10 +558,21 @@
         }
 
         public void updateRttCapability() {
-            boolean isRttEnabled = PhoneGlobals.getInstance().phoneMgr
+            // In the rare case that mMmTelCapabilities hasn't been set yet, try fetching it
+            // directly.
+            boolean hasVoiceCapability;
+            if (mMmTelCapabilities != null) {
+                hasVoiceCapability = mMmTelCapabilities.isCapable(
+                        MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE);
+            } else {
+                hasVoiceCapability = isImsVoiceCapable(this);
+            }
+
+            boolean isRttSupported = PhoneGlobals.getInstance().phoneMgr
                     .isRttEnabled(mPhone.getSubId());
-            boolean oldRttEnabled = mAccount.hasCapabilities(PhoneAccount.CAPABILITY_RTT);
-            if (isRttEnabled != oldRttEnabled) {
+
+            boolean isRttEnabled = hasVoiceCapability && isRttSupported;
+            if (isRttEnabled != mIsRttCapable) {
                 mAccount = registerPstnPhoneAccount(mIsEmergency, mIsDummy);
             }
         }
@@ -989,6 +1033,20 @@
         }
     }
 
+    private boolean isImsVoiceCapable(AccountEntry entry) {
+        if (entry.mMmTelCapabilities != null) {
+            return entry.mMmTelCapabilities.isCapable(
+                    MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE);
+        }
+
+        ImsMmTelManager manager = ImsMmTelManager.createForSubscriptionId(mContext,
+                entry.getSubId());
+        return manager.isCapable(ImsRegistrationImplBase.REGISTRATION_TECH_LTE,
+                MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE)
+                && manager.isCapable(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN,
+                MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE);
+    }
+
     /**
      * Handles changes to the carrier configuration which may impact a phone account.  There are
      * some extras defined in the {@link PhoneAccount} which are based on carrier config options.