Merge "ProcessList refactor"
diff --git a/Android.bp b/Android.bp
index 52e2508..d94bd84 100644
--- a/Android.bp
+++ b/Android.bp
@@ -560,6 +560,7 @@
         "telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl",
         "telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl",
         "telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl",
+        "telephony/java/com/android/internal/telephony/IRcs.aidl",
         "telephony/java/com/android/internal/telephony/ISms.aidl",
         "telephony/java/com/android/internal/telephony/ISub.aidl",
         "telephony/java/com/android/internal/telephony/IAns.aidl",
diff --git a/api/current.txt b/api/current.txt
index a78a4e3..a52c1cc 100755
--- a/api/current.txt
+++ b/api/current.txt
@@ -1403,6 +1403,7 @@
     field public static final int textFilterEnabled = 16843007; // 0x10100ff
     field public static final int textFontWeight = 16844165; // 0x1010585
     field public static final int textIsSelectable = 16843542; // 0x1010316
+    field public static final int textLocale = 16844178; // 0x1010592
     field public static final int textOff = 16843045; // 0x1010125
     field public static final int textOn = 16843044; // 0x1010124
     field public static final int textScaleX = 16843089; // 0x1010151
@@ -45266,6 +45267,7 @@
     method public int getSpanTypeId();
     method public android.content.res.ColorStateList getTextColor();
     method public int getTextFontWeight();
+    method public android.os.LocaleList getTextLocales();
     method public int getTextSize();
     method public int getTextStyle();
     method public android.graphics.Typeface getTypeface();
diff --git a/api/system-current.txt b/api/system-current.txt
index 580a760..26036ea 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4471,6 +4471,23 @@
     field public static final java.lang.String VOLUME_HUSH_GESTURE = "volume_hush_gesture";
   }
 
+  public static final class Telephony.Carriers implements android.provider.BaseColumns {
+    field public static final java.lang.String APN_SET_ID = "apn_set_id";
+    field public static final int CARRIER_EDITED = 4; // 0x4
+    field public static final java.lang.String EDITED = "edited";
+    field public static final java.lang.String MAX_CONNS = "max_conns";
+    field public static final java.lang.String MAX_CONNS_TIME = "max_conns_time";
+    field public static final java.lang.String MODEM_COGNITIVE = "modem_cognitive";
+    field public static final java.lang.String MTU = "mtu";
+    field public static final int NO_SET_SET = 0; // 0x0
+    field public static final int UNEDITED = 0; // 0x0
+    field public static final int USER_DELETED = 2; // 0x2
+    field public static final java.lang.String USER_EDITABLE = "user_editable";
+    field public static final int USER_EDITED = 1; // 0x1
+    field public static final java.lang.String USER_VISIBLE = "user_visible";
+    field public static final java.lang.String WAIT_TIME = "wait_time";
+  }
+
   public final class TimeZoneRulesDataContract {
     field public static final java.lang.String AUTHORITY = "com.android.timezone";
   }
@@ -5486,6 +5503,7 @@
     method public deprecated boolean isVisualVoicemailEnabled(android.telecom.PhoneAccountHandle);
     method public boolean needsOtaServiceProvisioning();
     method public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>);
+    method public void setCarrierDataEnabled(boolean);
     method public void setDataActivationState(int);
     method public deprecated void setDataEnabled(int, boolean);
     method public void setDataRoamingEnabled(boolean);
@@ -6372,7 +6390,8 @@
   }
 
   public static class MmTelFeature.MmTelCapabilities {
-    ctor public MmTelFeature.MmTelCapabilities(android.telephony.ims.feature.ImsFeature.Capabilities);
+    ctor public MmTelFeature.MmTelCapabilities();
+    ctor public deprecated MmTelFeature.MmTelCapabilities(android.telephony.ims.feature.ImsFeature.Capabilities);
     ctor public MmTelFeature.MmTelCapabilities(int);
     method public final void addCapabilities(int);
     method public final boolean isCapable(int);
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index d00650d..069effd 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -250,4 +250,34 @@
     public abstract boolean inputDispatchingTimedOut(Object proc, String activityShortComponentName,
             ApplicationInfo aInfo, String parentShortComponentName, Object parentProc,
             boolean aboveSystem, String reason);
+
+    /**
+     * Sends {@link android.content.Intent#ACTION_CONFIGURATION_CHANGED} with all the appropriate
+     * flags.
+     */
+    public abstract void broadcastGlobalConfigurationChanged(int changes, boolean initLocale);
+
+    /**
+     * Sends {@link android.content.Intent#ACTION_CLOSE_SYSTEM_DIALOGS} with all the appropriate
+     * flags.
+     */
+    public abstract void broadcastCloseSystemDialogs(String reason);
+
+    /**
+     * Kills all background processes, except those matching any of the specified properties.
+     *
+     * @param minTargetSdk the target SDK version at or above which to preserve processes,
+     *                     or {@code -1} to ignore the target SDK
+     * @param maxProcState the process state at or below which to preserve processes,
+     *                     or {@code -1} to ignore the process state
+     */
+    public abstract void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState);
+
+    /** Starts a given process. */
+    public abstract void startProcess(String processName, ApplicationInfo info,
+            boolean knownToBeDead, String hostingType, ComponentName hostingName);
+
+    /** Starts up the starting activity process for debugging if needed. */
+    public abstract void setDebugFlagsForStartingActivity(ActivityInfo aInfo, int startFlags,
+            ProfilerInfo profilerInfo);
 }
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index b289a3e..92daf08 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -51,6 +51,7 @@
 import android.graphics.Bitmap;
 import android.net.ProxyInfo;
 import android.net.Uri;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.Parcelable;
 import android.os.PersistableBundle;
@@ -5786,7 +5787,8 @@
         }
         if (mService != null) {
             try {
-                return mService.checkDeviceIdentifierAccess(packageName, userId);
+                return mService.checkDeviceIdentifierAccess(packageName, userId,
+                        Binder.getCallingPid(), Binder.getCallingUid());
             } catch (RemoteException re) {
                 throw re.rethrowFromSystemServer();
             }
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index cf0cad8..ce1f4ef 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -153,7 +153,7 @@
     void clearProfileOwner(in ComponentName who);
     boolean hasUserSetupCompleted();
 
-    boolean checkDeviceIdentifierAccess(in String packageName, int userHandle);
+    boolean checkDeviceIdentifierAccess(in String packageName, int userHandle, int pid, int uid);
 
     void setDeviceOwnerLockScreenInfo(in ComponentName who, CharSequence deviceOwnerInfo);
     CharSequence getDeviceOwnerLockScreenInfo();
diff --git a/core/java/android/bluetooth/BluetoothA2dpSink.java b/core/java/android/bluetooth/BluetoothA2dpSink.java
index fda2f89..cb996f3 100755
--- a/core/java/android/bluetooth/BluetoothA2dpSink.java
+++ b/core/java/android/bluetooth/BluetoothA2dpSink.java
@@ -24,6 +24,7 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -183,7 +184,7 @@
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
         if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                mContext.getUser())) {
+                UserHandle.CURRENT_OR_SELF)) {
             Log.e(TAG, "Could not bind to Bluetooth A2DP Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothAvrcpController.java b/core/java/android/bluetooth/BluetoothAvrcpController.java
index e7c8944..c447868 100644
--- a/core/java/android/bluetooth/BluetoothAvrcpController.java
+++ b/core/java/android/bluetooth/BluetoothAvrcpController.java
@@ -23,6 +23,7 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -138,7 +139,7 @@
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
         if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                mContext.getUser())) {
+                UserHandle.CURRENT_OR_SELF)) {
             Log.e(TAG, "Could not bind to Bluetooth AVRCP Controller Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothHeadsetClient.java b/core/java/android/bluetooth/BluetoothHeadsetClient.java
index ec18d42..549c1fa 100644
--- a/core/java/android/bluetooth/BluetoothHeadsetClient.java
+++ b/core/java/android/bluetooth/BluetoothHeadsetClient.java
@@ -25,6 +25,7 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -428,7 +429,7 @@
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
         if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                mContext.getUser())) {
+                UserHandle.CURRENT_OR_SELF)) {
             Log.e(TAG, "Could not bind to Bluetooth Headset Client Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothHealth.java b/core/java/android/bluetooth/BluetoothHealth.java
index b967fb2..22d41d9 100644
--- a/core/java/android/bluetooth/BluetoothHealth.java
+++ b/core/java/android/bluetooth/BluetoothHealth.java
@@ -24,6 +24,7 @@
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -491,7 +492,7 @@
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
         if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                mContext.getUser())) {
+                UserHandle.CURRENT_OR_SELF)) {
             Log.e(TAG, "Could not bind to Bluetooth Health Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothHearingAid.java b/core/java/android/bluetooth/BluetoothHearingAid.java
index 606f00a..47c4ee6 100644
--- a/core/java/android/bluetooth/BluetoothHearingAid.java
+++ b/core/java/android/bluetooth/BluetoothHearingAid.java
@@ -29,6 +29,7 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import com.android.internal.annotations.GuardedBy;
@@ -205,7 +206,7 @@
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
         if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                android.os.Process.myUserHandle())) {
+                UserHandle.CURRENT_OR_SELF)) {
             Log.e(TAG, "Could not bind to Bluetooth Hearing Aid Service with " + intent);
             return;
         }
diff --git a/core/java/android/bluetooth/BluetoothHidDevice.java b/core/java/android/bluetooth/BluetoothHidDevice.java
index 3bc8544..e44f36e 100644
--- a/core/java/android/bluetooth/BluetoothHidDevice.java
+++ b/core/java/android/bluetooth/BluetoothHidDevice.java
@@ -24,6 +24,7 @@
 import android.content.ServiceConnection;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -454,7 +455,7 @@
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
         if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                mContext.getUser())) {
+                UserHandle.CURRENT_OR_SELF)) {
             Log.e(TAG, "Could not bind to Bluetooth HID Device Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothHidHost.java b/core/java/android/bluetooth/BluetoothHidHost.java
index 0ca39f1..58a2522 100644
--- a/core/java/android/bluetooth/BluetoothHidHost.java
+++ b/core/java/android/bluetooth/BluetoothHidHost.java
@@ -25,6 +25,7 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -279,7 +280,7 @@
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
         if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                mContext.getUser())) {
+                UserHandle.CURRENT_OR_SELF)) {
             Log.e(TAG, "Could not bind to Bluetooth HID Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothMap.java b/core/java/android/bluetooth/BluetoothMap.java
index 98c23c6..fc5f830 100644
--- a/core/java/android/bluetooth/BluetoothMap.java
+++ b/core/java/android/bluetooth/BluetoothMap.java
@@ -24,6 +24,7 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -110,7 +111,7 @@
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
         if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                mContext.getUser())) {
+                UserHandle.CURRENT_OR_SELF)) {
             Log.e(TAG, "Could not bind to Bluetooth MAP Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothMapClient.java b/core/java/android/bluetooth/BluetoothMapClient.java
index 559a59b..1c82e19 100644
--- a/core/java/android/bluetooth/BluetoothMapClient.java
+++ b/core/java/android/bluetooth/BluetoothMapClient.java
@@ -25,6 +25,7 @@
 import android.net.Uri;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -128,7 +129,7 @@
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
         if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                mContext.getUser())) {
+                UserHandle.CURRENT_OR_SELF)) {
             Log.e(TAG, "Could not bind to Bluetooth MAP MCE Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
index 58be732..8923d73 100644
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ b/core/java/android/bluetooth/BluetoothPan.java
@@ -26,6 +26,7 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -150,7 +151,7 @@
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
         if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                mContext.getUser())) {
+                UserHandle.CURRENT_OR_SELF)) {
             Log.e(TAG, "Could not bind to Bluetooth Pan Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothPbap.java b/core/java/android/bluetooth/BluetoothPbap.java
index ae264e1..a601df0 100644
--- a/core/java/android/bluetooth/BluetoothPbap.java
+++ b/core/java/android/bluetooth/BluetoothPbap.java
@@ -24,6 +24,7 @@
 import android.content.ServiceConnection;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -164,7 +165,7 @@
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
         if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                mContext.getUser())) {
+                UserHandle.CURRENT_OR_SELF)) {
             Log.e(TAG, "Could not bind to Bluetooth Pbap Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothPbapClient.java b/core/java/android/bluetooth/BluetoothPbapClient.java
index 1446adc..cbc96c0 100644
--- a/core/java/android/bluetooth/BluetoothPbapClient.java
+++ b/core/java/android/bluetooth/BluetoothPbapClient.java
@@ -23,6 +23,7 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -116,7 +117,7 @@
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
         if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                mContext.getUser())) {
+                UserHandle.CURRENT_OR_SELF)) {
             Log.e(TAG, "Could not bind to Bluetooth PBAP Client Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothSap.java b/core/java/android/bluetooth/BluetoothSap.java
index 1b73206..ebf6bed 100644
--- a/core/java/android/bluetooth/BluetoothSap.java
+++ b/core/java/android/bluetooth/BluetoothSap.java
@@ -24,6 +24,7 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -148,7 +149,7 @@
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
         if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                mContext.getUser())) {
+                UserHandle.CURRENT_OR_SELF)) {
             Log.e(TAG, "Could not bind to Bluetooth SAP Service with " + intent);
             return false;
         }
