Merge "Import translations. DO NOT MERGE ANYWHERE" into tm-d1-dev
diff --git a/src/com/android/phone/ImsProvisioningController.java b/src/com/android/phone/ImsProvisioningController.java
index 1de2dcd..696f567 100644
--- a/src/com/android/phone/ImsProvisioningController.java
+++ b/src/com/android/phone/ImsProvisioningController.java
@@ -668,6 +668,10 @@
             return retValue;
         }
 
+        public boolean isConnectionReady() {
+            return mReady;
+        }
+
         public void onRcsAvailable() {
             log(LOG_PREFIX, mSlotId, "onRcsAvailable");
 
@@ -1117,8 +1121,19 @@
         int key =  ProvisioningManager.KEY_EAB_PROVISIONING_STATUS;
         int value = getIntValue(isProvisioned);
         try {
-            // set key and value to vendor ImsService for Rcs
-            mRcsFeatureListenersSlotMap.get(slotId).setProvisioningValue(key, value);
+            // On some older devices, EAB is managed on the MmTel ImsService when the RCS
+            // ImsService is not configured. If there is no RCS ImsService defined, fallback to
+            // MmTel. In the rare case that we hit a race condition where the RCS ImsService has
+            // crashed or has not come up yet, the value will be synchronized via
+            // setInitialProvisioningKeys().
+            if (mRcsFeatureListenersSlotMap.get(slotId).isConnectionReady()) {
+                mRcsFeatureListenersSlotMap.get(slotId).setProvisioningValue(key, value);
+            }
+
+            // EAB provisioning status should be updated to both the Rcs and MmTel ImsService,
+            // because the provisioning callback is listening to only MmTel provisioning key
+            // changes.
+            mMmTelFeatureListenersSlotMap.get(slotId).setProvisioningValue(key, value);
         } catch (NullPointerException e) {
             loge("can not access RcsFeatureListener with capability " + capability);
         }
@@ -1155,14 +1170,21 @@
         }
 
         try {
-            if (key == KEY_EAB_PROVISIONING_STATUS) {
-                // set key and value to vendor ImsService for Rcs
-                retVal = mRcsFeatureListenersSlotMap.get(slotId)
-                        .setProvisioningValue(key, value);
-            } else {
-                // set key and value to vendor ImsService for MmTel
-                retVal = mMmTelFeatureListenersSlotMap.get(slotId)
-                        .setProvisioningValue(key, value);
+            // set key and value to vendor ImsService for MmTel
+            // EAB provisioning status should be updated to both the Rcs and MmTel ImsService,
+            // because the provisioning callback is listening to only MmTel provisioning key
+            // changes.
+            retVal = mMmTelFeatureListenersSlotMap.get(slotId).setProvisioningValue(key, value);
+
+            // If the  Rcs ImsService is not available, the EAB provisioning status will be written
+            // to the MmTel ImsService for backwards compatibility. In the rare case that this is
+            // hit due to RCS ImsService temporarily unavailable, the value will be synchronized
+            // via setInitialProvisioningKeys() when the RCS ImsService comes back up.
+            if (key == KEY_EAB_PROVISIONING_STATUS
+                    && mRcsFeatureListenersSlotMap.get(slotId).isConnectionReady()) {
+                // set key and value to vendor ImsService for RCS and use retVal from RCS if
+                // related to EAB when possible.
+                retVal = mRcsFeatureListenersSlotMap.get(slotId).setProvisioningValue(key, value);
             }
         } catch (NullPointerException e) {
             loge("can not access FeatureListener to set provisioning value");
@@ -1332,16 +1354,24 @@
 
     private int getRcsValueFromImsService(int subId, int capability) {
         int config = ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
+        int slotId = getSlotId(subId);
 
-        if (capability == CAPABILITY_TYPE_PRESENCE_UCE) {
-            try {
-                config = mRcsFeatureListenersSlotMap.get(getSlotId(subId))
-                        .getProvisioningValue(ProvisioningManager.KEY_EAB_PROVISIONING_STATUS);
-            } catch (NullPointerException e) {
-                logw("can not access RcsFeatureListener");
-            }
-        } else {
+        if (capability != CAPABILITY_TYPE_PRESENCE_UCE) {
             log("Capability " + capability + " has been provisioning");
+            return config;
+        }
+        try {
+            if (mRcsFeatureListenersSlotMap.get(slotId).isConnectionReady()) {
+                config = mRcsFeatureListenersSlotMap.get(slotId)
+                        .getProvisioningValue(ProvisioningManager.KEY_EAB_PROVISIONING_STATUS);
+            } else {
+                log("Rcs ImsService is not available, "
+                        + "EAB provisioning status should be read from MmTel ImsService");
+                config = mMmTelFeatureListenersSlotMap.get(slotId)
+                        .getProvisioningValue(ProvisioningManager.KEY_EAB_PROVISIONING_STATUS);
+            }
+        } catch (NullPointerException e) {
+            logw("can not access FeatureListener : " + e.getMessage());
         }
 
         return config;
diff --git a/tests/src/com/android/phone/ImsProvisioningControllerTest.java b/tests/src/com/android/phone/ImsProvisioningControllerTest.java
index 49ce6b5..2094e20 100644
--- a/tests/src/com/android/phone/ImsProvisioningControllerTest.java
+++ b/tests/src/com/android/phone/ImsProvisioningControllerTest.java
@@ -21,6 +21,7 @@
 import static android.telephony.ims.ProvisioningManager.KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE;
 import static android.telephony.ims.ProvisioningManager.KEY_VOLTE_PROVISIONING_STATUS;
 import static android.telephony.ims.ProvisioningManager.KEY_VT_PROVISIONING_STATUS;
+import static android.telephony.ims.ProvisioningManager.PROVISIONING_VALUE_DISABLED;
 import static android.telephony.ims.ProvisioningManager.PROVISIONING_VALUE_ENABLED;
 import static android.telephony.ims.feature.ImsFeature.FEATURE_MMTEL;
 import static android.telephony.ims.feature.ImsFeature.FEATURE_RCS;
@@ -631,7 +632,7 @@
             // verify return value
             assertEquals(expectedVoiceProvisioningStatus[i], provisioned);
 
-            // verify weather ImsProvisioningLoader is called or not
+            // verify whether ImsProvisioningLoader is called or not
             verify(mImsProvisioningLoader, times(1))
                     .getProvisioningStatus(eq(mSubId0), eq(FEATURE_MMTEL), eq(capability),
                             eq(RADIO_TECHS[i]));
@@ -646,7 +647,7 @@
             // verify return value
             assertEquals(expectedVideoProvisioningStatus[i], provisioned);
 
-            // verify weather ImsProvisioningLoader is called or not
+            // verify whether ImsProvisioningLoader is called or not
             verify(mImsProvisioningLoader, times(1))
                     .getProvisioningStatus(eq(mSubId0), eq(FEATURE_MMTEL), eq(capability),
                             eq(RADIO_TECHS[i]));
@@ -661,7 +662,7 @@
             // verify return value
             assertEquals(expectedUtProvisioningStatus[i], provisioned);
 
-            // verify weather ImsProvisioningLoader is called or not
+            // verify whether ImsProvisioningLoader is called or not
             verify(mImsProvisioningLoader, times(1))
                     .getProvisioningStatus(eq(mSubId0), eq(FEATURE_MMTEL), eq(capability),
                             eq(RADIO_TECHS[i]));
@@ -716,10 +717,10 @@
         verify(mImsProvisioningLoader, times(1))
                 .getProvisioningStatus(eq(mSubId0), eq(FEATURE_MMTEL), eq(capability), eq(tech));
 
-        // verify weather ImsProvisioningLoader is called or not
+        // verify whether ImsProvisioningLoader is called or not
         verify(mImsConfig, times(1)).getConfigInt(eq(KEY_VOLTE_PROVISIONING_STATUS));
 
-        // verify weather ImsProvisioningLoader is called or not
+        // verify whether ImsProvisioningLoader is called or not
         verify(mImsProvisioningLoader, times(1))
                 .setProvisioningStatus(eq(mSubId0), eq(FEATURE_MMTEL), eq(capability), eq(tech),
                         eq(provisioned));
@@ -739,10 +740,10 @@
         verify(mImsProvisioningLoader, times(1))
                 .getProvisioningStatus(eq(mSubId0), eq(FEATURE_MMTEL), eq(capability), eq(tech));
 
-        // verify weather ImsProvisioningLoader is called or not
+        // verify whether ImsProvisioningLoader is called or not
         verify(mImsConfig, times(1)).getConfigInt(eq(KEY_VT_PROVISIONING_STATUS));
 
-        // verify weather ImsProvisioningLoader is called or not
+        // verify whether ImsProvisioningLoader is called or not
         verify(mImsProvisioningLoader, times(1))
                 .setProvisioningStatus(eq(mSubId0), eq(FEATURE_MMTEL), eq(capability), eq(tech),
                         eq(provisioned));
@@ -781,7 +782,7 @@
             // verify return value
             assertEquals(expectedPresenceProvisioningStatus[i], provisioned);
 
-            // verify weather ImsProvisioningLoader is called or not
+            // verify whether ImsProvisioningLoader is called or not
             verify(mImsProvisioningLoader, times(1)).getProvisioningStatus(
                     eq(mSubId0), eq(FEATURE_RCS), eq(capability), eq(RADIO_TECHS[i]));
         }
@@ -832,10 +833,10 @@
         verify(mImsProvisioningLoader, times(1)).getProvisioningStatus(
                 eq(mSubId0), eq(FEATURE_RCS), eq(capability), eq(tech));
 
-        // verify weather ImsProvisioningLoader is called or not
+        // verify whether ImsProvisioningLoader is called or not
         verify(mImsConfig, times(1)).getConfigInt(eq(KEY_EAB_PROVISIONING_STATUS));
 
-        // verify weather ImsProvisioningLoader is called or not
+        // verify whether ImsProvisioningLoader is called or not
         verify(mImsProvisioningLoader, times(RADIO_TECHS.length)).setProvisioningStatus(
                 eq(mSubId0), eq(FEATURE_RCS), eq(capability), anyInt(), eq(provisioned));
 
@@ -896,7 +897,7 @@
             // verify return value default false - provisioned
             assertEquals(!provisionedFirst, provisionedSecond);
 
-            // verify weather ImsProvisioningLoader is called or not
+            // verify whether ImsProvisioningLoader is called or not
             verify(mImsProvisioningLoader, times(2))
                     .getProvisioningStatus(eq(mSubId0), eq(FEATURE_MMTEL), eq(capability),
                             eq(RADIO_TECHS[i]));
@@ -904,13 +905,13 @@
                     .setProvisioningStatus(eq(mSubId0), eq(FEATURE_MMTEL), eq(capability),
                             eq(RADIO_TECHS[i]), eq(provisionedSecond));
 
-            // verify weather Callback is called or not
+            // verify whether Callback is called or not
             verify(mIFeatureProvisioningCallback0, times(1))
                     .onFeatureProvisioningChanged(eq(capability), eq(RADIO_TECHS[i]),
                             eq(provisionedSecond));
         }
 
-        // verify weather ImsConfig is called or not
+        // verify whether ImsConfig is called or not
         verify(mImsConfig, times(1)).setConfig(
                 eq(KEY_VOLTE_PROVISIONING_STATUS), eq(PROVISIONING_VALUE_ENABLED));
         verify(mImsConfig, times(1)).setConfig(
@@ -975,7 +976,7 @@
             // verify return value default false - provisioned
             assertEquals(!provisionedFirst, provisionedSecond);
 
-            // verify weather ImsProvisioningLoader is called or not
+            // verify whether ImsProvisioningLoader is called or not
             verify(mImsProvisioningLoader, times(2))
                     .getProvisioningStatus(eq(mSubId0), eq(FEATURE_MMTEL), eq(capability),
                             eq(RADIO_TECHS[i]));
@@ -983,13 +984,13 @@
                     .setProvisioningStatus(eq(mSubId0), eq(FEATURE_MMTEL), eq(capability),
                             eq(RADIO_TECHS[i]), eq(provisionedSecond));
 
-            // verify weather Callback is called or not
+            // verify whether Callback is called or not
             verify(mIFeatureProvisioningCallback0, times(1))
                     .onFeatureProvisioningChanged(eq(capability), eq(RADIO_TECHS[i]),
                             eq(provisionedSecond));
         }
 
-        // verify weather ImsConfig is called or not
+        // verify whether ImsConfig is called or not
         verify(mImsConfig, times(1)).setConfig(
                 eq(KEY_VT_PROVISIONING_STATUS), eq(PROVISIONING_VALUE_ENABLED));
 
@@ -1004,6 +1005,7 @@
     public void setRcsProvisioningRequiredForCapability_withPresence() throws Exception {
         createImsProvisioningController();
 
+        mMmTelConnectorListener0.getValue().connectionReady(mImsManager, mSubId0);
         mRcsConnectorListener0.getValue().connectionReady(mRcsFeatureManager, mSubId0);
         processAllMessages();
 
@@ -1052,20 +1054,21 @@
         // verify return value default false - provisioned
         assertEquals(!provisionedFirst, provisionedSecond);
 
-        // verify weather ImsProvisioningLoader is called or not
+        // verify whether ImsProvisioningLoader is called or not
         verify(mImsProvisioningLoader, times(2)).getProvisioningStatus(
                 eq(mSubId0), eq(FEATURE_RCS), eq(capability), eq(REGISTRATION_TECH_LTE));
         // verify setProvisioningStatus is called RADIO_TECHS.length times for all tech or not
         verify(mImsProvisioningLoader, times(1)).setProvisioningStatus(
                 eq(mSubId0), eq(FEATURE_RCS), eq(capability), anyInt(), eq(provisionedSecond));
 
-        // verify weather Callback is called RADIO_TECHS.length times for all tech or not
+        // verify whether Callback is called RADIO_TECHS.length times for all tech or not
         verify(mIFeatureProvisioningCallback0, times(1))
                 .onRcsFeatureProvisioningChanged(eq(capability), eq(REGISTRATION_TECH_LTE),
                         eq(provisionedSecond));
 
-        // verify weather ImsConfig is called or not
-        verify(mImsConfig, times(1)).setConfig(
+        // verify whether ImsConfig is called or not
+        // EAB provisioning status should be updated to both the Rcs and MmTel ImsService
+        verify(mImsConfig, times(2)).setConfig(
                 eq(KEY_EAB_PROVISIONING_STATUS), eq(PROVISIONING_VALUE_ENABLED));
 
         // verify reset
@@ -1080,7 +1083,7 @@
             // verify return value
             assertEquals(expected[i], provisionedSecond);
 
-            // verify weather ImsProvisioningLoader is called or not
+            // verify whether ImsProvisioningLoader is called or not
             verify(mImsProvisioningLoader, times(1)).getProvisioningStatus(
                     eq(mSubId0), eq(FEATURE_RCS), eq(capability), eq(RADIO_TECHS[i]));
         }
@@ -1157,7 +1160,7 @@
             // check return value
             assertEquals(ImsConfig.OperationStatusConstants.SUCCESS, result);
 
-            // check weather to save
+            // check whether to save
             verify(mImsProvisioningLoader, times(1)).setProvisioningStatus(
                     eq(mSubId0), eq(FEATURE_MMTEL), eq(capas[i]), eq(techs[i]), eq(true));
 
@@ -1178,6 +1181,7 @@
     public void setProvisioningValue_withRcsKey() throws Exception {
         createImsProvisioningController();
 
+        mMmTelConnectorListener0.getValue().connectionReady(mImsManager, mSubId0);
         mRcsConnectorListener0.getValue().connectionReady(mRcsFeatureManager, mSubId0);
         processAllMessages();
 
@@ -1215,14 +1219,16 @@
         // check return value
         assertEquals(ImsConfig.OperationStatusConstants.SUCCESS, result);
 
-        // check weather to save, for all techs 4 times
+        // check to save, for all techs 4 times
         verify(mImsProvisioningLoader, times(RADIO_TECHS.length)).setProvisioningStatus(
                 eq(mSubId0), eq(FEATURE_RCS), eq(capa), anyInt(), eq(true));
 
         verify(mIFeatureProvisioningCallback0, times(RADIO_TECHS.length))
                 .onRcsFeatureProvisioningChanged(eq(capa), anyInt(), eq(true));
 
-        verify(mImsConfig, times(1)).setConfig(eq(key), eq(PROVISIONING_VALUE_ENABLED));
+        // verify whether ImsConfig is called or not
+        // EAB provisioning status should be updated to both the Rcs and MmTel ImsService
+        verify(mImsConfig, times(2)).setConfig(eq(key), eq(PROVISIONING_VALUE_ENABLED));
 
         verifyNoMoreInteractions(mIFeatureProvisioningCallback0);
         verifyNoMoreInteractions(mIFeatureProvisioningCallback1);
@@ -1342,7 +1348,7 @@
             // check return value
             assertEquals(PROVISIONING_VALUE_ENABLED, result);
 
-            // verify weather ImsProvisioningLoader is called or not
+            // verify whether ImsProvisioningLoader is called or not
             verify(mImsProvisioningLoader, times(1)).getProvisioningStatus(eq(mSubId0),
                     eq(FEATURE_MMTEL), eq(capas[i]), eq(techs[i]));
         }
@@ -1358,7 +1364,7 @@
         // check return value
         assertEquals(PROVISIONING_VALUE_ENABLED, result);
 
-        // verify weather ImsProvisioningLoader is called or not
+        // verify whether ImsProvisioningLoader is called or not
         verify(mImsProvisioningLoader, times(1)).getProvisioningStatus(
                 eq(mSubId0), eq(FEATURE_RCS), eq(capa), anyInt());
 
@@ -1446,18 +1452,18 @@
             // check return value
             assertEquals(PROVISIONING_VALUE_ENABLED, result);
 
-            // verify weather ImsProvisioningLoader is called or not
+            // verify whether ImsProvisioningLoader is called or not
             verify(mImsProvisioningLoader, times(1)).getProvisioningStatus(eq(mSubId0),
                     eq(FEATURE_MMTEL), eq(capas[i]), eq(techs[i]));
 
-            // verify weather ImsConfig is called or not
+            // verify whether ImsConfig is called or not
             verify(mImsConfig, times(1)).getConfigInt(eq(keys[i]));
 
-            // verify weather ImsProvisioningLoader is called or not
+            // verify whether ImsProvisioningLoader is called or not
             verify(mImsProvisioningLoader, times(1)).setProvisioningStatus(eq(mSubId0),
                     eq(FEATURE_MMTEL), eq(capas[i]), eq(techs[i]), eq(true));
 
-            // verify weather callback is called or not
+            // verify whether callback is called or not
             verify(mIFeatureProvisioningCallback0, times(1)).onFeatureProvisioningChanged(
                     eq(capas[i]), eq(techs[i]), eq(true));
         }
@@ -1474,18 +1480,18 @@
         // check return value
         assertEquals(PROVISIONING_VALUE_ENABLED, result);
 
-        // verify weather ImsProvisioningLoader is called or not
+        // verify whether ImsProvisioningLoader is called or not
         verify(mImsProvisioningLoader, times(1)).getProvisioningStatus(
                 eq(mSubId0), eq(FEATURE_RCS), eq(capa), anyInt());
 
-        // verify weather ImsConfig is called or not
+        // verify whether ImsConfig is called or not
         verify(mImsConfig, times(1)).getConfigInt(eq(key));
 
-        // verify weather ImsProvisioningLoader is called or not
+        // verify whether ImsProvisioningLoader is called or not
         verify(mImsProvisioningLoader, times(RADIO_TECHS.length)).setProvisioningStatus(
                 eq(mSubId0), eq(FEATURE_RCS), eq(capa), anyInt(), eq(true));
 
-        // verify weather callback is called or not
+        // verify whether callback is called or not
         verify(mIFeatureProvisioningCallback0, times(RADIO_TECHS.length))
                 .onRcsFeatureProvisioningChanged(eq(capa), anyInt(), eq(true));
 
@@ -1582,7 +1588,7 @@
                 capability, tech, !provisioned);
         processAllMessages();
 
-        // verify weather Callback is called or not
+        // verify whether Callback is called or not
         verify(mIFeatureProvisioningCallback1, times(1))
                 .onFeatureProvisioningChanged(eq(capability), eq(tech), eq(!provisioned));
 
@@ -1591,6 +1597,145 @@
         clearInvocations(mImsConfig);
     }
 
