Integrate MMTel APIs into the framework am: 936a7d1641 am: fd04a75710
am: 6c96d2cb30  -s ours

Change-Id: I1a0c5536419890813722e95ae19adb76a345646e
diff --git a/src/java/com/android/ims/ImsCall.java b/src/java/com/android/ims/ImsCall.java
index 6200a07..e32103e 100644
--- a/src/java/com/android/ims/ImsCall.java
+++ b/src/java/com/android/ims/ImsCall.java
@@ -36,10 +36,15 @@
 import java.util.concurrent.atomic.AtomicInteger;
 
 import android.telephony.ServiceState;
+import android.telephony.ims.ImsCallProfile;
+import android.telephony.ims.ImsConferenceState;
+import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.ImsStreamMediaProfile;
+import android.telephony.ims.ImsSuppServiceNotification;
 import android.util.Log;
 
 import com.android.ims.internal.ICall;
-import com.android.ims.internal.ImsCallSession;
+import android.telephony.ims.ImsCallSession;
 import com.android.ims.internal.ImsStreamMediaSession;
 import com.android.internal.annotations.VisibleForTesting;
 
@@ -1623,6 +1628,7 @@
             // Make a copy of the current ImsCallProfile and modify it to enable RTT
             Parcel p = Parcel.obtain();
             mCallProfile.writeToParcel(p, 0);
+            p.setDataPosition(0);
             ImsCallProfile requestedProfile = new ImsCallProfile(p);
             requestedProfile.mMediaProfile.setRttMode(ImsStreamMediaProfile.RTT_MODE_FULL);
 