diff --git a/core/java/android/hardware/location/ContextHubClient.java b/core/java/android/hardware/location/ContextHubClient.java
index 6609b76..5de89e3 100644
--- a/core/java/android/hardware/location/ContextHubClient.java
+++ b/core/java/android/hardware/location/ContextHubClient.java
@@ -105,12 +105,15 @@
      *
      * This method should be used if the caller wants to receive notifications even after the
      * process exits. The client must have an open connection with the Context Hub Service (i.e. it
-     * cannot have been closed through the {@link #close()} method). If registered successfully,
-     * intents will be delivered regarding events for the specified nanoapp from the attached
-     * Context Hub. Any unicast messages for this client will also be delivered. The intent will
-     * have an extra {@link #EXTRA_EVENT_TYPE} of type {@link ContextHubManager.Event}, which will
-     * contain the type of the event. See {@link ContextHubManager.Event} for description of each
-     * event type.
+     * cannot have been closed through the {@link #close()} method). Only one PendingIntent can be
+     * registered at a time for a single ContextHubClient. If registered successfully, intents will
+     * be delivered regarding events for the specified nanoapp from the attached Context Hub. Any
+     * unicast messages for this client will also be delivered. The intent will have an extra
+     * {@link ContextHubManager.EXTRA_CONTEXT_HUB_INFO} of type {@link ContextHubInfo}, which
+     * describes the Context Hub the intent event was for. The intent will also have an extra
+     * {@link ContextHubManager.EXTRA_EVENT_TYPE} of type {@link ContextHubManager.Event}, which
+     * will contain the type of the event. See {@link ContextHubManager.Event} for description of
+     * each event type, along with event-specific extra fields.
      *
      * When the intent is received, this client can be recreated through
      * {@link ContextHubManager.createClient(PendingIntent, ContextHubInfo,
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 412a700..292543c 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -130,9 +130,9 @@
      * <a href="/training/articles/security-key-attestation.html">key attestation</a> to obtain
      * proof of the device's original identifiers.
      *
-     * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE or for the calling package to be the
-     * device or profile owner. Profile owner access is deprecated and will be removed in a future
-     * release.
+     * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, or for the calling package to be the
+     * device or profile owner and have the READ_PHONE_STATE permission. Profile owner access is
+     * deprecated and will be removed in a future release.
      *
      * @return The serial number if specified.
      */
diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java
index 10d7911..ec63cd9 100644
--- a/core/java/android/speech/tts/TextToSpeechService.java
+++ b/core/java/android/speech/tts/TextToSpeechService.java
@@ -1112,7 +1112,6 @@
 
         @Override
         protected void playImpl() {
-            dispatchOnStart();
             super.playImpl();
             try {
               mFileOutputStream.close();
diff --git a/core/java/android/text/style/TextAppearanceSpan.java b/core/java/android/text/style/TextAppearanceSpan.java
index 648bd1b..f846a35 100644
--- a/core/java/android/text/style/TextAppearanceSpan.java
+++ b/core/java/android/text/style/TextAppearanceSpan.java
@@ -23,6 +23,7 @@
 import android.graphics.LeakyTypefaceStorage;
 import android.graphics.Typeface;
 import android.graphics.fonts.Font;
+import android.os.LocaleList;
 import android.os.Parcel;
 import android.text.ParcelableSpan;
 import android.text.TextPaint;
@@ -66,6 +67,7 @@
     private final Typeface mTypeface;
 
     private final int mTextFontWeight;
+    private final LocaleList mTextLocales;
 
     private final float mShadowRadius;
     private final float mShadowDx;
@@ -149,6 +151,19 @@
         mTextFontWeight = a.getInt(com.android.internal.R.styleable
                 .TextAppearance_textFontWeight, -1);
 
+        final String localeString = a.getString(com.android.internal.R.styleable
+                .TextAppearance_textLocale);
+        if (localeString != null) {
+            LocaleList localeList = LocaleList.forLanguageTags(localeString);
+            if (!localeList.isEmpty()) {
+                mTextLocales = localeList;
+            } else {
+                mTextLocales = null;
+            }
+        } else {
+            mTextLocales = null;
+        }
+
         mShadowRadius = a.getFloat(com.android.internal.R.styleable
                 .TextAppearance_shadowRadius, 0.0f);
         mShadowDx = a.getFloat(com.android.internal.R.styleable
@@ -201,6 +216,7 @@
         mTypeface = null;
 
         mTextFontWeight = -1;
+        mTextLocales = null;
 
         mShadowRadius = 0.0f;
         mShadowDx = 0.0f;
@@ -233,6 +249,7 @@
         mTypeface = LeakyTypefaceStorage.readTypefaceFromParcel(src);
 
         mTextFontWeight = src.readInt();
+        mTextLocales = src.readParcelable(LocaleList.class.getClassLoader());
 
         mShadowRadius = src.readFloat();
         mShadowDx = src.readFloat();
@@ -285,6 +302,7 @@
         LeakyTypefaceStorage.writeTypefaceToParcel(mTypeface, dest);
 
         dest.writeInt(mTextFontWeight);
+        dest.writeParcelable(mTextLocales, flags);
 
         dest.writeFloat(mShadowRadius);
         dest.writeFloat(mShadowDx);
@@ -349,6 +367,15 @@
     }
 
     /**
+     * Returns the {@link android.os.LocaleList} specified by this span, or <code>null</code>
+     * if it does not specify one.
+     */
+    @Nullable
+    public LocaleList getTextLocales() {
+        return mTextLocales;
+    }
+
+    /**
      * Returns the typeface specified by this span, or <code>null</code>
      * if it does not specify one.
      */
@@ -487,6 +514,10 @@
             ds.setTextSize(mTextSize);
         }
 
+        if (mTextLocales != null) {
+            ds.setTextLocales(mTextLocales);
+        }
+
         if (mHasElegantTextHeight) {
             ds.setElegantTextHeight(mElegantTextHeight);
         }
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index 69d7202..300bb6f 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -299,7 +299,7 @@
     /**
      * The resource was blocked because it may trick the user into a billing agreement.
      *
-     * <p>This constant is only used when targetSdkVersion is greater than {@link
+     * <p>This constant is only used when targetSdkVersion is at least {@link
      * android.os.Build.VERSION_CODES#Q}. Otherwise, {@link #SAFE_BROWSING_THREAT_UNKNOWN} is used
      * instead.
      */
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index f74c234..3dd6fd1 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -3517,6 +3517,7 @@
         ColorStateList mTextColorHint = null;
         ColorStateList mTextColorLink = null;
         int mTextSize = -1;
+        LocaleList mTextLocales = null;
         String mFontFamily = null;
         Typeface mFontTypeface = null;
         boolean mFontFamilyExplicit = false;
@@ -3543,6 +3544,7 @@
                     + "    mTextColorHint:" + mTextColorHint + "\n"
                     + "    mTextColorLink:" + mTextColorLink + "\n"
                     + "    mTextSize:" + mTextSize + "\n"
+                    + "    mTextLocales:" + mTextLocales + "\n"
                     + "    mFontFamily:" + mFontFamily + "\n"
                     + "    mFontTypeface:" + mFontTypeface + "\n"
                     + "    mFontFamilyExplicit:" + mFontFamilyExplicit + "\n"
@@ -3579,6 +3581,8 @@
                 com.android.internal.R.styleable.TextAppearance_textColorLink);
         sAppearanceValues.put(com.android.internal.R.styleable.TextView_textSize,
                 com.android.internal.R.styleable.TextAppearance_textSize);
+        sAppearanceValues.put(com.android.internal.R.styleable.TextView_textLocale,
+                com.android.internal.R.styleable.TextAppearance_textLocale);
         sAppearanceValues.put(com.android.internal.R.styleable.TextView_typeface,
                 com.android.internal.R.styleable.TextAppearance_typeface);
         sAppearanceValues.put(com.android.internal.R.styleable.TextView_fontFamily,
@@ -3652,6 +3656,15 @@
                     attributes.mTextSize =
                             appearance.getDimensionPixelSize(attr, attributes.mTextSize);
                     break;
+                case com.android.internal.R.styleable.TextAppearance_textLocale:
+                    final String localeString = appearance.getString(attr);
+                    if (localeString != null) {
+                        final LocaleList localeList = LocaleList.forLanguageTags(localeString);
+                        if (!localeList.isEmpty()) {
+                            attributes.mTextLocales = localeList;
+                        }
+                    }
+                    break;
                 case com.android.internal.R.styleable.TextAppearance_typeface:
                     attributes.mTypefaceIndex = appearance.getInt(attr, attributes.mTypefaceIndex);
                     if (attributes.mTypefaceIndex != -1 && !attributes.mFontFamilyExplicit) {
@@ -3738,6 +3751,10 @@
             setRawTextSize(attributes.mTextSize, true /* shouldRequestLayout */);
         }
 
+        if (attributes.mTextLocales != null) {
+            setTextLocales(attributes.mTextLocales);
+        }
+
         if (attributes.mTypefaceIndex != -1 && !attributes.mFontFamilyExplicit) {
             attributes.mFontFamily = null;
         }
diff --git a/core/java/com/android/internal/os/KernelWakelockReader.java b/core/java/com/android/internal/os/KernelWakelockReader.java
index 46667d1..2442d0b 100644
--- a/core/java/com/android/internal/os/KernelWakelockReader.java
+++ b/core/java/com/android/internal/os/KernelWakelockReader.java
@@ -158,7 +158,7 @@
                                          PROC_WAKELOCKS_FORMAT,
                         nameStringArray, wlData, null);
 
-                name = nameStringArray[0];
+                name = nameStringArray[0].trim();
                 count = (int) wlData[1];
 
                 if (wakeup_sources) {
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index cdb65ed..9bedab5 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4551,6 +4551,11 @@
         <attr name="typeface" />
         <!-- Font family (named by string or as a font resource reference) for the text. -->
         <attr name="fontFamily" />
+        <!-- Specifies the {@link android.os.LocaleList} for the text.
+             May be a string value, which is a comma-separated language tag list, such as "ja-JP,zh-CN".
+             When not specified or an empty string is given, it will fallback to the default one.
+             {@see android.os.LocaleList#forLanguageTags(String)} -->
+        <attr name="textLocale" format="string" />
         <!-- Color of the text selection highlight. -->
         <attr name="textColorHighlight" />
         <!-- Color of the hint text. -->
@@ -4642,6 +4647,13 @@
         <attr name="textFontWeight" />
         <!-- Font family (named by string or as a font resource reference) for the text. -->
         <attr name="fontFamily" />
+        <!-- Specifies the {@link android.os.LocaleList} for the text in this TextView.
+             If not given, the system default will be used.
+             May be a string value, which is a comma-separated language tag list, such as "ja-JP,zh-CN".
+             When not specified or an empty string is given, it will fallback to the default one.
+             {@see android.os.LocaleList#forLanguageTags(String)}
+             {@see android.text.TextView#setTextLocales(android.os.LocaleList)} -->
+        <attr name="textLocale" format="string" />
         <!-- Text color for links. -->
         <attr name="textColorLink" />
         <!-- Makes the cursor visible (the default) or invisible. -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 9551718..31212a6 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2915,6 +2915,7 @@
         <public name="minimumUiTimeout" />
         <public name="isLightTheme" />
         <public name="isSplitRequired" />
+        <public name="textLocale" />
     </public-group>
 
     <public-group type="drawable" first-id="0x010800b4">
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
index 33cb5964..4518d79 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
@@ -30,7 +30,7 @@
 import android.text.TextUtils;
 import android.util.Log;
 import com.android.internal.telephony.PhoneConstants;
-import com.android.carrierdefaultapp.R;
+
 /**
  * This util class provides common logic for carrier actions
  */
@@ -102,7 +102,7 @@
                 SubscriptionManager.getDefaultVoiceSubscriptionId());
         logd("onDisableAllMeteredApns subId: " + subId);
         final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
-        telephonyMgr.carrierActionSetMeteredApnsEnabled(subId, !ENABLE);
+        telephonyMgr.createForSubscriptionId(subId).setCarrierDataEnabled(!ENABLE);
     }
 
     private static void onEnableAllMeteredApns(Intent intent, Context context) {
@@ -110,7 +110,7 @@
                 SubscriptionManager.getDefaultVoiceSubscriptionId());
         logd("onEnableAllMeteredApns subId: " + subId);
         final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
-        telephonyMgr.carrierActionSetMeteredApnsEnabled(subId, ENABLE);
+        telephonyMgr.createForSubscriptionId(subId).setCarrierDataEnabled(ENABLE);
     }
 
     private static void onEnableDefaultURLHandler(Context context) {
diff --git a/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/CarrierDefaultReceiverTest.java b/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/CarrierDefaultReceiverTest.java
index f9dbcd4..5d84d64 100644
--- a/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/CarrierDefaultReceiverTest.java
+++ b/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/CarrierDefaultReceiverTest.java
@@ -104,6 +104,6 @@
         assertNotNull(pendingIntent);
 
         Rlog.d(TAG, "verify carrier action: disable all metered apns");
-        verify(mTelephonyMgr).carrierActionSetMeteredApnsEnabled(eq(subId), eq(false));
+        verify(mTelephonyMgr).setCarrierDataEnabled(eq(false));
     }
 }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index c14f8c3..6f043ec 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -187,6 +187,7 @@
 import android.app.PendingIntent;
 import android.app.ProcessMemoryState;
 import android.app.ProfilerInfo;
+import android.app.WaitResult;
 import android.app.WindowConfiguration.ActivityType;
 import android.app.WindowConfiguration.WindowingMode;
 import android.app.backup.IBackupManager;
@@ -2985,9 +2986,35 @@
     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
-        return mActivityTaskManager.startActivityAsUser(caller, callingPackage, intent,
-                resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
-                userId);
+        synchronized (this) {
+            /**
+             * Flags like {@link android.app.ActivityManager#START_FLAG_DEBUG} maybe be set on this
+             * call when called/invoked from the shell command. To avoid deadlock, we go ahead and
+             * acquire the AMS lock now since ATMS will need to synchronously call back into AMS
+             * later to modify process settings due to the flags.
+             * TODO(b/80414790): Investigate a better way of untangling this.
+             */
+            return mActivityTaskManager.startActivityAsUser(caller, callingPackage, intent,
+                    resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo,
+                    bOptions, userId);
+        }
+    }
+
+    WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
+            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
+            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
+        synchronized (this) {
+            /**
+             * Flags like {@link android.app.ActivityManager#START_FLAG_DEBUG} maybe be set on this
+             * call when called/invoked from the shell command. To avoid deadlock, we go ahead and
+             * acquire the AMS lock now since ATMS will need to synchronously call back into AMS
+             * later to modify process settings due to the flags.
+             * TODO(b/80414790): Investigate a better way of untangling this.
+             */
+            return mActivityTaskManager.startActivityAndWait(caller, callingPackage, intent,
+                    resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo,
+                    bOptions, userId);
+        }
     }
 
     @Override
@@ -18883,6 +18910,110 @@
                     (WindowProcessController) parentProc, aboveSystem, reason);
 
         }
+
+        @Override
+        public void broadcastGlobalConfigurationChanged(int changes, boolean initLocale) {
+            synchronized (ActivityManagerService.this) {
+                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
+                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
+                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
+                        | Intent.FLAG_RECEIVER_FOREGROUND
+                        | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
+                broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
+                        OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
+                        UserHandle.USER_ALL);
+                if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
+                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
+                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
+                            | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
+                            | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
+                    if (initLocale || !mProcessesReady) {
+                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+                    }
+                    broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
+                            OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
+                            UserHandle.USER_ALL);
+                }
+
+                // Send a broadcast to PackageInstallers if the configuration change is interesting
+                // for the purposes of installing additional splits.
+                if (!initLocale && isSplitConfigurationChange(changes)) {
+                    intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
+                    intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
+                            | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+
+                    // Typically only app stores will have this permission.
+                    String[] permissions =
+                            new String[] { android.Manifest.permission.INSTALL_PACKAGES };
+                    broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
+                            permissions, OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
+                            UserHandle.USER_ALL);
+                }
+            }
+        }
+
+        /**
+         * Returns true if this configuration change is interesting enough to send an
+         * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
+         */
+        private boolean isSplitConfigurationChange(int configDiff) {
+            return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
+        }
+
+        @Override
+        public void broadcastCloseSystemDialogs(String reason) {
+            synchronized (ActivityManagerService.this) {
+                final Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
+                        | Intent.FLAG_RECEIVER_FOREGROUND);
+                if (reason != null) {
+                    intent.putExtra("reason", reason);
+                }
+
+                broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
+                        OP_NONE, null, false, false, -1, SYSTEM_UID, UserHandle.USER_ALL);
+            }
+        }
+
+        @Override
+        public void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
+            synchronized (ActivityManagerService.this) {
+                ActivityManagerService.this.killAllBackgroundProcessesExcept(
+                        minTargetSdk, maxProcState);
+            }
+        }
+
+        @Override
+        public void startProcess(String processName, ApplicationInfo info,
+                boolean knownToBeDead, String hostingType, ComponentName hostingName) {
+            synchronized (ActivityManagerService.this) {
+                startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
+                        hostingType, hostingName, false /* allowWhileBooting */,
+                        false /* isolated */, true /* keepIfLarge */);
+            }
+        }
+
+        @Override
+        public void setDebugFlagsForStartingActivity(ActivityInfo aInfo, int startFlags,
+                ProfilerInfo profilerInfo) {
+            synchronized (ActivityManagerService.this) {
+                if ((startFlags & ActivityManager.START_FLAG_DEBUG) != 0) {
+                    setDebugApp(aInfo.processName, true, false);
+                }
+
+                if ((startFlags & ActivityManager.START_FLAG_NATIVE_DEBUGGING) != 0) {
+                    setNativeDebuggingAppLocked(aInfo.applicationInfo, aInfo.processName);
+                }
+
+                if ((startFlags & ActivityManager.START_FLAG_TRACK_ALLOCATION) != 0) {
+                    setTrackAllocationApp(aInfo.applicationInfo, aInfo.processName);
+                }
+
+                if (profilerInfo != null) {
+                    setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo);
+                }
+            }
+        }
     }
 
     long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 9f768a8..692b2d4 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -481,12 +481,12 @@
                 options.setLockTaskEnabled(true);
             }
             if (mWaitOption) {
-                result = mTaskInterface.startActivityAndWait(null, null, intent, mimeType,
+                result = mInternal.startActivityAndWait(null, null, intent, mimeType,
                         null, null, 0, mStartFlags, profilerInfo,
                         options != null ? options.toBundle() : null, mUserId);
                 res = result.result;
             } else {
-                res = mTaskInterface.startActivityAsUser(null, null, intent, mimeType,
+                res = mInternal.startActivityAsUser(null, null, intent, mimeType,
                         null, null, 0, mStartFlags, profilerInfo,
                         options != null ? options.toBundle() : null, mUserId);
             }
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index b7eba11..90e2f5b 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -21,6 +21,9 @@
 import static android.Manifest.permission.START_ANY_ACTIVITY;
 import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED;
 import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
+import static android.app.ActivityManager.START_FLAG_DEBUG;
+import static android.app.ActivityManager.START_FLAG_NATIVE_DEBUGGING;
+import static android.app.ActivityManager.START_FLAG_TRACK_ALLOCATION;
 import static android.app.ActivityManager.START_TASK_TO_FRONT;
 import static android.app.ActivityTaskManager.INVALID_STACK_ID;
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
@@ -113,6 +116,7 @@
 import android.app.ActivityManagerInternal;
 import android.app.ActivityOptions;
 import android.app.AppOpsManager;
+import android.app.IApplicationThread;
 import android.app.ProfilerInfo;
 import android.app.ResultInfo;
 import android.app.WaitResult;
@@ -1013,7 +1017,7 @@
                     if (activity.app == null && app.mUid == activity.info.applicationInfo.uid
                             && processName.equals(activity.processName)) {
                         try {
-                            if (realStartActivityLocked(activity, (ProcessRecord) app.mOwner,
+                            if (realStartActivityLocked(activity, app,
                                     top == activity /* andResume */, true /* checkConfig */)) {
                                 didSomething = true;
                             }
@@ -1300,20 +1304,17 @@
 
             // Don't debug things in the system process
             if (!aInfo.processName.equals("system")) {
-                if ((startFlags & ActivityManager.START_FLAG_DEBUG) != 0) {
-                    mService.mAm.setDebugApp(aInfo.processName, true, false);
-                }
-
-                if ((startFlags & ActivityManager.START_FLAG_NATIVE_DEBUGGING) != 0) {
-                    mService.mAm.setNativeDebuggingAppLocked(aInfo.applicationInfo, aInfo.processName);
-                }
-
-                if ((startFlags & ActivityManager.START_FLAG_TRACK_ALLOCATION) != 0) {
-                    mService.mAm.setTrackAllocationApp(aInfo.applicationInfo, aInfo.processName);
-                }
-
-                if (profilerInfo != null) {
-                    mService.mAm.setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo);
+                if ((startFlags & (START_FLAG_DEBUG | START_FLAG_NATIVE_DEBUGGING
+                        | START_FLAG_TRACK_ALLOCATION)) != 0 || profilerInfo != null) {
+                    /**
+                     * Assume safe to call into AMS synchronously because the call that set these
+                     * flags should have originated from AMS which will already have its lock held.
+                     * @see ActivityManagerService#startActivityAndWait(IApplicationThread, String,
+                     * Intent, String, IBinder, String, int, int, ProfilerInfo, Bundle, int)
+                     * TODO(b/80414790): Investigate a better way of untangling this.
+                     */
+                    mService.mAmInternal.setDebugFlagsForStartingActivity(
+                            aInfo, startFlags, profilerInfo);
                 }
             }
             final String intentLaunchToken = intent.getLaunchToken();
@@ -1360,7 +1361,7 @@
         return resolveActivity(intent, rInfo, startFlags, profilerInfo);
     }
 
-    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
+    private boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
             boolean andResume, boolean checkConfig) throws RemoteException {
 
         if (!allPausedActivitiesComplete()) {
@@ -1379,7 +1380,6 @@
         beginDeferResume();
 
         try {
-            final WindowProcessController proc = app.getWindowProcessController();
             r.startFreezingScreenLocked(proc, 0);
 
             // schedule launch ticks to collect information about slow apps.
@@ -1415,15 +1415,15 @@
 
             final int applicationInfoUid =
                     (r.info.applicationInfo != null) ? r.info.applicationInfo.uid : -1;
-            if ((r.userId != app.userId) || (r.appInfo.uid != applicationInfoUid)) {
+            if ((r.userId != proc.mUserId) || (r.appInfo.uid != applicationInfoUid)) {
                 Slog.wtf(TAG,
                         "User ID for activity changing for " + r
                                 + " appInfo.uid=" + r.appInfo.uid
                                 + " info.ai.uid=" + applicationInfoUid
-                                + " old=" + r.app + " new=" + app);
+                                + " old=" + r.app + " new=" + proc);
             }
 
-            app.waitingToKill = null;
+            proc.clearWaitingToKill();
             r.launchCount++;
             r.lastLaunchTime = SystemClock.uptimeMillis();
 
@@ -1442,7 +1442,7 @@
             }
 
             try {
-                if (app.thread == null) {
+                if (!proc.hasThread()) {
                     throw new RemoteException();
                 }
                 List<ResultInfo> results = null;
@@ -1468,50 +1468,29 @@
                 r.forceNewConfig = false;
                 mService.getAppWarningsLocked().onStartActivity(r);
                 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
-                ProfilerInfo profilerInfo = null;
-                if (mService.mAm.mProfileApp != null && mService.mAm.mProfileApp.equals(app.processName)) {
-                    if (mService.mAm.mProfileProc == null || mService.mAm.mProfileProc == app) {
-                        mService.mAm.mProfileProc = app;
-                        ProfilerInfo profilerInfoSvc = mService.mAm.mProfilerInfo;
-                        if (profilerInfoSvc != null && profilerInfoSvc.profileFile != null) {
-                            if (profilerInfoSvc.profileFd != null) {
-                                try {
-                                    profilerInfoSvc.profileFd = profilerInfoSvc.profileFd.dup();
-                                } catch (IOException e) {
-                                    profilerInfoSvc.closeFd();
-                                }
-                            }
+                ProfilerInfo profilerInfo = proc.onStartActivity(mService.mTopProcessState);
 
-                            profilerInfo = new ProfilerInfo(profilerInfoSvc);
-                        }
-                    }
-                }
-
-                app.hasShownUi = true;
-                app.setPendingUiClean(true);
-                app.forceProcessStateUpTo(mService.mTopProcessState);
                 // Because we could be starting an Activity in the system process this may not go
                 // across a Binder interface which would create a new Configuration. Consequently
                 // we have to always create a new Configuration here.
 
                 final MergedConfiguration mergedConfiguration = new MergedConfiguration(
-                        app.getWindowProcessController().getConfiguration(),
-                        r.getMergedOverrideConfiguration());
+                        proc.getConfiguration(), r.getMergedOverrideConfiguration());
                 r.setLastReportedConfiguration(mergedConfiguration);
 
                 logIfTransactionTooLarge(r.intent, r.icicle);
 
 
                 // Create activity launch transaction.
-                final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
-                        r.appToken);
+                final ClientTransaction clientTransaction = ClientTransaction.obtain(
+                        proc.getThread(), r.appToken);
                 clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                         System.identityHashCode(r), r.info,
                         // TODO: Have this take the merged configuration instead of separate global
                         // and override configs.
                         mergedConfiguration.getGlobalConfiguration(),
                         mergedConfiguration.getOverrideConfiguration(), r.compat,
-                        r.launchedFromPackage, task.voiceInteractor, app.getReportedProcState(),
+                        r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
                         r.icicle, r.persistentState, results, newIntents,
                         mService.isNextTransitionForward(), profilerInfo));
 
@@ -1527,12 +1506,12 @@
                 // Schedule transaction.
                 mService.getLifecycleManager().scheduleTransaction(clientTransaction);
 
-                if ((app.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0
+                if ((proc.mInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0
                         && mService.mHasHeavyWeightFeature) {
                     // This may be a heavy-weight process! Note that the package manager will ensure
                     // that only activity can run in the main process of the .apk, which is the only
                     // thing that will be considered heavy-weight.
-                    if (app.processName.equals(app.info.packageName)) {
+                    if (proc.mName.equals(proc.mInfo.packageName)) {
                         if (mService.mHeavyWeightProcess != null
                                 && mService.mHeavyWeightProcess != proc) {
                             Slog.w(TAG, "Starting new heavy weight process " + proc
@@ -1545,12 +1524,10 @@
 
             } catch (RemoteException e) {
                 if (r.launchFailed) {
-                    // This is the second time we failed -- finish activity
-                    // and give up.
+                    // This is the second time we failed -- finish activity and give up.
                     Slog.e(TAG, "Second failure launching "
-                            + r.intent.getComponent().flattenToShortString()
-                            + ", giving up", e);
-                    mService.mAm.appDiedLocked(app);
+                            + r.intent.getComponent().flattenToShortString() + ", giving up", e);
+                    proc.appDied();
                     stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
                             "2nd-crash", false);
                     return false;
@@ -1659,24 +1636,21 @@
         }
     }
 
-    void startSpecificActivityLocked(ActivityRecord r,
-            boolean andResume, boolean checkConfig) {
+    void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
         // Is this activity's application already running?
-        ProcessRecord app = mService.mAm.getProcessRecordLocked(r.processName,
-                r.info.applicationInfo.uid, true);
+        final WindowProcessController wpc =
+                mService.getProcessController(r.processName, r.info.applicationInfo.uid);
 
-        if (app != null && app.thread != null) {
+        if (wpc != null && wpc.hasThread()) {
             try {
-                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
+                if ((r.info.flags & ActivityInfo.FLAG_MULTIPROCESS) == 0
                         || !"android".equals(r.info.packageName)) {
-                    // Don't add this if it is a platform component that is marked
-                    // to run in multiple processes, because this is actually
-                    // part of the framework so doesn't make sense to track as a
-                    // separate apk in the process.
-                    app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode,
-                            mService.mAm.mProcessStats);
+                    // Don't add this if it is a platform component that is marked to run in
+                    // multiple processes, because this is actually part of the framework so doesn't
+                    // make sense to track as a separate apk in the process.
+                    wpc.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode);
                 }
-                realStartActivityLocked(r, app, andResume, checkConfig);
+                realStartActivityLocked(r, wpc, andResume, checkConfig);
                 return;
             } catch (RemoteException e) {
                 Slog.w(TAG, "Exception when starting activity "
@@ -1687,8 +1661,12 @@
             // restart the application.
         }
 
-        mService.mAm.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
-                "activity", r.intent.getComponent(), false, false, true);
+        // Post message to start process to avoid possible deadlock of calling into AMS with the
+        // ATMS lock held.
+        final Message msg = PooledLambda.obtainMessage(
+                ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
+                r.info.applicationInfo, true, "activity", r.intent.getComponent());
+        mService.mH.sendMessage(msg);
     }
 
     void sendPowerHintForLaunchStartIfNeeded(boolean forceSend, ActivityRecord targetActivity) {
diff --git a/services/core/java/com/android/server/am/ActivityTaskManagerService.java b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
index 2d27017..8ae5495 100644
--- a/services/core/java/com/android/server/am/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
@@ -4670,14 +4670,6 @@
         return kept;
     }
 
-    /**
-     * Returns true if this configuration change is interesting enough to send an
-     * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
-     */
-    private static boolean isSplitConfigurationChange(int configDiff) {
-        return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
-    }
-
     /** Update default (global) configuration and notify listeners about changes. */
     private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
             boolean persistent, int userId, boolean deferResume) {
@@ -4777,38 +4769,10 @@
             app.onConfigurationChanged(configCopy);
         }
 
-        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
-                | Intent.FLAG_RECEIVER_FOREGROUND
-                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
-        mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
-                OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
-                UserHandle.USER_ALL);
-        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
-            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
-            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
-                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
-                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
-            if (initLocale || !mAm.mProcessesReady) {
-                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
-            }
-            mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
-                    OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
-                    UserHandle.USER_ALL);
-        }
-
-        // Send a broadcast to PackageInstallers if the configuration change is interesting
-        // for the purposes of installing additional splits.
-        if (!initLocale && isSplitConfigurationChange(changes)) {
-            intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
-            intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
-                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
-
-            // Typically only app stores will have this permission.
-            String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
-            mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
-                    OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
-        }
+        final Message msg = PooledLambda.obtainMessage(
+                ActivityManagerInternal::broadcastGlobalConfigurationChanged,
+                mAmInternal, changes, initLocale);
+        mH.sendMessage(msg);
 
         // Override configuration of the default display duplicates global config, so we need to
         // update it also. This will also notify WindowManager about changes.
@@ -4877,8 +4841,12 @@
             if (isDensityChange && displayId == DEFAULT_DISPLAY) {
                 mAppWarnings.onDensityChanged();
 
-                mAm.killAllBackgroundProcessesExcept(N,
-                        ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
+                // Post message to start process to avoid possible deadlock of calling into AMS with
+                // the ATMS lock held.
+                final Message msg = PooledLambda.obtainMessage(
+                        ActivityManagerInternal::killAllBackgroundProcessesExcept, mAmInternal,
+                        N, ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
+                mH.sendMessage(msg);
             }
         }
 
@@ -5446,7 +5414,7 @@
         return newInfo;
     }
 
-    private WindowProcessController getProcessController(String processName, int uid) {
+    WindowProcessController getProcessController(String processName, int uid) {
         if (uid == SYSTEM_UID) {
             // The system gets to run in any process. If there are multiple processes with the same
             // uid, just pick the first (this should never happen).
@@ -6247,20 +6215,12 @@
                             return;
                         }
                     }
-                    Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
-                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
-                            | Intent.FLAG_RECEIVER_FOREGROUND);
-                    if (reason != null) {
-                        intent.putExtra("reason", reason);
-                    }
                     mWindowManager.closeSystemDialogs(reason);
 
                     mStackSupervisor.closeSystemDialogsLocked();
-
-                    mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
-                            OP_NONE, null, false, false,
-                            -1, SYSTEM_UID, UserHandle.USER_ALL);
                 }
+                // Call into AM outside the synchronized block.
+                mAmInternal.broadcastCloseSystemDialogs(reason);
             } finally {
                 Binder.restoreCallingIdentity(origId);
             }
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index af4230d..fa7a08b 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -28,6 +28,7 @@
 import android.app.ApplicationErrorReport;
 import android.app.Dialog;
 import android.app.IApplicationThread;
+import android.app.ProfilerInfo;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
@@ -60,6 +61,7 @@
 import com.android.server.Watchdog;
 
 import java.io.File;
+import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -836,6 +838,13 @@
         return null;
     }
 
+    @Override
+    public void addPackage(String pkg, long versionCode) {
+        synchronized (mService) {
+            addPackage(pkg, versionCode, mService.mProcessStats);
+        }
+    }
+
     /*
      *  Return true if package has been added false if not
      */
@@ -1176,10 +1185,55 @@
      * Returns the total time (in milliseconds) spent executing in both user and system code.
      * Safe to call without lock held.
      */
+    @Override
     public long getCpuTime() {
         return mService.mProcessCpuTracker.getCpuTimeForPid(pid);
     }
 
+    @Override
+    public void clearWaitingToKill() {
+        synchronized (mService) {
+            waitingToKill = null;
+        }
+    }
+
+    @Override
+    public ProfilerInfo onStartActivity(int topProcessState) {
+        synchronized (mService) {
+            ProfilerInfo profilerInfo = null;
+            if (mService.mProfileApp != null && mService.mProfileApp.equals(processName)) {
+                if (mService.mProfileProc == null || mService.mProfileProc == this) {
+                    mService.mProfileProc = this;
+                    final ProfilerInfo profilerInfoSvc = mService.mProfilerInfo;
+                    if (profilerInfoSvc != null && profilerInfoSvc.profileFile != null) {
+                        if (profilerInfoSvc.profileFd != null) {
+                            try {
+                                profilerInfoSvc.profileFd = profilerInfoSvc.profileFd.dup();
+                            } catch (IOException e) {
+                                profilerInfoSvc.closeFd();
+                            }
+                        }
+
+                        profilerInfo = new ProfilerInfo(profilerInfoSvc);
+                    }
+                }
+            }
+
+            hasShownUi = true;
+            setPendingUiClean(true);
+            forceProcessStateUpTo(topProcessState);
+
+            return profilerInfo;
+        }
+    }
+
+    @Override
+    public void appDied() {
+        synchronized (mService) {
+            mService.appDiedLocked(this);
+        }
+    }
+
     public long getInputDispatchingTimeout() {
         return mWindowProcessController.getInputDispatchingTimeout();
     }
diff --git a/services/core/java/com/android/server/am/WindowProcessController.java b/services/core/java/com/android/server/am/WindowProcessController.java
index 792b66b..1743dde 100644
--- a/services/core/java/com/android/server/am/WindowProcessController.java
+++ b/services/core/java/com/android/server/am/WindowProcessController.java
@@ -37,6 +37,7 @@
 import android.app.Activity;
 import android.app.ActivityThread;
 import android.app.IApplicationThread;
+import android.app.ProfilerInfo;
 import android.app.servertransaction.ConfigurationChangeItem;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
@@ -674,6 +675,35 @@
         mAtm.mH.sendMessage(m);
     }
 