+    @Test
+    @SmallTest
+    public void eabProvisioningStatus_onlyMmTelConnectionReady() throws Exception {
+        createImsProvisioningController();
+
+        mMmTelConnectorListener0.getValue().connectionReady(mImsManager, mSubId0);
+        processAllMessages();
+
+        // add callback with valid obj
+        mTestImsProvisioningController.addFeatureProvisioningChangedCallback(
+                mSubId0, mIFeatureProvisioningCallback0);
+
+        clearInvocations(mIFeatureProvisioningCallback0);
+        clearInvocations(mImsConfig);
+        clearInvocations(mImsProvisioningLoader);
+
+        // provisioning required capability
+        // presence, all tech
+        setCarrierConfig(mSubId0,
+                CarrierConfigManager.Ims.KEY_CAPABILITY_TYPE_PRESENCE_UCE_INT_ARRAY, RADIO_TECHS);
+
+        // provisioning Status, all of provisioning status is not set
+        mRcsProvisioningStorage = new int[][]{
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_LTE, -1},
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_IWLAN, -1},
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_CROSS_SIM, -1},
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_NR, -1}
+        };
+
+        // provisioning status in ImsService
+        mImsConfigStorage = new int[][] {
+                {KEY_EAB_PROVISIONING_STATUS, 1}
+        };
+
+        // Rcs keys
+        int key = KEY_EAB_PROVISIONING_STATUS;
+        int capa = CAPABILITY_TYPE_PRESENCE_UCE;
+        int tech = REGISTRATION_TECH_LTE;
+
+        int result = mTestImsProvisioningController.getProvisioningValue(mSubId0, key);
+        processAllMessages();
+
+        // check return value
+        assertEquals(PROVISIONING_VALUE_ENABLED, result);
+
+        // verify whether ImsProvisioningLoader is called or not
+        verify(mImsProvisioningLoader, times(1)).getProvisioningStatus(
+                eq(mSubId0), eq(FEATURE_RCS), eq(capa), anyInt());
+
+        // even if ImsConfig is not available in RcsFeatureListener, ImsConfig in
+        // MmTelFeatureListener will be called.
+        verify(mImsConfig, times(1)).getConfigInt(
+                eq(KEY_EAB_PROVISIONING_STATUS));
+
+        // verify whether ImsProvisioningLoader is called or not
+        verify(mImsProvisioningLoader, times(RADIO_TECHS.length)).setProvisioningStatus(
+                eq(mSubId0), eq(FEATURE_RCS), eq(capa), anyInt(), eq(true));
+
+        verifyNoMoreInteractions(mImsConfig);
+        verifyNoMoreInteractions(mImsProvisioningLoader);
+
+        clearInvocations(mImsConfig);
+        clearInvocations(mImsProvisioningLoader);
+
+        mTestImsProvisioningController.setProvisioningValue(mSubId0, key,
+                PROVISIONING_VALUE_DISABLED);
+        processAllMessages();
+
+        // verify whether ImsProvisioningLoader is called or not
+        verify(mImsProvisioningLoader, times(RADIO_TECHS.length)).setProvisioningStatus(
+                eq(mSubId0), eq(FEATURE_RCS), eq(capa), anyInt(), eq(false));
+
+        // even if ImsConfig is not available in RcsFeatureListener, ImsConfig in
+        // MmTelFeatureListener will be called.
+        verify(mImsConfig, times(1)).setConfig(
+                eq(KEY_EAB_PROVISIONING_STATUS), eq(PROVISIONING_VALUE_DISABLED));
+
+        verifyNoMoreInteractions(mImsConfig);
+        verifyNoMoreInteractions(mImsProvisioningLoader);
+
+        clearInvocations(mImsConfig);
+        clearInvocations(mImsProvisioningLoader);
+
+        // reset provisioning status, all of provisioning status is not set
+        mRcsProvisioningStorage = new int[][]{
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_LTE, -1},
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_IWLAN, -1},
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_CROSS_SIM, -1},
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_NR, -1}
+        };
+
+        // reset provisioning status in ImsService
+        mImsConfigStorage = new int[][] {
+                {KEY_EAB_PROVISIONING_STATUS, 1}
+        };
+
+        boolean expected = true;
+        boolean provisioned = mTestImsProvisioningController.getRcsProvisioningStatusForCapability(
+                mSubId0, capa, tech);
+        processAllMessages();
+
+        assertEquals(expected, provisioned);
+
+        // verify whether ImsProvisioningLoader is called or not
+        verify(mImsProvisioningLoader, times(1)).getProvisioningStatus(
+                eq(mSubId0), eq(FEATURE_RCS), eq(capa), eq(tech));
+
+        // even if ImsConfig is not available in RcsFeatureListener, ImsConfig in
+        // MmTelFeatureListener will be called.
+        verify(mImsConfig, times(1)).getConfigInt(
+                eq(KEY_EAB_PROVISIONING_STATUS));
+
+        // verify whether ImsProvisioningLoader is called or not
+        verify(mImsProvisioningLoader, times(RADIO_TECHS.length)).setProvisioningStatus(
+                eq(mSubId0), eq(FEATURE_RCS), eq(capa), anyInt(), eq(true));
+
+        verifyNoMoreInteractions(mImsConfig);
+        verifyNoMoreInteractions(mImsProvisioningLoader);
+
+        clearInvocations(mImsConfig);
+        clearInvocations(mImsProvisioningLoader);
+
+        mTestImsProvisioningController.setRcsProvisioningStatusForCapability(
+                mSubId0, capa, tech, !expected);
+        processAllMessages();
+
+        // verify whether ImsProvisioningLoader is called or not
+        verify(mImsProvisioningLoader, times(1)).setProvisioningStatus(
+                eq(mSubId0), eq(FEATURE_RCS), eq(capa), eq(tech), eq(!expected));
+
+        // even if ImsConfig is not available in RcsFeatureListener, ImsConfig in
+        // MmTelFeatureListener will be called.
+        verify(mImsConfig, times(1)).setConfig(
+                eq(KEY_EAB_PROVISIONING_STATUS), eq(PROVISIONING_VALUE_DISABLED));
+
+        verifyNoMoreInteractions(mImsConfig);
+        verifyNoMoreInteractions(mImsProvisioningLoader);
+    }
+
     private void createImsProvisioningController() throws Exception {
         if (Looper.myLooper() == null) {
             Looper.prepare();