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 e3d17e1..063f5a8 100644
--- a/src/java/com/android/ims/ImsManager.java
+++ b/src/java/com/android/ims/ImsManager.java
@@ -16,51 +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.internal.feature.ImsFeature;
 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;
 
 /**
@@ -87,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";
 
@@ -168,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;
 
@@ -178,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;
@@ -193,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";
@@ -229,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.
      *
@@ -285,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(
@@ -407,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;
         }
 
@@ -541,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;
         }
 
@@ -577,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);
     }
 
     /**
@@ -598,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");
@@ -618,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);
         }
     }
@@ -645,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);
     }
@@ -683,7 +660,7 @@
             return getBooleanCarrierConfig(
                     CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL);
         } else {
-            return setting == 1;
+            return setting == ImsConfig.FeatureValueConstants.ON;
         }
     }
 
@@ -717,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");
@@ -741,7 +713,7 @@
             }
 
             setWfcModeInternal(imsWfcModeFeatureValue);
-        } catch (ImsException e) {
+        } catch (ImsException | RemoteException e) {
             loge("setWfcSetting(): ", e);
         }
     }
@@ -915,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) {
@@ -931,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
@@ -968,7 +940,7 @@
             return getBooleanCarrierConfig(
                             CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_ENABLED_BOOL);
         } else {
-            return (setting == 1);
+            return setting == ImsConfig.FeatureValueConstants.ON;
         }
     }
 
@@ -1001,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
@@ -1034,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;
         }
 
@@ -1070,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;
         }
     }
 
@@ -1204,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) {
@@ -1220,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();
@@ -1245,7 +1129,7 @@
                 }
 
                 mConfigUpdated = true;
-            } catch (ImsException e) {
+            } catch (ImsException | RemoteException e) {
                 loge("updateImsServiceConfig: ", e);
                 mConfigUpdated = false;
             }
@@ -1257,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();
@@ -1267,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;
     }
@@ -1283,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();
@@ -1299,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;
     }
@@ -1315,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();
@@ -1330,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;
@@ -1359,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();
     }
 
@@ -1382,7 +1246,7 @@
     public boolean isServiceAvailable() {
         connectIfServiceIsAvailable();
         // mImsServiceProxy will always create an ImsServiceProxy.
-        return mImsServiceProxy.isBinderAlive();
+        return mMmTelFeatureConnection.isBinderAlive();
     }
 
     /*
@@ -1390,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;
     }
 
@@ -1411,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);
         }
@@ -1422,7 +1286,7 @@
         }
     }
 
-    public void removeNotifyStatusChangedCallback(ImsServiceProxy.IFeatureUpdate c) {
+    public void removeNotifyStatusChangedCallback(MmTelFeatureConnection.IFeatureUpdate c) {
         if (c != null) {
             mStatusCallbacks.remove(c);
         } else {
@@ -1432,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;
     }
 
     /**
@@ -1513,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);
         }
     }
 
@@ -1558,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;
     }
 
     /**
@@ -1593,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;
@@ -1602,7 +1471,7 @@
 
         checkAndThrowExceptionIfServiceUnavailable();
         try {
-            IImsUt iUt = mImsServiceProxy.getUtInterface();
+            IImsUt iUt = mMmTelFeatureConnection.getUtInterface();
 
             if (iUt == null) {
                 throw new ImsException("getSupplementaryServiceConfiguration()",
@@ -1618,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}
@@ -1682,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);
@@ -1697,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();
@@ -1717,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]);
@@ -1732,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",
@@ -1766,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);
@@ -1797,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);
@@ -1810,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)
      */
@@ -1831,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);
@@ -1863,8 +1692,8 @@
         return disconnectReasons;
     }
 