+    void clearWaitingToKill() {
+        if (mListener == null) return;
+        // Posting on handler so WM lock isn't held when we call into AM.
+        final Message m = PooledLambda.obtainMessage(
+                WindowProcessListener::clearWaitingToKill, mListener);
+        mAtm.mH.sendMessage(m);
+    }
+
+    void addPackage(String pkg, long versionCode) {
+        // TODO(b/80414790): Calling directly into AM for now which can lead to deadlock once we are
+        // using WM lock. Need to figure-out if it is okay to do this asynchronously.
+        if (mListener == null) return;
+        mListener.addPackage(pkg, versionCode);
+    }
+
+    ProfilerInfo onStartActivity(int topProcessState) {
+        // TODO(b/80414790): Calling directly into AM for now which can lead to deadlock once we are
+        // using WM lock. Need to figure-out if it is okay to do this asynchronously.
+        if (mListener == null) return null;
+        return mListener.onStartActivity(topProcessState);
+    }
+
+    public void appDied() {
+        // TODO(b/80414790): Calling directly into AM for now which can lead to deadlock once we are
+        // using WM lock. Need to figure-out if it is okay to do this asynchronously.
+        if (mListener == null) return;
+        mListener.appDied();
+    }
+
     @Override
     public void onConfigurationChanged(Configuration newGlobalConfig) {
         super.onConfigurationChanged(newGlobalConfig);
diff --git a/services/core/java/com/android/server/am/WindowProcessListener.java b/services/core/java/com/android/server/am/WindowProcessListener.java
index 9cad6fe4..4a7e6e8 100644
--- a/services/core/java/com/android/server/am/WindowProcessListener.java
+++ b/services/core/java/com/android/server/am/WindowProcessListener.java
@@ -16,6 +16,7 @@
 
 package com.android.server.am;
 
+import android.app.ProfilerInfo;
 import android.content.pm.ApplicationInfo;
 import android.util.proto.ProtoOutputStream;
 
@@ -51,5 +52,16 @@
     /** Returns the total time (in milliseconds) spent executing in both user and system code. */
     long getCpuTime();
 
+    /** Clears the waiting to kill reason for this process. */
+    void clearWaitingToKill();
+
+    /** Adds the package to the process. */
+    void addPackage(String pkg, long versionCode);
+
+    /** Called when we are in the process on starting an activity. */
+    ProfilerInfo onStartActivity(int topProcessState);
+
+    /** App died :(...oh well */
+    void appDied();
     void writeToProto(ProtoOutputStream proto, long fieldId);
 }
