Merge "Expose setCallProfile for unit testing." am: 0877155c81 am: 298d8c7576
am: 047d04cf63

Change-Id: I0ae8ac5325c9e6c16068e3117340f269de095570
diff --git a/src/java/com/android/ims/ImsManager.java b/src/java/com/android/ims/ImsManager.java
index a1d659c..1f38bce 100644
--- a/src/java/com/android/ims/ImsManager.java
+++ b/src/java/com/android/ims/ImsManager.java
@@ -20,10 +20,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Handler;
 import android.os.IBinder;
-import android.os.Looper;
 import android.os.Message;
 import android.os.Parcel;
 import android.os.PersistableBundle;
@@ -50,15 +47,14 @@
 import com.android.ims.internal.IImsUt;
 import com.android.ims.internal.ImsCallSession;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.ExponentialBackoff;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.concurrent.ConcurrentLinkedDeque;
 import java.util.HashSet;
 import java.util.Set;
+import java.util.concurrent.ConcurrentLinkedDeque;
 
 /**
  * Provides APIs for IMS services, such as initiating IMS calls, and provides access to
@@ -172,6 +168,11 @@
      */
     public static final String EXTRA_IS_UNKNOWN_CALL = "android:isUnknown";
 
+    private static final int SYSTEM_PROPERTY_NOT_SET = -1;
+
+    // -1 indicates a subscriptionProperty value that is never set.
+    private static final int SUB_PROPERTY_NOT_INITIALIZED = -1;
+
     private static final String TAG = "ImsManager";
     private static final boolean DBG = true;
 
@@ -211,10 +212,6 @@
     private boolean mHasRegisteredForProxy = false;
     private final Object mHasRegisteredLock = new Object();
 
-    // SystemProperties used as cache
-    private static final String VOLTE_PROVISIONED_PROP = "net.lte.ims.volte.provisioned";
-    private static final String WFC_PROVISIONED_PROP = "net.lte.ims.wfc.provisioned";
-    private static final String VT_PROVISIONED_PROP = "net.lte.ims.vt.provisioned";
     // Flag indicating data enabled or not. This flag should be in sync with
     // DcTracker.isDataEnabled(). The flag will be set later during boot up.
     private static final String DATA_ENABLED_PROP = "net.lte.ims.data.enabled";
@@ -227,17 +224,6 @@
     private ConcurrentLinkedDeque<ImsReasonInfo> mRecentDisconnectReasons =
             new ConcurrentLinkedDeque<>();
 
