Merge "Listen to IMS capability status for RTT" am: 74b643db64
am: 4c91d5888e

Change-Id: Ic53bd175336ddecb7ce2f7f722e6082472317a23
diff --git a/src/com/android/services/telephony/TelecomAccountRegistry.java b/src/com/android/services/telephony/TelecomAccountRegistry.java
index a0e5530..228eed1 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,53 @@
             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;
+                }
+
+                boolean isImsVoiceCapable = manager.isCapable(
+                        ImsRegistrationImplBase.REGISTRATION_TECH_LTE,
+                        MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE)
+                        || manager.isCapable(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN,
+                        MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE);
+
+                if (!isImsVoiceCapable) {
+                    Log.i(this, "Not registering MmTel listener because"
+                            + " voice over IMS isn't supported");
+                    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) {
+                try {
+                    ImsMmTelManager.createForSubscriptionId(mContext, getSubId())
+                            .unregisterMmTelCapabilityCallback(mMmtelCapabilityCallback);
+                } catch (IllegalArgumentException e) {
+                    // TODO (breadley): Tearing down may fail if the sim has been removed.
+                }
+            }
         }
 
         /**
@@ -260,8 +308,10 @@
                 extras.putBoolean(PhoneAccount.EXTRA_PLAY_CALL_RECORDING_TONE, true);
             }
 
-            if (PhoneGlobals.getInstance().phoneMgr.isRttEnabled(subId)) {
+            if (PhoneGlobals.getInstance().phoneMgr.isRttEnabled(subId)
+                    && isImsVoiceAvailable()) {
                 capabilities |= PhoneAccount.CAPABILITY_RTT;
+                mIsRttCapable = true;
             }
 
             extras.putBoolean(PhoneAccount.EXTRA_SUPPORTS_VIDEO_CALLING_FALLBACK,
@@ -525,10 +575,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 hasVoiceAvailability;
+            if (mMmTelCapabilities != null) {
+                hasVoiceAvailability = mMmTelCapabilities.isCapable(
+                        MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE);
+            } else {
+                hasVoiceAvailability = isImsVoiceAvailable();
+            }
+
+            boolean isRttSupported = PhoneGlobals.getInstance().phoneMgr
                     .isRttEnabled(mPhone.getSubId());
-            boolean oldRttEnabled = mAccount.hasCapabilities(PhoneAccount.CAPABILITY_RTT);
-            if (isRttEnabled != oldRttEnabled) {
+
+            boolean isRttEnabled = hasVoiceAvailability && isRttSupported;
+            if (isRttEnabled != mIsRttCapable) {
                 mAccount = registerPstnPhoneAccount(mIsEmergency, mIsDummy);
             }
         }
@@ -591,6 +652,20 @@
         public boolean isShowPreciseFailedCause() {
             return mIsShowPreciseFailedCause;
         }
+
+        private boolean isImsVoiceAvailable() {
+            if (mMmTelCapabilities != null) {
+                return mMmTelCapabilities.isCapable(
+                        MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE);
+            }
+
+            ImsMmTelManager manager = ImsMmTelManager.createForSubscriptionId(
+                    mContext, getSubId());
+            return manager.isAvailable(ImsRegistrationImplBase.REGISTRATION_TECH_LTE,
+                    MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE)
+                    || manager.isAvailable(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN,
+                    MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE);
+        }
     }
 
     private OnSubscriptionsChangedListener mOnSubscriptionsChangedListener =