diff --git a/services/core/java/com/android/server/location/ContextHubClientBroker.java b/services/core/java/com/android/server/location/ContextHubClientBroker.java
index b29b7cf..99a04d7 100644
--- a/services/core/java/com/android/server/location/ContextHubClientBroker.java
+++ b/services/core/java/com/android/server/location/ContextHubClientBroker.java
@@ -20,6 +20,7 @@
 import android.hardware.contexthub.V1_0.ContextHubMsg;
 import android.hardware.contexthub.V1_0.IContexthub;
 import android.hardware.contexthub.V1_0.Result;
+import android.hardware.location.ContextHubInfo;
 import android.hardware.location.ContextHubTransaction;
 import android.hardware.location.IContextHubClient;
 import android.hardware.location.IContextHubClientCallback;
@@ -57,9 +58,9 @@
     private final ContextHubClientManager mClientManager;
 
     /*
-     * The ID of the hub that this client is attached to.
+     * The object describing the hub that this client is attached to.
      */
-    private final int mAttachedContextHubId;
+    private final ContextHubInfo mAttachedContextHubInfo;
 
     /*
      * The host end point ID of this client.
@@ -85,11 +86,12 @@
 
     /* package */ ContextHubClientBroker(
             Context context, IContexthub contextHubProxy, ContextHubClientManager clientManager,
-            int contextHubId, short hostEndPointId, IContextHubClientCallback callback) {
+            ContextHubInfo contextHubInfo, short hostEndPointId,
+            IContextHubClientCallback callback) {
         mContext = context;
         mContextHubProxy = contextHubProxy;
         mClientManager = clientManager;
-        mAttachedContextHubId = contextHubId;
+        mAttachedContextHubInfo = contextHubInfo;
         mHostEndPointId = hostEndPointId;
         mCallbackInterface = callback;
     }
@@ -119,11 +121,12 @@
             ContextHubMsg messageToNanoApp = ContextHubServiceUtil.createHidlContextHubMessage(
                     mHostEndPointId, message);
 