-    // Exponential backoff for provisioning cache update. May be null for instances of ImsManager
-    // that are not on a thread supporting a looper.
-    private ExponentialBackoff mProvisionBackoff;
-    // Initial Provisioning check delay in ms
-    private static final long BACKOFF_INITIAL_DELAY_MS = 500;
-    // Max Provisioning check delay in ms (5 Minutes)
-    private static final long BACKOFF_MAX_DELAY_MS = 300000;
-    // Multiplier for exponential delay
-    private static final int BACKOFF_MULTIPLIER = 2;
-
-
     /**
      * Gets a manager instance.
      *
@@ -281,26 +267,27 @@
 
     /**
      * Returns the user configuration of Enhanced 4G LTE Mode setting for slot. If the option is
-     * not editable ({@link CarrierConfigManager#KEY_EDITABLE_ENHANCED_4G_LTE_BOOL} is false),
-     * this method will return default value specified by
+     * not editable ({@link CarrierConfigManager#KEY_EDITABLE_ENHANCED_4G_LTE_BOOL} is false), or
+     * the setting is not initialized, this method will return default value specified by
      * {@link CarrierConfigManager#KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL}.
+     *
+     * Note that even if the setting was set, it may no longer be editable. If this is the case we
+     * return the default value.
      */
     public boolean isEnhanced4gLteModeSettingEnabledByUser() {
-        // If user can't edit Enhanced 4G LTE Mode, it assumes Enhanced 4G LTE Mode is default
-        // value.
-        // If user changes SIM from editable mode to uneditable mode, need to return default value.
-        int defaultValue = getBooleanCarrierConfig(
-                CarrierConfigManager.KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL) ?
-                ImsConfig.FeatureValueConstants.ON : ImsConfig.FeatureValueConstants.OFF;
-        if (!getBooleanCarrierConfig(
-                CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL)) {
-            return (defaultValue == ImsConfig.FeatureValueConstants.ON);
+        int setting = SubscriptionManager.getIntegerSubscriptionProperty(
+                getSubId(), SubscriptionManager.ENHANCED_4G_MODE_ENABLED,
+                SUB_PROPERTY_NOT_INITIALIZED, mContext);
+        boolean onByDefault = getBooleanCarrierConfig(
+                CarrierConfigManager.KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL);
+
+        // If Enhanced 4G LTE Mode is uneditable or not initialized, we use the default value
+        if (!getBooleanCarrierConfig(CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL)
+                || setting == SUB_PROPERTY_NOT_INITIALIZED) {
+            return onByDefault;
+        } else {
+            return (setting == ImsConfig.FeatureValueConstants.ON);
         }
-        int enabled = android.provider.Settings.Global.getInt(
-                mContext.getContentResolver(),
-                android.provider.Settings.Global.ENHANCED_4G_MODE_ENABLED,
-                defaultValue);
-        return (enabled == ImsConfig.FeatureValueConstants.ON);
     }
 
     /**
@@ -326,33 +313,27 @@
      *
      */
     public void setEnhanced4gLteModeSetting(boolean enabled) {
-        int value = enabled ? ImsConfig.FeatureValueConstants.ON :
-                ImsConfig.FeatureValueConstants.OFF;
         // If editable=false, we must keep default advanced 4G mode.
         if (!getBooleanCarrierConfig(CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL)) {
-            value = getBooleanCarrierConfig(
-                    CarrierConfigManager.KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL) ?
-                    ImsConfig.FeatureValueConstants.ON : ImsConfig.FeatureValueConstants.OFF;
+            enabled = getBooleanCarrierConfig(
+                    CarrierConfigManager.KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL);
         }
 
-        try {
-            int prevSetting = android.provider.Settings.Global.getInt(mContext.getContentResolver(),
-                    android.provider.Settings.Global.ENHANCED_4G_MODE_ENABLED);
-            if (prevSetting == value) {
-                // Don't trigger setAdvanced4GMode if the setting hasn't changed.
-                return;
-            }
-        } catch (Settings.SettingNotFoundException e) {
-            // Setting doesn't exist yet, so set it below.
-        }
+        int prevSetting = SubscriptionManager.getIntegerSubscriptionProperty(
+                getSubId(), SubscriptionManager.ENHANCED_4G_MODE_ENABLED,
+                SUB_PROPERTY_NOT_INITIALIZED, mContext);
 
-        android.provider.Settings.Global.putInt(mContext.getContentResolver(),
-                android.provider.Settings.Global.ENHANCED_4G_MODE_ENABLED, value);
-        if (isNonTtyOrTtyOnVolteEnabled()) {
-            try {
-                setAdvanced4GMode(value == ImsConfig.FeatureValueConstants.ON);
-            } catch (ImsException ie) {
-                // do nothing
+        if (prevSetting != (enabled ?
+                   ImsConfig.FeatureValueConstants.ON :
+                   ImsConfig.FeatureValueConstants.OFF)) {
+            SubscriptionManager.setSubscriptionProperty(getSubId(),
+                    SubscriptionManager.ENHANCED_4G_MODE_ENABLED, booleanToPropertyString(enabled));
+            if (isNonTtyOrTtyOnVolteEnabled()) {
+                try {
+                    setAdvanced4GMode(enabled);
+                } catch (ImsException ie) {
+                    // do nothing
+                }
             }
         }
     }
@@ -411,15 +392,19 @@
      * basis.
      */
     public boolean isVolteEnabledByPlatform() {
-        if (SystemProperties.getInt(PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE,
-                PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE_DEFAULT) == 1) {
+        // We first read the per slot value. If doesn't exist, we read the general value. If still
+        // doesn't exist, we use the hardcoded default value.
+        if (SystemProperties.getInt(
+                PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE + Integer.toString(mPhoneId),
+                SYSTEM_PROPERTY_NOT_SET) == 1 ||
+                SystemProperties.getInt(PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE,
+                        SYSTEM_PROPERTY_NOT_SET) == 1) {
             return true;
         }
 
         return mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_device_volte_available)
-                && getBooleanCarrierConfig(
-                        CarrierConfigManager.KEY_CARRIER_VOLTE_AVAILABLE_BOOL)
+                && getBooleanCarrierConfig(CarrierConfigManager.KEY_CARRIER_VOLTE_AVAILABLE_BOOL)
                 && isGbaValid();
     }
 
@@ -546,15 +531,18 @@
      * which must be done correctly).
      */
     public boolean isVtEnabledByPlatform() {
-        if (SystemProperties.getInt(PROPERTY_DBG_VT_AVAIL_OVERRIDE,
-                PROPERTY_DBG_VT_AVAIL_OVERRIDE_DEFAULT) == 1) {
+        // We first read the per slot value. If doesn't exist, we read the general value. If still
+        // doesn't exist, we use the hardcoded default value.
+        if (SystemProperties.getInt(PROPERTY_DBG_VT_AVAIL_OVERRIDE +
+                Integer.toString(mPhoneId), SYSTEM_PROPERTY_NOT_SET) == 1  ||
+                SystemProperties.getInt(
+                        PROPERTY_DBG_VT_AVAIL_OVERRIDE, SYSTEM_PROPERTY_NOT_SET) == 1) {
             return true;
         }
 
         return mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_device_vt_available) &&
-                getBooleanCarrierConfig(
-                        CarrierConfigManager.KEY_CARRIER_VT_AVAILABLE_BOOL) &&
+                getBooleanCarrierConfig(CarrierConfigManager.KEY_CARRIER_VT_AVAILABLE_BOOL) &&
                 isGbaValid();
     }
 
@@ -574,13 +562,17 @@
     }
 
     /**
-     * Returns the user configuration of VT setting per slot.
+     * Returns the user configuration of VT setting per slot. If not set, it
+     * returns true as default value.
      */
     public boolean isVtEnabledByUser() {
-        int enabled = android.provider.Settings.Global.getInt(mContext.getContentResolver(),
-                android.provider.Settings.Global.VT_IMS_ENABLED,
-                ImsConfig.FeatureValueConstants.ON);
-        return (enabled == 1);
+        int setting = SubscriptionManager.getIntegerSubscriptionProperty(
+                getSubId(), SubscriptionManager.VT_IMS_ENABLED,
+                SUB_PROPERTY_NOT_INITIALIZED, mContext);
+
+        // If it's never set, by default we return true.
+        return (setting == SUB_PROPERTY_NOT_INITIALIZED
+                || setting == ImsConfig.FeatureValueConstants.ON);
     }
 
     /**
@@ -601,10 +593,9 @@
      * Change persistent VT enabled setting for slot.
      */
     public void setVtSetting(boolean enabled) {
-        int value = enabled ? 1 : 0;
-        android.provider.Settings.Global.putInt(mContext.getContentResolver(),
-                android.provider.Settings.Global.VT_IMS_ENABLED, value);
-
+        SubscriptionManager.setSubscriptionProperty(getSubId(),
+                SubscriptionManager.VT_IMS_ENABLED,
+                booleanToPropertyString(enabled));
         try {
             ImsConfig config = getConfigInterface();
             config.setFeatureValue(ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE,
@@ -649,10 +640,15 @@
      * The platform property may override the carrier config.
      */
     private boolean isTurnOffImsAllowedByPlatform() {
-        if (SystemProperties.getInt(PROPERTY_DBG_ALLOW_IMS_OFF_OVERRIDE,
-                PROPERTY_DBG_ALLOW_IMS_OFF_OVERRIDE_DEFAULT) == 1) {
+        // We first read the per slot value. If doesn't exist, we read the general value. If still
+        // doesn't exist, we use the hardcoded default value.
+        if (SystemProperties.getInt(PROPERTY_DBG_ALLOW_IMS_OFF_OVERRIDE +
+                Integer.toString(mPhoneId), SYSTEM_PROPERTY_NOT_SET) == 1  ||
+                SystemProperties.getInt(
+                        PROPERTY_DBG_ALLOW_IMS_OFF_OVERRIDE, SYSTEM_PROPERTY_NOT_SET) == 1) {
             return true;
         }
+
         return getBooleanCarrierConfig(
                 CarrierConfigManager.KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL);
     }
@@ -674,15 +670,21 @@
     }
 
     /**
-     * Returns the user configuration of WFC setting for slot.
+     * Returns the user configuration of WFC setting for slot. If not set, it
+     * queries CarrierConfig value as default.
      */
     public boolean isWfcEnabledByUser() {
-        int enabled = android.provider.Settings.Global.getInt(mContext.getContentResolver(),
-                android.provider.Settings.Global.WFC_IMS_ENABLED,
-                getBooleanCarrierConfig(
-                        CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL) ?
-                        ImsConfig.FeatureValueConstants.ON : ImsConfig.FeatureValueConstants.OFF);
-        return enabled == 1;
+        int setting = SubscriptionManager.getIntegerSubscriptionProperty(
+                getSubId(), SubscriptionManager.WFC_IMS_ENABLED,
+                SUB_PROPERTY_NOT_INITIALIZED, mContext);
+
+        // SUB_PROPERTY_NOT_INITIALIZED indicates it's never set in sub db.
+        if (setting == SUB_PROPERTY_NOT_INITIALIZED) {
+            return getBooleanCarrierConfig(
+                    CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL);
+        } else {
+            return setting == ImsConfig.FeatureValueConstants.ON;
+        }
     }
 
     /**
@@ -703,9 +705,8 @@
      * Change persistent WFC enabled setting for slot.
      */
     public void setWfcSetting(boolean enabled) {
-        int value = enabled ? 1 : 0;
-        android.provider.Settings.Global.putInt(mContext.getContentResolver(),
-                android.provider.Settings.Global.WFC_IMS_ENABLED, value);
+        SubscriptionManager.setSubscriptionProperty(getSubId(),
+                SubscriptionManager.WFC_IMS_ENABLED, booleanToPropertyString(enabled));
 
         setWfcNonPersistent(enabled, getWfcMode());
     }
@@ -748,7 +749,7 @@
     /**
      * Returns the user configuration of WFC preference setting.
      *
-     * @deprecated Doesn't support MSIM devices. Use {@link #getWfcMode()} instead.
+     * @deprecated Doesn't support MSIM devices. Use {@link #getWfcMode(boolean roaming)} instead.
      */
     public static int getWfcMode(Context context) {
         ImsManager mgr = ImsManager.getInstance(context,
@@ -762,13 +763,10 @@
 
     /**
      * Returns the user configuration of WFC preference setting
+     * @deprecated. Use {@link #getWfcMode(boolean roaming)} instead.
      */
     public int getWfcMode() {
-        int setting = android.provider.Settings.Global.getInt(mContext.getContentResolver(),
-                android.provider.Settings.Global.WFC_IMS_MODE, getIntCarrierConfig(
-                        CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT));
-        if (DBG) log("getWfcMode - setting=" + setting);
-        return setting;
+        return getWfcMode(false);
     }
 
     /**
@@ -790,8 +788,9 @@
      */
     public void setWfcMode(int wfcMode) {
         if (DBG) log("setWfcMode(i) - setting=" + wfcMode);
-        android.provider.Settings.Global.putInt(mContext.getContentResolver(),
-                android.provider.Settings.Global.WFC_IMS_MODE, wfcMode);
+
+        SubscriptionManager.setSubscriptionProperty(getSubId(),
+                SubscriptionManager.WFC_IMS_MODE, Integer.toString(wfcMode));
 
         setWfcModeInternal(wfcMode);
     }
@@ -825,22 +824,35 @@
     }
 
     /**
-     * Returns the user configuration of WFC preference setting for slot
+     * Returns the user configuration of WFC preference setting for slot. If not set, it
+     * queries CarrierConfig value as default.
      *
      * @param roaming {@code false} for home network setting, {@code true} for roaming  setting
      */
     public int getWfcMode(boolean roaming) {
         int setting = 0;
         if (!roaming) {
-            setting = android.provider.Settings.Global.getInt(mContext.getContentResolver(),
-                    android.provider.Settings.Global.WFC_IMS_MODE, getIntCarrierConfig(
-                            CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT));
+            setting = SubscriptionManager.getIntegerSubscriptionProperty(
+                    getSubId(), SubscriptionManager.WFC_IMS_MODE,
+                    SUB_PROPERTY_NOT_INITIALIZED, mContext);
+
+            // SUB_PROPERTY_NOT_INITIALIZED indicates it's never set in sub db.
+            if (setting == SUB_PROPERTY_NOT_INITIALIZED) {
+                setting = getIntCarrierConfig(
+                        CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT);
+            }
             if (DBG) log("getWfcMode - setting=" + setting);
         } else {
-            setting = android.provider.Settings.Global.getInt(mContext.getContentResolver(),
-                    android.provider.Settings.Global.WFC_IMS_ROAMING_MODE,
-                    getIntCarrierConfig(
-                            CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT));
+            setting = SubscriptionManager.getIntegerSubscriptionProperty(
+                    getSubId(), SubscriptionManager.WFC_IMS_ROAMING_MODE,
+                    SUB_PROPERTY_NOT_INITIALIZED, mContext);
+
+            // SUB_PROPERTY_NOT_INITIALIZED indicates it's never set in sub db.
+            if (setting == SUB_PROPERTY_NOT_INITIALIZED) {
+                setting = getIntCarrierConfig(
+                        CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT);
+            }
+
             if (DBG) log("getWfcMode (roaming) - setting=" + setting);
         }
         return setting;
@@ -871,15 +883,14 @@
     public void setWfcMode(int wfcMode, boolean roaming) {
         if (!roaming) {
             if (DBG) log("setWfcMode(i,b) - setting=" + wfcMode);
-            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
-                    android.provider.Settings.Global.WFC_IMS_MODE, wfcMode);
+            SubscriptionManager.setSubscriptionProperty(getSubId(),
+                    SubscriptionManager.WFC_IMS_MODE, Integer.toString(wfcMode));
         } else {
             if (DBG) log("setWfcMode(i,b) (roaming) - setting=" + wfcMode);
-            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
-                    android.provider.Settings.Global.WFC_IMS_ROAMING_MODE, wfcMode);
+            SubscriptionManager.setSubscriptionProperty(getSubId(),
+                    SubscriptionManager.WFC_IMS_ROAMING_MODE, Integer.toString(wfcMode));
         }
 
-
         TelephonyManager tm = (TelephonyManager)
                 mContext.getSystemService(Context.TELEPHONY_SERVICE);
         if (roaming == tm.isNetworkRoaming(getSubId())) {
@@ -919,13 +930,12 @@
     private void setWfcModeInternal(int wfcMode) {
         final int value = wfcMode;
         Thread thread = new Thread(() -> {
-                try {
-                    getConfigInterface().setProvisionedValue(
-                            ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE,
-                            value);
-                } catch (ImsException e) {
-                    // do nothing
-                }
+            try {
+                getConfigInterface().setProvisionedValue(
+                        ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE, value);
+            } catch (ImsException e) {
+                // do nothing
+            }
         });
         thread.start();
     }
@@ -947,15 +957,19 @@
     }
 
     /**
-     * Returns the user configuration of WFC roaming setting for slot
+     * Returns the user configuration of WFC roaming setting for slot. If not set, it
+     * queries CarrierConfig value as default.
      */
     public boolean isWfcRoamingEnabledByUser() {
-        int enabled = android.provider.Settings.Global.getInt(mContext.getContentResolver(),
-                android.provider.Settings.Global.WFC_IMS_ROAMING_ENABLED,
-                getBooleanCarrierConfig(
-                        CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_ENABLED_BOOL) ?
-                        ImsConfig.FeatureValueConstants.ON : ImsConfig.FeatureValueConstants.OFF);
-        return (enabled == 1);
+        int setting =  SubscriptionManager.getIntegerSubscriptionProperty(
+                getSubId(), SubscriptionManager.WFC_IMS_ROAMING_ENABLED,
+                SUB_PROPERTY_NOT_INITIALIZED, mContext);
+        if (setting == SUB_PROPERTY_NOT_INITIALIZED) {
+            return getBooleanCarrierConfig(
+                            CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_ENABLED_BOOL);
+        } else {
+            return setting == ImsConfig.FeatureValueConstants.ON;
+        }
     }
 
     /**
@@ -974,10 +988,9 @@
      * Change persistent WFC roaming enabled setting
      */
     public void setWfcRoamingSetting(boolean enabled) {
-        android.provider.Settings.Global.putInt(mContext.getContentResolver(),
-                android.provider.Settings.Global.WFC_IMS_ROAMING_ENABLED,
-                enabled ? ImsConfig.FeatureValueConstants.ON
-                        : ImsConfig.FeatureValueConstants.OFF);
+        SubscriptionManager.setSubscriptionProperty(getSubId(),
+                SubscriptionManager.WFC_IMS_ROAMING_ENABLED, booleanToPropertyString(enabled)
+        );
 
         setWfcRoamingSettingInternal(enabled);
     }
@@ -987,13 +1000,12 @@
                 ? ImsConfig.FeatureValueConstants.ON
                 : ImsConfig.FeatureValueConstants.OFF;
         Thread thread = new Thread(() -> {
-                try {
-                    getConfigInterface().setProvisionedValue(
-                            ImsConfig.ConfigConstants.VOICE_OVER_WIFI_ROAMING,
-                            value);
-                } catch (ImsException e) {
-                    // do nothing
-                }
+            try {
+                getConfigInterface().setProvisionedValue(
+                        ImsConfig.ConfigConstants.VOICE_OVER_WIFI_ROAMING, value);
+            } catch (ImsException e) {
+                // do nothing
+            }
         });
         thread.start();
     }
@@ -1022,8 +1034,12 @@
      * configuration settings which must be done correctly).
      */
     public boolean isWfcEnabledByPlatform() {
-        if (SystemProperties.getInt(PROPERTY_DBG_WFC_AVAIL_OVERRIDE,
-                PROPERTY_DBG_WFC_AVAIL_OVERRIDE_DEFAULT) == 1) {
+        // We first read the per slot value. If doesn't exist, we read the general value. If still
+        // doesn't exist, we use the hardcoded default value.
+        if (SystemProperties.getInt(PROPERTY_DBG_WFC_AVAIL_OVERRIDE +
+                Integer.toString(mPhoneId), SYSTEM_PROPERTY_NOT_SET) == 1  ||
+                SystemProperties.getInt(
+                        PROPERTY_DBG_WFC_AVAIL_OVERRIDE, SYSTEM_PROPERTY_NOT_SET) == 1) {
             return true;
         }
 
@@ -1058,116 +1074,28 @@
     }
 
     /**
-     * This function should be called when ImsConfig.ACTION_IMS_CONFIG_CHANGED is received.
-     *
-     * We cannot register receiver in ImsManager because this would lead to resource leak.
-     * ImsManager can be created in different processes and it is not notified when that process
-     * is about to be terminated.
-     *
-     * @hide
-     * */
-    public static void onProvisionedValueChanged(Context context, int item, String value) {
-        if (DBG) Rlog.d(TAG, "onProvisionedValueChanged: item=" + item + " val=" + value);
-        ImsManager mgr = ImsManager.getInstance(context,
-                SubscriptionManager.getDefaultVoicePhoneId());
-
-        switch (item) {
-            case ImsConfig.ConfigConstants.VLT_SETTING_ENABLED:
-                mgr.setVolteProvisionedProperty(value.equals("1"));
-                if (DBG) Rlog.d(TAG,"isVoLteProvisioned = " + mgr.isVolteProvisioned());
-                break;
-
-            case ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED:
-                mgr.setWfcProvisionedProperty(value.equals("1"));
-                if (DBG) Rlog.d(TAG,"isWfcProvisioned = " + mgr.isWfcProvisioned());
-                break;
-
-            case ImsConfig.ConfigConstants.LVC_SETTING_ENABLED:
-                mgr.setVtProvisionedProperty(value.equals("1"));
-                if (DBG) Rlog.d(TAG,"isVtProvisioned = " + mgr.isVtProvisioned());
-                break;
-
+     * Will return with config value or throw an ImsException if we receive an error from
+     * ImsConfig for that value.
+     */
+    private boolean getProvisionedBool(ImsConfig config, int item) throws ImsException {
+        int value = config.getProvisionedValue(item);
+        if (value == ImsConfig.OperationStatusConstants.UNKNOWN) {
+            throw new ImsException("getProvisionedBool failed with error for item: " + item,
+                    ImsReasonInfo.CODE_LOCAL_INTERNAL_ERROR);
         }
-    }
-
-    private class AsyncUpdateProvisionedValues extends AsyncTask<Void, Void, Boolean> {
-        @Override
-        protected Boolean doInBackground(Void... params) {
-            // disable on any error
-            setVolteProvisionedProperty(false);
-            setWfcProvisionedProperty(false);
-            setVtProvisionedProperty(false);
-
-            try {
-                ImsConfig config = getConfigInterface();
-                if (config != null) {
-                    setVolteProvisionedProperty(getProvisionedBool(config,
-                            ImsConfig.ConfigConstants.VLT_SETTING_ENABLED));
-                    if (DBG) Rlog.d(TAG, "isVoLteProvisioned = " + isVolteProvisioned());
-
-                    setWfcProvisionedProperty(getProvisionedBool(config,
-                            ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED));
-                    if (DBG) Rlog.d(TAG, "isWfcProvisioned = " + isWfcProvisioned());
-
-                    setVtProvisionedProperty(getProvisionedBool(config,
-                            ImsConfig.ConfigConstants.LVC_SETTING_ENABLED));
-                    if (DBG) Rlog.d(TAG, "isVtProvisioned = " + isVtProvisioned());
-
-                }
-            } catch (ImsException ie) {
-                Rlog.e(TAG, "AsyncUpdateProvisionedValues error: ", ie);
-                return false;
-            }
-
-            return true;
-        }
-
-        @Override
-        protected void onPostExecute(Boolean completed) {
-            if (mProvisionBackoff == null) {
-                return;
-            }
-            if (!completed) {
-                mProvisionBackoff.notifyFailed();
-            } else {
-                mProvisionBackoff.stop();
-            }
-        }
-
-        /**
-         * Will return with config value or throw an ImsException if we receive an error from
-         * ImsConfig for that value.
-         */
-        private boolean getProvisionedBool(ImsConfig config, int item) throws ImsException {
-            int value = config.getProvisionedValue(item);
-            if (value == ImsConfig.FeatureValueConstants.ERROR) {
-                throw new ImsException("getProvisionedBool failed with error for item: " + item,
-                        ImsReasonInfo.CODE_LOCAL_INTERNAL_ERROR);
-            }
-            return config.getProvisionedValue(item) == ImsConfig.FeatureValueConstants.ON;
-        }
-    }
-
-    // used internally only, use #updateProvisionedValues instead.
-    private void handleUpdateProvisionedValues() {
-        if (getBooleanCarrierConfig(
-                CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL)) {
-
-            new AsyncUpdateProvisionedValues().execute();
-        }
+        return config.getProvisionedValue(item) == ImsConfig.FeatureValueConstants.ON;
     }
 
     /**
-     * Asynchronously get VoLTE, WFC, VT provisioning statuses. If ImsConfig is not available, we
-     * will retry with exponential backoff.
+     * Will return with config value or return false if we receive an error from
+     * ImsConfig for that value.
      */
-    private void updateProvisionedValues() {
-        // Start trying to receive provisioning status after BACKOFF_INITIAL_DELAY_MS.
-        if (mProvisionBackoff != null) {
-            mProvisionBackoff.start();
-        } else {
-            // bypass and launch async thread once without backoff.
-            handleUpdateProvisionedValues();
+    private boolean getProvisionedBoolNoException(int item) {
+        try {
+            ImsConfig config = getConfigInterface();
+            return getProvisionedBool(config, item);
+        } catch (ImsException ex) {
+            return false;
         }
     }
 
@@ -1192,8 +1120,6 @@
     /**
      * Sync carrier config and user settings with ImsConfig.
      *
-     * @param context for the manager object
-     * @param phoneId phone id
      * @param force update
      */
     public void updateImsServiceConfig(boolean force) {
@@ -1208,8 +1134,6 @@
 
         if (!mConfigUpdated || force) {
             try {
-                updateProvisionedValues();
-
                 // TODO: Extend ImsConfig API and set all feature values in single function call.
 
                 // Note: currently the order of updates is set to produce different order of
@@ -1347,11 +1271,6 @@
                 com.android.internal.R.bool.config_dynamic_bind_ims);
         mConfigManager = (CarrierConfigManager) context.getSystemService(
                 Context.CARRIER_CONFIG_SERVICE);
-        if (Looper.getMainLooper() != null) {
-            mProvisionBackoff = new ExponentialBackoff(BACKOFF_INITIAL_DELAY_MS,
-                    BACKOFF_MAX_DELAY_MS, BACKOFF_MULTIPLIER,
-                    new Handler(Looper.getMainLooper()), this::handleUpdateProvisionedValues);
-        }
         createImsService();
     }
 
@@ -2402,35 +2321,33 @@
      * @hide
      */
     public void factoryReset() {
-        // Delete VoLTE row to retrieve the default value.
-        mContext.getContentResolver().delete(
-                Settings.Global.getUriFor(Settings.Global.ENHANCED_4G_MODE_ENABLED),
-                null, null);
+        // Set VoLTE to default
+        SubscriptionManager.setSubscriptionProperty(getSubId(),
+                SubscriptionManager.ENHANCED_4G_MODE_ENABLED,
+                booleanToPropertyString(getBooleanCarrierConfig(
+                        CarrierConfigManager.KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL)));
 
         // Set VoWiFi to default
-        android.provider.Settings.Global.putInt(mContext.getContentResolver(),
-                android.provider.Settings.Global.WFC_IMS_ENABLED,
-                getBooleanCarrierConfig(
-                        CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL) ?
-                        ImsConfig.FeatureValueConstants.ON : ImsConfig.FeatureValueConstants.OFF);
+        SubscriptionManager.setSubscriptionProperty(getSubId(),
+                SubscriptionManager.WFC_IMS_ENABLED,
+                booleanToPropertyString(getBooleanCarrierConfig(
+                        CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL)));
 
         // Set VoWiFi mode to default
-        android.provider.Settings.Global.putInt(mContext.getContentResolver(),
-                android.provider.Settings.Global.WFC_IMS_MODE,
-                getIntCarrierConfig(
-                        CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT));
+        SubscriptionManager.setSubscriptionProperty(getSubId(),
+                SubscriptionManager.WFC_IMS_MODE,
+                Integer.toString(getIntCarrierConfig(
+                        CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT)));
 
         // Set VoWiFi roaming to default
-        android.provider.Settings.Global.putInt(mContext.getContentResolver(),
-                android.provider.Settings.Global.WFC_IMS_ROAMING_ENABLED,
-                getBooleanCarrierConfig(
-                        CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_ENABLED_BOOL) ?
-                        ImsConfig.FeatureValueConstants.ON : ImsConfig.FeatureValueConstants.OFF);
+        SubscriptionManager.setSubscriptionProperty(getSubId(),
+                SubscriptionManager.WFC_IMS_ROAMING_ENABLED,
+                booleanToPropertyString(getBooleanCarrierConfig(
+                        CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_ENABLED_BOOL)));
 
         // Set VT to default
-        android.provider.Settings.Global.putInt(mContext.getContentResolver(),
-                android.provider.Settings.Global.VT_IMS_ENABLED,
-                ImsConfig.FeatureValueConstants.ON);
+        SubscriptionManager.setSubscriptionProperty(getSubId(),
+                SubscriptionManager.VT_IMS_ENABLED, booleanToPropertyString(true));
 
         // Push settings to ImsConfig
         updateImsServiceConfig(true);
@@ -2450,29 +2367,25 @@
     }
 
     private boolean isVolteProvisioned() {
-        return SystemProperties.getBoolean(VOLTE_PROVISIONED_PROP, true);
-    }
-
-    private void setVolteProvisionedProperty(boolean provisioned) {
-        SystemProperties.set(VOLTE_PROVISIONED_PROP, provisioned ? TRUE : FALSE);
+        return getProvisionedBoolNoException(
+                ImsConfig.ConfigConstants.VLT_SETTING_ENABLED);
     }
 
     private boolean isWfcProvisioned() {
-        return SystemProperties.getBoolean(WFC_PROVISIONED_PROP, true);
-    }
-
-    private void setWfcProvisionedProperty(boolean provisioned) {
-        SystemProperties.set(WFC_PROVISIONED_PROP, provisioned ? TRUE : FALSE);
+        return getProvisionedBoolNoException(
+                ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED);
     }
 
     private boolean isVtProvisioned() {
-        return SystemProperties.getBoolean(VT_PROVISIONED_PROP, true);
+        return getProvisionedBoolNoException(
+                ImsConfig.ConfigConstants.LVC_SETTING_ENABLED);
     }
 
-    private void setVtProvisionedProperty(boolean provisioned) {
-        SystemProperties.set(VT_PROVISIONED_PROP, provisioned ? TRUE : FALSE);
+    private static String booleanToPropertyString(boolean bool) {
+        return bool ? "1" : "0";
     }
 
+
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("ImsManager:");
         pw.println("  mPhoneId = " + mPhoneId);