@@ -3072,6 +3078,7 @@
         public void callSessionRttModifyRequestReceived(ImsCallSession session,
                 ImsCallProfile callProfile) {
             ImsCall.Listener listener;
+            logi("callSessionRttModifyRequestReceived");
 
             synchronized(ImsCall.this) {
                 listener = mListener;
@@ -3096,6 +3103,7 @@
         public void callSessionRttModifyResponseReceived(int status) {
             ImsCall.Listener listener;
 
+            logi("callSessionRttModifyResponseReceived");
             synchronized(ImsCall.this) {
                 listener = mListener;
             }
diff --git a/src/java/com/android/ims/ImsConnectionStateListener.java b/src/java/com/android/ims/ImsConnectionStateListener.java
index 049b846..d5fb633 100644
--- a/src/java/com/android/ims/ImsConnectionStateListener.java
+++ b/src/java/com/android/ims/ImsConnectionStateListener.java
@@ -17,6 +17,7 @@
 package com.android.ims;
 
 import android.net.Uri;
+import android.telephony.ims.ImsReasonInfo;
 import android.telephony.ims.feature.ImsFeature;
 import android.telephony.ims.feature.MmTelFeature;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
diff --git a/src/java/com/android/ims/ImsEcbm.java b/src/java/com/android/ims/ImsEcbm.java
index 53549bf..99d99f1 100644
--- a/src/java/com/android/ims/ImsEcbm.java
+++ b/src/java/com/android/ims/ImsEcbm.java
@@ -29,18 +29,12 @@
 
 package com.android.ims;
 
-import java.util.HashMap;
-import java.util.Map;
-
-import android.os.AsyncResult;
-import android.os.Bundle;
-import android.os.Message;
 import android.os.RemoteException;
 import android.telephony.Rlog;
+import android.telephony.ims.ImsReasonInfo;
 
 import com.android.ims.internal.IImsEcbm;
 import com.android.ims.internal.IImsEcbmListener;
-import com.android.ims.ImsEcbmStateListener;
 
 /**
  * Provides APIs for the supplementary service settings using IMS (Ut interface).
diff --git a/src/java/com/android/ims/ImsExternalCallStateListener.java b/src/java/com/android/ims/ImsExternalCallStateListener.java
index 3f4f163..aae4c9b 100644
--- a/src/java/com/android/ims/ImsExternalCallStateListener.java
+++ b/src/java/com/android/ims/ImsExternalCallStateListener.java
@@ -16,6 +16,8 @@
 
 package com.android.ims;
 
+import android.telephony.ims.ImsExternalCallState;
+
 import java.util.List;
 
 /**
diff --git a/src/java/com/android/ims/ImsManager.java b/src/java/com/android/ims/ImsManager.java
index 9cfff78..0a0eb24 100644
--- a/src/java/com/android/ims/ImsManager.java
+++ b/src/java/com/android/ims/ImsManager.java
@@ -19,11 +19,8 @@
 import android.annotation.Nullable;
 import android.app.PendingIntent;
 import android.content.Context;
-import android.os.AsyncTask;
-import android.os.Handler;
 import android.os.Bundle;
 import android.os.IBinder;
-import android.os.Looper;
 import android.os.Message;
 import android.os.Parcel;
 import android.os.PersistableBundle;
@@ -31,33 +28,32 @@
 import android.os.SystemProperties;
 import android.telecom.TelecomManager;
 import android.telephony.CarrierConfigManager;
-import android.telephony.ims.internal.feature.ImsFeature;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
 import android.telephony.Rlog;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.telephony.ims.ImsCallProfile;
+import android.telephony.ims.ImsReasonInfo;
 import android.telephony.ims.aidl.IImsConfig;
 import android.telephony.ims.aidl.IImsSmsListener;
 import android.telephony.ims.feature.CapabilityChangeRequest;
 import android.telephony.ims.feature.ImsFeature;
 import android.telephony.ims.feature.MmTelFeature;
-import android.telephony.ims.stub.ImsRegistrationImplBase;
 import android.util.Log;
 
 import com.android.ims.internal.IImsCallSession;
 import com.android.ims.internal.IImsEcbm;
 import com.android.ims.internal.IImsMultiEndpoint;
 import com.android.ims.internal.IImsUt;
-import com.android.ims.internal.ImsCallSession;
+import android.telephony.ims.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.Set;
+import java.util.concurrent.ConcurrentLinkedDeque;
 import java.util.concurrent.CopyOnWriteArraySet;
 
 /**
@@ -165,6 +161,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;
 
@@ -193,14 +194,6 @@
     private Set<MmTelFeatureConnection.IFeatureUpdate> mStatusCallbacks =
             new CopyOnWriteArraySet<>();
 
-    // 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";
-
     public static final String TRUE = "true";
     public static final String FALSE = "false";
 
@@ -209,19 +202,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;
-    // -1 indicates a subscriptionProperty value that is never set.
-    private static final int SUB_PROPERTY_NOT_INITIALIZED = -1;
-
-
     /**
      * Gets a manager instance.
      *
@@ -265,9 +245,12 @@
 
     /**
      * 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() {
         int setting = SubscriptionManager.getIntegerSubscriptionProperty(
@@ -387,8 +370,13 @@
      * 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;
         }
 
@@ -521,8 +509,12 @@
      * 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;
         }
 
@@ -557,7 +549,8 @@
                 SUB_PROPERTY_NOT_INITIALIZED, mContext);
 
         // If it's never set, by default we return true.
-        return (setting == SUB_PROPERTY_NOT_INITIALIZED || setting == 1);
+        return (setting == SUB_PROPERTY_NOT_INITIALIZED
+                || setting == ImsConfig.FeatureValueConstants.ON);
     }
 
     /**
@@ -624,10 +617,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);
     }
@@ -662,7 +660,7 @@
             return getBooleanCarrierConfig(
                     CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL);
         } else {
-            return setting == 1;
+            return setting == ImsConfig.FeatureValueConstants.ON;
         }
     }
 
@@ -942,7 +940,7 @@
             return getBooleanCarrierConfig(
                             CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_ENABLED_BOOL);
         } else {
-            return (setting == 1);
+            return setting == ImsConfig.FeatureValueConstants.ON;
         }
     }
 
@@ -1008,8 +1006,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;
         }
 
@@ -1044,116 +1046,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;
         }
     }
 
@@ -1178,8 +1092,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) {
@@ -1194,8 +1106,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
@@ -1318,11 +1228,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();
     }
 
@@ -1734,6 +1639,28 @@
         }
     }
 
+    public void setRttEnabled(boolean enabled) {
+        try {
+            setAdvanced4GMode(enabled || isEnhanced4gLteModeSettingEnabledByUser());
+            final int value = enabled ? ImsConfig.FeatureValueConstants.ON :
+                    ImsConfig.FeatureValueConstants.OFF;
+            Thread thread = new Thread(() -> {
+                try {
+                    Log.i(ImsManager.class.getSimpleName(), "Setting RTT enabled to " + enabled);
+                    getConfigInterface().setProvisionedValue(
+                            ImsConfig.ConfigConstants.RTT_SETTING_ENABLED, value);
+                } catch (ImsException e) {
+                    Log.e(ImsManager.class.getSimpleName(), "Unable to set RTT enabled to "
+                            + enabled + ": " + e);
+                }
+            });
+            thread.start();
+        } catch (ImsException e) {
+            Log.e(ImsManager.class.getSimpleName(), "Unable to set RTT enabled to " + enabled
+                    + ": " + e);
+        }
+    }
+
     /**
      * Set the TTY mode. This is the actual tty mode (varies depending on peripheral status)
      */
@@ -2101,21 +2028,13 @@
 
     public void onSmsReady() throws ImsException{
         try {
-            mImsServiceProxy.onSmsReady();
+            mMmTelFeatureConnection.onSmsReady();
         } catch (RemoteException e) {
             throw new ImsException("onSmsReady()", e,
                     ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
         }
     }
 
-    public void addRegistrationCallback(ImsRegistrationImplBase.Callback callback) {
-        // TODO: implement (coming in ag/3472519)
-    }
-
-    public void addCapabilitiesCallback(ImsFeature.CapabilityCallback callback) {
-        // TODO: implement (coming in ag/3472519)
-    }
-
     /**
      * Gets the Multi-Endpoint interface to subscribe to multi-enpoint notifications..
      *
@@ -2168,7 +2087,9 @@
     public void factoryReset() {
         // Set VoLTE to default
         SubscriptionManager.setSubscriptionProperty(getSubId(),
-                SubscriptionManager.ENHANCED_4G_MODE_ENABLED, booleanToPropertyString(true));
+                SubscriptionManager.ENHANCED_4G_MODE_ENABLED,
+                booleanToPropertyString(getBooleanCarrierConfig(
+                        CarrierConfigManager.KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL)));
 
         // Set VoWiFi to default
         SubscriptionManager.setSubscriptionProperty(getSubId(),
@@ -2197,40 +2118,22 @@
     }
 
     private boolean isDataEnabled() {
-        return SystemProperties.getBoolean(DATA_ENABLED_PROP, true);
-    }
-
-    /**
-     * Set data enabled/disabled flag.
-     * @param enabled True if data is enabled, otherwise disabled.
-     */
-    public void setDataEnabled(boolean enabled) {
-        log("setDataEnabled: " + enabled);
-        SystemProperties.set(DATA_ENABLED_PROP, enabled ? TRUE : FALSE);
+        return new TelephonyManager(mContext, getSubId()).isMobileDataEnabled();
     }
 
     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);
-    }
-
-    private void setVtProvisionedProperty(boolean provisioned) {
-        SystemProperties.set(VT_PROVISIONED_PROP, provisioned ? TRUE : FALSE);
+        return getProvisionedBoolNoException(
+                ImsConfig.ConfigConstants.LVC_SETTING_ENABLED);
     }
 
     private static String booleanToPropertyString(boolean bool) {
diff --git a/src/java/com/android/ims/ImsMultiEndpoint.java b/src/java/com/android/ims/ImsMultiEndpoint.java
index 9692696..1315dbd 100644
--- a/src/java/com/android/ims/ImsMultiEndpoint.java
+++ b/src/java/com/android/ims/ImsMultiEndpoint.java
@@ -21,6 +21,8 @@
 
 import android.os.RemoteException;
 import android.telephony.Rlog;
+import android.telephony.ims.ImsExternalCallState;
+import android.telephony.ims.ImsReasonInfo;
 
 import java.util.List;
 
diff --git a/src/java/com/android/ims/ImsServiceBase.java b/src/java/com/android/ims/ImsServiceBase.java
index 66122df..0a15c9d 100644
--- a/src/java/com/android/ims/ImsServiceBase.java
+++ b/src/java/com/android/ims/ImsServiceBase.java
@@ -18,7 +18,7 @@
 
 import android.app.PendingIntent;
 
-import com.android.ims.ImsCallProfile;
+import android.telephony.ims.ImsCallProfile;
 import com.android.ims.internal.IImsCallSession;
 import com.android.ims.internal.IImsCallSessionListener;
 import com.android.ims.internal.IImsConfig;
diff --git a/src/java/com/android/ims/ImsServiceProxy.java b/src/java/com/android/ims/ImsServiceProxy.java
deleted file mode 100644
index a874436..0000000
--- a/src/java/com/android/ims/ImsServiceProxy.java
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.ims;
-
-import android.annotation.Nullable;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.RemoteException;
-import android.telephony.Rlog;
-import android.telephony.TelephonyManager;
-import android.telephony.ims.aidl.IImsCallSessionListener;
-import android.telephony.ims.feature.ImsFeature;
-import android.telephony.SmsMessage;
-import android.telephony.ims.internal.stub.SmsImplBase;
-import android.util.Log;
-
-import com.android.ims.internal.IImsCallSession;
-import com.android.ims.internal.IImsConfig;
-import com.android.ims.internal.IImsEcbm;
-import com.android.ims.internal.IImsMMTelFeature;
-import com.android.ims.internal.IImsMultiEndpoint;
-import com.android.ims.internal.IImsRegistration;
-import com.android.ims.internal.IImsRegistrationListener;
-import com.android.ims.internal.IImsServiceFeatureCallback;
-import com.android.ims.internal.IImsSmsListener;
-import com.android.ims.internal.IImsUt;
-
-/**
- * A container of the IImsServiceController binder, which implements all of the ImsFeatures that
- * the platform currently supports: MMTel and RCS.
- * @hide
- */
-
-public class ImsServiceProxy {
-
-    protected static final String TAG = "ImsServiceProxy";
-    protected final int mSlotId;
-    protected IBinder mBinder;
-    private final int mSupportedFeature;
-    private Context mContext;
-
-    // Start by assuming the proxy is available for usage.
-    private boolean mIsAvailable = true;
-    // ImsFeature Status from the ImsService. Cached.
-    private Integer mFeatureStatusCached = null;
-    private IFeatureUpdate mStatusCallback;
-    private final Object mLock = new Object();
-
-    public static ImsServiceProxy create(Context context , int slotId) {
-        ImsServiceProxy serviceProxy = new ImsServiceProxy(context, slotId, ImsFeature.MMTEL);
-
-        TelephonyManager tm  = getTelephonyManager(context);
-        if (tm == null) {
-            Rlog.w(TAG, "getServiceProxy: TelephonyManager is null!");
-            // Binder can be unset in this case because it will be torn down/recreated as part of
-            // a retry mechanism until the serviceProxy binder is set successfully.
-            return serviceProxy;
-        }
-
-        IImsMMTelFeature binder = tm.getImsMMTelFeatureAndListen(slotId,
-                serviceProxy.getListener());
-        if (binder != null) {
-            serviceProxy.setBinder(binder.asBinder());
-            // Trigger the cache to be updated for feature status.
-            serviceProxy.getFeatureStatus();
-        } else {
-            Rlog.w(TAG, "getServiceProxy: binder is null! Phone Id: " + slotId);
-        }
-        return serviceProxy;
-    }
-
-    public static TelephonyManager getTelephonyManager(Context context) {
-        return (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
-    }
-
-    public interface IFeatureUpdate {
-        /**
-         * Called when the ImsFeature has changed its state. Use
-         * {@link ImsFeature#getFeatureState()} to get the new state.
-         */
-        void notifyStateChanged();
-
-        /**
-         * Called when the ImsFeature has become unavailable due to the binder switching or app
-         * crashing. A new ImsServiceProxy should be requested for that feature.
-         */
-        void notifyUnavailable();
-    }
-
-    private final IImsServiceFeatureCallback mListenerBinder =
-            new IImsServiceFeatureCallback.Stub() {
-
-        @Override
-        public void imsFeatureCreated(int slotId, int feature) throws RemoteException {
-            // The feature has been re-enabled. This may happen when the service crashes.
-            synchronized (mLock) {
-                if (!mIsAvailable && mSlotId == slotId && feature == mSupportedFeature) {
-                    Log.i(TAG, "Feature enabled on slotId: " + slotId + " for feature: " +
-                            feature);
-                    mIsAvailable = true;
-                }
-            }
-        }
-
-        @Override
-        public void imsFeatureRemoved(int slotId, int feature) throws RemoteException {
-            synchronized (mLock) {
-                if (mIsAvailable && mSlotId == slotId && feature == mSupportedFeature) {
-                    Log.i(TAG, "Feature disabled on slotId: " + slotId + " for feature: " +
-                            feature);
-                    mIsAvailable = false;
-                    if (mStatusCallback != null) {
-                        mStatusCallback.notifyUnavailable();
-                    }
-                }
-            }
-        }
-
-        @Override
-        public void imsStatusChanged(int slotId, int feature, int status) throws RemoteException {
-            synchronized (mLock) {
-                Log.i(TAG, "imsStatusChanged: slot: " + slotId + " feature: " + feature +
-                        " status: " + status);
-                if (mSlotId == slotId && feature == mSupportedFeature) {
-                    mFeatureStatusCached = status;
-                    if (mStatusCallback != null) {
-                        mStatusCallback.notifyStateChanged();
-                    }
-                }
-            }
-        }
-    };
-
-    public ImsServiceProxy(Context context, int slotId, IBinder binder, int featureType) {
-        mSlotId = slotId;
-        mBinder = binder;
-        mSupportedFeature = featureType;
-        mContext = context;
-    }
-
-    public ImsServiceProxy(Context context, int slotId, int featureType) {
-        this(context, slotId, null, featureType);
-    }
-
-    public @Nullable IImsRegistration getRegistration() {
-        TelephonyManager tm = getTelephonyManager(mContext);
-        return tm != null ? tm.getImsRegistration(mSlotId, ImsFeature.MMTEL) : null;
-    }
-
-    public IImsServiceFeatureCallback getListener() {
-        return mListenerBinder;
-    }
-
-    public void setBinder(IBinder binder) {
-        mBinder = binder;
-    }
-
-    public int startSession(PendingIntent incomingCallIntent, IImsRegistrationListener listener)
-            throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            return getServiceInterface(mBinder).startSession(incomingCallIntent, listener);
-        }
-    }
-
-    public void endSession(int sessionId) throws RemoteException {
-        synchronized (mLock) {
-            // Only check to make sure the binder connection still exists. This method should
-            // still be able to be called when the state is STATE_NOT_AVAILABLE.
-            checkBinderConnection();
-            getServiceInterface(mBinder).endSession(sessionId);
-        }
-    }
-
-    public boolean isConnected(int callServiceType, int callType)
-            throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            return getServiceInterface(mBinder).isConnected(callServiceType, callType);
-        }
-    }
-
-    public boolean isOpened() throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            return getServiceInterface(mBinder).isOpened();
-        }
-    }
-
-    public void addRegistrationListener(IImsRegistrationListener listener)
-    throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            getServiceInterface(mBinder).addRegistrationListener(listener);
-        }
-    }
-
-    public void removeRegistrationListener(IImsRegistrationListener listener)
-            throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            getServiceInterface(mBinder).removeRegistrationListener(listener);
-        }
-    }
-
-    public ImsCallProfile createCallProfile(int sessionId, int callServiceType, int callType)
-            throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            return getServiceInterface(mBinder).createCallProfile(sessionId, callServiceType,
-                    callType);
-        }
-    }
-
-    public IImsCallSession createCallSession(int sessionId, ImsCallProfile profile)
-            throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            return getServiceInterface(mBinder).createCallSession(sessionId, profile);
-        }
-    }
-
-    public IImsCallSession getPendingCallSession(int sessionId, String callId)
-            throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            return getServiceInterface(mBinder).getPendingCallSession(sessionId, callId);
-        }
-    }
-
-    public IImsUt getUtInterface() throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            return getServiceInterface(mBinder).getUtInterface();
-        }
-    }
-
-    public IImsConfig getConfigInterface() throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            return getServiceInterface(mBinder).getConfigInterface();
-        }
-    }
-
-    public void turnOnIms() throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            getServiceInterface(mBinder).turnOnIms();
-        }
-    }
-
-    public void turnOffIms() throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            getServiceInterface(mBinder).turnOffIms();
-        }
-    }
-
-    public IImsEcbm getEcbmInterface() throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            return getServiceInterface(mBinder).getEcbmInterface();
-        }
-    }
-
-    public void setUiTTYMode(int uiTtyMode, Message onComplete)
-            throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            getServiceInterface(mBinder).setUiTTYMode(uiTtyMode, onComplete);
-        }
-    }
-
-    public IImsMultiEndpoint getMultiEndpointInterface() throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            return getServiceInterface(mBinder).getMultiEndpointInterface();
-        }
-    }
-
-    /**
-     * @return an integer describing the current Feature Status, defined in
-     * {@link ImsFeature.ImsState}.
-     */
-    public int getFeatureStatus() {
-        synchronized (mLock) {
-            if (isBinderAlive() && mFeatureStatusCached != null) {
-                Log.i(TAG, "getFeatureStatus - returning cached: " + mFeatureStatusCached);
-                return mFeatureStatusCached;
-            }
-        }
-        // Don't synchronize on Binder call.
-        Integer status = retrieveFeatureStatus();
-        synchronized (mLock) {
-            if (status == null) {
-                return ImsFeature.STATE_NOT_AVAILABLE;
-            }
-            // Cache only non-null value for feature status.
-            mFeatureStatusCached = status;
-        }
-        Log.i(TAG, "getFeatureStatus - returning " + status);
-        return status;
-    }
-
-    /**
-     * Internal method used to retrieve the feature status from the corresponding ImsService.
-     */
-    private Integer retrieveFeatureStatus() {
-        if (mBinder != null) {
-            try {
-                return getServiceInterface(mBinder).getFeatureStatus();
-            } catch (RemoteException e) {
-                // Status check failed, don't update cache
-            }
-        }
-        return null;
-    }
-
-    /**
-     * @param c Callback that will fire when the feature status has changed.
-     */
-    public void setStatusCallback(IFeatureUpdate c) {
-        mStatusCallback = c;
-    }
-
-    public void sendSms(int token, int messageRef, String format, String smsc, boolean isRetry,
-            byte[] pdu) throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            getServiceInterface(mBinder).sendSms(token, messageRef, format, smsc, isRetry,
-                    pdu);
-        }
-    }
-
-    public void acknowledgeSms(int token, int messageRef,
-            @SmsImplBase.SendStatusResult int result) throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            getServiceInterface(mBinder).acknowledgeSms(token, messageRef, result);
-        }
-    }
-
-    public void acknowledgeSmsReport(int token, int messageRef,
-            @SmsImplBase.StatusReportResult int result) throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            getServiceInterface(mBinder).acknowledgeSmsReport(token, messageRef, result);
-        }
-    }
-
-    public String getSmsFormat() throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            return getServiceInterface(mBinder).getSmsFormat();
-        }
-    }
-
-    public void onSmsReady() throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            getServiceInterface(mBinder).onSmsReady();
-        }
-    }
-
-    public void setSmsListener(IImsSmsListener listener) throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            getServiceInterface(mBinder).setSmsListener(listener);
-        }
-    }
-
-    /**
-     * @return Returns true if the ImsService is ready to take commands, false otherwise. If this
-     * method returns false, it doesn't mean that the Binder connection is not available (use
-     * {@link #isBinderReady()} to check that), but that the ImsService is not accepting commands
-     * at this time.
-     *
-     * For example, for DSDS devices, only one slot can be {@link ImsFeature#STATE_READY} to take
-     * commands at a time, so the other slot must stay at {@link ImsFeature#STATE_NOT_AVAILABLE}.
-     */
-    public boolean isBinderReady() {
-        return isBinderAlive() && getFeatureStatus() == ImsFeature.STATE_READY;
-    }
-
-    /**
-     * @return false if the binder connection is no longer alive.
-     */
-    public boolean isBinderAlive() {
-        return mIsAvailable && mBinder != null && mBinder.isBinderAlive();
-    }
-
-    protected void checkServiceIsReady() throws RemoteException {
-        if (!isBinderReady()) {
-            throw new RemoteException("ImsServiceProxy is not ready to accept commands.");
-        }
-    }
-
-    private IImsMMTelFeature getServiceInterface(IBinder b) {
-        return IImsMMTelFeature.Stub.asInterface(b);
-    }
-
-    protected void checkBinderConnection() throws RemoteException {
-        if (!isBinderAlive()) {
-            throw new RemoteException("ImsServiceProxy is not available for that feature.");
-        }
-    }
-}
diff --git a/src/java/com/android/ims/ImsUt.java b/src/java/com/android/ims/ImsUt.java
index eaeb551..b3d4c8a 100644
--- a/src/java/com/android/ims/ImsUt.java
+++ b/src/java/com/android/ims/ImsUt.java
@@ -27,6 +27,10 @@
 import android.os.Registrant;
 import android.os.RemoteException;
 import android.telephony.Rlog;
