diff --git a/src/java/com/android/ims/ImsCall.java b/src/java/com/android/ims/ImsCall.java
index 6200a07..760e5e8 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;
 
diff --git a/src/java/com/android/ims/ImsConnectionStateListener.java b/src/java/com/android/ims/ImsConnectionStateListener.java
index 216bc41..d5fb633 100644
--- a/src/java/com/android/ims/ImsConnectionStateListener.java
+++ b/src/java/com/android/ims/ImsConnectionStateListener.java
@@ -17,8 +17,13 @@
 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;
 
+import java.util.Arrays;
+
 /**
  * Listener for receiving notifications about changes to the IMS connection.
  * It provides a state of IMS registration between UE and IMS network, the service
@@ -53,6 +58,69 @@
     public void onSubscriberAssociatedUriChanged(Uri[] uris) {
         registrationAssociatedUriChanged(uris);
     }
+
+    /**
+     * Used to convert from the new capabilities structure to the old features structure for
+     * backwards compatibility.
+     * @param imsRadioTech The registration that will be used to convert to the old feature
+     *         structure. Can be either {@link ImsRegistrationImplBase#REGISTRATION_TECH_LTE} or
+     *         {@link ImsRegistrationImplBase#REGISTRATION_TECH_IWLAN}
+     * @param c Capabilities that will be turned into old feature array.
+     */
+    public void onFeatureCapabilityChangedAdapter(
+            @ImsRegistrationImplBase.ImsRegistrationTech int imsRadioTech,
+            ImsFeature.Capabilities c) {
+        // Size of ImsConfig.FeatureConstants
+        int[] enabledCapabilities = new int[6];
+        // UNKNOWN means disabled.
+        Arrays.fill(enabledCapabilities, ImsConfig.FeatureConstants.FEATURE_TYPE_UNKNOWN);
+        // Size of ImsConfig.FeatureConstants
+        int[] disabledCapabilities = new int[6];
+        Arrays.fill(disabledCapabilities, ImsConfig.FeatureConstants.FEATURE_TYPE_UNKNOWN);
+        // populate enabledCapabilities
+        switch (imsRadioTech) {
+            case ImsRegistrationImplBase.REGISTRATION_TECH_LTE: {
+                if (c.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE)) {
+                    // enabled means equal to its own integer value.
+                    enabledCapabilities[ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE] =
+                            ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE;
+                }
+                if (c.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO)) {
+                    enabledCapabilities[ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE] =
+                            ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE;
+                }
+                if (c.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT)) {
+                    enabledCapabilities[ImsConfig.FeatureConstants.FEATURE_TYPE_UT_OVER_LTE] =
+                            ImsConfig.FeatureConstants.FEATURE_TYPE_UT_OVER_LTE;
+                }
+                break;
+            }
+            case ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN: {
+                if (c.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE)) {
+                    enabledCapabilities[ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_WIFI] =
+                            ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_WIFI;
+                }
+                if (c.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO)) {
+                    enabledCapabilities[ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_WIFI] =
+                            ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_WIFI;
+                }
+                if (c.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT)) {
+                    enabledCapabilities[ImsConfig.FeatureConstants.FEATURE_TYPE_UT_OVER_WIFI] =
+                            ImsConfig.FeatureConstants.FEATURE_TYPE_UT_OVER_WIFI;
+                }
+                break;
+            }
+        }
+        // make disabledCapabilities the opposite of enabledCapabilities. Since the disabled
+        // capabilities array was defaulted to -1 it is UNKNOWN if not disabled.
+        for (int i = 0; i < enabledCapabilities.length; i++) {
+            if (enabledCapabilities[i] != i) {
+                disabledCapabilities[i] = i;
+            }
+        }
+        onFeatureCapabilityChanged(ImsServiceClass.MMTEL, enabledCapabilities,
+                disabledCapabilities);
+    }
     /**
      * Called when the device is connected to the IMS network with {@param imsRadioTech}.
      */
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 48a3165..063f5a8 100644
--- a/src/java/com/android/ims/ImsManager.java
+++ b/src/java/com/android/ims/ImsManager.java
@@ -16,49 +16,44 @@
 
 package com.android.ims;
 
+import android.annotation.Nullable;
 import android.app.PendingIntent;
 import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-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;
 import android.os.RemoteException;
 import android.os.SystemProperties;
-import android.provider.Settings;
 import android.telecom.TelecomManager;
 import android.telephony.CarrierConfigManager;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
 import android.telephony.Rlog;
-import android.telephony.ServiceState;
 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.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.IImsMultiEndpoint;
-import com.android.ims.internal.IImsRegistration;
-import com.android.ims.internal.IImsRegistrationCallback;
-import com.android.ims.internal.IImsRegistrationListener;
-import com.android.ims.internal.IImsServiceController;
-import com.android.ims.internal.IImsSmsListener;
 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.HashSet;
 import java.util.Set;
+import java.util.concurrent.ConcurrentLinkedDeque;
 import java.util.concurrent.CopyOnWriteArraySet;
 
 /**
@@ -85,13 +80,13 @@
 
     /**
      * The result code to be sent back with the incoming call {@link PendingIntent}.
-     * @see #open(PendingIntent, ImsConnectionStateListener)
+     * @see #open(MmTelFeature.Listener)
      */
     public static final int INCOMING_CALL_RESULT_CODE = 101;
 
     /**
      * Key to retrieve the call ID from an incoming call intent.
-     * @see #open(PendingIntent, ImsConnectionStateListener)
+     * @see #open(MmTelFeature.Listener)
      */
     public static final String EXTRA_CALL_ID = "android:imsCallID";
 
@@ -166,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;
 
@@ -176,7 +176,7 @@
     private CarrierConfigManager mConfigManager;
     private int mPhoneId;
     private final boolean mConfigDynamicBind;
-    private ImsServiceProxy mImsServiceProxy = null;
+    private @Nullable MmTelFeatureConnection mMmTelFeatureConnection = null;
     private ImsServiceDeathRecipient mDeathRecipient = new ImsServiceDeathRecipient();
     // Ut interface for the supplementary service configuration
     private ImsUt mUt = null;
@@ -191,33 +191,8 @@
 
     private ImsMultiEndpoint mMultiEndpoint = null;
 
-    private Set<ImsServiceProxy.IFeatureUpdate> mStatusCallbacks = new CopyOnWriteArraySet<>();
-
-    // Keep track of the ImsRegistrationListenerProxys that have been created so that we can
-    // remove them from the ImsService.
-    private final Set<ImsConnectionStateListener> mRegistrationListeners = new HashSet<>();
-
-
-    // Used for compatibility with the old Registration method
-    // TODO: Remove once the compat layer is in place
-    private final ImsRegistrationListenerProxy mImsRegistrationListenerProxy =
-            new ImsRegistrationListenerProxy();
-    // New API for registration to the ImsService.
-    private final ImsRegistrationCallback mRegistrationCallback = new ImsRegistrationCallback();
-
-
-    // When true, we have registered the mRegistrationListenerProxy with the ImsService. Don't do
-    // it again.
-    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";
+    private Set<MmTelFeatureConnection.IFeatureUpdate> mStatusCallbacks =
+            new CopyOnWriteArraySet<>();
 
     public static final String TRUE = "true";
     public static final String FALSE = "false";
@@ -227,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.
      *
@@ -283,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(
@@ -405,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;
         }
 
@@ -539,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;
         }
 
@@ -575,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);
     }
 
     /**
@@ -596,16 +571,12 @@
      * Change persistent VT enabled setting for slot.
      */
     public void setVtSetting(boolean enabled) {
-        SubscriptionManager.setSubscriptionProperty(getSubId(),
-                SubscriptionManager.VT_IMS_ENABLED,
+        SubscriptionManager.setSubscriptionProperty(getSubId(), SubscriptionManager.VT_IMS_ENABLED,
                 booleanToPropertyString(enabled));
+
         try {
-            ImsConfig config = getConfigInterface();
-            config.setFeatureValue(ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE,
-                    TelephonyManager.NETWORK_TYPE_LTE,
-                    enabled ? ImsConfig.FeatureValueConstants.ON
-                            : ImsConfig.FeatureValueConstants.OFF,
-                    mImsConfigListener);
+            changeMmTelCapability(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO,
+                    ImsRegistrationImplBase.REGISTRATION_TECH_LTE, enabled);
 
             if (enabled) {
                 log("setVtSetting(b) : turnOnIms");
@@ -616,7 +587,10 @@
                 log("setVtSetting(b) : imsServiceAllowTurnOff -> turnOffIms");
                 turnOffIms();
             }
-        } catch (ImsException e) {
+        } catch (ImsException | RemoteException e) {
+            // The ImsService is down. Since the SubscriptionManager already recorded the user's
+            // preference, it will be resent in updateImsServiceConfig when the ImsPhoneCallTracker
+            // reconnects.
             loge("setVtSetting(b): ", e);
         }
     }
@@ -643,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);
     }
@@ -681,7 +660,7 @@
             return getBooleanCarrierConfig(
                     CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL);
         } else {
-            return setting == 1;
+            return setting == ImsConfig.FeatureValueConstants.ON;
         }
     }
 
@@ -715,18 +694,13 @@
      * @param wfcMode The WFC preference if WFC is enabled
      */
     public void setWfcNonPersistent(boolean enabled, int wfcMode) {
-        int imsFeatureValue =
-                enabled ? ImsConfig.FeatureValueConstants.ON : ImsConfig.FeatureValueConstants.OFF;
         // Force IMS to register over LTE when turning off WFC
         int imsWfcModeFeatureValue =
                 enabled ? wfcMode : ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED;
 
         try {
-            ImsConfig config = getConfigInterface();
-            config.setFeatureValue(ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_WIFI,
-                    TelephonyManager.NETWORK_TYPE_IWLAN,
-                    imsFeatureValue,
-                    mImsConfigListener);
+            changeMmTelCapability(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
+                    ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN, enabled);
 
             if (enabled) {
                 log("setWfcSetting() : turnOnIms");
@@ -739,7 +713,7 @@
             }
 
             setWfcModeInternal(imsWfcModeFeatureValue);
-        } catch (ImsException e) {
+        } catch (ImsException | RemoteException e) {
             loge("setWfcSetting(): ", e);
         }
     }