+            int contextHubId = mAttachedContextHubInfo.getId();
             try {
-                result = mContextHubProxy.sendMessageToHub(mAttachedContextHubId, messageToNanoApp);
+                result = mContextHubProxy.sendMessageToHub(contextHubId, messageToNanoApp);
             } catch (RemoteException e) {
                 Log.e(TAG, "RemoteException in sendMessageToNanoApp (target hub ID = "
-                        + mAttachedContextHubId + ")", e);
+                        + contextHubId + ")", e);
                 result = Result.UNKNOWN_FAILURE;
             }
         } else {
@@ -156,7 +159,7 @@
      * @return the ID of the context hub this client is attached to
      */
     /* package */ int getAttachedContextHubId() {
-        return mAttachedContextHubId;
+        return mAttachedContextHubInfo.getId();
     }
 
     /**
diff --git a/services/core/java/com/android/server/location/ContextHubClientManager.java b/services/core/java/com/android/server/location/ContextHubClientManager.java
index 4243f02..eda8c6f 100644
--- a/services/core/java/com/android/server/location/ContextHubClientManager.java
+++ b/services/core/java/com/android/server/location/ContextHubClientManager.java
@@ -19,13 +19,13 @@
 import android.content.Context;
 import android.hardware.contexthub.V1_0.ContextHubMsg;
 import android.hardware.contexthub.V1_0.IContexthub;
+import android.hardware.location.ContextHubInfo;
 import android.hardware.location.IContextHubClient;
 import android.hardware.location.IContextHubClientCallback;
 import android.hardware.location.NanoAppMessage;
 import android.os.RemoteException;
 import android.util.Log;
 
-import java.util.NoSuchElementException;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.Consumer;
 
@@ -80,15 +80,15 @@
      * Registers a new client with the service.
      *
      * @param clientCallback the callback interface of the client to register
-     * @param contextHubId   the ID of the hub this client is attached to
+     * @param contextHubInfo the object describing the hub this client is attached to
      *
      * @return the client interface
      *
      * @throws IllegalStateException if max number of clients have already registered
      */
     /* package */ IContextHubClient registerClient(
-            IContextHubClientCallback clientCallback, int contextHubId) {
-        ContextHubClientBroker broker = createNewClientBroker(clientCallback, contextHubId);
+            IContextHubClientCallback clientCallback, ContextHubInfo contextHubInfo) {
+        ContextHubClientBroker broker = createNewClientBroker(clientCallback, contextHubInfo);
 
         try {
             broker.attachDeathRecipient();
@@ -183,14 +183,14 @@
      * manager.
      *
      * @param clientCallback the callback interface of the client to register
-     * @param contextHubId   the ID of the hub this client is attached to
+     * @param contextHubInfo the object describing the hub this client is attached to
      *
      * @return the ContextHubClientBroker object
      *
      * @throws IllegalStateException if max number of clients have already registered
      */
     private synchronized ContextHubClientBroker createNewClientBroker(
-            IContextHubClientCallback clientCallback, int contextHubId) {
+            IContextHubClientCallback clientCallback, ContextHubInfo contextHubInfo) {
         if (mHostEndPointIdToClientMap.size() == MAX_CLIENT_ID + 1) {
             throw new IllegalStateException("Could not register client - max limit exceeded");
         }
@@ -198,10 +198,11 @@
         ContextHubClientBroker broker = null;
         int id = mNextHostEndpointId;
         for (int i = 0; i <= MAX_CLIENT_ID; i++) {
-            if (!mHostEndPointIdToClientMap.containsKey((short)id)) {
+            if (!mHostEndPointIdToClientMap.containsKey((short) id)) {
                 broker = new ContextHubClientBroker(
-                        mContext, mContextHubProxy, this, contextHubId, (short)id, clientCallback);
-                mHostEndPointIdToClientMap.put((short)id, broker);
+                        mContext, mContextHubProxy, this, contextHubInfo, (short) id,
+                        clientCallback);
+                mHostEndPointIdToClientMap.put((short) id, broker);
                 mNextHostEndpointId = (id == MAX_CLIENT_ID) ? 0 : id + 1;
                 break;
             }
diff --git a/services/core/java/com/android/server/location/ContextHubService.java b/services/core/java/com/android/server/location/ContextHubService.java
index 27509de..96e9337 100644
--- a/services/core/java/com/android/server/location/ContextHubService.java
+++ b/services/core/java/com/android/server/location/ContextHubService.java
@@ -170,8 +170,9 @@
 
         HashMap<Integer, IContextHubClient> defaultClientMap = new HashMap<>();
         for (int contextHubId : mContextHubIdToInfoMap.keySet()) {
+            ContextHubInfo contextHubInfo = mContextHubIdToInfoMap.get(contextHubId);
             IContextHubClient client = mClientManager.registerClient(
-                    createDefaultClientCallback(contextHubId), contextHubId);
+                    createDefaultClientCallback(contextHubId), contextHubInfo);
             defaultClientMap.put(contextHubId, client);
 
             try {
@@ -623,7 +624,8 @@
             throw new NullPointerException("Cannot register client with null callback");
         }
 
-        return mClientManager.registerClient(clientCallback, contextHubId);
+        ContextHubInfo contextHubInfo = mContextHubIdToInfoMap.get(contextHubId);
+        return mClientManager.registerClient(clientCallback, contextHubInfo);
     }
 
     /**
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
index b06be1a..2dbbf55 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
@@ -70,7 +70,8 @@
     }
 
     @Override
-    public boolean checkDeviceIdentifierAccess(String packageName, int userHandle) {
+    public boolean checkDeviceIdentifierAccess(String packageName, int userHandle, int pid,
+            int uid) {
         return false;
     }
 
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 70cdba2..26ea152 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -7871,7 +7871,21 @@
     }
 
     @Override
-    public boolean checkDeviceIdentifierAccess(String packageName, int userHandle) {
+    public boolean checkDeviceIdentifierAccess(String packageName, int userHandle, int pid,
+            int uid) {
+        // If the caller is not a system app then it should only be able to check its own device
+        // identifier access.
+        int callingAppId = UserHandle.getAppId(mInjector.binderGetCallingUid());
+        if (callingAppId >= Process.FIRST_APPLICATION_UID
+                && callingAppId != UserHandle.getAppId(uid)) {
+            return false;
+        }
+        // A device or profile owner must also have the READ_PHONE_STATE permission to access device
+        // identifiers. If the package being checked does not have this permission then deny access.
+        if (mContext.checkPermission(android.Manifest.permission.READ_PHONE_STATE, pid, uid)
+                != PackageManager.PERMISSION_GRANTED) {
+            return false;
+        }
         // Allow access to the device owner.
         ComponentName deviceOwner = getDeviceOwnerComponent(true);
         if (deviceOwner != null && deviceOwner.getPackageName().equals(packageName)) {
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
index 856a1776..f42f5b1 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -64,6 +64,7 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 
+import androidx.test.filters.FlakyTest;
 import androidx.test.filters.MediumTest;
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -102,6 +103,7 @@
  *     com.android.frameworks.servicestests/androidx.test.runner.AndroidJUnitRunner
  */
 @SmallTest
+@FlakyTest(bugId = 113616538)
 @RunWith(AndroidJUnit4.class)
 public class ActivityManagerServiceTest {
     private static final String TAG = ActivityManagerServiceTest.class.getSimpleName();
@@ -829,4 +831,4 @@
             mRestricted = restricted;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java b/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java
index 3819e21..06d41f1 100644
--- a/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java
@@ -21,6 +21,7 @@
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.annotation.UiThreadTest;
+import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
@@ -37,6 +38,7 @@
  */
 @RunWith(AndroidJUnit4.class)
 @SmallTest
+@FlakyTest(bugId = 113616538)
 public class AppErrorDialogTest {
 
     private Context mContext;
diff --git a/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java b/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java
index a030210..1b823ff 100644
--- a/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java
@@ -46,6 +46,7 @@
 import android.view.IWindowManager;
 
 import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.FlakyTest;
 import androidx.test.filters.MediumTest;
 import androidx.test.runner.AndroidJUnit4;
 
@@ -67,6 +68,7 @@
  * runtest --path frameworks/base/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java
  */
 @MediumTest
+@FlakyTest(bugId = 113616538)
 @RunWith(AndroidJUnit4.class)
 public class AssistDataRequesterTest extends ActivityTestsBase {
 
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskPositioningControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskPositioningControllerTests.java
index ced0847..f8e7403 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskPositioningControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskPositioningControllerTests.java
@@ -30,6 +30,7 @@
 import android.platform.test.annotations.Presubmit;
 import android.view.InputChannel;
 
+import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
@@ -43,6 +44,7 @@
  * atest com.android.server.wm.TaskPositioningControllerTests
  */
 @SmallTest
+@FlakyTest(bugId = 117924387)
 @RunWith(AndroidJUnit4.class)
 @Presubmit
 public class TaskPositioningControllerTests extends WindowTestsBase {
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 3127b35..d33a537 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -676,7 +676,7 @@
     /**
      * @hide
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public static TelecomManager from(Context context) {
         return (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
     }
diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java
index 1efa906..d9e7167 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -18,6 +18,7 @@
 
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.app.job.JobService;
@@ -2889,100 +2890,131 @@
         public static final String SUBSCRIPTION_ID = "sub_id";
 
         /**
-         * The profile_id to which the APN saved in modem
+         * The profile_id to which the APN saved in modem.
          * <p>Type: INTEGER</p>
          *@hide
          */
         public static final String PROFILE_ID = "profile_id";
 
         /**
-         * Is the apn setting to be set in modem
-         * <P>Type: INTEGER (boolean)</P>
+         * If set to {@code true}, then the APN setting will persist to the modem.
+         * <p>Type: INTEGER (boolean)</p>
          *@hide
          */
+        @SystemApi
         public static final String MODEM_COGNITIVE = "modem_cognitive";
 
         /**
-         * The max connections of this apn
+         * The max connections of this APN.
          * <p>Type: INTEGER</p>
          *@hide
          */
+        @SystemApi
         public static final String MAX_CONNS = "max_conns";
 
         /**
-         * The wait time for retry of the apn
+         * The wait time for retry of the APN.
          * <p>Type: INTEGER</p>
          *@hide
          */
+        @SystemApi
         public static final String WAIT_TIME = "wait_time";
 
         /**
-         * The time to limit max connection for the apn
+         * The time to limit max connection for the APN.
          * <p>Type: INTEGER</p>
          *@hide
          */
+        @SystemApi
         public static final String MAX_CONNS_TIME = "max_conns_time";
 
         /**
-         * The MTU size of the mobile interface to  which the APN connected
+         * The MTU(Maxinum transmit unit) size of the mobile interface to which the APN connected.
          * <p>Type: INTEGER </p>
          * @hide
          */
+        @SystemApi
         public static final String MTU = "mtu";
 
         /**
-         * Is this APN added/edited/deleted by a user or carrier?
+         * APN edit status. APN could be added/edited/deleted by a user or carrier.
          * <p>Type: INTEGER </p>
          * @hide
          */
+        @SystemApi
         public static final String EDITED = "edited";
 
         /**
-         * Is this APN visible to the user?
-         * <p>Type: INTEGER (boolean) </p>
+         * {@code true} if this APN visible to the user, {@code false} otherwise.
+         * <p>Type: INTEGER (boolean)</p>
          * @hide
          */
+        @SystemApi
         public static final String USER_VISIBLE = "user_visible";
 
         /**
-         * Is the user allowed to edit this APN?
-         * <p>Type: INTEGER (boolean) </p>
+         * {@code true} if the user allowed to edit this APN, {@code false} otherwise.
+         * <p>Type: INTEGER (boolean)</p>
          * @hide
          */
+        @SystemApi
         public static final String USER_EDITABLE = "user_editable";
 
         /**
-         * Following are possible values for the EDITED field
+         * {@link #EDITED APN edit status} indicates that this APN has not been edited or fails to
+         * edit.
+         * <p>Type: INTEGER </p>
          * @hide
          */
+        @SystemApi
         public static final int UNEDITED = 0;
+
         /**
-         *  @hide
+         * {@link #EDITED APN edit status} indicates that this APN has been edited by users.
+         * <p>Type: INTEGER </p>
+         * @hide
          */
+        @SystemApi
         public static final int USER_EDITED = 1;
+
         /**
-         *  @hide
+         * {@link #EDITED APN edit status} indicates that this APN has been deleted by users.
+         * <p>Type: INTEGER </p>
+         * @hide
          */
+        @SystemApi
         public static final int USER_DELETED = 2;
+
         /**
-         * DELETED_BUT_PRESENT is an intermediate value used to indicate that an entry deleted
-         * by the user is still present in the new APN database and therefore must remain tagged
-         * as user deleted rather than completely removed from the database
+         * {@link #EDITED APN edit status} is an intermediate value used to indicate that an entry
+         * deleted by the user is still present in the new APN database and therefore must remain
+         * tagged as user deleted rather than completely removed from the database.
          * @hide
          */
         public static final int USER_DELETED_BUT_PRESENT_IN_XML = 3;
+
         /**
-         *  @hide
+         * {@link #EDITED APN edit status} indicates that this APN has been edited by carriers.
+         * <p>Type: INTEGER </p>
+         * @hide
          */
+        @SystemApi
         public static final int CARRIER_EDITED = 4;
+
         /**
-         * CARRIER_DELETED values are currently not used as there is no usecase. If they are used,
+         * {@link #EDITED APN edit status} indicates that this APN has been deleted by carriers.
+         * CARRIER_DELETED values are currently not used as there is no use case. If they are used,
          * delete() will have to change accordingly. Currently it is hardcoded to USER_DELETED.
+         * <p>Type: INTEGER </p>
          * @hide
          */
         public static final int CARRIER_DELETED = 5;
+
         /**
-         *  @hide
+         * {@link #EDITED APN edit status} is an intermediate value used to indicate that an entry
+         * deleted by the carrier is still present in the new APN database and therefore must remain
+         * tagged as user deleted rather than completely removed from the database.
+         * @hide
          */
         public static final int CARRIER_DELETED_BUT_PRESENT_IN_XML = 6;
 
@@ -3011,16 +3043,20 @@
          * The APN set id. When the user manually selects an APN or the framework sets an APN as
          * preferred, all APNs with the same set id as the selected APN should be prioritized over
          * APNs in other sets.
+         * <p>Type: INTEGER</p>
          * @hide
          */
+        @SystemApi
         public static final String APN_SET_ID = "apn_set_id";
 
         /**
-         * Possible value for the APN_SET_ID field. By default APNs will not belong to a set. If the
-         * user manually selects an APN with no set set, there is no need to prioritize any specific
-         * APN set ids.
+         * Possible value for the{@link #APN_SET_ID} field. By default APNs will not belong to a
+         * set. If the user manually selects an APN with no set set, there is no need to prioritize
+         * any specific APN set ids.
+         * <p>Type: INTEGER</p>
          * @hide
          */
+        @SystemApi
         public static final int NO_SET_SET = 0;
 
     }
diff --git a/telephony/java/android/telephony/RcsManager.java b/telephony/java/android/telephony/RcsManager.java
new file mode 100644
index 0000000..00ce03a
--- /dev/null
+++ b/telephony/java/android/telephony/RcsManager.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2018 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 android.telephony;
+
+import android.os.RemoteException;
+import android.os.ServiceManager;
+
+import com.android.internal.telephony.IRcs;
+
+/**
+ * RcsManager is the application interface to RcsProvider and provides access methods to
+ * RCS related database tables.
+ * @hide - TODO make this public
+ */
+public class RcsManager {
+    private static final String TAG = "RcsManager";
+    private static final boolean VDBG = false;
+
+    /**
+     * Delete the RcsThread identified by the given threadId.
+     * @param threadId threadId of the thread to be deleted.
+     */
+    public void deleteThread(int threadId) {
+        if (VDBG) logd("deleteThread: threadId: " + threadId);
+        try {
+            IRcs iRcs = IRcs.Stub.asInterface(ServiceManager.getService("ircs"));
+            if (iRcs != null) {
+                iRcs.deleteThread(threadId);
+            }
+        } catch (RemoteException re) {
+
+        }
+    }
+
+    private static void logd(String msg) {
+        Rlog.d(TAG, msg);
+    }
+}
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index bfbcd57..e0ec2c5 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -21,7 +21,6 @@
 import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.content.Intent;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -247,7 +246,7 @@
     private String mDataOperatorAlphaLong;
     private String mDataOperatorAlphaShort;
     private String mDataOperatorNumeric;
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     private boolean mIsManualNetworkSelection;
 
     private boolean mIsEmergencyOnly;
@@ -257,9 +256,9 @@
 
     @UnsupportedAppUsage
     private boolean mCssIndicator;
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     private int mNetworkId;
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     private int mSystemId;
     @UnsupportedAppUsage
     private int mCdmaRoamingIndicator;
@@ -457,7 +456,7 @@
      *
      * @hide
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public int getVoiceRegState() {
         return mVoiceRegState;
     }
@@ -472,7 +471,7 @@
      *
      * @hide
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public int getDataRegState() {
         return mDataRegState;
     }
@@ -533,7 +532,7 @@
      * @return roaming status
      * @hide
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public boolean getVoiceRoaming() {
         return getVoiceRoamingType() != ROAMING_TYPE_NOT_ROAMING;
     }
@@ -557,7 +556,7 @@
      * @return roaming type
      * @hide
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public boolean getDataRoaming() {
         return getDataRoamingType() != ROAMING_TYPE_NOT_ROAMING;
     }
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index d0c6c49..3b40164 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -1368,7 +1368,7 @@
     }
 
     /** @hide */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public static int getPhoneId(int subId) {
         if (!isValidSubscriptionId(subId)) {
             if (DBG) {
@@ -1664,7 +1664,7 @@
      * usable subId means its neither a INVALID_SUBSCRIPTION_ID nor a DEFAULT_SUB_ID.
      * @hide
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public static boolean isUsableSubIdValue(int subId) {
         return subId >= MIN_SUBSCRIPTION_ID_VALUE && subId <= MAX_SUBSCRIPTION_ID_VALUE;
     }
@@ -1682,7 +1682,7 @@
     }
 
     /** @hide */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId) {
         int[] subIds = SubscriptionManager.getSubId(phoneId);
         if (subIds != null && subIds.length > 0) {
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 4e391f1..69901d2 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -17,6 +17,7 @@
 package android.telephony;
 
 import static android.content.Context.TELECOM_SERVICE;
+
 import static com.android.internal.util.Preconditions.checkNotNull;
 
 import android.annotation.IntDef;
@@ -59,6 +60,7 @@
 import android.telephony.ims.aidl.IImsMmTelFeature;
 import android.telephony.ims.aidl.IImsRcsFeature;
 import android.telephony.ims.aidl.IImsRegistration;
+import android.telephony.ims.feature.MmTelFeature;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
 import android.text.TextUtils;
 import android.util.Log;
@@ -230,8 +232,7 @@
 
     /** @hide
     /* @deprecated - use getSystemService as described above */
-    @Deprecated
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public static TelephonyManager getDefault() {
         return sInstance;
     }
@@ -320,7 +321,7 @@
     }
 
     /** {@hide} */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public static TelephonyManager from(Context context) {
         return (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
     }
@@ -706,7 +707,7 @@
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     @Deprecated
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    @UnsupportedAppUsage
     public static final String ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED =
             "android.intent.action.PRECISE_DATA_CONNECTION_STATE_CHANGED";
 
@@ -1310,11 +1311,11 @@
      * Returns the unique device ID, for example, the IMEI for GSM and the MEID
      * or ESN for CDMA phones. Return null if device ID is not available.
      *
-     * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE or for the calling package to be the
-     * device or profile owner. The profile owner is an app that owns a managed profile on the
-     * device; for more details see <a href="https://developer.android.com/work/managed-profiles">
-     * Work profiles</a>. Profile owner access is deprecated and will be removed in a future
-     * release.
+     * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, or for the calling package to be the
+     * device or profile owner and have the READ_PHONE_STATE permission. The profile owner is an app
+     * that owns a managed profile on the device; for more details see <a
+     * href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
+     * access is deprecated and will be removed in a future release.
      *
      * @deprecated Use (@link getImei} which returns IMEI for GSM or (@link getMeid} which returns
      * MEID for CDMA.
@@ -1339,11 +1340,11 @@
      * Returns the unique device ID of a subscription, for example, the IMEI for
      * GSM and the MEID for CDMA phones. Return null if device ID is not available.
      *
-     * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE or for the calling package to be the
-     * device or profile owner. The profile owner is an app that owns a managed profile on the
-     * device; for more details see <a href="https://developer.android.com/work/managed-profiles">
-     * Work profiles</a>. Profile owner access is deprecated and will be removed in a future
-     * release.
+     * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, or for the calling package to be the
+     * device or profile owner and have the READ_PHONE_STATE permission. The profile owner is an app
+     * that owns a managed profile on the device; for more details see <a
+     * href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
+     * access is deprecated and will be removed in a future release.
      *
      * @param slotIndex of which deviceID is returned
      *
@@ -1371,11 +1372,11 @@
      * Returns the IMEI (International Mobile Equipment Identity). Return null if IMEI is not
      * available.
      *
-     * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE or for the calling package to be the
-     * device or profile owner. The profile owner is an app that owns a managed profile on the
-     * device; for more details see <a href="https://developer.android.com/work/managed-profiles">
-     * Work profiles</a>. Profile owner access is deprecated and will be removed in a future
-     * release.
+     * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, or for the calling package to be the
+     * device or profile owner and have the READ_PHONE_STATE permission. The profile owner is an app
+     * that owns a managed profile on the device; for more details see <a
+     * href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
+     * access is deprecated and will be removed in a future release.
      */
     @SuppressAutoDoc // No support for device / profile owner.
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
@@ -1387,11 +1388,11 @@
      * Returns the IMEI (International Mobile Equipment Identity). Return null if IMEI is not
      * available.
      *
-     * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE or for the calling package to be the
-     * device or profile owner. The profile owner is an app that owns a managed profile on the
-     * device; for more details see <a href="https://developer.android.com/work/managed-profiles">
-     * Work profiles</a>. Profile owner access is deprecated and will be removed in a future
-     * release.
+     * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, or for the calling package to be the
+     * device or profile owner and have the READ_PHONE_STATE permission. The profile owner is an app
+     * that owns a managed profile on the device; for more details see <a
+     * href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
+     * access is deprecated and will be removed in a future release.
      *
      * @param slotIndex of which IMEI is returned
      */
@@ -1440,11 +1441,11 @@
     /**
      * Returns the MEID (Mobile Equipment Identifier). Return null if MEID is not available.
      *
-     * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE or for the calling package to be the
-     * device or profile owner. The profile owner is an app that owns a managed profile on the
-     * device; for more details see <a href="https://developer.android.com/work/managed-profiles">
-     * Work profiles</a>. Profile owner access is deprecated and will be removed in a future
-     * release.
+     * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, or for the calling package to be the
+     * device or profile owner and have the READ_PHONE_STATE permission. The profile owner is an app
+     * that owns a managed profile on the device; for more details see <a
+     * href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
+     * access is deprecated and will be removed in a future release.
      */
     @SuppressAutoDoc // No support for device / profile owner.
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
@@ -1455,11 +1456,11 @@
     /**
      * Returns the MEID (Mobile Equipment Identifier). Return null if MEID is not available.
      *
-     * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE or for the calling package to be the
-     * device or profile owner. The profile owner is an app that owns a managed profile on the
-     * device; for more details see <a href="https://developer.android.com/work/managed-profiles">
-     * Work profiles</a>. Profile owner access is deprecated and will be removed in a future
-     * release.
+     * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, or for the calling package to be the
+     * device or profile owner and have the READ_PHONE_STATE permission. The profile owner is an app
+     * that owns a managed profile on the device; for more details see <a
+     * href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
+     * access is deprecated and will be removed in a future release.
      *
      * @param slotIndex of which MEID is returned
      */
@@ -1764,7 +1765,7 @@
     }
 
     /** {@hide} */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    @UnsupportedAppUsage
     private int getPhoneTypeFromProperty(int phoneId) {
         String type = getTelephonyProperty(phoneId,
                 TelephonyProperties.CURRENT_ACTIVE_PHONE, null);
@@ -1948,7 +1949,7 @@
      * @param subId
      * @hide
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public String getNetworkOperatorName(int subId) {
         int phoneId = SubscriptionManager.getPhoneId(subId);
         return getTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_OPERATOR_ALPHA, "");
@@ -1976,7 +1977,7 @@
      * @param subId
      * @hide
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public String getNetworkOperator(int subId) {
         int phoneId = SubscriptionManager.getPhoneId(subId);
         return getNetworkOperatorForPhone(phoneId);
@@ -2300,7 +2301,7 @@
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public int getDataNetworkType(int subId) {
         try{
             ITelephony telephony = getITelephony();
@@ -2336,7 +2337,7 @@
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public int getVoiceNetworkType(int subId) {
         try{
             ITelephony telephony = getITelephony();
@@ -2819,7 +2820,7 @@
      * @param subId for which SimOperator is returned
      * @hide
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public String getSimOperator(int subId) {
         return getSimOperatorNumeric(subId);
     }
@@ -2833,7 +2834,7 @@
      * @see #getSimState
      * @hide
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public String getSimOperatorNumeric() {
         int subId = mSubId;
         if (!SubscriptionManager.isUsableSubIdValue(subId)) {
@@ -2862,7 +2863,7 @@
      * @param subId for which SimOperator is returned
      * @hide
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public String getSimOperatorNumeric(int subId) {
         int phoneId = SubscriptionManager.getPhoneId(subId);
         return getSimOperatorNumericForPhone(phoneId);
@@ -2876,7 +2877,7 @@
      * @param phoneId for which SimOperator is returned
      * @hide
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public String getSimOperatorNumericForPhone(int phoneId) {
         return getTelephonyProperty(phoneId,
                 TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, "");
@@ -2903,7 +2904,7 @@
      * @param subId for which SimOperatorName is returned
      * @hide
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public String getSimOperatorName(int subId) {
         int phoneId = SubscriptionManager.getPhoneId(subId);
         return getSimOperatorNameForPhone(phoneId);
@@ -2933,7 +2934,7 @@
      * @param subId for which SimCountryIso is returned
      * @hide
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public String getSimCountryIso(int subId) {
         int phoneId = SubscriptionManager.getPhoneId(subId);
         return getSimCountryIsoForPhone(phoneId);
@@ -2955,11 +2956,11 @@
      * unavailable.
      *
      * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, for the calling app to be the device or
-     * profile owner, or that the calling app has carrier privileges (see {@link
-     * #hasCarrierPrivileges}). The profile owner is an app that owns a managed profile on the
-     * device; for more details see <a href="https://developer.android.com/work/managed-profiles">
-     * Work profiles</a>. Profile owner access is deprecated and will be removed in a future
-     * release.
+     * profile owner and have the READ_PHONE_STATE permission, or that the calling app has carrier
+     * privileges (see {@link #hasCarrierPrivileges}). The profile owner is an app that owns a
+     * managed profile on the device; for more details see <a
+     * href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
+     * access is deprecated and will be removed in a future release.
      */
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
@@ -2972,11 +2973,11 @@
      * unavailable.
      *
      * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, for the calling app to be the device or
-     * profile owner, or that the calling app has carrier privileges (see {@link
-     * #hasCarrierPrivileges}). The profile owner is an app that owns a managed profile on the
-     * device; for more details see <a href="https://developer.android.com/work/managed-profiles">
-     * Work profiles</a>. Profile owner access is deprecated and will be removed in a future
-     * release.
+     * profile owner and have the READ_PHONE_STATE permission, or that the calling app has carrier
+     * privileges (see {@link #hasCarrierPrivileges}). The profile owner is an app that owns a
+     * managed profile on the device; for more details see <a
+     * href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
+     * access is deprecated and will be removed in a future release.
      *
      * @param subId for which Sim Serial number is returned
      * @hide
@@ -3117,11 +3118,11 @@
      * Return null if it is unavailable.
      *
      * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, for the calling app to be the device or
-     * profile owner, or that the calling app has carrier privileges (see {@link
-     * #hasCarrierPrivileges}). The profile owner is an app that owns a managed profile on the
-     * device; for more details see <a href="https://developer.android.com/work/managed-profiles">
-     * Work profiles</a>. Profile owner access is deprecated and will be removed in a future
-     * release.
+     * profile owner and have the READ_PHONE_STATE permission, or that the calling app has carrier
+     * privileges (see {@link #hasCarrierPrivileges}). The profile owner is an app that owns a
+     * managed profile on the device; for more details see <a
+     * href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
+     * access is deprecated and will be removed in a future release.
      */
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
@@ -3135,17 +3136,17 @@
      * Return null if it is unavailable.
      *
      * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, for the calling app to be the device or
-     * profile owner, or that the calling app has carrier privileges (see {@link
-     * #hasCarrierPrivileges}). The profile owner is an app that owns a managed profile on the
-     * device; for more details see <a href="https://developer.android.com/work/managed-profiles">
-     * Work profiles</a>. Profile owner access is deprecated and will be removed in a future
-     * release.
+     * profile owner and have the READ_PHONE_STATE permission, or that the calling app has carrier
+     * privileges (see {@link #hasCarrierPrivileges}). The profile owner is an app that owns a
+     * managed profile on the device; for more details see <a
+     * href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
+     * access is deprecated and will be removed in a future release.
      *
      * @param subId whose subscriber id is returned
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public String getSubscriberId(int subId) {
         try {
             IPhoneSubInfo info = getSubscriberInfo();
@@ -3530,7 +3531,7 @@
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public String getMsisdn(int subId) {
         try {
             IPhoneSubInfo info = getSubscriberInfo();
@@ -4463,7 +4464,7 @@
    /**
     * @hide
     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     private ITelephony getITelephony() {
         return ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE));
     }
@@ -7436,7 +7437,9 @@
     @UnsupportedAppUsage
     public boolean isVolteAvailable() {
         try {
-            return getITelephony().isVolteAvailable(getSubId());
+            return getITelephony().isAvailable(getSubId(),
+                    MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
+                    ImsRegistrationImplBase.REGISTRATION_TECH_LTE, getOpPackageName());
         } catch (RemoteException | NullPointerException ex) {
             return false;
         }
@@ -8041,7 +8044,7 @@
      * either READ_PRIVILEGED_PHONE_STATE or READ_PHONE_STATE to retrieve the information.
      * @hide
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public ServiceState getServiceStateForSubscriber(int subId) {
         try {
             ITelephony service = getITelephony();
@@ -8375,20 +8378,31 @@
     }
 
     /**
-     * Action set from carrier signalling broadcast receivers to enable/disable metered apns
-     * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required
-     * @param subId the subscription ID that this action applies to.
-     * @param enabled control enable or disable metered apns.
+     * Used to enable or disable carrier data by the system based on carrier signalling or
+     * carrier privileged apps. Different from {@link #setDataEnabled(boolean)} which is linked to
+     * user settings, carrier data on/off won't affect user settings but will bypass the
+     * settings and turns off data internally if set to {@code false}.
+     *
+     * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     *
+     * <p>Requires Permission:
+     * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
+     *
+     * @param enabled control enable or disable carrier data.
      * @hide
      */
-    public void carrierActionSetMeteredApnsEnabled(int subId, boolean enabled) {
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public void setCarrierDataEnabled(boolean enabled) {
         try {
             ITelephony service = getITelephony();
             if (service != null) {
-                service.carrierActionSetMeteredApnsEnabled(subId, enabled);
+                service.carrierActionSetMeteredApnsEnabled(
+                        getSubId(SubscriptionManager.getDefaultDataSubscriptionId()), enabled);
             }
         } catch (RemoteException e) {
-            Log.e(TAG, "Error calling ITelephony#carrierActionSetMeteredApnsEnabled", e);
+            Log.e(TAG, "Error calling ITelephony#setCarrierDataEnabled", e);
         }
     }
 
diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java
new file mode 100644
index 0000000..c9cf473
--- /dev/null
+++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java
@@ -0,0 +1,760 @@
+/*
+ * Copyright (C) 2018 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 android.telephony.ims;
+
+
+import android.Manifest;
+import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.content.Context;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.telephony.SubscriptionManager;
+import android.telephony.ims.aidl.IImsCapabilityCallback;
+import android.telephony.ims.aidl.IImsRegistrationCallback;
+import android.telephony.ims.feature.ImsFeature;
+import android.telephony.ims.feature.MmTelFeature;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
+
+import com.android.internal.telephony.ITelephony;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.concurrent.Executor;
+
+/**
+ * A manager for the MmTel (Multimedia Telephony) feature of an IMS network, given an associated
+ * subscription.
+ *
+ * Allows a user to query the IMS MmTel feature information for a subscription, register for
+ * registration and MmTel capability status callbacks, as well as query/modify user settings for the
+ * associated subscription.
+ *
+ * @see #createForSubscriptionId(Context, int)
+ * @hide
+ */
+public class ImsMmTelManager {
+
+    private static final String TAG = "ImsMmTelManager";
+
+    /**
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "WIFI_MODE_", value = {
+            WIFI_MODE_WIFI_ONLY,
+            WIFI_MODE_CELLULAR_PREFERRED,
+            WIFI_MODE_WIFI_PREFERRED
+            })
+    public @interface WiFiCallingMode {}
+
+    /**
+     * Register for IMS over IWLAN if WiFi signal quality is high enough. Do not hand over to LTE
+     * registration if signal quality degrades.
+     * @hide
+     */
+    @SystemApi
+    public static final int WIFI_MODE_WIFI_ONLY = 0;
+
+    /**
+     * Prefer registering for IMS over LTE if LTE signal quality is high enough.
+     * @hide
+     */
+    @SystemApi
+    public static final int WIFI_MODE_CELLULAR_PREFERRED = 1;
+
+    /**
+     * Prefer registering for IMS over IWLAN if possible if WiFi signal quality is high enough.
+     * @hide
+     */
+    @SystemApi
+    public static final int WIFI_MODE_WIFI_PREFERRED = 2;
+
+    /**
+     * Callback class for receiving Registration callback events.
+     * @see #addImsRegistrationCallback(Executor, RegistrationCallback) (RegistrationCallback)
+     * @see #removeImsRegistrationCallback(RegistrationCallback)
+     */
+    public static class RegistrationCallback {
+
+        private static class RegistrationBinder extends IImsRegistrationCallback.Stub {
+
+            private final RegistrationCallback mLocalCallback;
+            private Executor mExecutor;
+
+            RegistrationBinder(RegistrationCallback localCallback) {
+                mLocalCallback = localCallback;
+            }
+
+            @Override
+            public void onRegistered(int imsRadioTech) {
+                if (mLocalCallback == null) return;
+
+                Binder.withCleanCallingIdentity(() ->
+                        mExecutor.execute(() -> mLocalCallback.onRegistered(imsRadioTech)));
+            }
+
+            @Override
+            public void onRegistering(int imsRadioTech) {
+                if (mLocalCallback == null) return;
+
+                Binder.withCleanCallingIdentity(() ->
+                        mExecutor.execute(() -> mLocalCallback.onRegistering(imsRadioTech)));
+            }
+
+            @Override
+            public void onDeregistered(ImsReasonInfo info) {
+                if (mLocalCallback == null) return;
+
+                Binder.withCleanCallingIdentity(() ->
+                        mExecutor.execute(() -> mLocalCallback.onDeregistered(info)));
+            }
+
+            @Override
+            public void onTechnologyChangeFailed(int imsRadioTech, ImsReasonInfo info) {
+                if (mLocalCallback == null) return;
+
+                Binder.withCleanCallingIdentity(() ->
+                        mExecutor.execute(() ->
+                                mLocalCallback.onTechnologyChangeFailed(imsRadioTech, info)));
+            }
+
+            @Override
+            public void onSubscriberAssociatedUriChanged(Uri[] uris) {
+                if (mLocalCallback == null) return;
+
+                Binder.withCleanCallingIdentity(() ->
+                        mExecutor.execute(() ->
+                                mLocalCallback.onSubscriberAssociatedUriChanged(uris)));
+            }
+
+            private void setExecutor(Executor executor) {
+                mExecutor = executor;
+            }
+        }
+
+        private final RegistrationBinder mBinder = new RegistrationBinder(this);
+
+        /**
+         * Notifies the framework when the IMS Provider is registered to the IMS network.
+         *
+         * @param imsRadioTech the radio access technology. Valid values are defined in
+         * {@link ImsRegistrationImplBase.ImsRegistrationTech}.
+         */
+        public void onRegistered(@ImsRegistrationImplBase.ImsRegistrationTech int imsRadioTech) {
+        }
+
+        /**
+         * Notifies the framework when the IMS Provider is trying to register the IMS network.
+         *
+         * @param imsRadioTech the radio access technology. Valid values are defined in
+         * {@link ImsRegistrationImplBase.ImsRegistrationTech}.
+         */
+        public void onRegistering(@ImsRegistrationImplBase.ImsRegistrationTech int imsRadioTech) {
+        }
+
+        /**
+         * Notifies the framework when the IMS Provider is deregistered from the IMS network.
+         *
+         * @param info the {@link ImsReasonInfo} associated with why registration was disconnected.
+         */
+        public void onDeregistered(ImsReasonInfo info) {
+        }
+
+        /**
+         * A failure has occurred when trying to handover registration to another technology type,
+         * defined in {@link ImsRegistrationImplBase.ImsRegistrationTech}
+         *
+         * @param imsRadioTech The {@link ImsRegistrationImplBase.ImsRegistrationTech} type that has
+         *         failed
+         * @param info A {@link ImsReasonInfo} that identifies the reason for failure.
+         */
+        public void onTechnologyChangeFailed(
+                @ImsRegistrationImplBase.ImsRegistrationTech int imsRadioTech, ImsReasonInfo info) {
+        }
+
+        /**
+         * Returns a list of subscriber {@link Uri}s associated with this IMS subscription when
+         * it changes. Per RFC3455, an associated URI is a URI that the service provider has
+         * allocated to a user for their own usage. A user's phone number is typically one of the
+         * associated URIs.
+         * @param uris new array of subscriber {@link Uri}s that are associated with this IMS
+         *         subscription.
+         * @hide
+         */
+        public void onSubscriberAssociatedUriChanged(Uri[] uris) {
+        }
+
+        /**@hide*/
+        public final IImsRegistrationCallback getBinder() {
+            return mBinder;
+        }
+
+        /**@hide*/
+        //Only exposed as public for compatibility with deprecated ImsManager APIs.
+        public void setExecutor(Executor executor) {
+            mBinder.setExecutor(executor);
+        }
+    }
+
+    /**
+     * Receives IMS capability status updates from the ImsService.
+     *
+     * @see #addMmTelCapabilityCallback(Executor, CapabilityCallback) (CapabilityCallback)
+     * @see #removeMmTelCapabilityCallback(CapabilityCallback)
+     */
+    public static class CapabilityCallback {
+
+        private static class CapabilityBinder extends IImsCapabilityCallback.Stub {
+
+            private final CapabilityCallback mLocalCallback;
+            private Executor mExecutor;
+
+            CapabilityBinder(CapabilityCallback c) {
+                mLocalCallback = c;
+            }
+
+            @Override
+            public void onCapabilitiesStatusChanged(int config) {
+                if (mLocalCallback == null) return;
+
+                Binder.withCleanCallingIdentity(() ->
+                        mExecutor.execute(() -> mLocalCallback.onCapabilitiesStatusChanged(
+                                new MmTelFeature.MmTelCapabilities(config))));
+            }
+
+            @Override
+            public void onQueryCapabilityConfiguration(int capability, int radioTech,
+                    boolean isEnabled) {
+                // This is not used for public interfaces.
+            }
+
+            @Override
+            public void onChangeCapabilityConfigurationError(int capability, int radioTech,
+                    @ImsFeature.ImsCapabilityError int reason) {
+                // This is not used for public interfaces
+            }
+
+            private void setExecutor(Executor executor) {
+                mExecutor = executor;
+            }
+        }
+
+        private final CapabilityBinder mBinder = new CapabilityBinder(this);
+
+        /**
+         * The status of the feature's capabilities has changed to either available or unavailable.
+         * If unavailable, the feature is not able to support the unavailable capability at this
+         * time.
+         *
+         * @param capabilities The new availability of the capabilities.
+         */
+        public void onCapabilitiesStatusChanged(
+                MmTelFeature.MmTelCapabilities capabilities) {
+        }
+
+        /**@hide*/
+        public final IImsCapabilityCallback getBinder() {
+            return mBinder;
+        }
+
+        /**@hide*/
+        // Only exposed as public method for compatibility with deprecated ImsManager APIs.
+        // TODO: clean up dependencies and change back to private visibility.
+        public void setExecutor(Executor executor) {
+            mBinder.setExecutor(executor);
+        }
+    }
+
+    private Context mContext;
+    private int mSubId;
+
+    /**
+     * Create an instance of ImsManager for the subscription id specified.
+     *
+     * @param context
+     * @param subId The ID of the subscription that this ImsManager will use.
+     * @see android.telephony.SubscriptionManager#getActiveSubscriptionInfoList()
+     * @throws IllegalArgumentException if the subscription is invalid or
+     *         the subscription ID is not an active subscription.
+     */
+    public static ImsMmTelManager createForSubscriptionId(Context context, int subId) {
+        if (!SubscriptionManager.isValidSubscriptionId(subId)
+                || !getSubscriptionManager(context).isActiveSubscriptionId(subId)) {
+            throw new IllegalArgumentException("Invalid subscription ID");
+        }
+
+        return new ImsMmTelManager(context, subId);
+    }
+
+    private ImsMmTelManager(Context context, int subId) {
+        mContext = context;
+        mSubId = subId;
+    }
+
+    /**
+     * Registers a {@link RegistrationCallback} with the system, which will provide registration
+     * updates for the subscription specified in {@link #createForSubscriptionId(Context, int)}. Use
+     * {@link SubscriptionManager.OnSubscriptionsChangedListener} to listen to Subscription changed
+     * events and call {@link #removeImsRegistrationCallback(RegistrationCallback)} to clean up
+     * after a subscription is removed.
+     * @param executor The executor the callback events should be run on.
+     * @param c The {@link RegistrationCallback} to be added.
+     * @see #removeImsRegistrationCallback(RegistrationCallback)
+     */
+    @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
+    public void addImsRegistrationCallback(@CallbackExecutor Executor executor,
+            @NonNull RegistrationCallback c) {
+        if (c == null) {
+            throw new IllegalArgumentException("Must include a non-null RegistrationCallback.");
+        }
+        if (executor == null) {
+            throw new IllegalArgumentException("Must include a non-null Executor.");
+        }
+        c.setExecutor(executor);
+        try {
+            getITelephony().addImsRegistrationCallback(mSubId, c.getBinder(),
+                    mContext.getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Removes an existing {@link RegistrationCallback}. Ensure to call this method when cleaning
+     * up to avoid memory leaks or when the subscription is removed.
+     * @param c The {@link RegistrationCallback} to be removed.
+     * @see SubscriptionManager.OnSubscriptionsChangedListener
+     * @see #addImsRegistrationCallback(Executor, RegistrationCallback)
+     */
+    @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
+    public void removeImsRegistrationCallback(@NonNull RegistrationCallback c) {
+        if (c == null) {
+            throw new IllegalArgumentException("Must include a non-null RegistrationCallback.");
+        }
+        try {
+            getITelephony().removeImsRegistrationCallback(mSubId, c.getBinder(),
+                    mContext.getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Registers a {@link CapabilityCallback} with the system, which will provide MmTel capability
+     * updates for the subscription specified in {@link #createForSubscriptionId(Context, int)}.
+     * Use {@link SubscriptionManager.OnSubscriptionsChangedListener} to listen to
+     * subscription changed events and call
+     * {@link #removeImsRegistrationCallback(RegistrationCallback)} to clean up after a subscription
+     * is removed.
+     * @param executor The executor the callback events should be run on.
+     * @param c The MmTel {@link CapabilityCallback} to be registered.
+     * @see #removeMmTelCapabilityCallback(CapabilityCallback)
+     */
+    @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
+    public void addMmTelCapabilityCallback(@CallbackExecutor Executor executor,
+            @NonNull CapabilityCallback c) {
+        if (c == null) {
+            throw new IllegalArgumentException("Must include a non-null RegistrationCallback.");
+        }
+        if (executor == null) {
+            throw new IllegalArgumentException("Must include a non-null Executor.");
+        }
+        c.setExecutor(executor);
+        try {
+            getITelephony().addMmTelCapabilityCallback(mSubId, c.getBinder(),
+                    mContext.getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Removes an existing MmTel {@link CapabilityCallback}. Be sure to call this when cleaning
+     * up to avoid memory leaks.
+     * @param c The MmTel {@link CapabilityCallback} to be removed.
+     * @see #addMmTelCapabilityCallback(Executor, CapabilityCallback)
+     */
+    @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
+    public void removeMmTelCapabilityCallback(@NonNull CapabilityCallback c) {
+        if (c == null) {
+            throw new IllegalArgumentException("Must include a non-null RegistrationCallback.");
+        }
+        try {
+            getITelephony().removeMmTelCapabilityCallback(mSubId, c.getBinder(),
+                    mContext.getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Query the user's setting for whether or not to use MmTel capabilities over IMS,
+     * such as voice and video, depending on carrier configuration for the current subscription.
+     * @see #setAdvancedCallingSetting(boolean)
+     * @return true if the user’s setting for advanced calling is enabled and false otherwise.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public boolean isAdvancedCallingSettingEnabled() {
+        try {
+            return getITelephony().isAdvancedCallingSettingEnabled(mSubId);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Modify the user’s setting for “Advanced Calling” or "Enhanced 4G LTE", which is used to
+     * enable MmTel IMS features, such as voice and video calling, depending on the carrier
+     * configuration for the current subscription. Modifying this value may also trigger an IMS
+     * registration or deregistration, depending on the new value.
+     * @see #isAdvancedCallingEnabled()
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public void setAdvancedCallingSetting(boolean isEnabled) {
+        try {
+            getITelephony().setAdvancedCallingSetting(mSubId, isEnabled);
+            return;
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Query the IMS MmTel capability for a given registration technology. This does not
+     * necessarily mean that we are registered and the capability is available, but rather the
+     * subscription is capable of this service over IMS.
+     *
+     * @see android.telephony.CarrierConfigManager#KEY_CARRIER_VOLTE_AVAILABLE_BOOL
+     * @see android.telephony.CarrierConfigManager#KEY_CARRIER_VT_AVAILABLE_BOOL
+     * @see android.telephony.CarrierConfigManager#KEY_CARRIER_IMS_GBA_REQUIRED_BOOL
+     * @see #isAvailable(int, int)
+     *
+     * @param imsRegTech The IMS registration technology, can be one of the following:
+     *         {@link ImsRegistrationImplBase#REGISTRATION_TECH_LTE},
+     *         {@link ImsRegistrationImplBase#REGISTRATION_TECH_IWLAN}
+     * @param capability The IMS MmTel capability to query, can be one of the following:
+     *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VOICE},
+     *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VIDEO,
+     *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_UT},
+     *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_SMS}
+     * @return {@code true} if the MmTel IMS capability is capable for this subscription, false
+     *         otherwise.
+     */
+    @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
+    public boolean isCapable(@MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
+            @ImsRegistrationImplBase.ImsRegistrationTech int imsRegTech) {
+        try {
+            return getITelephony().isCapable(mSubId, capability, imsRegTech,
+                    mContext.getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Query the availability of an IMS MmTel capability for a given registration technology. If
+     * a capability is available, IMS is registered and the service is currently available over IMS.
+     *
+     * @see #isCapable(int, int)
+     *
+     * @param imsRegTech The IMS registration technology, can be one of the following:
+     *         {@link ImsRegistrationImplBase#REGISTRATION_TECH_LTE},
+     *         {@link ImsRegistrationImplBase#REGISTRATION_TECH_IWLAN}
+     * @param capability The IMS MmTel capability to query, can be one of the following:
+     *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VOICE},
+     *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VIDEO,
+     *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_UT},
+     *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_SMS}
+     * @return {@code true} if the MmTel IMS capability is available for this subscription, false
+     *         otherwise.
+     */
+    @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
+    public boolean isAvailable(@MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
+            @ImsRegistrationImplBase.ImsRegistrationTech int imsRegTech) {
+        try {
+            return getITelephony().isAvailable(mSubId, capability, imsRegTech,
+                    mContext.getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * The user's setting for whether or not they have enabled the "Video Calling" setting.
+     * @return true if the user’s “Video Calling” setting is currently enabled.
+     * @see #setVtSetting(boolean)
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
+    public boolean isVtSettingEnabled() {
+        try {
+            return getITelephony().isVtSettingEnabled(mSubId, mContext.getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Change the user's setting for Video Telephony and enable the Video Telephony capability.
+     * @see #isVtSettingEnabled()
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public void setVtSetting(boolean isEnabled) {
+        try {
+            getITelephony().setVtSetting(mSubId, isEnabled);
+            return;
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * @return true if the user's setting for Voice over WiFi is enabled and false if it is not.
+     * @see #setVoWiFiSetting(boolean)
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public boolean isVoWiFiSettingEnabled() {
+        try {
+            return getITelephony().isVoWiFiSettingEnabled(mSubId);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Sets the user's setting for whether or not Voice over WiFi is enabled.
+     * @param isEnabled true if the user's setting for Voice over WiFi is enabled, false otherwise=
+     * @see #isVoWiFiSettingEnabled()
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public void setVoWiFiSetting(boolean isEnabled) {
+        try {
+            getITelephony().setVoWiFiSetting(mSubId, isEnabled);
+            return;
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * @return true if the user's setting for Voice over WiFi while roaming is enabled, false
+     * if disabled.
+     * @see #setVoWiFiRoamingSetting(boolean)
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public boolean isVoWiFiRoamingSettingEnabled() {
+        try {
+            return getITelephony().isVoWiFiRoamingSettingEnabled(mSubId);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Change the user's setting for Voice over WiFi while roaming.
+     * @param isEnabled true if the user's setting for Voice over WiFi while roaming is enabled,
+     *     false otherwise.
+     * @see #isVoWiFiRoamingSettingEnabled()
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public void setVoWiFiRoamingSetting(boolean isEnabled) {
+        try {
+            getITelephony().setVoWiFiRoamingSetting(mSubId, isEnabled);
+            return;
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Overrides the Voice over WiFi capability to true for IMS, but do not persist the setting.
+     * Typically used during the Voice over WiFi registration process for some carriers.
+     *
+     * @param isCapable true if the IMS stack should try to register for IMS over IWLAN, false
+     *     otherwise.
+     * @param mode the Voice over WiFi mode preference to set, which can be one of the following:
+     * - {@link #WIFI_MODE_WIFI_ONLY}
+     * - {@link #WIFI_MODE_CELLULAR_PREFERRED}
+     * - {@link #WIFI_MODE_WIFI_PREFERRED}
+     * @see #setVoWiFiSetting(boolean)
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public void setVoWiFiNonPersistent(boolean isCapable, int mode) {
+        try {
+            getITelephony().setVoWiFiNonPersistent(mSubId, isCapable, mode);
+            return;
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * @return The Voice over WiFi Mode preference set by the user, which can be one of the
+     * following:
+     * - {@link #WIFI_MODE_WIFI_ONLY}
+     * - {@link #WIFI_MODE_CELLULAR_PREFERRED}
+     * - {@link #WIFI_MODE_WIFI_PREFERRED}
+     * @see #setVoWiFiSetting(boolean)
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public @WiFiCallingMode int getVoWiFiModeSetting() {
+        try {
+            return getITelephony().getVoWiFiModeSetting(mSubId);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Set the user's preference for Voice over WiFi calling mode.
+     * @param mode The user's preference for the technology to register for IMS over, can be one of
+     *    the following:
+     * - {@link #WIFI_MODE_WIFI_ONLY}
+     * - {@link #WIFI_MODE_CELLULAR_PREFERRED}
+     * - {@link #WIFI_MODE_WIFI_PREFERRED}
+     * @see #getVoWiFiModeSetting()
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public void setVoWiFiModeSetting(@WiFiCallingMode int mode) {
+        try {
+            getITelephony().setVoWiFiModeSetting(mSubId, mode);
+            return;
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Set the user's preference for Voice over WiFi calling mode while the device is roaming on
+     * another network.
+     *
+     * @return The user's preference for the technology to register for IMS over when roaming on
+     *     another network, can be one of the following:
+     *     - {@link #WIFI_MODE_WIFI_ONLY}
+     *     - {@link #WIFI_MODE_CELLULAR_PREFERRED}
+     *     - {@link #WIFI_MODE_WIFI_PREFERRED}
+     * @see #setVoWiFiRoamingSetting(boolean)
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @WiFiCallingMode int getVoWiFiRoamingModeSetting() {
+        try {
+            return getITelephony().getVoWiFiRoamingModeSetting(mSubId);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Set the user's preference for Voice over WiFi mode while the device is roaming on another
+     * network.
+     *
+     * @param mode The user's preference for the technology to register for IMS over when roaming on
+     *     another network, can be one of the following:
+     *     - {@link #WIFI_MODE_WIFI_ONLY}
+     *     - {@link #WIFI_MODE_CELLULAR_PREFERRED}
+     *     - {@link #WIFI_MODE_WIFI_PREFERRED}
+     * @see #getVoWiFiRoamingModeSetting()
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public void setVoWiFiRoamingModeSetting(@WiFiCallingMode int mode) {
+        try {
+            getITelephony().setVoWiFiRoamingModeSetting(mSubId, mode);
+            return;
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Change the user's setting for RTT capability of this device.
+     * @param isEnabled if true RTT will be enabled during calls.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public void setRttCapabilitySetting(boolean isEnabled) {
+        try {
+            getITelephony().setRttCapabilitySetting(mSubId, isEnabled);
+            return;
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * @return true if TTY over VoLTE is supported
+     * @see android.telecom.TelecomManager#getCurrentTtyMode
+     * @see android.telephony.CarrierConfigManager#KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    boolean isTtyOverVolteEnabled() {
+        try {
+            return getITelephony().isTtyOverVolteEnabled(mSubId);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    private static SubscriptionManager getSubscriptionManager(Context context) {
+        SubscriptionManager manager = context.getSystemService(SubscriptionManager.class);
+        if (manager == null) {
+            throw new RuntimeException("Could not find SubscriptionManager.");
+        }
+        return manager;
+    }
+
+    private static ITelephony getITelephony() {
+        ITelephony binder = ITelephony.Stub.asInterface(
+                ServiceManager.getService(Context.TELEPHONY_SERVICE));
+        if (binder == null) {
+            throw new RuntimeException("Could not find Telephony Service.");
+        }
+        return binder;
+    }
+}
diff --git a/telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl b/telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl
index 4f37caa..749b191 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl
@@ -23,7 +23,7 @@
 import android.telephony.ims.ImsReasonInfo;
 
 /**
- * See ImsRegistrationImplBase.Callback for more information.
+ * See {@link ImsManager#RegistrationCallback} for more information.
  *
  * {@hide}
  */
diff --git a/telephony/java/android/telephony/ims/feature/ImsFeature.java b/telephony/java/android/telephony/ims/feature/ImsFeature.java
index b77881e..7f69f43 100644
--- a/telephony/java/android/telephony/ims/feature/ImsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/ImsFeature.java
@@ -167,59 +167,6 @@
      */
     public static final int CAPABILITY_SUCCESS = 0;
 
-
-    /**
-     * The framework implements this callback in order to register for Feature Capability status
-     * updates, via {@link #onCapabilitiesStatusChanged(Capabilities)}, query Capability
-     * configurations, via {@link #onQueryCapabilityConfiguration}, as well as to receive error
-     * callbacks when the ImsService can not change the capability as requested, via
-     * {@link #onChangeCapabilityConfigurationError}.
-     *
-     * @hide
-     */
-    public static class CapabilityCallback extends IImsCapabilityCallback.Stub {
-
-        @Override
-        public final void onCapabilitiesStatusChanged(int config) throws RemoteException {
-            onCapabilitiesStatusChanged(new Capabilities(config));
-        }
-
-        /**
-         * Returns the result of a query for the capability configuration of a requested capability.
-         *
-         * @param capability The capability that was requested.
-         * @param radioTech The IMS radio technology associated with the capability.
-         * @param isEnabled true if the capability is enabled, false otherwise.
-         */
-        @Override
-        public void onQueryCapabilityConfiguration(int capability, int radioTech,
-                boolean isEnabled) {
-
-        }
-
-        /**
-         * Called when a change to the capability configuration has returned an error.
-         *
-         * @param capability The capability that was requested to be changed.
-         * @param radioTech The IMS radio technology associated with the capability.
-         * @param reason error associated with the failure to change configuration.
-         */
-        @Override
-        public void onChangeCapabilityConfigurationError(int capability, int radioTech,
-                @ImsCapabilityError int reason) {
-        }
-
-        /**
-         * The status of the feature's capabilities has changed to either available or unavailable.
-         * If unavailable, the feature is not able to support the unavailable capability at this
-         * time.
-         *
-         * @param config The new availability of the capabilities.
-         */
-        public void onCapabilitiesStatusChanged(Capabilities config) {
-        }
-    }
-
     /**
      * Used by the ImsFeature to call back to the CapabilityCallback that the framework has
      * provided.
diff --git a/telephony/java/android/telephony/ims/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
index 7681aef..96995943 100644
--- a/telephony/java/android/telephony/ims/feature/MmTelFeature.java
+++ b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
@@ -17,6 +17,8 @@
 package android.telephony.ims.feature;
 
 import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.os.Bundle;
 import android.os.Message;
@@ -222,21 +224,31 @@
      * This MmTelFeature can then return the status of each of these capabilities (enabled or not)
      * by sending a {@link #notifyCapabilitiesStatusChanged} callback to the framework. The current
      * status can also be queried using {@link #queryCapabilityStatus()}.
+     * @see #isCapable(int)
      */
     public static class MmTelCapabilities extends Capabilities {
 
         /**
-         * @hide
+         * Create a new empty {@link MmTelCapabilities} instance.
+         * @see #addCapabilities(int)
+         * @see #removeCapabilities(int)
          */
         @VisibleForTesting
         public MmTelCapabilities() {
             super();
         }
 
+        /**@deprecated Use {@link MmTelCapabilities} to construct a new instance instead.*/
+        @Deprecated
         public MmTelCapabilities(Capabilities c) {
             mCapabilities = c.mCapabilities;
         }
 
+        /**
+         * Create a new {link @MmTelCapabilities} instance with the provided capabilities.
+         * @param capabilities The capabilities that are supported for MmTel in the form of a
+         *                     bitfield.
+         */
         public MmTelCapabilities(int capabilities) {
             mCapabilities = capabilities;
         }
@@ -406,7 +418,10 @@
      * support the capability that is enabled. A capability that is disabled by the framework (via
      * {@link #changeEnabledCapabilities}) should also show the status as disabled.
      */
-    public final void notifyCapabilitiesStatusChanged(MmTelCapabilities c) {
+    public final void notifyCapabilitiesStatusChanged(@NonNull MmTelCapabilities c) {
+        if (c == null) {
+            throw new IllegalArgumentException("MmTelCapabilities must be non-null!");
+        }
         super.notifyCapabilitiesStatusChanged(c);
     }
 
@@ -414,7 +429,12 @@
      * Notify the framework of an incoming call.
      * @param c The {@link ImsCallSessionImplBase} of the new incoming call.
      */
-    public final void notifyIncomingCall(ImsCallSessionImplBase c, Bundle extras) {
+    public final void notifyIncomingCall(@NonNull ImsCallSessionImplBase c,
+            @NonNull Bundle extras) {
+        if (c == null || extras == null) {
+            throw new IllegalArgumentException("ImsCallSessionImplBase and Bundle can not be "
+                    + "null.");
+        }
         synchronized (mLock) {
             if (mListener == null) {
                 throw new IllegalStateException("Session is not available.");
@@ -434,7 +454,12 @@
      *        This can be null if no call information is available for the rejected call.
      * @param reason The {@link ImsReasonInfo} call rejection reason.
      */
-    public final void notifyRejectedCall(ImsCallProfile callProfile, ImsReasonInfo reason) {
+    public final void notifyRejectedCall(@NonNull ImsCallProfile callProfile,
+            @NonNull ImsReasonInfo reason) {
+        if (callProfile == null || reason == null) {
+            throw new IllegalArgumentException("ImsCallProfile and ImsReasonInfo must not be "
+                    + "null.");
+        }
         synchronized (mLock) {
             if (mListener == null) {
                 throw new IllegalStateException("Session is not available.");
@@ -508,8 +533,8 @@
      * the framework.
      */
     @Override
-    public void changeEnabledCapabilities(CapabilityChangeRequest request,
-            CapabilityCallbackProxy c) {
+    public void changeEnabledCapabilities(@NonNull CapabilityChangeRequest request,
+            @NonNull CapabilityCallbackProxy c) {
         // Base implementation, no-op
     }
 
@@ -531,7 +556,7 @@
      *        {@link ImsCallProfile#CALL_TYPE_VS_RX}
      * @return a {@link ImsCallProfile} object
      */
-    public ImsCallProfile createCallProfile(int callSessionType, int callType) {
+    public @Nullable ImsCallProfile createCallProfile(int callSessionType, int callType) {
         // Base Implementation - Should be overridden
         return null;
     }
@@ -552,7 +577,7 @@
      *
      * @param profile a call profile to make the call
      */
-    public ImsCallSessionImplBase createCallSession(ImsCallProfile profile) {
+    public @Nullable ImsCallSessionImplBase createCallSession(@NonNull ImsCallProfile profile) {
         // Base Implementation - Should be overridden
         return null;
     }
@@ -569,7 +594,7 @@
      * @return a {@link ProcessCallResult} to the framework, which will be used to determine if the
      *        call will be placed over IMS or via CSFB.
      */
-    public @ProcessCallResult int shouldProcessCall(String[] numbers) {
+    public @ProcessCallResult int shouldProcessCall(@NonNull String[] numbers) {
         return PROCESS_CALL_IMS;
     }
 
@@ -602,7 +627,7 @@
      * @return The {@link ImsUtImplBase} Ut interface implementation for the supplementary service
      * configuration.
      */
-    public ImsUtImplBase getUt() {
+    public @NonNull ImsUtImplBase getUt() {
         // Base Implementation - Should be overridden
         return new ImsUtImplBase();
     }
@@ -611,7 +636,7 @@
      * @return The {@link ImsEcbmImplBase} Emergency call-back mode interface for emergency VoLTE
      * calls that support it.
      */
-    public ImsEcbmImplBase getEcbm() {
+    public @NonNull ImsEcbmImplBase getEcbm() {
         // Base Implementation - Should be overridden
         return new ImsEcbmImplBase();
     }
@@ -620,7 +645,7 @@
      * @return The {@link ImsMultiEndpointImplBase} implementation for implementing Dialog event
      * package processing for multi-endpoint.
      */
-    public ImsMultiEndpointImplBase getMultiEndpoint() {
+    public @NonNull ImsMultiEndpointImplBase getMultiEndpoint() {
         // Base Implementation - Should be overridden
         return new ImsMultiEndpointImplBase();
     }
@@ -646,7 +671,7 @@
      *     }
      * }
      */
-    public void setUiTtyMode(int mode, Message onCompleteMessage) {
+    public void setUiTtyMode(int mode, @Nullable Message onCompleteMessage) {
         // Base Implementation - Should be overridden
     }
 
@@ -680,7 +705,7 @@
      * @return an instance of {@link ImsSmsImplBase} which should be implemented by the IMS
      * Provider.
      */
-    public ImsSmsImplBase getSmsImplementation() {
+    public @NonNull ImsSmsImplBase getSmsImplementation() {
         return new ImsSmsImplBase();
     }
 
diff --git a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
index cecf2e2..a08e031 100644
--- a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
@@ -76,64 +76,6 @@
     private static final int REGISTRATION_STATE_REGISTERING = 1;
     private static final int REGISTRATION_STATE_REGISTERED = 2;
 
-    /**
-     * Callback class for receiving Registration callback events.
-     * @hide
-     */
-    public static class Callback extends IImsRegistrationCallback.Stub {
-        /**
-         * Notifies the framework when the IMS Provider is connected to the IMS network.
-         *
-         * @param imsRadioTech the radio access technology. Valid values are defined in
-         * {@link ImsRegistrationTech}.
-         */
-        @Override
-        public void onRegistered(@ImsRegistrationTech int imsRadioTech) {
-        }
-
-        /**
-         * Notifies the framework when the IMS Provider is trying to connect the IMS network.
-         *
-         * @param imsRadioTech the radio access technology. Valid values are defined in
-         * {@link ImsRegistrationTech}.
-         */
-        @Override
-        public void onRegistering(@ImsRegistrationTech int imsRadioTech) {
-        }
-
-        /**
-         * Notifies the framework when the IMS Provider is disconnected from the IMS network.
-         *
-         * @param info the {@link ImsReasonInfo} associated with why registration was disconnected.
-         */
-        @Override
-        public void onDeregistered(ImsReasonInfo info) {
-        }
-
-        /**
-         * A failure has occurred when trying to handover registration to another technology type,
-         * defined in {@link ImsRegistrationTech}
-         *
-         * @param imsRadioTech The {@link ImsRegistrationTech} type that has failed
-         * @param info A {@link ImsReasonInfo} that identifies the reason for failure.
-         */
-        @Override
-        public void onTechnologyChangeFailed(@ImsRegistrationTech int imsRadioTech,
-                ImsReasonInfo info) {
-        }
-
-        /**
-         * Returns a list of subscriber {@link Uri}s associated with this IMS subscription when
-         * it changes.
-         * @param uris new array of subscriber {@link Uri}s that are associated with this IMS
-         *         subscription.
-         */
-        @Override
-        public void onSubscriberAssociatedUriChanged(Uri[] uris) {
-
-        }
-    }
-
     private final IImsRegistration mBinder = new IImsRegistration.Stub() {
 
         @Override
diff --git a/telephony/java/com/android/internal/telephony/IRcs.aidl b/telephony/java/com/android/internal/telephony/IRcs.aidl
new file mode 100644
index 0000000..ede8695
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/IRcs.aidl
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2018 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.internal.telephony;
+
+interface IRcs {
+    void deleteThread(int threadId);
+}
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 006b040..dc23358 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -38,10 +38,12 @@
 import android.telephony.SignalStrength;
 import android.telephony.TelephonyHistogram;
 import android.telephony.VisualVoicemailSmsFilterSettings;
+import android.telephony.ims.aidl.IImsCapabilityCallback;
 import android.telephony.ims.aidl.IImsConfig;
 import android.telephony.ims.aidl.IImsMmTelFeature;
 import android.telephony.ims.aidl.IImsRcsFeature;
 import android.telephony.ims.aidl.IImsRegistration;
+import android.telephony.ims.aidl.IImsRegistrationCallback;
 import com.android.ims.internal.IImsServiceFeatureCallback;
 import com.android.internal.telephony.CellNetworkScanResult;
 import com.android.internal.telephony.OperatorInfo;
@@ -1057,11 +1059,6 @@
      */
     boolean isWifiCallingAvailable(int subId);
 
-    /**
-     * Returns the Status of VoLTE for the subscription ID specified.
-     */
-    boolean isVolteAvailable(int subId);
-
      /**
      * Returns the Status of VT (video telephony) for the subscription ID specified.
      */
@@ -1505,4 +1502,117 @@
      *
      */
     int getRadioPowerState(int slotIndex, String callingPackage);
+
+    // IMS specific AIDL commands, see ImsMmTelManager.java
+
+    /**
+     * Adds an IMS registration status callback for the subscription id specified.
+     */
+    oneway void addImsRegistrationCallback(int subId, IImsRegistrationCallback c,
+            String callingPackage);
+     /**
+      * Removes an existing IMS registration status callback for the subscription specified.
+      */
+    oneway void removeImsRegistrationCallback(int subId, IImsRegistrationCallback c,
+            String callingPackage);
+
+    /**
+     * Adds an IMS MmTel capabilities callback for the subscription specified.
+     */
+    oneway void addMmTelCapabilityCallback(int subId, IImsCapabilityCallback c,
+            String callingPackage);
+
+    /**
+     * Removes an existing IMS MmTel capabilities callback for the subscription specified.
+     */
+    oneway void removeMmTelCapabilityCallback(int subId, IImsCapabilityCallback c,
+            String callingPackage);
+
+    /**
+     * return true if the IMS MmTel capability for the given registration tech is capable.
+     */
+    boolean isCapable(int subId, int capability, int regTech, String callingPackage);
+
+    /**
+     * return true if the IMS MmTel capability for the given registration tech is available.
+     */
+    boolean isAvailable(int subId, int capability, int regTech, String callingPackage);
+
+    /**
+     * Returns true if the user's setting for 4G LTE is enabled, for the subscription specified.
+     */
+    boolean isAdvancedCallingSettingEnabled(int subId);
+
+    /**
+     * Modify the user's setting for whether or not 4G LTE is enabled.
+     */
+    void setAdvancedCallingSetting(int subId, boolean isEnabled);
+
+    /**
+     * return true if the user's setting for VT is enabled for the subscription.
+     */
+    boolean isVtSettingEnabled(int subId, String callingPackage);
+
+    /**
+     * Modify the user's setting for whether or not VT is available for the subscrption specified.
+     */
+    void setVtSetting(int subId, boolean isEnabled);
+
+    /**
+     * return true if the user's setting for whether or not Voice over WiFi is currently enabled.
+     */
+    boolean isVoWiFiSettingEnabled(int subId);
+
+    /**
+     * sets the user's setting for Voice over WiFi enabled state.
+     */
+    void setVoWiFiSetting(int subId, boolean isEnabled);
+
+    /**
+     * return true if the user's setting for Voice over WiFi while roaming is enabled.
+     */
+    boolean isVoWiFiRoamingSettingEnabled(int subId);
+
+    /**
+     * Sets the user's preference for whether or not Voice over WiFi is enabled for the current
+     * subscription while roaming.
+     */
+    void setVoWiFiRoamingSetting(int subId, boolean isEnabled);
+
+    /**
+     * Set the Voice over WiFi enabled state, but do not persist the setting.
+     */
+    void setVoWiFiNonPersistent(int subId, boolean isCapable, int mode);
+
+    /**
+     * return the Voice over WiFi mode preference set by the user for the subscription specified.
+     */
+    int getVoWiFiModeSetting(int subId);
+
+    /**
+     * sets the user's preference for the Voice over WiFi mode for the subscription specified.
+     */
+    void setVoWiFiModeSetting(int subId, int mode);
+
+    /**
+     * return the Voice over WiFi mode preference set by the user for the subscription specified
+     * while roaming.
+     */
+    int getVoWiFiRoamingModeSetting(int subId);
+
+    /**
+     * sets the user's preference for the Voice over WiFi mode for the subscription specified
+     * while roaming.
+     */
+    void setVoWiFiRoamingModeSetting(int subId, int mode);
+
+    /**
+     * Modify the user's setting for whether or not RTT is enabled for the subscrption specified.
+     */
+    void setRttCapabilitySetting(int subId, boolean isEnabled);
+
+    /**
+     * return true if TTY over VoLTE is enabled for the subscription specified.
+     */
+    boolean isTtyOverVolteEnabled(int subId);
 }