+import android.telephony.ims.ImsCallForwardInfo;
+import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.ImsSsData;
+import android.telephony.ims.ImsSsInfo;
 
 import com.android.ims.internal.IImsUt;
 import com.android.ims.internal.IImsUtListener;
diff --git a/src/java/com/android/ims/MmTelFeatureConnection.java b/src/java/com/android/ims/MmTelFeatureConnection.java
index 00dec65..571670d 100644
--- a/src/java/com/android/ims/MmTelFeatureConnection.java
+++ b/src/java/com/android/ims/MmTelFeatureConnection.java
@@ -24,6 +24,8 @@
 import android.os.RemoteException;
 import android.telephony.Rlog;
 import android.telephony.TelephonyManager;
+import android.telephony.ims.ImsCallProfile;
+import android.telephony.ims.ImsReasonInfo;
 import android.telephony.ims.aidl.IImsConfig;
 import android.telephony.ims.aidl.IImsMmTelFeature;
 import android.telephony.ims.aidl.IImsRegistration;
@@ -524,6 +526,13 @@
         }
     }
 
+    public void onSmsReady() throws RemoteException {
+        synchronized (mLock) {
+            checkServiceIsReady();
+            getServiceInterface(mBinder).onSmsReady();
+        }
+    }
+
     public void setSmsListener(IImsSmsListener listener) throws RemoteException {
         synchronized (mLock) {
             checkServiceIsReady();
diff --git a/src/java/com/android/ims/internal/VideoPauseTracker.java b/src/java/com/android/ims/internal/VideoPauseTracker.java
index baa3163..9243008 100644
--- a/src/java/com/android/ims/internal/VideoPauseTracker.java
+++ b/src/java/com/android/ims/internal/VideoPauseTracker.java
@@ -18,11 +18,11 @@
 
 import android.telecom.Log;
 import android.telecom.VideoProfile;
+import android.telephony.ims.ImsVideoCallProvider;
 import android.util.ArraySet;
 
 import java.util.Collection;
 import java.util.Set;
-import java.util.StringJoiner;
 import java.util.stream.Collectors;
 
 /**
@@ -71,7 +71,7 @@
      *
      * @param source The source of the pause request.
      * @return {@code true} if a pause should be issued to the
-     *      {@link com.android.ims.internal.ImsVideoCallProvider}, {@code false} otherwise.
+     *      {@link ImsVideoCallProvider}, {@code false} otherwise.
      */
     public boolean shouldPauseVideoFor(int source) {
         synchronized (mPauseRequestsLock) {
@@ -102,7 +102,7 @@
      *
      * @param source The source of the resume request.
      * @return {@code true} if a resume should be issued to the
-     *      {@link com.android.ims.internal.ImsVideoCallProvider}, {@code false} otherwise.
+     *      {@link ImsVideoCallProvider}, {@code false} otherwise.
      */
     public boolean shouldResumeVideoFor(int source) {
         synchronized (mPauseRequestsLock) {
diff --git a/tests/src/com/android/ims/ImsConfigTest.java b/tests/src/com/android/ims/ImsConfigTest.java
index 18d53b1..4cf7a92 100644
--- a/tests/src/com/android/ims/ImsConfigTest.java
+++ b/tests/src/com/android/ims/ImsConfigTest.java
@@ -17,8 +17,7 @@
 package com.android.ims;
 
 import android.support.test.runner.AndroidJUnit4;
-
-import com.android.ims.internal.IImsConfig;
+import android.telephony.ims.aidl.IImsConfig;
 
 import org.junit.After;
 import org.junit.Before;
@@ -59,6 +58,6 @@
 
         mTestImsConfig.getProvisionedValue(testItem);
 
-        verify(mMockImsConfigInterface).getProvisionedValue(eq(testItem));
+        verify(mMockImsConfigInterface).getConfigInt(eq(testItem));
     }
 }