-    public int getImsServiceStatus() throws ImsException {
-        return mImsServiceProxy.getFeatureStatus();
+    public int getImsServiceState() throws ImsException {
+        return mMmTelFeatureConnection.getFeatureState();
     }
 
     /**
@@ -1920,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);
     }
 
     /**
@@ -1951,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);
             }
@@ -1968,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;
-        }
     }
 
     /**
@@ -1999,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,
@@ -2031,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() {
@@ -2048,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());
         }
     }
 
@@ -2094,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) {
@@ -2117,7 +1924,7 @@
     private class ImsServiceDeathRecipient implements IBinder.DeathRecipient {
         @Override
         public void binderDied() {
-            mImsServiceProxy = null;
+            mMmTelFeatureConnection = null;
             mUt = null;
             mConfig = null;
             mEcbm = null;
@@ -2126,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()",
@@ -2406,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);
         }
@@ -2414,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);
@@ -2423,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);
@@ -2432,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);
@@ -2441,7 +1997,7 @@
 
     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);
@@ -2450,36 +2006,27 @@
 
     public void onSmsReady() throws ImsException{
         try {
-            mImsServiceProxy.onSmsReady();
+            mMmTelFeatureConnection.onSmsReady();
         } catch (RemoteException e) {
             throw new ImsException("onSmsReady()", e,
                     ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
         }
     }
 
-    public void addRegistrationCallback(ImsRegistrationImplBase.Callback callback) {
-        // TODO: implement (coming in ag/3472519)
-    }
-
-    public void addCapabilitiesCallback(ImsFeature.CapabilityCallback callback) {
-        // TODO: implement (coming in ag/3472519)
-    }
-
     /**
      * Gets the Multi-Endpoint interface to subscribe to multi-enpoint notifications..
      *
-     * @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()",
@@ -2518,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(),
@@ -2547,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) {
@@ -2592,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 4ac8fea..0000000
--- a/src/java/com/android/ims/ImsServiceProxy.java
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.ims;
-
-import android.annotation.Nullable;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.RemoteException;
-import android.telephony.Rlog;
-import android.telephony.TelephonyManager;
-import android.telephony.ims.feature.ImsFeature;
-import android.telephony.SmsMessage;
-import android.telephony.ims.internal.stub.SmsImplBase;
-import android.util.Log;
-
-import com.android.ims.internal.IImsCallSession;
-import com.android.ims.internal.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 onSmsReady() throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            getServiceInterface(mBinder).onSmsReady();
-        }
-    }
-
-    public void setSmsListener(IImsSmsListener listener) throws RemoteException {
-        synchronized (mLock) {
-            checkServiceIsReady();
-            getServiceInterface(mBinder).setSmsListener(listener);
-        }
-    }
-
-    /**
-     * @return Returns true if the ImsService is ready to take commands, false otherwise. If this
-     * method returns false, it doesn't mean that the Binder connection is not available (use
-     * {@link #isBinderReady()} to check that), but that the ImsService is not accepting commands
-     * at this time.
-     *
-     * For example, for DSDS devices, only one slot can be {@link ImsFeature#STATE_READY} to take
-     * commands at a time, so the other slot must stay at {@link ImsFeature#STATE_NOT_AVAILABLE}.
-     */
-    public boolean isBinderReady() {
-        return isBinderAlive() && getFeatureStatus() == ImsFeature.STATE_READY;
-    }
-
-    /**
-     * @return false if the binder connection is no longer alive.
-     */
-    public boolean isBinderAlive() {
-        return mIsAvailable && mBinder != null && mBinder.isBinderAlive();
-    }
-
-    protected void checkServiceIsReady() throws RemoteException {
-        if (!isBinderReady()) {
-            throw new RemoteException("ImsServiceProxy is not ready to accept commands.");
-        }
-    }
-
-    private IImsMMTelFeature getServiceInterface(IBinder b) {
-        return IImsMMTelFeature.Stub.asInterface(b);
-    }
-
-    protected void checkBinderConnection() throws RemoteException {
-        if (!isBinderAlive()) {
-            throw new RemoteException("ImsServiceProxy is not available for that feature.");
-        }
-    }
-}
diff --git a/src/java/com/android/ims/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));
     }
 }