@@ -913,7 +887,7 @@
             Thread thread = new Thread(new Runnable() {
                 public void run() {
                     try {
-                        imsManager.getConfigInterface().setProvisionedValue(
+                        imsManager.getConfigInterface().setConfig(
                                 ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE,
                                 value);
                     } catch (ImsException e) {
@@ -929,7 +903,7 @@
         final int value = wfcMode;
         Thread thread = new Thread(() -> {
             try {
-                getConfigInterface().setProvisionedValue(
+                getConfigInterface().setConfig(
                         ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE, value);
             } catch (ImsException e) {
                 // do nothing
@@ -966,7 +940,7 @@
             return getBooleanCarrierConfig(
                             CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_ENABLED_BOOL);
         } else {
-            return (setting == 1);
+            return setting == ImsConfig.FeatureValueConstants.ON;
         }
     }
 
@@ -999,7 +973,7 @@
                 : ImsConfig.FeatureValueConstants.OFF;
         Thread thread = new Thread(() -> {
             try {
-                getConfigInterface().setProvisionedValue(
+                getConfigInterface().setConfig(
                         ImsConfig.ConfigConstants.VOICE_OVER_WIFI_ROAMING, value);
             } catch (ImsException e) {
                 // do nothing
@@ -1032,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;
         }
 
@@ -1068,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;
         }
     }
 
@@ -1202,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) {
@@ -1218,13 +1106,11 @@
 
         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
-                // setFeatureValue() function calls from setAdvanced4GMode(). This is done to
-                // differentiate this code path from vendor code perspective.
+                // changeEnabledCapabilities() function calls from setAdvanced4GMode(). This is done
+                // to differentiate this code path from vendor code perspective.
                 boolean isImsUsed = updateVolteFeatureValue();
                 isImsUsed |= updateWfcFeatureAndProvisionedValues();
                 isImsUsed |= updateVideoCallFeatureValue();
@@ -1243,7 +1129,7 @@
                 }
 
                 mConfigUpdated = true;
-            } catch (ImsException e) {
+            } catch (ImsException | RemoteException e) {
                 loge("updateImsServiceConfig: ", e);
                 mConfigUpdated = false;
             }
@@ -1255,7 +1141,7 @@
      * @return whether feature is On
      * @throws ImsException
      */
-    private boolean updateVolteFeatureValue() throws ImsException {
+    private boolean updateVolteFeatureValue() throws RemoteException {
         boolean available = isVolteEnabledByPlatform();
         boolean enabled = isEnhanced4gLteModeSettingEnabledByUser();
         boolean isNonTty = isNonTtyOrTtyOnVolteEnabled();
@@ -1265,13 +1151,8 @@
                 + ", enabled = " + enabled
                 + ", nonTTY = " + isNonTty);
 
-        getConfigInterface().setFeatureValue(
-                ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE,
-                TelephonyManager.NETWORK_TYPE_LTE,
-                isFeatureOn ?
-                        ImsConfig.FeatureValueConstants.ON :
-                        ImsConfig.FeatureValueConstants.OFF,
-                mImsConfigListener);
+        changeMmTelCapability(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
+                ImsRegistrationImplBase.REGISTRATION_TECH_LTE, isFeatureOn);
 
         return isFeatureOn;
     }
@@ -1281,7 +1162,7 @@
      * @return whether feature is On
      * @throws ImsException
      */
-    private boolean updateVideoCallFeatureValue() throws ImsException {
+    private boolean updateVideoCallFeatureValue() throws RemoteException {
         boolean available = isVtEnabledByPlatform();
         boolean enabled = isVtEnabledByUser();
         boolean isNonTty = isNonTtyOrTtyOnVolteEnabled();
@@ -1297,13 +1178,8 @@
                 + ", nonTTY = " + isNonTty
                 + ", data enabled = " + isDataEnabled);
 
-        getConfigInterface().setFeatureValue(
-                ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE,
-                TelephonyManager.NETWORK_TYPE_LTE,
-                isFeatureOn ?
-                        ImsConfig.FeatureValueConstants.ON :
-                        ImsConfig.FeatureValueConstants.OFF,
-                mImsConfigListener);
+        changeMmTelCapability(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO,
+                ImsRegistrationImplBase.REGISTRATION_TECH_LTE, isFeatureOn);
 
         return isFeatureOn;
     }
@@ -1313,7 +1189,7 @@
      * @return whether feature is On
      * @throws ImsException
      */
-    private boolean updateWfcFeatureAndProvisionedValues() throws ImsException {
+    private boolean updateWfcFeatureAndProvisionedValues() throws RemoteException {
         TelephonyManager tm = new TelephonyManager(mContext, getSubId());
         boolean isNetworkRoaming = tm.isNetworkRoaming();
         boolean available = isWfcEnabledByPlatform();
@@ -1328,13 +1204,8 @@
                 + ", mode = " + mode
                 + ", roaming = " + roaming);
 
-        getConfigInterface().setFeatureValue(
-                ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_WIFI,
-                TelephonyManager.NETWORK_TYPE_IWLAN,
-                isFeatureOn ?
-                        ImsConfig.FeatureValueConstants.ON :
-                        ImsConfig.FeatureValueConstants.OFF,
-                mImsConfigListener);
+        changeMmTelCapability(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
+                ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN, isFeatureOn);
 
         if (!isFeatureOn) {
             mode = ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED;
@@ -1357,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();
     }
 
@@ -1380,7 +1246,7 @@
     public boolean isServiceAvailable() {
         connectIfServiceIsAvailable();
         // mImsServiceProxy will always create an ImsServiceProxy.
-        return mImsServiceProxy.isBinderAlive();
+        return mMmTelFeatureConnection.isBinderAlive();
     }
 
     /*
@@ -1388,19 +1254,19 @@
      */
     public boolean isServiceReady() {
         connectIfServiceIsAvailable();
-        return mImsServiceProxy.isBinderReady();
+        return mMmTelFeatureConnection.isBinderReady();
     }
 
     /**
      * If the service is available, try to reconnect.
      */
     public void connectIfServiceIsAvailable() {
-        if (mImsServiceProxy == null || !mImsServiceProxy.isBinderAlive()) {
+        if (mMmTelFeatureConnection == null || !mMmTelFeatureConnection.isBinderAlive()) {
             createImsService();
         }
     }
 
-    public void setImsConfigListener(ImsConfigListener listener) {
+    public void setConfigListener(ImsConfigListener listener) {
         mImsConfigListener = listener;
     }
 
@@ -1409,9 +1275,9 @@
      * Adds a callback for status changed events if the binder is already available. If it is not,
      * this method will throw an ImsException.
      */
-    public void addNotifyStatusChangedCallbackIfAvailable(ImsServiceProxy.IFeatureUpdate c)
+    public void addNotifyStatusChangedCallbackIfAvailable(MmTelFeatureConnection.IFeatureUpdate c)
             throws ImsException {
-        if (!mImsServiceProxy.isBinderAlive()) {
+        if (!mMmTelFeatureConnection.isBinderAlive()) {
             throw new ImsException("Binder is not active!",
                     ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
         }
@@ -1420,7 +1286,7 @@
         }
     }
 
-    public void removeNotifyStatusChangedCallback(ImsServiceProxy.IFeatureUpdate c) {
+    public void removeNotifyStatusChangedCallback(MmTelFeatureConnection.IFeatureUpdate c) {
         if (c != null) {
             mStatusCallbacks.remove(c);
         } else {
@@ -1430,63 +1296,30 @@
 
     /**
      * Opens the IMS service for making calls and/or receiving generic IMS calls.
-     * The caller may make subsquent calls through {@link #makeCall}.
+     * The caller may make subsequent calls through {@link #makeCall}.
      * The IMS service will register the device to the operator's network with the credentials
      * (from ISIM) periodically in order to receive calls from the operator's network.
-     * When the IMS service receives a new call, it will send out an intent with
-     * the provided action string.
-     * The intent contains a call ID extra {@link getCallId} and it can be used to take a call.
-     *
-     * @param serviceClass a service class specified in {@link ImsServiceClass}
-     *      For VoLTE service, it MUST be a {@link ImsServiceClass#MMTEL}.
-     * @param incomingCallPendingIntent When an incoming call is received,
-     *        the IMS service will call {@link PendingIntent#send(Context, int, Intent)} to
-     *        send back the intent to the caller with {@link #INCOMING_CALL_RESULT_CODE}
-     *        as the result code and the intent to fill in the call ID; It cannot be null
-     * @param listener To listen to IMS registration events; It cannot be null
-     * @return identifier (greater than 0) for the specified service
-     * @throws NullPointerException if {@code incomingCallPendingIntent}
-     *      or {@code listener} is null
+     * When the IMS service receives a new call, it will call
+     * {@link MmTelFeature.Listener#onIncomingCall}
+     * The listener contains a call ID extra {@link #getCallId} and it can be used to take a call.
+     * @param listener A {@link MmTelFeature.Listener}, which is the interface the
+     * {@link MmTelFeature} uses to notify the framework of updates
+     * @throws NullPointerException if {@code listener} is null
      * @throws ImsException if calling the IMS service results in an error
      * @see #getCallId
-     * @see #getImsSessionId
      */
-    public int open(int serviceClass, PendingIntent incomingCallPendingIntent,
-            ImsConnectionStateListener listener) throws ImsException {
+    public void open(MmTelFeature.Listener listener) throws ImsException {
         checkAndThrowExceptionIfServiceUnavailable();
 
-        if (incomingCallPendingIntent == null) {
-            throw new NullPointerException("incomingCallPendingIntent can't be null");
-        }
-
         if (listener == null) {
             throw new NullPointerException("listener can't be null");
         }
 
-        int result = 0;
-
         try {
-            // Register a stub implementation of the ImsRegistrationListener. There is the
-            // possibility that if we use the real implementation of the ImsRegistrationListener,
-            // it will be added twice.
-            // TODO: Remove ImsRegistrationListener from startSession API (b/62588776)
-            result = mImsServiceProxy.startSession(incomingCallPendingIntent,
-                    new ImsRegistrationListenerBase());
-            addRegistrationListener(listener);
-            log("open: Session started and registration listener added.");
+            mMmTelFeatureConnection.openConnection(listener);
         } catch (RemoteException e) {
-            throw new ImsException("open()", e,
-                    ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
+            throw new ImsException("open()", e, ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
         }
-
-        if (result <= 0) {
-            // If the return value is a minus value,
-            // it means that an error occurred in the service.
-            // So, it needs to convert to the reason code specified in ImsReasonInfo.
-            throw new ImsException("open()", (result * (-1)));
-        }
-
-        return result;
     }
 
     /**
@@ -1511,34 +1344,68 @@
      * @param listener To listen to IMS registration events; It cannot be null
      * @throws NullPointerException if {@code listener} is null
      * @throws ImsException if calling the IMS service results in an error
+     * @deprecated use {@link #addRegistrationCallback(ImsRegistrationImplBase.Callback)} and
+     * {@link #addCapabilitiesCallback(ImsFeature.CapabilityCallback)} instead.
      */
     public void addRegistrationListener(ImsConnectionStateListener listener) throws ImsException {
         if (listener == null) {
             throw new NullPointerException("listener can't be null");
         }
-        // We only want this Proxy registered once.
-        synchronized (mHasRegisteredLock) {
-            if (!mHasRegisteredForProxy) {
-                try {
-                    checkAndThrowExceptionIfServiceUnavailable();
-                    // TODO: Remove once new MmTelFeature is merged in
-                    mImsServiceProxy.addRegistrationListener(mImsRegistrationListenerProxy);
-                    IImsRegistration regBinder = mImsServiceProxy.getRegistration();
-                    if (regBinder != null) {
-                        regBinder.addRegistrationCallback(mRegistrationCallback);
-                    }
-                    log("Registration Callback/Listener registered.");
-                    // Only record if there isn't a RemoteException.
-                    mHasRegisteredForProxy = true;
-                } catch (RemoteException e) {
-                    throw new ImsException("addRegistrationListener()", e,
-                            ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
-                }
+        addRegistrationCallback(listener);
+        // connect the ImsConnectionStateListener to the new CapabilityCallback.
+        addCapabilitiesCallback(new ImsFeature.CapabilityCallback() {
+            @Override
+            public void onCapabilitiesStatusChanged(ImsFeature.Capabilities config) {
+                listener.onFeatureCapabilityChangedAdapter(getRegistrationTech(), config);
             }
+        });
+        log("Registration Callback registered.");
+    }
+
+    /**
+     * Adds a callback that gets called when IMS registration has changed.
+     * @param callback A {@link ImsRegistrationImplBase.Callback} that will notify the caller when
+     *         IMS registration status has changed.
+     * @throws ImsException when the ImsService connection is not available.
+     */
+    public void addRegistrationCallback(ImsRegistrationImplBase.Callback callback)
+            throws ImsException {
+        if (callback == null) {
+            throw new NullPointerException("registration callback can't be null");
         }
-        synchronized (mRegistrationListeners) {
-            log("Local registration listener added: " + listener);
-            mRegistrationListeners.add(listener);
+
+        checkAndThrowExceptionIfServiceUnavailable();
+        try {
+            mMmTelFeatureConnection.addRegistrationCallback(callback);
+            log("Registration Callback registered.");
+            // Only record if there isn't a RemoteException.
+        } catch (RemoteException e) {
+            throw new ImsException("addRegistrationCallback(IRIB)", e,
+                    ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
+        }
+    }
+
+    /**
+     * Adds a callback that gets called when MMTel capability status has changed, for example when
+     * Voice over IMS or VT over IMS is not available currently.
+     * @param callback A {@link ImsFeature.CapabilityCallback} that will notify the caller when
+     *         MMTel capability status has changed.
+     * @throws ImsException when the ImsService connection is not available.
+     */
+    public void addCapabilitiesCallback(ImsFeature.CapabilityCallback callback)
+            throws ImsException {
+        if (callback == null) {
+            throw new NullPointerException("capabilities callback can't be null");
+        }
+
+        checkAndThrowExceptionIfServiceUnavailable();
+        try {
+            mMmTelFeatureConnection.addCapabilityCallback(callback);
+            log("Capability Callback registered.");
+            // Only record if there isn't a RemoteException.
+        } catch (RemoteException e) {
+            throw new ImsException("addCapabilitiesCallback(IF)", e,
+                    ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
         }
     }
 
@@ -1556,33 +1423,38 @@
             throw new NullPointerException("listener can't be null");
         }
 
-        synchronized (mRegistrationListeners) {
-            log("Local registration listener removed: " + listener);
-            mRegistrationListeners.remove(listener);
+        checkAndThrowExceptionIfServiceUnavailable();
+        try {
+            mMmTelFeatureConnection.removeRegistrationCallback(listener);
+            log("Registration Callback/Listener registered.");
+            // Only record if there isn't a RemoteException.
+        } catch (RemoteException e) {
+            throw new ImsException("addRegistrationCallback()", e,
+                    ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
+        }
+    }
+
+    public @ImsRegistrationImplBase.ImsRegistrationTech int getRegistrationTech() {
+        try {
+            return mMmTelFeatureConnection.getRegistrationTech();
+        } catch (RemoteException e) {
+            Log.w(TAG, "getRegistrationTech: no connection to ImsService.");
+            return ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
         }
     }
 
     /**
-     * Closes the specified service ({@link ImsServiceClass}) not to make/receive calls.
+     * Closes the connection and removes all active callbacks.
      * All the resources that were allocated to the service are also released.
-     *
-     * @param sessionId a session id to be closed which is obtained from {@link ImsManager#open}
-     * @throws ImsException if calling the IMS service results in an error
      */
-    public void close(int sessionId) throws ImsException {
-        checkAndThrowExceptionIfServiceUnavailable();
-
-        try {
-            mImsServiceProxy.endSession(sessionId);
-        } catch (RemoteException e) {
-            throw new ImsException("close()", e,
-                    ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
-        } finally {
-            mUt = null;
-            mConfig = null;
-            mEcbm = null;
-            mMultiEndpoint = null;
+    public void close() {
+        if (mMmTelFeatureConnection != null) {
+            mMmTelFeatureConnection.closeConnection();
         }
+        mUt = null;
+        mConfig = null;
+        mEcbm = null;
+        mMultiEndpoint = null;
     }
 
     /**
@@ -1591,8 +1463,7 @@
      * @return the Ut interface instance
      * @throws ImsException if getting the Ut interface results in an error
      */
-    public ImsUtInterface getSupplementaryServiceConfiguration()
-            throws ImsException {
+    public ImsUtInterface getSupplementaryServiceConfiguration() throws ImsException {
         // FIXME: manage the multiple Ut interfaces based on the session id
         if (mUt != null && mUt.isBinderAlive()) {
             return mUt;
@@ -1600,7 +1471,7 @@
 
         checkAndThrowExceptionIfServiceUnavailable();
         try {
-            IImsUt iUt = mImsServiceProxy.getUtInterface();
+            IImsUt iUt = mMmTelFeatureConnection.getUtInterface();
 
             if (iUt == null) {
                 throw new ImsException("getSupplementaryServiceConfiguration()",
@@ -1616,54 +1487,8 @@
     }
 
     /**
-     * Checks if the IMS service has successfully registered to the IMS network
-     * with the specified service & call type.
-     *
-     * @param serviceType a service type that is specified in {@link ImsCallProfile}
-     *        {@link ImsCallProfile#SERVICE_TYPE_NORMAL}
-     *        {@link ImsCallProfile#SERVICE_TYPE_EMERGENCY}
-     * @param callType a call type that is specified in {@link ImsCallProfile}
-     *        {@link ImsCallProfile#CALL_TYPE_VOICE_N_VIDEO}
-     *        {@link ImsCallProfile#CALL_TYPE_VOICE}
-     *        {@link ImsCallProfile#CALL_TYPE_VT}
-     *        {@link ImsCallProfile#CALL_TYPE_VS}
-     * @return true if the specified service id is connected to the IMS network;
-     *        false otherwise
-     * @throws ImsException if calling the IMS service results in an error
-     */
-    public boolean isConnected(int serviceType, int callType)
-            throws ImsException {
-        checkAndThrowExceptionIfServiceUnavailable();
-
-        try {
-            return mImsServiceProxy.isConnected(serviceType, callType);
-        } catch (RemoteException e) {
-            throw new ImsException("isServiceConnected()", e,
-                    ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
-        }
-    }
-
-    /**
-     * Checks if the specified IMS service is opend.
-     *
-     * @return true if the specified service id is opened; false otherwise
-     * @throws ImsException if calling the IMS service results in an error
-     */
-    public boolean isOpened() throws ImsException {
-        checkAndThrowExceptionIfServiceUnavailable();
-
-        try {
-            return mImsServiceProxy.isOpened();
-        } catch (RemoteException e) {
-            throw new ImsException("isOpened()", e,
-                    ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
-        }
-    }
-
-    /**
      * Creates a {@link ImsCallProfile} from the service capabilities & IMS registration state.
      *
-     * @param sessionId a session id which is obtained from {@link ImsManager#open}
      * @param serviceType a service type that is specified in {@link ImsCallProfile}
      *        {@link ImsCallProfile#SERVICE_TYPE_NONE}
      *        {@link ImsCallProfile#SERVICE_TYPE_NORMAL}
@@ -1680,12 +1505,11 @@
      * @return a {@link ImsCallProfile} object
      * @throws ImsException if calling the IMS service results in an error
      */
-    public ImsCallProfile createCallProfile(int sessionId, int serviceType, int callType)
-            throws ImsException {
+    public ImsCallProfile createCallProfile(int serviceType, int callType) throws ImsException {
         checkAndThrowExceptionIfServiceUnavailable();
 
         try {
-            return mImsServiceProxy.createCallProfile(sessionId, serviceType, callType);
+            return mMmTelFeatureConnection.createCallProfile(serviceType, callType);
         } catch (RemoteException e) {
             throw new ImsException("createCallProfile()", e,
                     ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
@@ -1695,19 +1519,17 @@
     /**
      * Creates a {@link ImsCall} to make a call.
      *
-     * @param sessionId a session id which is obtained from {@link ImsManager#open}
      * @param profile a call profile to make the call
      *      (it contains service type, call type, media information, etc.)
-     * @param participants participants to invite the conference call
+     * @param callees participants to invite the conference call
      * @param listener listen to the call events from {@link ImsCall}
      * @return a {@link ImsCall} object
      * @throws ImsException if calling the IMS service results in an error
      */
-    public ImsCall makeCall(int sessionId, ImsCallProfile profile, String[] callees,
+    public ImsCall makeCall(ImsCallProfile profile, String[] callees,
             ImsCall.Listener listener) throws ImsException {
         if (DBG) {
-            log("makeCall :: sessionId=" + sessionId
-                    + ", profile=" + profile);
+            log("makeCall :: profile=" + profile);
         }
 
         checkAndThrowExceptionIfServiceUnavailable();
@@ -1715,7 +1537,7 @@
         ImsCall call = new ImsCall(mContext, profile);
 
         call.setListener(listener);
-        ImsCallSession session = createCallSession(sessionId, profile);
+        ImsCallSession session = createCallSession(profile);
 
         if ((callees != null) && (callees.length == 1)) {
             call.start(session, callees[0]);
@@ -1730,33 +1552,25 @@
      * Creates a {@link ImsCall} to take an incoming call.
      *
      * @param sessionId a session id which is obtained from {@link ImsManager#open}
-     * @param incomingCallIntent the incoming call broadcast intent
+     * @param incomingCallExtras the incoming call broadcast intent
      * @param listener to listen to the call events from {@link ImsCall}
      * @return a {@link ImsCall} object
      * @throws ImsException if calling the IMS service results in an error
      */
-    public ImsCall takeCall(int sessionId, Intent incomingCallIntent,
+    public ImsCall takeCall(IImsCallSession session, Bundle incomingCallExtras,
             ImsCall.Listener listener) throws ImsException {
         if (DBG) {
-            log("takeCall :: sessionId=" + sessionId
-                    + ", incomingCall=" + incomingCallIntent);
+            log("takeCall :: incomingCall=" + incomingCallExtras);
         }
 
         checkAndThrowExceptionIfServiceUnavailable();
 
-        if (incomingCallIntent == null) {
+        if (incomingCallExtras == null) {
             throw new ImsException("Can't retrieve session with null intent",
                     ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT);
         }
 
-        int incomingServiceId = getImsSessionId(incomingCallIntent);
-
-        if (sessionId != incomingServiceId) {
-            throw new ImsException("Service id is mismatched in the incoming call intent",
-                    ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT);
-        }
-
-        String callId = getCallId(incomingCallIntent);
+        String callId = getCallId(incomingCallExtras);
 
         if (callId == null) {
             throw new ImsException("Call ID missing in the incoming call intent",
@@ -1764,8 +1578,6 @@
         }
 
         try {
-            IImsCallSession session = mImsServiceProxy.getPendingCallSession(sessionId, callId);
-
             if (session == null) {
                 throw new ImsException("No pending session for the call",
                         ImsReasonInfo.CODE_LOCAL_NO_PENDING_CALL);
@@ -1795,7 +1607,7 @@
 
         checkAndThrowExceptionIfServiceUnavailable();
         try {
-            IImsConfig config = mImsServiceProxy.getConfigInterface();
+            IImsConfig config = mMmTelFeatureConnection.getConfigInterface();
             if (config == null) {
                 throw new ImsException("getConfigInterface()",
                         ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE);
@@ -1808,6 +1620,25 @@
         return mConfig;
     }
 
+    public void changeMmTelCapability(
+            @MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
+            @ImsRegistrationImplBase.ImsRegistrationTech int radioTech,
+            boolean isEnabled) throws RemoteException {
+        CapabilityChangeRequest request = new CapabilityChangeRequest();
+        if (isEnabled) {
+            request.addCapabilitiesToEnableForTech(capability, radioTech);
+        } else {
+            request.addCapabilitiesToDisableForTech(capability, radioTech);
+        }
+        mMmTelFeatureConnection.changeEnabledCapabilities(request, null);
+        if (mImsConfigListener != null) {
+            mImsConfigListener.onSetFeatureResponse(capability,
+                    mMmTelFeatureConnection.getRegistrationTech(),
+                    isEnabled ? ImsConfig.FeatureValueConstants.ON
+                            : ImsConfig.FeatureValueConstants.OFF, -1);
+        }
+    }
+
     /**
      * Set the TTY mode. This is the actual tty mode (varies depending on peripheral status)
      */
@@ -1829,7 +1660,7 @@
         checkAndThrowExceptionIfServiceUnavailable();
 
         try {
-            mImsServiceProxy.setUiTTYMode(uiTtyMode, onComplete);
+            mMmTelFeatureConnection.setUiTTYMode(uiTtyMode, onComplete);
         } catch (RemoteException e) {
             throw new ImsException("setTTYMode()", e,
                     ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
@@ -1861,8 +1692,8 @@
         return disconnectReasons;
     }
 
-    public int getImsServiceStatus() throws ImsException {
-        return mImsServiceProxy.getFeatureStatus();
+    public int getImsServiceState() throws ImsException {
+        return mMmTelFeatureConnection.getFeatureState();
     }
 
     /**
@@ -1918,29 +1749,15 @@
     /**
      * Gets the call ID from the specified incoming call broadcast intent.
      *
-     * @param incomingCallIntent the incoming call broadcast intent
+     * @param incomingCallExtras the incoming call broadcast intent
      * @return the call ID or null if the intent does not contain it
      */
-    private static String getCallId(Intent incomingCallIntent) {
-        if (incomingCallIntent == null) {
+    private static String getCallId(Bundle incomingCallExtras) {
+        if (incomingCallExtras == null) {
             return null;
         }
 
-        return incomingCallIntent.getStringExtra(EXTRA_CALL_ID);
-    }
-
-    /**
-     * Gets the service type from the specified incoming call broadcast intent.
-     *
-     * @param incomingCallIntent the incoming call broadcast intent
-     * @return the session identifier or -1 if the intent does not contain it
-     */
-    private static int getImsSessionId(Intent incomingCallIntent) {
-        if (incomingCallIntent == null) {
-            return (-1);
-        }
-
-        return incomingCallIntent.getIntExtra(EXTRA_SERVICE_ID, -1);
+        return incomingCallExtras.getString(EXTRA_CALL_ID);
     }
 
     /**
@@ -1949,10 +1766,10 @@
      */
     private void checkAndThrowExceptionIfServiceUnavailable()
             throws ImsException {
-        if (mImsServiceProxy == null || !mImsServiceProxy.isBinderAlive()) {
+        if (mMmTelFeatureConnection == null || !mMmTelFeatureConnection.isBinderAlive()) {
             createImsService();
 
-            if (mImsServiceProxy == null) {
+            if (mMmTelFeatureConnection == null) {
                 throw new ImsException("Service is unavailable",
                         ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
             }
@@ -1966,30 +1783,21 @@
      * 2) android.telephony.ims.ImsService implementation through ImsResolver.
      */
     private void createImsService() {
-        if (!mConfigDynamicBind) {
-            // Deprecated method of binding
-            Rlog.i(TAG, "Creating ImsService using ServiceManager");
-            mImsServiceProxy = ImsServiceProxyCompat.create(mContext, mPhoneId, mDeathRecipient);
-        } else {
-            Rlog.i(TAG, "Creating ImsService using ImsResolver");
-            mImsServiceProxy = ImsServiceProxy.create(mContext, mPhoneId);
-        }
+        Rlog.i(TAG, "Creating ImsService");
+        mMmTelFeatureConnection = MmTelFeatureConnection.create(mContext, mPhoneId);
+
         // Forwarding interface to tell mStatusCallbacks that the Proxy is unavailable.
-        mImsServiceProxy.setStatusCallback(new ImsServiceProxy.IFeatureUpdate() {
+        mMmTelFeatureConnection.setStatusCallback(new MmTelFeatureConnection.IFeatureUpdate() {
             @Override
             public void notifyStateChanged() {
-                mStatusCallbacks.forEach(ImsServiceProxy.IFeatureUpdate::notifyStateChanged);
+                mStatusCallbacks.forEach(MmTelFeatureConnection.IFeatureUpdate::notifyStateChanged);
             }
 
             @Override
             public void notifyUnavailable() {
-                mStatusCallbacks.forEach(ImsServiceProxy.IFeatureUpdate::notifyUnavailable);
+                mStatusCallbacks.forEach(MmTelFeatureConnection.IFeatureUpdate::notifyUnavailable);
             }
         });
-        // We have created a new ImsService connection, signal for re-registration
-        synchronized (mHasRegisteredLock) {
-            mHasRegisteredForProxy = false;
-        }
     }
 
     /**
@@ -1997,14 +1805,12 @@
      * Use other methods, if applicable, instead of interacting with
      * {@link ImsCallSession} directly.
      *
-     * @param serviceId a service id which is obtained from {@link ImsManager#open}
      * @param profile a call profile to make the call
      */
-    private ImsCallSession createCallSession(int serviceId,
-            ImsCallProfile profile) throws ImsException {
+    private ImsCallSession createCallSession(ImsCallProfile profile) throws ImsException {
         try {
             // Throws an exception if the ImsService Feature is not ready to accept commands.
-            return new ImsCallSession(mImsServiceProxy.createCallSession(serviceId, profile, null));
+            return new ImsCallSession(mMmTelFeatureConnection.createCallSession(profile));
         } catch (RemoteException e) {
             Rlog.w(TAG, "CreateCallSession: Error, remote exception: " + e.getMessage());
             throw new ImsException("createCallSession()", e,
@@ -2029,13 +1835,9 @@
      * Used for turning on IMS.if its off already
      */
     private void turnOnIms() throws ImsException {
-        checkAndThrowExceptionIfServiceUnavailable();
-
-        try {
-            mImsServiceProxy.turnOnIms();
-        } catch (RemoteException e) {
-            throw new ImsException("turnOnIms() ", e, ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
-        }
+        TelephonyManager tm = (TelephonyManager)
+                mContext.getSystemService(Context.TELEPHONY_SERVICE);
+        tm.enableIms(mPhoneId);
     }
 
     private boolean isImsTurnOffAllowed() {
@@ -2046,25 +1848,36 @@
 
     private void setLteFeatureValues(boolean turnOn) {
         log("setLteFeatureValues: " + turnOn);
-        try {
-            ImsConfig config = getConfigInterface();
-            if (config != null) {
-                config.setFeatureValue(ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE,
-                        TelephonyManager.NETWORK_TYPE_LTE, turnOn ? 1 : 0, mImsConfigListener);
+        CapabilityChangeRequest request = new CapabilityChangeRequest();
+        if (turnOn) {
+            request.addCapabilitiesToEnableForTech(
+                    MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
+                    ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
+        } else {
+            request.addCapabilitiesToDisableForTech(
+                    MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
+                    ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
+        }
 
-                if (isVolteEnabledByPlatform()) {
-                    boolean ignoreDataEnabledChanged = getBooleanCarrierConfig(
-                            CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS);
-                    boolean enableViLte = turnOn && isVtEnabledByUser() &&
-                            (ignoreDataEnabledChanged || isDataEnabled());
-                    config.setFeatureValue(ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE,
-                            TelephonyManager.NETWORK_TYPE_LTE,
-                            enableViLte ? 1 : 0,
-                            mImsConfigListener);
-                }
+        if (isVolteEnabledByPlatform()) {
+            boolean ignoreDataEnabledChanged = getBooleanCarrierConfig(
+                    CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS);
+            boolean enableViLte = turnOn && isVtEnabledByUser() &&
+                    (ignoreDataEnabledChanged || isDataEnabled());
+            if (enableViLte) {
+                request.addCapabilitiesToEnableForTech(
+                        MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO,
+                        ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
+            } else {
+                request.addCapabilitiesToDisableForTech(
+                        MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO,
+                        ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
             }
-        } catch (ImsException e) {
-            loge("setLteFeatureValues: exception ", e);
+        }
+        try {
+            mMmTelFeatureConnection.changeEnabledCapabilities(request, null);
+        } catch (RemoteException e) {
+            Log.e(TAG, "setLteFeatureValues: Exception: " + e.getMessage());
         }
     }
 
@@ -2092,13 +1905,9 @@
      * Once turned off, all calls will be over CS.
      */
     private void turnOffIms() throws ImsException {
-        checkAndThrowExceptionIfServiceUnavailable();
-
-        try {
-            mImsServiceProxy.turnOffIms();
-        } catch (RemoteException e) {
-            throw new ImsException("turnOffIms() ", e, ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
-        }
+        TelephonyManager tm = (TelephonyManager)
+                mContext.getSystemService(Context.TELEPHONY_SERVICE);
+        tm.disableIms(mPhoneId);
     }
 
     private void addToRecentDisconnectReasons(ImsReasonInfo reason) {
@@ -2115,7 +1924,7 @@
     private class ImsServiceDeathRecipient implements IBinder.DeathRecipient {
         @Override
         public void binderDied() {
-            mImsServiceProxy = null;
+            mMmTelFeatureConnection = null;
             mUt = null;
             mConfig = null;
             mEcbm = null;
@@ -2124,270 +1933,19 @@
     }
 
     /**
-     * Stub implementation of the Registration listener that provides no functionality.
-     */
-    private class ImsRegistrationListenerBase extends IImsRegistrationListener.Stub {
-
-        @Override
-        public void registrationConnected() throws RemoteException {
-        }
-
-        @Override
-        public void registrationProgressing() throws RemoteException {
-        }
-
-        @Override
-        public void registrationConnectedWithRadioTech(int imsRadioTech) throws RemoteException {
-        }
-
-        @Override
-        public void registrationProgressingWithRadioTech(int imsRadioTech) throws RemoteException {
-        }
-
-        @Override
-        public void registrationDisconnected(ImsReasonInfo imsReasonInfo) throws RemoteException {
-        }
-
-        @Override
-        public void registrationResumed() throws RemoteException {
-        }
-
-        @Override
-        public void registrationSuspended() throws RemoteException {
-        }
-
-        @Override
-        public void registrationServiceCapabilityChanged(int serviceClass, int event)
-                throws RemoteException {
-        }
-
-        @Override
-        public void registrationFeatureCapabilityChanged(int serviceClass, int[] enabledFeatures,
-                int[] disabledFeatures) throws RemoteException {
-        }
-
-        @Override
-        public void voiceMessageCountUpdate(int count) throws RemoteException {
-        }
-
-        @Override
-        public void registrationAssociatedUriChanged(Uri[] uris) throws RemoteException {
-        }
-
-        @Override
-        public void registrationChangeFailed(int targetAccessTech, ImsReasonInfo imsReasonInfo)
-                throws RemoteException {
-        }
-    }
-
-    /**
-     * Adapter class for {@link IImsRegistrationListener}.
-     */
-    private class ImsRegistrationListenerProxy extends IImsRegistrationListener.Stub {
-
-        @Deprecated
-        public void registrationConnected() {
-            if (DBG) {
-                log("registrationConnected ::");
-            }
-
-            synchronized (mRegistrationListeners) {
-                mRegistrationListeners.forEach(l -> l.onImsConnected(
-                        ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN));
-            }
-        }
-
-        @Deprecated
-        public void registrationProgressing() {
-            if (DBG) {
-                log("registrationProgressing ::");
-            }
-
-            synchronized (mRegistrationListeners) {
-                mRegistrationListeners.forEach(l -> l.onImsProgressing(
-                        ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN));
-            }
-        }
-
-        @Override
-        public void registrationConnectedWithRadioTech(int imsRadioTech) {
-            // Note: imsRadioTech value maps to RIL_RADIO_TECHNOLOGY
-            //       values in ServiceState.java.
-            if (DBG) {
-                log("registrationConnectedWithRadioTech :: imsRadioTech=" + imsRadioTech);
-            }
-
-            synchronized (mRegistrationListeners) {
-                mRegistrationListeners.forEach(l -> l.onImsConnected(imsRadioTech));
-            }
-        }
-
-        @Override
-        public void registrationProgressingWithRadioTech(int imsRadioTech) {
-            // Note: imsRadioTech value maps to RIL_RADIO_TECHNOLOGY
-            //       values in ServiceState.java.
-            if (DBG) {
-                log("registrationProgressingWithRadioTech :: imsRadioTech=" + imsRadioTech);
-            }
-
-            synchronized (mRegistrationListeners) {
-                mRegistrationListeners.forEach(l -> l.onImsProgressing(imsRadioTech));
-            }
-        }
-
-        @Override
-        public void registrationDisconnected(ImsReasonInfo imsReasonInfo) {
-            if (DBG) {
-                log("registrationDisconnected :: imsReasonInfo" + imsReasonInfo);
-            }
-
-            addToRecentDisconnectReasons(imsReasonInfo);
-            synchronized (mRegistrationListeners) {
-                mRegistrationListeners.forEach(l -> l.onImsDisconnected(imsReasonInfo));
-            }
-        }
-
-        @Override
-        public void registrationResumed() {
-            if (DBG) {
-                log("registrationResumed ::");
-            }
-
-            synchronized (mRegistrationListeners) {
-                mRegistrationListeners.forEach(ImsConnectionStateListener::onImsResumed);
-            }
-        }
-
-        @Override
-        public void registrationSuspended() {
-            if (DBG) {
-                log("registrationSuspended ::");
-            }
-
-            synchronized (mRegistrationListeners) {
-                mRegistrationListeners.forEach(ImsConnectionStateListener::onImsSuspended);
-            }
-        }
-
-        @Override
-        public void registrationServiceCapabilityChanged(int serviceClass, int event) {
-            log("registrationServiceCapabilityChanged :: serviceClass=" +
-                    serviceClass + ", event=" + event);
-
-            synchronized (mRegistrationListeners) {
-                mRegistrationListeners.forEach(l -> l.onImsConnected(
-                        ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN));
-            }
-        }
-
-        @Override
-        public void registrationFeatureCapabilityChanged(int serviceClass,
-                int[] enabledFeatures, int[] disabledFeatures) {
-            log("registrationFeatureCapabilityChanged :: serviceClass=" +
-                    serviceClass);
-
-            synchronized (mRegistrationListeners) {
-                mRegistrationListeners.forEach(l -> l.onFeatureCapabilityChanged(serviceClass,
-                        enabledFeatures, disabledFeatures));
-            }
-        }
-
-        @Override
-        public void voiceMessageCountUpdate(int count) {
-            log("voiceMessageCountUpdate :: count=" + count);
-
-            synchronized (mRegistrationListeners) {
-                mRegistrationListeners.forEach(l -> l.onVoiceMessageCountChanged(count));
-            }
-        }
-
-        @Override
-        public void registrationAssociatedUriChanged(Uri[] uris) {
-            if (DBG) log("registrationAssociatedUriChanged ::");
-
-            synchronized (mRegistrationListeners) {
-                mRegistrationListeners.forEach(l -> l.registrationAssociatedUriChanged(uris));
-            }
-        }
-
-        @Override
-        public void registrationChangeFailed(int targetAccessTech, ImsReasonInfo imsReasonInfo) {
-            if (DBG) log("registrationChangeFailed :: targetAccessTech=" + targetAccessTech +
-                    ", imsReasonInfo=" + imsReasonInfo);
-
-            synchronized (mRegistrationListeners) {
-                mRegistrationListeners.forEach(l -> l.onRegistrationChangeFailed(targetAccessTech,
-                        imsReasonInfo));
-            }
-        }
-    }
-
-    // New API for Registration, uses ImsConnectionStateListener for backwards compatibility with
-    // deprecated APIs.
-    private class ImsRegistrationCallback extends IImsRegistrationCallback.Stub {
-
-        @Override
-        public void onRegistered(int imsRadioTech) {
-            if (DBG) log("onRegistered ::");
-
-            synchronized (mRegistrationListeners) {
-                mRegistrationListeners.forEach(l -> l.onRegistered(imsRadioTech));
-            }
-        }
-
-        @Override
-        public void onRegistering(int imsRadioTech) {
-            if (DBG) log("onRegistering ::");
-
-            synchronized (mRegistrationListeners) {
-                mRegistrationListeners.forEach(l -> l.onRegistering(imsRadioTech));
-            }
-        }
-
-        @Override
-        public void onDeregistered(ImsReasonInfo imsReasonInfo) {
-            if (DBG) log("onDeregistered ::");
-
-            synchronized (mRegistrationListeners) {
-                mRegistrationListeners.forEach(l -> l.onDeregistered(imsReasonInfo));
-            }
-        }
-
-        @Override
-        public void onTechnologyChangeFailed(int targetRadioTech, ImsReasonInfo imsReasonInfo) {
-            if (DBG) log("onTechnologyChangeFailed :: targetAccessTech=" + targetRadioTech +
-                    ", imsReasonInfo=" + imsReasonInfo);
-
-            synchronized (mRegistrationListeners) {
-                mRegistrationListeners.forEach(l -> l.onTechnologyChangeFailed(targetRadioTech,
-                        imsReasonInfo));
-            }
-        }
-
-        @Override
-        public void onSubscriberAssociatedUriChanged(Uri[] uris) {
-            if (DBG) log("onSubscriberAssociatedUriChanged");
-            synchronized (mRegistrationListeners) {
-                mRegistrationListeners.forEach(l -> l.onSubscriberAssociatedUriChanged(uris));
-            }
-        }
-    }
-
-    /**
      * Gets the ECBM interface to request ECBM exit.
      *
-     * @param serviceId a service id which is obtained from {@link ImsManager#open}
      * @return the ECBM interface instance
      * @throws ImsException if getting the ECBM interface results in an error
      */
-    public ImsEcbm getEcbmInterface(int serviceId) throws ImsException {
+    public ImsEcbm getEcbmInterface() throws ImsException {
         if (mEcbm != null && mEcbm.isBinderAlive()) {
             return mEcbm;
         }
 
         checkAndThrowExceptionIfServiceUnavailable();
         try {
-            IImsEcbm iEcbm = mImsServiceProxy.getEcbmInterface();
+            IImsEcbm iEcbm = mMmTelFeatureConnection.getEcbmInterface();
 
             if (iEcbm == null) {
                 throw new ImsException("getEcbmInterface()",
@@ -2404,7 +1962,7 @@
     public void sendSms(int token, int messageRef, String format, String smsc, boolean isRetry,
             byte[] pdu) throws ImsException {
         try {
-            mImsServiceProxy.sendSms(token, messageRef, format, smsc, isRetry, pdu);
+            mMmTelFeatureConnection.sendSms(token, messageRef, format, smsc, isRetry, pdu);
         } catch (RemoteException e) {
             throw new ImsException("sendSms()", e, ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
         }
@@ -2412,7 +1970,7 @@
 
     public void acknowledgeSms(int token, int messageRef, int result) throws ImsException {
         try {
-            mImsServiceProxy.acknowledgeSms(token, messageRef, result);
+            mMmTelFeatureConnection.acknowledgeSms(token, messageRef, result);
         } catch (RemoteException e) {
             throw new ImsException("acknowledgeSms()", e,
                     ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
@@ -2421,7 +1979,7 @@
 
     public void acknowledgeSmsReport(int token, int messageRef, int result) throws  ImsException{
         try {
-            mImsServiceProxy.acknowledgeSmsReport(token, messageRef, result);
+            mMmTelFeatureConnection.acknowledgeSmsReport(token, messageRef, result);
         } catch (RemoteException e) {
             throw new ImsException("acknowledgeSmsReport()", e,
                     ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
@@ -2430,7 +1988,7 @@
 
     public String getSmsFormat() throws ImsException{
         try {
-            return mImsServiceProxy.getSmsFormat();
+            return mMmTelFeatureConnection.getSmsFormat();
         } catch (RemoteException e) {
             throw new ImsException("getSmsFormat()", e,
                     ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
@@ -2439,27 +1997,36 @@
 
     public void setSmsListener(IImsSmsListener listener) throws ImsException {
         try {
-            mImsServiceProxy.setSmsListener(listener);
+            mMmTelFeatureConnection.setSmsListener(listener);
         } catch (RemoteException e) {
             throw new ImsException("setSmsListener()", e,
                     ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
         }
     }
+
+    public void onSmsReady() throws ImsException{
+        try {
+            mMmTelFeatureConnection.onSmsReady();
+        } catch (RemoteException e) {
+            throw new ImsException("onSmsReady()", e,
+                    ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
+        }
+    }
+
     /**
      * Gets the Multi-Endpoint interface to subscribe to multi-enpoint notifications..
      *
-     * @param serviceId a service id which is obtained from {@link ImsManager#open}
      * @return the multi-endpoint interface instance
      * @throws ImsException if getting the multi-endpoint interface results in an error
      */
-    public ImsMultiEndpoint getMultiEndpointInterface(int serviceId) throws ImsException {
+    public ImsMultiEndpoint getMultiEndpointInterface() throws ImsException {
         if (mMultiEndpoint != null && mMultiEndpoint.isBinderAlive()) {
             return mMultiEndpoint;
         }
 
         checkAndThrowExceptionIfServiceUnavailable();
         try {
-            IImsMultiEndpoint iImsMultiEndpoint = mImsServiceProxy.getMultiEndpointInterface();
+            IImsMultiEndpoint iImsMultiEndpoint = mMmTelFeatureConnection.getMultiEndpointInterface();
 
             if (iImsMultiEndpoint == null) {
                 throw new ImsException("getMultiEndpointInterface()",
@@ -2498,7 +2065,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(),
@@ -2527,40 +2096,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) {
@@ -2572,7 +2123,7 @@
         pw.println("ImsManager:");
         pw.println("  mPhoneId = " + mPhoneId);
         pw.println("  mConfigUpdated = " + mConfigUpdated);
-        pw.println("  mImsServiceProxy = " + mImsServiceProxy);
+        pw.println("  mImsServiceProxy = " + mMmTelFeatureConnection);
         pw.println("  mDataEnabled = " + isDataEnabled());
         pw.println("  ignoreDataEnabledChanged = " + getBooleanCarrierConfig(
                 CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS));
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 153c5f5..0000000
--- a/src/java/com/android/ims/ImsServiceProxy.java
+++ /dev/null
@@ -1,416 +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.feature.ImsFeature;
-import android.telephony.SmsMessage;
-import android.telephony.ims.internal.SmsImplBase;
-import android.util.Log;
-
-import com.android.ims.internal.IImsCallSession;
-import com.android.ims.internal.IImsCallSessionListener;
-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,
-            IImsCallSessionListener listener) throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            return getServiceInterface(mBinder).createCallSession(sessionId, profile, listener);
-        }
-    }
-
-    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 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/ImsServiceProxyCompat.java b/src/java/com/android/ims/ImsServiceProxyCompat.java
deleted file mode 100644
index a6d1865..0000000
--- a/src/java/com/android/ims/ImsServiceProxyCompat.java
+++ /dev/null
@@ -1,194 +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.app.PendingIntent;
-import android.content.Context;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.telephony.Rlog;
-import android.telephony.TelephonyManager;
-import android.telephony.ims.feature.ImsFeature;
-
-import com.android.ims.internal.IImsCallSession;
-import com.android.ims.internal.IImsCallSessionListener;
-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.IImsRegistrationListener;
-import com.android.ims.internal.IImsService;
-import com.android.ims.internal.IImsUt;
-
-/**
- * Compatibility class that implements the new ImsService MMTelFeature interface, but
- * uses the old IImsService interface to support older devices that implement the deprecated
- * opt/net/ims interface.
- * @hide
- */
-
-public class ImsServiceProxyCompat extends ImsServiceProxy {
-
-    private static final int SERVICE_ID = ImsFeature.MMTEL;
-
-    /**
-     * For accessing the IMS related service.
-     * Internal use only.
-     * @hide
-     */
-    private static final String IMS_SERVICE = "ims";
-
-    public static ImsServiceProxyCompat create(Context context, int slotId,
-            IBinder.DeathRecipient recipient) {
-        IBinder binder = ServiceManager.checkService(IMS_SERVICE);
-
-        if (binder != null) {
-            try {
-                binder.linkToDeath(recipient, 0);
-            } catch (RemoteException e) {
-            }
-        }
-
-        // If the proxy is created with a null binder, subsequent calls that depend on a live
-        // binder will fail, causing this structure to be torn down and created again.
-        return new ImsServiceProxyCompat(context, slotId, binder);
-    }
-
-    public ImsServiceProxyCompat(Context context, int slotId, IBinder binder) {
-        super(context, slotId, binder, SERVICE_ID);
-    }
-
-    @Override
-    public int startSession(PendingIntent incomingCallIntent, IImsRegistrationListener listener)
-            throws RemoteException {
-        checkBinderConnection();
-        return getServiceInterface(mBinder).open(mSlotId, ImsFeature.MMTEL, incomingCallIntent,
-                listener);
-    }
-
-    @Override
-    public void endSession(int sessionId) throws RemoteException {
-        checkBinderConnection();
-        getServiceInterface(mBinder).close(sessionId);
-    }
-
-    @Override
-    public boolean isConnected(int callServiceType, int callType)
-            throws RemoteException {
-        checkBinderConnection();
-        return getServiceInterface(mBinder).isConnected(SERVICE_ID,  callServiceType, callType);
-    }
-
-    @Override
-    public boolean isOpened() throws RemoteException {
-        checkBinderConnection();
-        return getServiceInterface(mBinder).isOpened(SERVICE_ID);
-    }
-
-    @Override
-    public void addRegistrationListener(IImsRegistrationListener listener)
-            throws RemoteException {
-        checkBinderConnection();
-        getServiceInterface(mBinder).addRegistrationListener(mSlotId, ImsFeature.MMTEL, listener);
-    }
-
-    @Override
-    public void removeRegistrationListener(IImsRegistrationListener listener)
-            throws RemoteException {
-        // Not Implemented in old ImsService. If the registration listener becomes invalid, the
-        // ImsService will remove.
-    }
-
-    @Override
-    public ImsCallProfile createCallProfile(int sessionId, int callServiceType, int callType)
-            throws RemoteException {
-        checkBinderConnection();
-        return getServiceInterface(mBinder).createCallProfile(sessionId, callServiceType, callType);
-    }
-
-    @Override
-    public IImsCallSession createCallSession(int sessionId, ImsCallProfile profile,
-            IImsCallSessionListener listener) throws RemoteException {
-        checkBinderConnection();
-        return getServiceInterface(mBinder).createCallSession(sessionId, profile, listener);
-    }
-
-    @Override
-    public IImsCallSession getPendingCallSession(int sessionId, String callId)
-            throws RemoteException {
-        checkBinderConnection();
-        return getServiceInterface(mBinder).getPendingCallSession(sessionId, callId);
-    }
-
-    @Override
-    public IImsUt getUtInterface() throws RemoteException {
-        checkBinderConnection();
-        return getServiceInterface(mBinder).getUtInterface(SERVICE_ID);
-    }
-
-    @Override
-    public IImsConfig getConfigInterface() throws RemoteException {
-        checkBinderConnection();
-        return getServiceInterface(mBinder).getConfigInterface(mSlotId);
-    }
-
-    @Override
-    public void turnOnIms() throws RemoteException {
-        checkBinderConnection();
-        getServiceInterface(mBinder).turnOnIms(mSlotId);
-    }
-
-    @Override
-    public void turnOffIms() throws RemoteException {
-        checkBinderConnection();
-        getServiceInterface(mBinder).turnOffIms(mSlotId);
-    }
-
-    @Override
-    public IImsEcbm getEcbmInterface() throws RemoteException {
-        checkBinderConnection();
-        return getServiceInterface(mBinder).getEcbmInterface(SERVICE_ID);
-    }
-
-    @Override
-    public void setUiTTYMode(int uiTtyMode, Message onComplete)
-            throws RemoteException {
-        checkBinderConnection();
-        getServiceInterface(mBinder).setUiTTYMode(SERVICE_ID, uiTtyMode, onComplete);
-    }
-
-    @Override
-    public IImsMultiEndpoint getMultiEndpointInterface() throws RemoteException {
-        checkBinderConnection();
-        return getServiceInterface(mBinder).getMultiEndpointInterface(SERVICE_ID);
-    }
-    @Override
-    public int getFeatureStatus() {
-        return ImsFeature.STATE_READY;
-    }
-
-    @Override
-    public boolean isBinderAlive() {
-        return mBinder != null && mBinder.isBinderAlive();
-    }
-
-    private IImsService getServiceInterface(IBinder b) {
-        return IImsService.Stub.asInterface(b);
-    }
-}
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
new file mode 100644
index 0000000..571670d
--- /dev/null
+++ b/src/java/com/android/ims/MmTelFeatureConnection.java
@@ -0,0 +1,623 @@
+/*
+ * 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.content.Context;
+import android.net.Uri;
+import android.os.IBinder;
+import android.os.Message;
+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;
+import android.telephony.ims.aidl.IImsRegistrationCallback;
+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.telephony.ims.stub.ImsSmsImplBase;
+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.IImsServiceFeatureCallback;
+import com.android.ims.internal.IImsUt;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * A container of the IImsServiceController binder, which implements all of the ImsFeatures that
+ * the platform currently supports: MMTel and RCS.
+ * @hide
+ */
+
+public class MmTelFeatureConnection {
+
+    protected static final String TAG = "MmTelFeatureConnection";
+    protected final int mSlotId;
+    protected IBinder mBinder;
+    private Context mContext;
+
+    // Start by assuming the proxy is available for usage.
+    private volatile boolean mIsAvailable = true;
+    // ImsFeature Status from the ImsService. Cached.
+    private Integer mFeatureStateCached = null;
+    private IFeatureUpdate mStatusCallback;
+    private final Object mLock = new Object();
+
+    private MmTelFeature.Listener mMmTelFeatureListener;
+
+    private abstract class CallbackAdapterManager<T> {
+        private static final String TAG = "CallbackAdapterManager";
+
+        protected final Set<T> mLocalCallbacks = new HashSet<>();
+        private boolean mHasConnected = false;
+
+        public void addCallback(T localCallback) throws RemoteException {
+            // We only one one binding to the ImsService per process.
+            // Store any more locally.
+            synchronized (mLock) {
+                if(!mHasConnected) {
+                    // throws a RemoteException if a connection can not be established.
+                    if(createConnection()) {
+                        mHasConnected = true;
+                    } else {
+                        throw new RemoteException("Can not create connection!");
+                    }
+                }
+                Log.i(TAG, "Local callback added: " + localCallback);
+                mLocalCallbacks.add(localCallback);
+            }
+        }
+
+        public void removeCallback(T localCallback) {
+            // We only maintain one binding to the ImsService per process.
+            synchronized (mLock) {
+                Log.i(TAG, "Local callback removed: " + localCallback);
+                mLocalCallbacks.remove(localCallback);
+            // If we have removed all local callbacks, remove callback to ImsService.
+                if(mHasConnected) {
+                    if (mLocalCallbacks.isEmpty()) {
+                        removeConnection();
+                        mHasConnected = false;
+                    }
+                }
+            }
+        }
+
+        public void close() {
+            synchronized (mLock) {
+                if (mHasConnected) {
+                    removeConnection();
+                    // Still mark the connection as disconnected, even if this fails.
+                    mHasConnected = false;
+                }
+                Log.i(TAG, "Closing connection and clearing callbacks");
+                mLocalCallbacks.clear();
+            }
+        }
+
+        abstract boolean createConnection() throws RemoteException;
+
+        abstract void removeConnection();
+    }
+    private ImsRegistrationCallbackAdapter mRegistrationCallbackManager
+            = new ImsRegistrationCallbackAdapter();
+    private class ImsRegistrationCallbackAdapter
+            extends CallbackAdapterManager<ImsRegistrationImplBase.Callback> {
+        private final RegistrationCallbackAdapter mRegistrationCallbackAdapter
+                = new RegistrationCallbackAdapter();
+
+        private class RegistrationCallbackAdapter extends IImsRegistrationCallback.Stub {
+
+            @Override
+            public void onRegistered(int imsRadioTech) {
+                Log.i(TAG, "onRegistered ::");
+
+                synchronized (mLock) {
+                    mLocalCallbacks.forEach(l -> l.onRegistered(imsRadioTech));
+                }
+            }
+
+            @Override
+            public void onRegistering(int imsRadioTech) {
+                Log.i(TAG, "onRegistering ::");
+
+                synchronized (mLock) {
+                    mLocalCallbacks.forEach(l -> l.onRegistering(imsRadioTech));
+                }
+            }
+
+            @Override
+            public void onDeregistered(ImsReasonInfo imsReasonInfo) {
+                Log.i(TAG, "onDeregistered ::");
+
+                synchronized (mLock) {
+                    mLocalCallbacks.forEach(l -> l.onDeregistered(imsReasonInfo));
+                }
+            }
+
+            @Override
+            public void onTechnologyChangeFailed(int targetRadioTech, ImsReasonInfo imsReasonInfo) {
+                Log.i(TAG, "onTechnologyChangeFailed :: targetAccessTech=" + targetRadioTech +
+                        ", imsReasonInfo=" + imsReasonInfo);
+
+                synchronized (mLock) {
+                    mLocalCallbacks.forEach(l -> l.onTechnologyChangeFailed(targetRadioTech,
+                            imsReasonInfo));
+                }
+            }
+
+            @Override
+            public void onSubscriberAssociatedUriChanged(Uri[] uris) {
+                Log.i(TAG, "onSubscriberAssociatedUriChanged");
+                synchronized (mLock) {
+                    mLocalCallbacks.forEach(l -> l.onSubscriberAssociatedUriChanged(uris));
+                }
+            }
+        }
+
+        @Override
+        boolean createConnection() throws RemoteException {
+            IImsRegistration imsRegistration = getRegistration();
+            if (imsRegistration != null) {
+                getRegistration().addRegistrationCallback(mRegistrationCallbackAdapter);
+                return true;
+            } else {
+                Log.e(TAG, "ImsRegistration is null");
+                return false;
+            }
+        }
+
+        @Override
+        void removeConnection() {
+            IImsRegistration imsRegistration = getRegistration();
+            if (imsRegistration != null) {
+                try {
+                    getRegistration().addRegistrationCallback(mRegistrationCallbackAdapter);
+                } catch (RemoteException e) {
+                    Log.w(TAG, "removeConnection: couldn't remove registration callback");
+                }
+            } else {
+                Log.e(TAG, "ImsRegistration is null");
+            }
+        }
+    }
+
+    private final CapabilityCallbackManager mCapabilityCallbackManager
+            = new CapabilityCallbackManager();
+    private class CapabilityCallbackManager
+            extends CallbackAdapterManager<ImsFeature.CapabilityCallback> {
+        private final CapabilityCallbackAdapter mCallbackAdapter = new CapabilityCallbackAdapter();
+
+        private class CapabilityCallbackAdapter extends ImsFeature.CapabilityCallback {
+            // Called when the Capabilities Status on this connection have changed.
+            @Override
+            public void onCapabilitiesStatusChanged(ImsFeature.Capabilities config) {
+                synchronized (mLock) {
+                    mLocalCallbacks.forEach(
+                            callback -> callback.onCapabilitiesStatusChanged(config));
+                }
+            }
+        }
+
+        @Override
+        boolean createConnection() throws RemoteException {
+            IImsMmTelFeature binder = getServiceInterface(mBinder);
+            if (binder != null) {
+                binder.addCapabilityCallback(mCallbackAdapter);
+                return true;
+            } else {
+                Log.w(TAG, "create: Couldn't get IImsMmTelFeature binder");
+                return false;
+            }
+        }
+
+        @Override
+        void removeConnection() {
+            IImsMmTelFeature binder = getServiceInterface(mBinder);
+            if (binder != null) {
+                try {
+                    binder.removeCapabilityCallback(mCallbackAdapter);
+                } catch (RemoteException e) {
+                    Log.w(TAG, "remove: IImsMmTelFeature binder is dead");
+                }
+            } else {
+                Log.w(TAG, "remove: Couldn't get IImsMmTelFeature binder");
+            }
+        }
+    }
+
+
+    public static MmTelFeatureConnection create(Context context , int slotId) {
+        MmTelFeatureConnection serviceProxy = new MmTelFeatureConnection(context, slotId);
+
+        TelephonyManager tm  = getTelephonyManager(context);
+        if (tm == null) {
+            Rlog.w(TAG, "create: 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.getFeatureState();
+        } else {
+            Rlog.w(TAG, "create: binder is null! Slot 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 == ImsFeature.FEATURE_MMTEL) {
+                    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 == ImsFeature.FEATURE_MMTEL) {
+                    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 == ImsFeature.FEATURE_MMTEL) {
+                    mFeatureStateCached = status;
+                    if (mStatusCallback != null) {
+                        mStatusCallback.notifyStateChanged();
+                    }
+                }
+            }
+        }
+    };
+
+    public MmTelFeatureConnection(Context context, int slotId) {
+        mSlotId = slotId;
+        mContext = context;
+    }
+
+    private @Nullable IImsRegistration getRegistration() {
+        TelephonyManager tm = getTelephonyManager(mContext);
+        return tm != null ? tm.getImsRegistration(mSlotId, ImsFeature.FEATURE_MMTEL) : null;
+    }
+
+    private IImsConfig getConfig() {
+        TelephonyManager tm = getTelephonyManager(mContext);
+        return tm != null ? tm.getImsConfig(mSlotId, ImsFeature.FEATURE_MMTEL) : null;
+    }
+
+    public IImsServiceFeatureCallback getListener() {
+        return mListenerBinder;
+    }
+
+    public void setBinder(IBinder binder) {
+        mBinder = binder;
+    }
+
+    /**
+     * Opens the connection to the {@link MmTelFeature} and establishes a listener back to the
+     * framework. Calling this method multiple times will reset the listener attached to the
+     * {@link MmTelFeature}.
+     * @param listener A {@link MmTelFeature.Listener} that will be used by the {@link MmTelFeature}
+     * to notify the framework of updates.
+     */
+    public void openConnection(MmTelFeature.Listener listener) throws RemoteException {
+        synchronized (mLock) {
+            checkServiceIsReady();
+            mMmTelFeatureListener = listener;
+            getServiceInterface(mBinder).setListener(mMmTelFeatureListener);
+        }
+    }
+
+    public void closeConnection() {
+        mRegistrationCallbackManager.close();
+        mCapabilityCallbackManager.close();
+        try {
+            getServiceInterface(mBinder).setListener(null);
+        } catch (RemoteException e) {
+            Log.w(TAG, "closeConnection: couldn't remove listener!");
+        }
+    }
+
+    public void addRegistrationCallback(ImsRegistrationImplBase.Callback callback)
+            throws RemoteException {
+        mRegistrationCallbackManager.addCallback(callback);
+    }
+
+    public void removeRegistrationCallback(ImsRegistrationImplBase.Callback callback)
+            throws RemoteException {
+        mRegistrationCallbackManager.removeCallback(callback);
+    }
+
+    public void addCapabilityCallback(ImsFeature.CapabilityCallback callback)
+            throws RemoteException {
+        mCapabilityCallbackManager.addCallback(callback);
+    }
+
+    public void removeCapabilityCallback(ImsFeature.CapabilityCallback callback)
+            throws RemoteException {
+        mCapabilityCallbackManager.removeCallback(callback);
+    }
+
+    public void changeEnabledCapabilities(CapabilityChangeRequest request,
+            ImsFeature.CapabilityCallback callback) throws RemoteException {
+        synchronized (mLock) {
+            checkServiceIsReady();
+            getServiceInterface(mBinder).changeCapabilitiesConfiguration(request, callback);
+        }
+    }
+
+    public void queryEnabledCapabilities(int capability, int radioTech,
+            ImsFeature.CapabilityCallback callback) throws RemoteException {
+        synchronized (mLock) {
+            checkServiceIsReady();
+            getServiceInterface(mBinder).queryCapabilityConfiguration(capability, radioTech,
+                    callback);
+        }
+    }
+
+    public MmTelFeature.MmTelCapabilities queryCapabilityStatus() throws RemoteException {
+        synchronized (mLock) {
+            checkServiceIsReady();
+            return new MmTelFeature.MmTelCapabilities(
+                    getServiceInterface(mBinder).queryCapabilityStatus());
+        }
+    }
+
+    public ImsCallProfile createCallProfile(int callServiceType, int callType)
+            throws RemoteException {
+        synchronized (mLock) {
+            checkServiceIsReady();
+            return getServiceInterface(mBinder).createCallProfile(callServiceType, callType);
+        }
+    }
+
+    public IImsCallSession createCallSession(ImsCallProfile profile)
+            throws RemoteException {
+        synchronized (mLock) {
+            checkServiceIsReady();
+            return getServiceInterface(mBinder).createCallSession(profile);
+        }
+    }
+
+    public IImsUt getUtInterface() throws RemoteException {
+        synchronized (mLock) {
+            checkServiceIsReady();
+            return getServiceInterface(mBinder).getUtInterface();
+        }
+    }
+
+    public IImsConfig getConfigInterface() throws RemoteException {
+        synchronized (mLock) {
+            checkServiceIsReady();
+            return getConfig();
+        }
+    }
+
+    public @ImsRegistrationImplBase.ImsRegistrationTech int getRegistrationTech()
+    throws RemoteException {
+        synchronized (mLock) {
+            checkServiceIsReady();
+            IImsRegistration registration = getRegistration();
+            if (registration != null) {
+                return registration.getRegistrationTechnology();
+            } else {
+                return ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
+            }
+        }
+    }
+
+    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();
+        }
+    }
+
+    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,
+            @ImsSmsImplBase.SendStatusResult int result) throws RemoteException {
+        synchronized (mLock) {
+            checkServiceIsReady();
+            getServiceInterface(mBinder).acknowledgeSms(token, messageRef, result);
+        }
+    }
+
+    public void acknowledgeSmsReport(int token, int messageRef,
+            @ImsSmsImplBase.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 an integer describing the current Feature Status, defined in
+     * {@link ImsFeature.ImsState}.
+     */
+    public int getFeatureState() {
+        synchronized (mLock) {
+            if (isBinderAlive() && mFeatureStateCached != null) {
+                Log.i(TAG, "getFeatureState - returning cached: " + mFeatureStateCached);
+                return mFeatureStateCached;
+            }
+        }
+        // Don't synchronize on Binder call.
+        Integer status = retrieveFeatureState();
+        synchronized (mLock) {
+            if (status == null) {
+                return ImsFeature.STATE_UNAVAILABLE;
+            }
+            // Cache only non-null value for feature status.
+            mFeatureStateCached = status;
+        }
+        Log.i(TAG, "getFeatureState - returning " + status);
+        return status;
+    }
+
+    /**
+     * Internal method used to retrieve the feature status from the corresponding ImsService.
+     */
+    private Integer retrieveFeatureState() {
+        if (mBinder != null) {
+            try {
+                return getServiceInterface(mBinder).getFeatureState();
+            } 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;
+    }
+
+    /**
+     * @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_UNAVAILABLE}.
+     */
+    public boolean isBinderReady() {
+        return isBinderAlive() && getFeatureState() == 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/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));
     }
 }
