Merge "Add javadoc for IMM.showInputMethodPicker"
diff --git a/Android.bp b/Android.bp
index e8f3561..5f81191 100644
--- a/Android.bp
+++ b/Android.bp
@@ -736,7 +736,7 @@
         "updatable_media_stubs",
     ],
 
-    jarjar_rules: "jarjar_rules_hidl.txt",
+    jarjar_rules: ":framework-jarjar-rules",
 
     static_libs: [
         "apex_aidl_interface-java",
@@ -789,6 +789,11 @@
 }
 
 filegroup {
+    name: "framework-jarjar-rules",
+    srcs: ["jarjar_rules_hidl.txt"],
+}
+
+filegroup {
     name: "libincident_aidl",
     srcs: [
         "core/java/android/os/IIncidentManager.aidl",
diff --git a/api/current.txt b/api/current.txt
index 9dc51b1..bfd4192 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6641,7 +6641,7 @@
     method @NonNull public java.util.List<java.lang.String> getDelegatedScopes(@Nullable android.content.ComponentName, @NonNull String);
     method public CharSequence getDeviceOwnerLockScreenInfo();
     method public CharSequence getEndUserSessionMessage(@NonNull android.content.ComponentName);
-    method public String getGlobalPrivateDnsHost(@NonNull android.content.ComponentName);
+    method @Nullable public String getGlobalPrivateDnsHost(@NonNull android.content.ComponentName);
     method public int getGlobalPrivateDnsMode(@NonNull android.content.ComponentName);
     method @NonNull public java.util.List<byte[]> getInstalledCaCerts(@Nullable android.content.ComponentName);
     method @Nullable public java.util.List<java.lang.String> getKeepUninstalledPackages(@Nullable android.content.ComponentName);
@@ -7966,9 +7966,9 @@
     method public boolean isMultipleAdvertisementSupported();
     method public boolean isOffloadedFilteringSupported();
     method public boolean isOffloadedScanBatchingSupported();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothServerSocket listenUsingInsecureL2capChannel() throws java.io.IOException;
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH) @NonNull public android.bluetooth.BluetoothServerSocket listenUsingInsecureL2capChannel() throws java.io.IOException;
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothServerSocket listenUsingInsecureRfcommWithServiceRecord(String, java.util.UUID) throws java.io.IOException;
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothServerSocket listenUsingL2capChannel() throws java.io.IOException;
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH) @NonNull public android.bluetooth.BluetoothServerSocket listenUsingL2capChannel() throws java.io.IOException;
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothServerSocket listenUsingRfcommWithServiceRecord(String, java.util.UUID) throws java.io.IOException;
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setName(String);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean startDiscovery();
@@ -8336,9 +8336,9 @@
     method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int);
     method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int, android.os.Handler);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean createBond();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothSocket createInsecureL2capChannel(int) throws java.io.IOException;
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH) @NonNull public android.bluetooth.BluetoothSocket createInsecureL2capChannel(int) throws java.io.IOException;
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothSocket createInsecureRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException;
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothSocket createL2capChannel(int) throws java.io.IOException;
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH) @NonNull public android.bluetooth.BluetoothSocket createL2capChannel(int) throws java.io.IOException;
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothSocket createRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException;
     method public int describeContents();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean fetchUuidsWithSdp();
@@ -15802,7 +15802,7 @@
     ctor public Font.Builder(@NonNull android.os.ParcelFileDescriptor, @IntRange(from=0) long, @IntRange(from=0xffffffff) long);
     ctor public Font.Builder(@NonNull android.content.res.AssetManager, @NonNull String);
     ctor public Font.Builder(@NonNull android.content.res.Resources, int);
-    method @Nullable public android.graphics.fonts.Font build() throws java.io.IOException;
+    method @NonNull public android.graphics.fonts.Font build() throws java.io.IOException;
     method @NonNull public android.graphics.fonts.Font.Builder setFontVariationSettings(@Nullable String);
     method @NonNull public android.graphics.fonts.Font.Builder setFontVariationSettings(@Nullable android.graphics.fonts.FontVariationAxis[]);
     method @NonNull public android.graphics.fonts.Font.Builder setSlant(int);
@@ -15929,13 +15929,13 @@
 
   public static class LineBreaker.ParagraphConstraints {
     ctor public LineBreaker.ParagraphConstraints();
-    method @Px @IntRange(from=0) public int getDefaultTabStop();
+    method @Px @FloatRange(from=0) public float getDefaultTabStop();
     method @Px @FloatRange(from=0.0f) public float getFirstWidth();
     method @Px @IntRange(from=0) public int getFirstWidthLineCount();
-    method @Nullable public int[] getTabStops();
+    method @Nullable public float[] getTabStops();
     method @Px @FloatRange(from=0.0f) public float getWidth();
     method public void setIndent(@Px @FloatRange(from=0.0f) float, @Px @IntRange(from=0) int);
-    method public void setTabStops(@Nullable int[], @Px @IntRange(from=0) int);
+    method public void setTabStops(@Nullable float[], @Px @FloatRange(from=0) float);
     method public void setWidth(@Px @FloatRange(from=0.0f) float);
   }
 
@@ -22850,6 +22850,24 @@
     method @Deprecated public boolean usedInFix();
   }
 
+  @Deprecated public final class GpsStatus {
+    method @Deprecated public int getMaxSatellites();
+    method @Deprecated public Iterable<android.location.GpsSatellite> getSatellites();
+    method @Deprecated public int getTimeToFirstFix();
+    field @Deprecated public static final int GPS_EVENT_FIRST_FIX = 3; // 0x3
+    field @Deprecated public static final int GPS_EVENT_SATELLITE_STATUS = 4; // 0x4
+    field @Deprecated public static final int GPS_EVENT_STARTED = 1; // 0x1
+    field @Deprecated public static final int GPS_EVENT_STOPPED = 2; // 0x2
+  }
+
+  @Deprecated public static interface GpsStatus.Listener {
+    method @Deprecated public void onGpsStatusChanged(int);
+  }
+
+  @Deprecated public static interface GpsStatus.NmeaListener {
+    method @Deprecated public void onNmeaReceived(long, String);
+  }
+
   public class Location implements android.os.Parcelable {
     ctor public Location(String);
     ctor public Location(android.location.Location);
@@ -22918,6 +22936,7 @@
   }
 
   public class LocationManager {
+    method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean addGpsStatusListener(android.location.GpsStatus.Listener);
     method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean addNmeaListener(@NonNull android.location.OnNmeaMessageListener);
     method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean addNmeaListener(@NonNull android.location.OnNmeaMessageListener, @Nullable android.os.Handler);
     method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void addProximityAlert(double, double, float, long, @NonNull android.app.PendingIntent);
@@ -22929,6 +22948,7 @@
     method @Nullable public String getBestProvider(@NonNull android.location.Criteria, boolean);
     method @Nullable public String getGnssHardwareModelName();
     method public int getGnssYearOfHardware();
+    method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public android.location.GpsStatus getGpsStatus(@Nullable android.location.GpsStatus);
     method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) @Nullable public android.location.Location getLastKnownLocation(@NonNull String);
     method @Nullable public android.location.LocationProvider getProvider(@NonNull String);
     method @NonNull public java.util.List<java.lang.String> getProviders(boolean);
@@ -22941,6 +22961,7 @@
     method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssNavigationMessageCallback(@NonNull android.location.GnssNavigationMessage.Callback, @Nullable android.os.Handler);
     method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssStatusCallback(@NonNull android.location.GnssStatus.Callback);
     method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssStatusCallback(@NonNull android.location.GnssStatus.Callback, @Nullable android.os.Handler);
+    method @Deprecated public void removeGpsStatusListener(android.location.GpsStatus.Listener);
     method public void removeNmeaListener(@NonNull android.location.OnNmeaMessageListener);
     method @RequiresPermission(anyOf={"android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"}, apis="..22") public void removeProximityAlert(@NonNull android.app.PendingIntent);
     method public void removeTestProvider(@NonNull String);
@@ -24753,6 +24774,10 @@
 
   public final class MediaDrm implements java.lang.AutoCloseable {
     ctor public MediaDrm(@NonNull java.util.UUID) throws android.media.UnsupportedSchemeException;
+    method public void clearOnEventListener();
+    method public void clearOnExpirationUpdateListener();
+    method public void clearOnKeyStatusChangeListener();
+    method public void clearOnSessionLostStateListener();
     method public void close();
     method public void closeSession(@NonNull byte[]);
     method @android.media.MediaDrm.HdcpLevel public int getConnectedHdcpLevel();
@@ -24789,9 +24814,14 @@
     method public void removeSecureStop(@NonNull byte[]);
     method public void restoreKeys(@NonNull byte[], @NonNull byte[]);
     method public void setOnEventListener(@Nullable android.media.MediaDrm.OnEventListener);
+    method public void setOnEventListener(@Nullable android.media.MediaDrm.OnEventListener, @Nullable android.os.Handler);
+    method public void setOnEventListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.MediaDrm.OnEventListener);
     method public void setOnExpirationUpdateListener(@Nullable android.media.MediaDrm.OnExpirationUpdateListener, @Nullable android.os.Handler);
+    method public void setOnExpirationUpdateListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.MediaDrm.OnExpirationUpdateListener);
     method public void setOnKeyStatusChangeListener(@Nullable android.media.MediaDrm.OnKeyStatusChangeListener, @Nullable android.os.Handler);
+    method public void setOnKeyStatusChangeListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.MediaDrm.OnKeyStatusChangeListener);
     method public void setOnSessionLostStateListener(@Nullable android.media.MediaDrm.OnSessionLostStateListener, @Nullable android.os.Handler);
+    method public void setOnSessionLostStateListener(@NonNull java.util.concurrent.Executor, @Nullable android.media.MediaDrm.OnSessionLostStateListener);
     method public void setPropertyByteArray(@NonNull String, @NonNull byte[]);
     method public void setPropertyString(@NonNull String, @NonNull String);
     field @Deprecated public static final int EVENT_KEY_EXPIRED = 3; // 0x3
@@ -26412,7 +26442,7 @@
   public final class Session2Token implements android.os.Parcelable {
     ctor public Session2Token(@NonNull android.content.Context, @NonNull android.content.ComponentName);
     method public int describeContents();
-    method @Nullable public android.os.Bundle getExtras();
+    method @NonNull public android.os.Bundle getExtras();
     method @NonNull public String getPackageName();
     method @Nullable public String getServiceName();
     method public int getType();
@@ -38993,12 +39023,10 @@
     method public static long getLong(android.content.ContentResolver, String) throws android.provider.Settings.SettingNotFoundException;
     method public static String getString(android.content.ContentResolver, String);
     method public static android.net.Uri getUriFor(String);
-    method @Deprecated public static boolean isLocationProviderEnabled(android.content.ContentResolver, String);
     method public static boolean putFloat(android.content.ContentResolver, String, float);
     method public static boolean putInt(android.content.ContentResolver, String, int);
     method public static boolean putLong(android.content.ContentResolver, String, long);
     method public static boolean putString(android.content.ContentResolver, String, String);
-    method @Deprecated public static void setLocationProviderEnabled(android.content.ContentResolver, String, boolean);
     field public static final String ACCESSIBILITY_DISPLAY_INVERSION_ENABLED = "accessibility_display_inversion_enabled";
     field public static final String ACCESSIBILITY_ENABLED = "accessibility_enabled";
     field @Deprecated public static final String ACCESSIBILITY_SPEAK_PASSWORD = "speak_password";
@@ -45455,26 +45483,26 @@
   public static class ApnSetting.Builder {
     ctor public ApnSetting.Builder();
     method public android.telephony.data.ApnSetting build();
-    method public android.telephony.data.ApnSetting.Builder setApnName(String);
-    method public android.telephony.data.ApnSetting.Builder setApnTypeBitmask(int);
-    method public android.telephony.data.ApnSetting.Builder setAuthType(int);
-    method public android.telephony.data.ApnSetting.Builder setCarrierEnabled(boolean);
+    method @NonNull public android.telephony.data.ApnSetting.Builder setApnName(String);
+    method @NonNull public android.telephony.data.ApnSetting.Builder setApnTypeBitmask(int);
+    method @NonNull public android.telephony.data.ApnSetting.Builder setAuthType(int);
+    method @NonNull public android.telephony.data.ApnSetting.Builder setCarrierEnabled(boolean);
     method @NonNull public android.telephony.data.ApnSetting.Builder setCarrierId(int);
-    method public android.telephony.data.ApnSetting.Builder setEntryName(String);
+    method @NonNull public android.telephony.data.ApnSetting.Builder setEntryName(String);
     method @Deprecated public android.telephony.data.ApnSetting.Builder setMmsProxyAddress(java.net.InetAddress);
-    method public android.telephony.data.ApnSetting.Builder setMmsProxyAddress(String);
-    method public android.telephony.data.ApnSetting.Builder setMmsProxyPort(int);
-    method public android.telephony.data.ApnSetting.Builder setMmsc(android.net.Uri);
-    method public android.telephony.data.ApnSetting.Builder setMvnoType(int);
-    method public android.telephony.data.ApnSetting.Builder setNetworkTypeBitmask(int);
-    method public android.telephony.data.ApnSetting.Builder setOperatorNumeric(String);
-    method public android.telephony.data.ApnSetting.Builder setPassword(String);
-    method public android.telephony.data.ApnSetting.Builder setProtocol(int);
+    method @NonNull public android.telephony.data.ApnSetting.Builder setMmsProxyAddress(String);
+    method @NonNull public android.telephony.data.ApnSetting.Builder setMmsProxyPort(int);
+    method @NonNull public android.telephony.data.ApnSetting.Builder setMmsc(android.net.Uri);
+    method @NonNull public android.telephony.data.ApnSetting.Builder setMvnoType(int);
+    method @NonNull public android.telephony.data.ApnSetting.Builder setNetworkTypeBitmask(int);
+    method @NonNull public android.telephony.data.ApnSetting.Builder setOperatorNumeric(String);
+    method @NonNull public android.telephony.data.ApnSetting.Builder setPassword(String);
+    method @NonNull public android.telephony.data.ApnSetting.Builder setProtocol(int);
     method @Deprecated public android.telephony.data.ApnSetting.Builder setProxyAddress(java.net.InetAddress);
-    method public android.telephony.data.ApnSetting.Builder setProxyAddress(String);
-    method public android.telephony.data.ApnSetting.Builder setProxyPort(int);
-    method public android.telephony.data.ApnSetting.Builder setRoamingProtocol(int);
-    method public android.telephony.data.ApnSetting.Builder setUser(String);
+    method @NonNull public android.telephony.data.ApnSetting.Builder setProxyAddress(String);
+    method @NonNull public android.telephony.data.ApnSetting.Builder setProxyPort(int);
+    method @NonNull public android.telephony.data.ApnSetting.Builder setRoamingProtocol(int);
+    method @NonNull public android.telephony.data.ApnSetting.Builder setUser(String);
   }
 
 }
@@ -50346,6 +50374,7 @@
     method @IdRes public int getAccessibilityTraversalBefore();
     method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getAlpha();
     method public android.view.animation.Animation getAnimation();
+    method @Nullable public android.graphics.Matrix getAnimationMatrix();
     method public android.os.IBinder getApplicationWindowToken();
     method @NonNull public int[] getAttributeResolutionStack(@AttrRes int);
     method @NonNull public java.util.Map<java.lang.Integer,java.lang.Integer> getAttributeSourceResourceMap();
@@ -56385,10 +56414,12 @@
     method public int getWindowLayoutType();
     method public boolean isAboveAnchor();
     method public boolean isAttachedInDecor();
-    method public boolean isClipToScreenEnabled();
+    method @Deprecated public boolean isClipToScreenEnabled();
+    method public boolean isClippedToScreen();
     method public boolean isClippingEnabled();
     method public boolean isFocusable();
-    method public boolean isLayoutInScreenEnabled();
+    method public boolean isLaidOutInScreen();
+    method @Deprecated public boolean isLayoutInScreenEnabled();
     method public boolean isOutsideTouchable();
     method public boolean isShowing();
     method public boolean isSplitTouchEnabled();
@@ -56397,7 +56428,7 @@
     method public void setAnimationStyle(int);
     method public void setAttachedInDecor(boolean);
     method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
-    method public void setClipToScreenEnabled(boolean);
+    method @Deprecated public void setClipToScreenEnabled(boolean);
     method public void setClippingEnabled(boolean);
     method public void setContentView(android.view.View);
     method public void setElevation(float);
@@ -56408,7 +56439,9 @@
     method public void setHeight(int);
     method public void setIgnoreCheekPress();
     method public void setInputMethodMode(int);
-    method public void setLayoutInScreenEnabled(boolean);
+    method public void setIsClippedToScreen(boolean);
+    method public void setIsLaidOutInScreen(boolean);
+    method @Deprecated public void setLayoutInScreenEnabled(boolean);
     method public void setOnDismissListener(android.widget.PopupWindow.OnDismissListener);
     method public void setOutsideTouchable(boolean);
     method public void setOverlapAnchor(boolean);
diff --git a/api/removed.txt b/api/removed.txt
index 93d06928..5108dd0 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -282,24 +282,6 @@
 
 package android.location {
 
-  @Deprecated public final class GpsStatus {
-    method public int getMaxSatellites();
-    method public Iterable<android.location.GpsSatellite> getSatellites();
-    method public int getTimeToFirstFix();
-    field public static final int GPS_EVENT_FIRST_FIX = 3; // 0x3
-    field public static final int GPS_EVENT_SATELLITE_STATUS = 4; // 0x4
-    field public static final int GPS_EVENT_STARTED = 1; // 0x1
-    field public static final int GPS_EVENT_STOPPED = 2; // 0x2
-  }
-
-  @Deprecated public static interface GpsStatus.Listener {
-    method public void onGpsStatusChanged(int);
-  }
-
-  @Deprecated public static interface GpsStatus.NmeaListener {
-    method public void onNmeaReceived(long, String);
-  }
-
   public class Location implements android.os.Parcelable {
     method @Deprecated public void removeBearingAccuracy();
     method @Deprecated public void removeSpeedAccuracy();
@@ -307,10 +289,7 @@
   }
 
   public class LocationManager {
-    method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean addGpsStatusListener(android.location.GpsStatus.Listener);
     method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean addNmeaListener(android.location.GpsStatus.NmeaListener);
-    method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public android.location.GpsStatus getGpsStatus(@Nullable android.location.GpsStatus);
-    method @Deprecated public void removeGpsStatusListener(android.location.GpsStatus.Listener);
     method @Deprecated public void removeNmeaListener(android.location.GpsStatus.NmeaListener);
   }
 
@@ -574,6 +553,11 @@
     field @Deprecated public static final String CONTACT_METADATA_SYNC = "contact_metadata_sync";
   }
 
+  public static final class Settings.Secure extends android.provider.Settings.NameValueTable {
+    method @Deprecated public static boolean isLocationProviderEnabled(android.content.ContentResolver, String);
+    method @Deprecated public static void setLocationProviderEnabled(android.content.ContentResolver, String, boolean);
+  }
+
   public static final class Settings.System extends android.provider.Settings.NameValueTable {
     field public static final String APPEND_FOR_LAST_AUDIBLE = "_last_audible";
     field public static final String VOLUME_ALARM = "volume_alarm";
diff --git a/api/system-current.txt b/api/system-current.txt
index 03a3a55..c1979fd 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -680,7 +680,7 @@
     method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public boolean packageHasActiveAdmins(String);
     method @Deprecated @RequiresPermission("android.permission.MANAGE_DEVICE_ADMINS") public boolean setActiveProfileOwner(@NonNull android.content.ComponentName, String) throws java.lang.IllegalArgumentException;
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setDeviceProvisioningConfigApplied();
-    method @RequiresPermission(value=android.Manifest.permission.GRANT_PROFILE_OWNER_DEVICE_IDS_ACCESS, conditional=true) public void setProfileOwnerCanAccessDeviceIdsForUser(@NonNull android.content.ComponentName, @NonNull android.os.UserHandle);
+    method @RequiresPermission(value=android.Manifest.permission.GRANT_PROFILE_OWNER_DEVICE_IDS_ACCESS, conditional=true) public void setProfileOwnerCanAccessDeviceIds(@NonNull android.content.ComponentName);
     field public static final String ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_ALLOWED = "android.account.DEVICE_OR_PROFILE_OWNER_ALLOWED";
     field public static final String ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_DISALLOWED = "android.account.DEVICE_OR_PROFILE_OWNER_DISALLOWED";
     field public static final String ACTION_PROVISION_FINALIZATION = "android.app.action.PROVISION_FINALIZATION";
@@ -1198,7 +1198,7 @@
     method public int getUsageSource();
     method @RequiresPermission(allOf={android.Manifest.permission.SUSPEND_APPS, android.Manifest.permission.OBSERVE_APP_USAGE}) public void registerAppUsageLimitObserver(int, @NonNull String[], @NonNull java.time.Duration, @NonNull java.time.Duration, @Nullable android.app.PendingIntent);
     method @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE) public void registerAppUsageObserver(int, @NonNull String[], long, @NonNull java.util.concurrent.TimeUnit, @NonNull android.app.PendingIntent);
-    method @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE) public void registerUsageSessionObserver(int, @NonNull String[], long, @NonNull java.util.concurrent.TimeUnit, long, @NonNull java.util.concurrent.TimeUnit, @NonNull android.app.PendingIntent, @Nullable android.app.PendingIntent);
+    method @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE) public void registerUsageSessionObserver(int, @NonNull String[], @NonNull java.time.Duration, @NonNull java.time.Duration, @NonNull android.app.PendingIntent, @Nullable android.app.PendingIntent);
     method public void reportUsageStart(@NonNull android.app.Activity, @NonNull String);
     method public void reportUsageStart(@NonNull android.app.Activity, @NonNull String, long);
     method public void reportUsageStop(@NonNull android.app.Activity, @NonNull String);
@@ -3721,10 +3721,6 @@
 
 package android.media.session {
 
-  public static final class MediaController.PlaybackInfo implements android.os.Parcelable {
-    ctor public MediaController.PlaybackInfo(int, int, int, int, android.media.AudioAttributes);
-  }
-
   public final class MediaSessionManager {
     method @RequiresPermission(android.Manifest.permission.SET_MEDIA_KEY_LISTENER) public void setOnMediaKeyListener(android.media.session.MediaSessionManager.OnMediaKeyListener, @Nullable android.os.Handler);
     method @RequiresPermission(android.Manifest.permission.SET_VOLUME_KEY_LONG_PRESS_LISTENER) public void setOnVolumeKeyLongPressListener(android.media.session.MediaSessionManager.OnVolumeKeyLongPressListener, @Nullable android.os.Handler);
@@ -4069,7 +4065,7 @@
   }
 
   public static interface ConnectivityManager.OnTetheringEntitlementResultListener {
-    method public void onEntitlementResult(int);
+    method public void onTetheringEntitlementResult(int);
   }
 
   public abstract static class ConnectivityManager.OnTetheringEventCallback {
@@ -4746,7 +4742,7 @@
     method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void disable(int, @Nullable android.net.wifi.WifiManager.ActionListener);
     method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void forget(int, @Nullable android.net.wifi.WifiManager.ActionListener);
     method @NonNull @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.List<android.util.Pair<android.net.wifi.WifiConfiguration,java.util.Map<java.lang.Integer,java.util.List<android.net.wifi.ScanResult>>>> getAllMatchingWifiConfigs(@NonNull java.util.List<android.net.wifi.ScanResult>);
-    method @NonNull @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.Map<android.net.wifi.hotspot2.OsuProvider,java.util.List<android.net.wifi.ScanResult>> getMatchingOsuProviders(java.util.List<android.net.wifi.ScanResult>);
+    method @NonNull @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.Map<android.net.wifi.hotspot2.OsuProvider,java.util.List<android.net.wifi.ScanResult>> getMatchingOsuProviders(@Nullable java.util.List<android.net.wifi.ScanResult>);
     method @NonNull @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.Map<android.net.wifi.hotspot2.OsuProvider,android.net.wifi.hotspot2.PasspointConfiguration> getMatchingPasspointConfigsForOsuProviders(@NonNull java.util.Set<android.net.wifi.hotspot2.OsuProvider>);
     method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE, android.Manifest.permission.READ_WIFI_CREDENTIAL}) public java.util.List<android.net.wifi.WifiConfiguration> getPrivilegedConfiguredNetworks();
     method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public android.net.wifi.WifiConfiguration getWifiApConfiguration();
@@ -5850,23 +5846,25 @@
   public final class DeviceConfig {
     method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static void addOnPropertiesChangedListener(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.provider.DeviceConfig.OnPropertiesChangedListener);
     method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static void addOnPropertyChangedListener(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.provider.DeviceConfig.OnPropertyChangedListener);
-    method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static boolean getBoolean(String, String, boolean);
-    method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static float getFloat(String, String, float);
-    method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static int getInt(String, String, int);
-    method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static long getLong(String, String, long);
-    method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static String getProperty(String, String);
-    method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static String getString(String, String, String);
+    method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static boolean getBoolean(@NonNull String, @NonNull String, boolean);
+    method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static float getFloat(@NonNull String, @NonNull String, float);
+    method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static int getInt(@NonNull String, @NonNull String, int);
+    method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static long getLong(@NonNull String, @NonNull String, long);
+    method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static String getProperty(@NonNull String, @NonNull String);
+    method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static String getString(@NonNull String, @NonNull String, @Nullable String);
     method public static void removeOnPropertiesChangedListener(@NonNull android.provider.DeviceConfig.OnPropertiesChangedListener);
     method public static void removeOnPropertyChangedListener(@NonNull android.provider.DeviceConfig.OnPropertyChangedListener);
     method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static void resetToDefaults(int, @Nullable String);
-    method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static boolean setProperty(String, String, String, boolean);
+    method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static boolean setProperty(@NonNull String, @NonNull String, @Nullable String, boolean);
     field public static final String NAMESPACE_ACTIVITY_MANAGER = "activity_manager";
     field public static final String NAMESPACE_ACTIVITY_MANAGER_NATIVE_BOOT = "activity_manager_native_boot";
     field public static final String NAMESPACE_AUTOFILL = "autofill";
     field public static final String NAMESPACE_CONNECTIVITY = "connectivity";
     field public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture";
+    field public static final String NAMESPACE_DEX_BOOT = "dex_boot";
     field public static final String NAMESPACE_GAME_DRIVER = "game_driver";
     field public static final String NAMESPACE_INPUT_NATIVE_BOOT = "input_native_boot";
+    field public static final String NAMESPACE_INTELLIGENCE_ATTENTION = "intelligence_attention";
     field public static final String NAMESPACE_MEDIA_NATIVE = "media_native";
     field public static final String NAMESPACE_NETD_NATIVE = "netd_native";
     field public static final String NAMESPACE_RUNTIME_NATIVE_BOOT = "runtime_native_boot";
@@ -5880,24 +5878,12 @@
     field public static final String SERVICE_ENABLED = "service_enabled";
   }
 
-  public static interface DeviceConfig.DexBoot {
-    field public static final String NAMESPACE = "dex_boot";
-    field public static final String PRIV_APPS_OOB_ENABLED = "priv_apps_oob_enabled";
-    field public static final String PRIV_APPS_OOB_WHITELIST = "priv_apps_oob_whitelist";
-  }
-
-  public static interface DeviceConfig.IntelligenceAttention {
-    field public static final String ATTENTION_ENABLED = "attention_enabled";
-    field public static final String ATTENTION_SETTINGS = "attention_settings";
-    field public static final String NAMESPACE = "intelligence_attention";
-  }
-
   public static interface DeviceConfig.OnPropertiesChangedListener {
     method public void onPropertiesChanged(@NonNull android.provider.DeviceConfig.Properties);
   }
 
   public static interface DeviceConfig.OnPropertyChangedListener {
-    method public void onPropertyChanged(String, String, String);
+    method public void onPropertyChanged(@NonNull String, @NonNull String, @Nullable String);
   }
 
   public static interface DeviceConfig.Privacy {
@@ -6142,7 +6128,6 @@
     field public static final String LOCATION_PERMISSIONS_UPGRADE_TO_Q_MODE = "location_permissions_upgrade_to_q_mode";
     field public static final String LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS = "lock_screen_allow_private_notifications";
     field public static final String LOCK_SCREEN_SHOW_NOTIFICATIONS = "lock_screen_show_notifications";
-    field public static final String MANUAL_RINGER_TOGGLE_COUNT = "manual_ringer_toggle_count";
     field public static final String THEME_CUSTOMIZATION_OVERLAY_PACKAGES = "theme_customization_overlay_packages";
     field public static final String USER_SETUP_COMPLETE = "user_setup_complete";
     field public static final int USER_SETUP_PERSONALIZATION_COMPLETE = 10; // 0xa
@@ -6151,6 +6136,9 @@
     field public static final int USER_SETUP_PERSONALIZATION_STARTED = 1; // 0x1
     field public static final String USER_SETUP_PERSONALIZATION_STATE = "user_setup_personalization_state";
     field public static final String VOLUME_HUSH_GESTURE = "volume_hush_gesture";
+    field public static final int VOLUME_HUSH_MUTE = 2; // 0x2
+    field public static final int VOLUME_HUSH_OFF = 0; // 0x0
+    field public static final int VOLUME_HUSH_VIBRATE = 1; // 0x1
   }
 
   public static final class Telephony.Carriers implements android.provider.BaseColumns {
@@ -6346,7 +6334,7 @@
 
   public abstract class AttentionService extends android.app.Service {
     ctor public AttentionService();
-    method public final android.os.IBinder onBind(android.content.Intent);
+    method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent);
     method public abstract void onCancelAttentionCheck(int);
     method public abstract void onCheckAttention(int, @NonNull android.service.attention.AttentionService.AttentionCallback);
     field public static final int ATTENTION_FAILURE_PREEMPTED = 2; // 0x2
@@ -8067,6 +8055,10 @@
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoiceActivationState();
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handlePinMmi(String);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handlePinMmiForSubscriber(int, String);
+    method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean iccCloseLogicalChannelBySlot(int, int);
+    method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannelBySlot(int, @Nullable String, int);
+    method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduBasicChannelBySlot(int, int, int, int, int, int, @Nullable String);
+    method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduLogicalChannelBySlot(int, int, int, int, int, int, int, @Nullable String);
     method public boolean isDataConnectivityPossible();
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isIdle();
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isOffhook();
@@ -8102,7 +8094,7 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean switchSlots(int[]);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void toggleRadioOnOff();
     method public void updateServiceLocation();
-    field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final String ACTION_DEBUG_EVENT = "android.telephony.action.DEBUG_EVENT";
+    field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final String ACTION_ANOMALY_REPORTED = "android.telephony.action.ANOMALY_REPORTED";
     field public static final String ACTION_SIM_APPLICATION_STATE_CHANGED = "android.telephony.action.SIM_APPLICATION_STATE_CHANGED";
     field public static final String ACTION_SIM_CARD_STATE_CHANGED = "android.telephony.action.SIM_CARD_STATE_CHANGED";
     field public static final String ACTION_SIM_SLOT_STATUS_CHANGED = "android.telephony.action.SIM_SLOT_STATUS_CHANGED";
@@ -8110,8 +8102,8 @@
     field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1
     field public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; // 0x0
     field public static final int CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED = -1; // 0xffffffff
-    field public static final String EXTRA_DEBUG_EVENT_DESCRIPTION = "android.telephony.extra.DEBUG_EVENT_DESCRIPTION";
-    field public static final String EXTRA_DEBUG_EVENT_ID = "android.telephony.extra.DEBUG_EVENT_ID";
+    field public static final String EXTRA_ANOMALY_DESCRIPTION = "android.telephony.extra.ANOMALY_DESCRIPTION";
+    field public static final String EXTRA_ANOMALY_ID = "android.telephony.extra.ANOMALY_ID";
     field public static final String EXTRA_SIM_STATE = "android.telephony.extra.SIM_STATE";
     field public static final String EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL = "android.telephony.extra.VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL";
     field public static final String EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING = "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING";
@@ -9540,6 +9532,7 @@
     method public int getTaskId();
     field public static final int FLAG_DISABLED_BY_APP = 1; // 0x1
     field public static final int FLAG_DISABLED_BY_FLAG_SECURE = 2; // 0x2
+    field public static final int FLAG_RECONNECTED = 4; // 0x4
   }
 
   public final class ContentCaptureEvent implements android.os.Parcelable {
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 18d0ec0..2c65029 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -28,6 +28,14 @@
 
 }
 
+package android.app.usage {
+
+  public final class UsageStatsManager {
+    method @Deprecated @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE) public void registerUsageSessionObserver(int, @NonNull String[], long, @NonNull java.util.concurrent.TimeUnit, long, @NonNull java.util.concurrent.TimeUnit, @NonNull android.app.PendingIntent, @Nullable android.app.PendingIntent);
+  }
+
+}
+
 package android.content {
 
   public class Intent implements java.lang.Cloneable android.os.Parcelable {
diff --git a/api/test-current.txt b/api/test-current.txt
index 2913743..af93d17 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -599,6 +599,7 @@
     method public void setAutofillOptions(@Nullable android.content.AutofillOptions);
     method public void setContentCaptureOptions(@Nullable android.content.ContentCaptureOptions);
     field public static final String ROLLBACK_SERVICE = "rollback";
+    field public static final String TEST_NETWORK_SERVICE = "test_network";
   }
 
   public class ContextWrapper extends android.content.Context {
@@ -2055,16 +2056,16 @@
   public final class DeviceConfig {
     method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static void addOnPropertiesChangedListener(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.provider.DeviceConfig.OnPropertiesChangedListener);
     method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static void addOnPropertyChangedListener(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.provider.DeviceConfig.OnPropertyChangedListener);
-    method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static boolean getBoolean(String, String, boolean);
-    method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static float getFloat(String, String, float);
-    method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static int getInt(String, String, int);
-    method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static long getLong(String, String, long);
-    method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static String getProperty(String, String);
-    method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static String getString(String, String, String);
+    method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static boolean getBoolean(@NonNull String, @NonNull String, boolean);
+    method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static float getFloat(@NonNull String, @NonNull String, float);
+    method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static int getInt(@NonNull String, @NonNull String, int);
+    method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static long getLong(@NonNull String, @NonNull String, long);
+    method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static String getProperty(@NonNull String, @NonNull String);
+    method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static String getString(@NonNull String, @NonNull String, @Nullable String);
     method public static void removeOnPropertiesChangedListener(@NonNull android.provider.DeviceConfig.OnPropertiesChangedListener);
     method public static void removeOnPropertyChangedListener(@NonNull android.provider.DeviceConfig.OnPropertyChangedListener);
     method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static void resetToDefaults(int, @Nullable String);
-    method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static boolean setProperty(String, String, String, boolean);
+    method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static boolean setProperty(@NonNull String, @NonNull String, @Nullable String, boolean);
     field public static final String NAMESPACE_AUTOFILL = "autofill";
     field public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture";
   }
@@ -2074,7 +2075,7 @@
   }
 
   public static interface DeviceConfig.OnPropertyChangedListener {
-    method public void onPropertyChanged(String, String, String);
+    method public void onPropertyChanged(@NonNull String, @NonNull String, @Nullable String);
   }
 
   public static interface DeviceConfig.Privacy {
@@ -3055,6 +3056,7 @@
     method public int getTaskId();
     field public static final int FLAG_DISABLED_BY_APP = 1; // 0x1
     field public static final int FLAG_DISABLED_BY_FLAG_SECURE = 2; // 0x2
+    field public static final int FLAG_RECONNECTED = 4; // 0x4
   }
 
   public final class ContentCaptureEvent implements android.os.Parcelable {
diff --git a/cmds/bootanimation/bootanim.rc b/cmds/bootanimation/bootanim.rc
index 3666d6a..469c964 100644
--- a/cmds/bootanimation/bootanim.rc
+++ b/cmds/bootanimation/bootanim.rc
@@ -2,9 +2,6 @@
     class core animation
     user graphics
     group graphics audio
-    # bootanimation depends on libandroidicu in the Runtime APEX.
-    # TODO(b/124939955): Remove this dependency on libandroidicu
-    updatable
     disabled
     oneshot
     writepid /dev/stune/top-app/tasks
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index 7298da6..ce07d6d 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -219,6 +219,7 @@
         "tests/anomaly/AnomalyTracker_test.cpp",
         "tests/ConfigManager_test.cpp",
         "tests/external/puller_util_test.cpp",
+        "tests/external/GpuStatsPuller_test.cpp",
         "tests/external/IncidentReportArgs_test.cpp",
         "tests/external/StatsPuller_test.cpp",
         "tests/indexed_priority_queue_test.cpp",
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 4856f77..3246d19 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -253,7 +253,7 @@
     }
 
     // Pulled events will start at field 10000.
-    // Next: 10056
+    // Next: 10057
     oneof pulled {
         WifiBytesTransfer wifi_bytes_transfer = 10000;
         WifiBytesTransferByFgBg wifi_bytes_transfer_by_fg_bg = 10001;
@@ -311,6 +311,7 @@
         SDCardInfo sdcard_info = 10053;
         GpuStatsGlobalInfo gpu_stats_global_info = 10054;
         GpuStatsAppInfo gpu_stats_app_info = 10055;
+        SystemIonHeapSize system_ion_heap_size = 10056;
     }
 
     // DO NOT USE field numbers above 100,000 in AOSP.
@@ -5759,7 +5760,7 @@
     optional string tzdb_version = 1;
 }
 
-/*
+/**
  * Logs the GPU stats global health information.
  *
  * Logged from:
@@ -5791,22 +5792,44 @@
     optional int64 vk_loading_failure_count = 8;
 }
 
-/*
+/**
+ * GPU driver loading time info.
+ */
+message GpuDriverLoadingTime {
+    // List of all the driver loading times for this app. The list size is
+    // capped at 50.
+    repeated int64 driver_loading_time = 1;
+}
+
+/**
  * Logs the GPU stats per app health information.
  *
  * Logged from:
  *   frameworks/native/services/gpuservice/gpustats/
  */
 message GpuStatsAppInfo {
-    // Package name of the application that loads the gpu driver.
+    // Package name of the application that loads the gpu driver. Total number
+    // of different packages is capped at 100.
     optional string app_package_name = 1;
 
     // Version code of the gpu driver this app loads.
     optional int64 driver_version_code = 2;
 
-    // List of all the gl driver loading times for this app.
-    repeated int64 gl_driver_loading_time = 3;
+    // gl driver loading time info.
+    optional GpuDriverLoadingTime gl_driver_loading_time = 3
+            [(android.os.statsd.log_mode) = MODE_BYTES];
 
-    // List of all the Vulkan driver laoding times for this app.
-    repeated int64 vk_driver_loading_time = 4;
+    // Vulkan driver loading time info.
+    optional GpuDriverLoadingTime vk_driver_loading_time = 4
+            [(android.os.statsd.log_mode) = MODE_BYTES];
+}
+
+/*
+ * Logs the size of the system ion heap.
+ *
+ * Pulled from StatsCompanionService.
+ */
+message SystemIonHeapSize {
+    // Size of the system ion heap in bytes.
+    optional int64 size_in_bytes = 1;
 }
diff --git a/cmds/statsd/src/external/GpuStatsPuller.cpp b/cmds/statsd/src/external/GpuStatsPuller.cpp
index 8445803..130bd85 100644
--- a/cmds/statsd/src/external/GpuStatsPuller.cpp
+++ b/cmds/statsd/src/external/GpuStatsPuller.cpp
@@ -70,6 +70,30 @@
     return true;
 }
 
+static bool pullGpuStatsAppInfo(const sp<IGpuService>& gpuService,
+                                std::vector<std::shared_ptr<LogEvent>>* data) {
+    std::vector<GpuStatsAppInfo> stats;
+    status_t status = gpuService->getGpuStatsAppInfo(&stats);
+    if (status != OK) {
+        return false;
+    }
+
+    data->clear();
+    data->reserve(stats.size());
+    for (const auto& info : stats) {
+        std::shared_ptr<LogEvent> event = make_shared<LogEvent>(
+                android::util::GPU_STATS_APP_INFO, getWallClockNs(), getElapsedRealtimeNs());
+        if (!event->write(info.appPackageName)) return false;
+        if (!event->write((int64_t)info.driverVersionCode)) return false;
+        if (!event->write(int64VectorToProtoByteString(info.glDriverLoadingTime))) return false;
+        if (!event->write(int64VectorToProtoByteString(info.vkDriverLoadingTime))) return false;
+        event->init();
+        data->emplace_back(event);
+    }
+
+    return true;
+}
+
 bool GpuStatsPuller::PullInternal(std::vector<std::shared_ptr<LogEvent>>* data) {
     const sp<IGpuService> gpuService = getGpuService();
     if (!gpuService) {
@@ -79,6 +103,8 @@
     switch (mTagId) {
         case android::util::GPU_STATS_GLOBAL_INFO:
             return pullGpuStatsGlobalInfo(gpuService, data);
+        case android::util::GPU_STATS_APP_INFO:
+            return pullGpuStatsAppInfo(gpuService, data);
         default:
             break;
     }
@@ -86,6 +112,35 @@
     return false;
 }
 
+static std::string protoOutputStreamToByteString(ProtoOutputStream& proto) {
+    if (!proto.size()) return "";
+
+    std::string byteString;
+    auto iter = proto.data();
+    while (iter.readBuffer() != nullptr) {
+        const size_t toRead = iter.currentToRead();
+        byteString.append((char*)iter.readBuffer(), toRead);
+        iter.rp()->move(toRead);
+    }
+
+    if (byteString.size() != proto.size()) return "";
+
+    return byteString;
+}
+
+std::string int64VectorToProtoByteString(const std::vector<int64_t>& value) {
+    if (value.empty()) return "";
+
+    ProtoOutputStream proto;
+    for (const auto& ele : value) {
+        proto.write(android::util::FIELD_TYPE_INT64 | android::util::FIELD_COUNT_REPEATED |
+                            1 /* field id */,
+                    (long long)ele);
+    }
+
+    return protoOutputStreamToByteString(proto);
+}
+
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/cmds/statsd/src/external/GpuStatsPuller.h b/cmds/statsd/src/external/GpuStatsPuller.h
index 4c7a4d6..2da199c 100644
--- a/cmds/statsd/src/external/GpuStatsPuller.h
+++ b/cmds/statsd/src/external/GpuStatsPuller.h
@@ -31,6 +31,12 @@
     bool PullInternal(std::vector<std::shared_ptr<LogEvent>>* data) override;
 };
 
+// convert a int64_t vector into a byte string for proto message like:
+// message RepeatedInt64Wrapper {
+//   repeated int64 value = 1;
+// }
+std::string int64VectorToProtoByteString(const std::vector<int64_t>& value);
+
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index 924704b..c7ae656 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -148,10 +148,14 @@
         {android::util::NATIVE_PROCESS_MEMORY_STATE,
          {.additiveFields = {3, 4, 5, 6},
           .puller = new StatsCompanionServicePuller(android::util::NATIVE_PROCESS_MEMORY_STATE)}},
+        // process_memory_high_water_mark
         {android::util::PROCESS_MEMORY_HIGH_WATER_MARK,
          {.additiveFields = {3},
           .puller =
                   new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_HIGH_WATER_MARK)}},
+        // system_ion_heap_size
+        {android::util::SYSTEM_ION_HEAP_SIZE,
+         {.puller = new StatsCompanionServicePuller(android::util::SYSTEM_ION_HEAP_SIZE)}},
         // temperature
         {android::util::TEMPERATURE,
          {.puller = new StatsCompanionServicePuller(android::util::TEMPERATURE)}},
@@ -244,6 +248,9 @@
         // GpuStatsGlobalInfo
         {android::util::GPU_STATS_GLOBAL_INFO,
          {.puller = new GpuStatsPuller(android::util::GPU_STATS_GLOBAL_INFO)}},
+        // GpuStatsAppInfo
+        {android::util::GPU_STATS_APP_INFO,
+         {.puller = new GpuStatsPuller(android::util::GPU_STATS_APP_INFO)}},
 };
 
 StatsPullerManager::StatsPullerManager() : mNextPullTimeNs(NO_ALARM_UPDATE) {
diff --git a/cmds/statsd/src/storage/StorageManager.cpp b/cmds/statsd/src/storage/StorageManager.cpp
index 5df8fb5..65b183c 100644
--- a/cmds/statsd/src/storage/StorageManager.cpp
+++ b/cmds/statsd/src/storage/StorageManager.cpp
@@ -116,14 +116,16 @@
     const size_t trainNameSizeByteCount = sizeof(trainNameSize);
     result = write(fd, (uint8_t*)&trainNameSize, trainNameSizeByteCount);
     if (result != trainNameSizeByteCount) {
-        VLOG("Failed to write %s", file_name.c_str());
+        VLOG("Failed to write train name size for %s", file_name.c_str());
+        close(fd);
         return false;
     }
 
     // Write trainName to file
     result = write(fd, trainName.c_str(), trainNameSize);
     if (result != trainNameSize) {
-        VLOG("Failed to write %s", file_name.c_str());
+        VLOG("Failed to write train name for%s", file_name.c_str());
+        close(fd);
         return false;
     }
 
@@ -131,7 +133,18 @@
     const size_t statusByteCount = sizeof(status);
     result = write(fd, (uint8_t*)&status, statusByteCount);
     if (result != statusByteCount) {
-        VLOG("Failed to write %s", file_name.c_str());
+        VLOG("Failed to write status for %s", file_name.c_str());
+        close(fd);
+        return false;
+    }
+
+    // Write experiment id size to file.
+    const size_t experimentIdSize = experimentIds.size();
+    const size_t experimentIdsSizeByteCount = sizeof(experimentIdSize);
+    result = write(fd, (uint8_t*) &experimentIdSize, experimentIdsSizeByteCount);
+    if (result != experimentIdsSizeByteCount) {
+        VLOG("Failed to write experiment id size for %s", file_name.c_str());
+        close(fd);
         return false;
     }
 
@@ -140,13 +153,15 @@
     if (result == experimentIds.size()) {
         VLOG("Successfully wrote %s", file_name.c_str());
     } else {
-        VLOG("Failed to write %s", file_name.c_str());
+        VLOG("Failed to write experiment ids for %s", file_name.c_str());
+        close(fd);
         return false;
     }
 
     result = fchown(fd, AID_STATSD, AID_STATSD);
     if (result) {
         VLOG("Failed to chown %s to statsd", file_name.c_str());
+        close(fd);
         return false;
     }
 
@@ -170,39 +185,73 @@
         if (name[0] == '.') {
             continue;
         }
+
+        size_t result;
+
         trainInfo.trainVersionCode = StrToInt64(name);
         string fullPath = StringPrintf("%s/%s", TRAIN_INFO_DIR, name);
         int fd = open(fullPath.c_str(), O_RDONLY | O_CLOEXEC);
-        if (fd != -1) {
-            string str;
-            if (android::base::ReadFdToString(fd, &str)) {
-                close(fd);
-
-                auto it = str.begin();
-
-                // Read # of bytes taken by trainName in the file
-                size_t trainNameSize;
-                const size_t trainNameSizeByteCount = sizeof(trainNameSize);
-                std::copy_n(it, trainNameSizeByteCount, &trainNameSize);
-                it += trainNameSizeByteCount;
-
-                // Read trainName
-                std::copy_n(it, trainNameSize, std::back_inserter(trainInfo.trainName));
-                it += trainNameSize;
-
-                // Read status
-                const size_t statusByteCount = sizeof(trainInfo.status);
-                std::copy_n(it, statusByteCount, &trainInfo.status);
-                it += statusByteCount;
-
-                // Read experimentIds
-                std::copy(it, str.end(), std::back_inserter(trainInfo.experimentIds));
-
-                VLOG("Read train info file successful: %s", fullPath.c_str());
-                return true;
-            }
+        if (fd == -1) {
+            return false;
         }
+
+        // Read # of bytes taken by trainName in the file.
+        size_t trainNameSize;
+        result = read(fd, &trainNameSize, sizeof(size_t));
+        if (result != sizeof(size_t)) {
+            VLOG("Failed to read train name size from file %s", fullPath.c_str());
+            close(fd);
+            return false;
+        }
+
+        // Read trainName
+        trainInfo.trainName.resize(trainNameSize);
+        result = read(fd, trainInfo.trainName.data(), trainNameSize);
+        if (result != trainNameSize) {
+            VLOG("Failed to read train name from file %s", fullPath.c_str());
+            close(fd);
+            return false;
+        }
+
+        // Read status
+        const size_t statusByteCount = sizeof(trainInfo.status);
+        result = read(fd, &trainInfo.status, statusByteCount);
+        if (result != statusByteCount) {
+            VLOG("Failed to read train status from file %s", fullPath.c_str());
+            close(fd);
+            return false;
+        }
+
+        // Read experiment ids size.
+        size_t experimentIdSize;
+        result = read(fd, &experimentIdSize, sizeof(size_t));
+        if (result != sizeof(size_t)) {
+            VLOG("Failed to read train experiment id size from file %s", fullPath.c_str());
+            close(fd);
+            return false;
+        }
+
+        // Read experimentIds
+        trainInfo.experimentIds.resize(experimentIdSize);
+        result = read(fd, trainInfo.experimentIds.data(), experimentIdSize);
+        if (result != experimentIdSize) {
+            VLOG("Failed to read train experiment ids from file %s", fullPath.c_str());
+            close(fd);
+            return false;
+        }
+
+        // Expect to be at EOF.
+        char c;
+        result = read(fd, &c, 1);
+        if (result != 0) {
+            VLOG("Failed to read train info from file %s. Did not get expected EOF.", fullPath.c_str());
+            close(fd);
+            return false;
+        }
+
+        VLOG("Read train info file successful: %s", fullPath.c_str());
         close(fd);
+        return true;
     }
     return false;
 }
diff --git a/cmds/statsd/tests/external/GpuStatsPuller_test.cpp b/cmds/statsd/tests/external/GpuStatsPuller_test.cpp
new file mode 100644
index 0000000..8625487
--- /dev/null
+++ b/cmds/statsd/tests/external/GpuStatsPuller_test.cpp
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2019 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.
+ */
+
+#undef LOG_TAG
+#define LOG_TAG "GpuStatsPuller_test"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <graphicsenv/GpuStatsInfo.h>
+#include <log/log.h>
+
+#include "src/external/GpuStatsPuller.h"
+
+#ifdef __ANDROID__
+
+namespace android {
+namespace os {
+namespace statsd {
+
+// clang-format off
+static const std::string DRIVER_PACKAGE_NAME    = "TEST_DRIVER";
+static const std::string DRIVER_VERSION_NAME    = "TEST_DRIVER_VERSION";
+static const std::string APP_PACKAGE_NAME       = "TEST_APP";
+static const int64_t TIMESTAMP_WALLCLOCK        = 111;
+static const int64_t TIMESTAMP_ELAPSED          = 222;
+static const int64_t DRIVER_VERSION_CODE        = 333;
+static const int64_t DRIVER_BUILD_TIME          = 444;
+static const int64_t GL_LOADING_COUNT           = 3;
+static const int64_t GL_LOADING_FAILURE_COUNT   = 1;
+static const int64_t VK_LOADING_COUNT           = 4;
+static const int64_t VK_LOADING_FAILURE_COUNT   = 0;
+static const int64_t GL_DRIVER_LOADING_TIME_0   = 555;
+static const int64_t GL_DRIVER_LOADING_TIME_1   = 666;
+static const int64_t VK_DRIVER_LOADING_TIME_0   = 777;
+static const int64_t VK_DRIVER_LOADING_TIME_1   = 888;
+static const int64_t VK_DRIVER_LOADING_TIME_2   = 999;
+static const size_t NUMBER_OF_VALUES_GLOBAL     = 8;
+static const size_t NUMBER_OF_VALUES_APP        = 4;
+// clang-format on
+
+class MockGpuStatsPuller : public GpuStatsPuller {
+public:
+    MockGpuStatsPuller(const int tagId, vector<std::shared_ptr<LogEvent>>* data)
+        : GpuStatsPuller(tagId), mData(data){};
+
+private:
+    bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override {
+        *data = *mData;
+        return true;
+    }
+
+    vector<std::shared_ptr<LogEvent>>* mData;
+};
+
+class GpuStatsPuller_test : public ::testing::Test {
+public:
+    GpuStatsPuller_test() {
+        const ::testing::TestInfo* const test_info =
+                ::testing::UnitTest::GetInstance()->current_test_info();
+        ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
+    }
+
+    ~GpuStatsPuller_test() {
+        const ::testing::TestInfo* const test_info =
+                ::testing::UnitTest::GetInstance()->current_test_info();
+        ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
+    }
+};
+
+TEST_F(GpuStatsPuller_test, PullGpuStatsGlobalInfo) {
+    vector<std::shared_ptr<LogEvent>> inData, outData;
+    std::shared_ptr<LogEvent> event = make_shared<LogEvent>(android::util::GPU_STATS_GLOBAL_INFO,
+                                                            TIMESTAMP_WALLCLOCK, TIMESTAMP_ELAPSED);
+    EXPECT_TRUE(event->write(DRIVER_PACKAGE_NAME));
+    EXPECT_TRUE(event->write(DRIVER_VERSION_NAME));
+    EXPECT_TRUE(event->write(DRIVER_VERSION_CODE));
+    EXPECT_TRUE(event->write(DRIVER_BUILD_TIME));
+    EXPECT_TRUE(event->write(GL_LOADING_COUNT));
+    EXPECT_TRUE(event->write(GL_LOADING_FAILURE_COUNT));
+    EXPECT_TRUE(event->write(VK_LOADING_COUNT));
+    EXPECT_TRUE(event->write(VK_LOADING_FAILURE_COUNT));
+    event->init();
+    inData.emplace_back(event);
+    MockGpuStatsPuller mockPuller(android::util::GPU_STATS_GLOBAL_INFO, &inData);
+    mockPuller.ForceClearCache();
+    mockPuller.Pull(&outData);
+
+    ASSERT_EQ(1, outData.size());
+    EXPECT_EQ(android::util::GPU_STATS_GLOBAL_INFO, outData[0]->GetTagId());
+    ASSERT_EQ(NUMBER_OF_VALUES_GLOBAL, outData[0]->size());
+    EXPECT_EQ(DRIVER_PACKAGE_NAME, outData[0]->getValues()[0].mValue.str_value);
+    EXPECT_EQ(DRIVER_VERSION_NAME, outData[0]->getValues()[1].mValue.str_value);
+    EXPECT_EQ(DRIVER_VERSION_CODE, outData[0]->getValues()[2].mValue.long_value);
+    EXPECT_EQ(DRIVER_BUILD_TIME, outData[0]->getValues()[3].mValue.long_value);
+    EXPECT_EQ(GL_LOADING_COUNT, outData[0]->getValues()[4].mValue.long_value);
+    EXPECT_EQ(GL_LOADING_FAILURE_COUNT, outData[0]->getValues()[5].mValue.long_value);
+    EXPECT_EQ(VK_LOADING_COUNT, outData[0]->getValues()[6].mValue.long_value);
+    EXPECT_EQ(VK_LOADING_FAILURE_COUNT, outData[0]->getValues()[7].mValue.long_value);
+}
+
+TEST_F(GpuStatsPuller_test, PullGpuStatsAppInfo) {
+    vector<std::shared_ptr<LogEvent>> inData, outData;
+    std::shared_ptr<LogEvent> event = make_shared<LogEvent>(android::util::GPU_STATS_APP_INFO,
+                                                            TIMESTAMP_WALLCLOCK, TIMESTAMP_ELAPSED);
+    EXPECT_TRUE(event->write(APP_PACKAGE_NAME));
+    EXPECT_TRUE(event->write(DRIVER_VERSION_CODE));
+    std::vector<int64_t> glDriverLoadingTime;
+    glDriverLoadingTime.emplace_back(GL_DRIVER_LOADING_TIME_0);
+    glDriverLoadingTime.emplace_back(GL_DRIVER_LOADING_TIME_1);
+    std::vector<int64_t> vkDriverLoadingTime;
+    vkDriverLoadingTime.emplace_back(VK_DRIVER_LOADING_TIME_0);
+    vkDriverLoadingTime.emplace_back(VK_DRIVER_LOADING_TIME_1);
+    vkDriverLoadingTime.emplace_back(VK_DRIVER_LOADING_TIME_2);
+    EXPECT_TRUE(event->write(int64VectorToProtoByteString(glDriverLoadingTime)));
+    EXPECT_TRUE(event->write(int64VectorToProtoByteString(vkDriverLoadingTime)));
+    event->init();
+    inData.emplace_back(event);
+    MockGpuStatsPuller mockPuller(android::util::GPU_STATS_APP_INFO, &inData);
+    mockPuller.ForceClearCache();
+    mockPuller.Pull(&outData);
+
+    ASSERT_EQ(1, outData.size());
+    EXPECT_EQ(android::util::GPU_STATS_APP_INFO, outData[0]->GetTagId());
+    ASSERT_EQ(NUMBER_OF_VALUES_APP, outData[0]->size());
+    EXPECT_EQ(APP_PACKAGE_NAME, outData[0]->getValues()[0].mValue.str_value);
+    EXPECT_EQ(DRIVER_VERSION_CODE, outData[0]->getValues()[1].mValue.long_value);
+    EXPECT_EQ(int64VectorToProtoByteString(glDriverLoadingTime),
+              outData[0]->getValues()[2].mValue.str_value);
+    EXPECT_EQ(int64VectorToProtoByteString(vkDriverLoadingTime),
+              outData[0]->getValues()[3].mValue.str_value);
+}
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
+#else
+GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt
index ff8dec1..c6a3d80 100644
--- a/config/hiddenapi-greylist.txt
+++ b/config/hiddenapi-greylist.txt
@@ -1756,48 +1756,6 @@
 Lcom/android/internal/statusbar/IStatusBarService$Stub;-><init>()V
 Lcom/android/internal/statusbar/IStatusBarService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/statusbar/IStatusBarService;
 Lcom/android/internal/telecom/ITelecomService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telecom/ITelecomService;
-Lcom/android/internal/telephony/BaseCommands;->mCallStateRegistrants:Landroid/os/RegistrantList;
-Lcom/android/internal/telephony/BaseCommands;->mCallWaitingInfoRegistrants:Landroid/os/RegistrantList;
-Lcom/android/internal/telephony/BaseCommands;->mCatCallSetUpRegistrant:Landroid/os/Registrant;
-Lcom/android/internal/telephony/BaseCommands;->mCatCcAlphaRegistrant:Landroid/os/Registrant;
-Lcom/android/internal/telephony/BaseCommands;->mCatEventRegistrant:Landroid/os/Registrant;
-Lcom/android/internal/telephony/BaseCommands;->mCatProCmdRegistrant:Landroid/os/Registrant;
-Lcom/android/internal/telephony/BaseCommands;->mCatSessionEndRegistrant:Landroid/os/Registrant;
-Lcom/android/internal/telephony/BaseCommands;->mCdmaPrlChangedRegistrants:Landroid/os/RegistrantList;
-Lcom/android/internal/telephony/BaseCommands;->mCdmaSmsRegistrant:Landroid/os/Registrant;
-Lcom/android/internal/telephony/BaseCommands;->mCdmaSubscriptionChangedRegistrants:Landroid/os/RegistrantList;
-Lcom/android/internal/telephony/BaseCommands;->mContext:Landroid/content/Context;
-Lcom/android/internal/telephony/BaseCommands;->mEmergencyCallbackModeRegistrant:Landroid/os/Registrant;
-Lcom/android/internal/telephony/BaseCommands;->mExitEmergencyCallbackModeRegistrants:Landroid/os/RegistrantList;
-Lcom/android/internal/telephony/BaseCommands;->mGsmBroadcastSmsRegistrant:Landroid/os/Registrant;
-Lcom/android/internal/telephony/BaseCommands;->mGsmSmsRegistrant:Landroid/os/Registrant;
-Lcom/android/internal/telephony/BaseCommands;->mHardwareConfigChangeRegistrants:Landroid/os/RegistrantList;
-Lcom/android/internal/telephony/BaseCommands;->mIccRefreshRegistrants:Landroid/os/RegistrantList;
-Lcom/android/internal/telephony/BaseCommands;->mIccSmsFullRegistrant:Landroid/os/Registrant;
-Lcom/android/internal/telephony/BaseCommands;->mIccStatusChangedRegistrants:Landroid/os/RegistrantList;
-Lcom/android/internal/telephony/BaseCommands;->mImsNetworkStateChangedRegistrants:Landroid/os/RegistrantList;
-Lcom/android/internal/telephony/BaseCommands;->mNITZTimeRegistrant:Landroid/os/Registrant;
-Lcom/android/internal/telephony/BaseCommands;->mOtaProvisionRegistrants:Landroid/os/RegistrantList;
-Lcom/android/internal/telephony/BaseCommands;->mPhoneRadioCapabilityChangedRegistrants:Landroid/os/RegistrantList;
-Lcom/android/internal/telephony/BaseCommands;->mPhoneType:I
-Lcom/android/internal/telephony/BaseCommands;->mPreferredNetworkType:I
-Lcom/android/internal/telephony/BaseCommands;->mResendIncallMuteRegistrants:Landroid/os/RegistrantList;
-Lcom/android/internal/telephony/BaseCommands;->mRestrictedStateRegistrant:Landroid/os/Registrant;
-Lcom/android/internal/telephony/BaseCommands;->mRilCellInfoListRegistrants:Landroid/os/RegistrantList;
-Lcom/android/internal/telephony/BaseCommands;->mRingbackToneRegistrants:Landroid/os/RegistrantList;
-Lcom/android/internal/telephony/BaseCommands;->mRingRegistrant:Landroid/os/Registrant;
-Lcom/android/internal/telephony/BaseCommands;->mSignalStrengthRegistrant:Landroid/os/Registrant;
-Lcom/android/internal/telephony/BaseCommands;->mSmsOnSimRegistrant:Landroid/os/Registrant;
-Lcom/android/internal/telephony/BaseCommands;->mSmsStatusRegistrant:Landroid/os/Registrant;
-Lcom/android/internal/telephony/BaseCommands;->mSrvccStateRegistrants:Landroid/os/RegistrantList;
-Lcom/android/internal/telephony/BaseCommands;->mSsnRegistrant:Landroid/os/Registrant;
-Lcom/android/internal/telephony/BaseCommands;->mSsRegistrant:Landroid/os/Registrant;
-Lcom/android/internal/telephony/BaseCommands;->mStateMonitor:Ljava/lang/Object;
-Lcom/android/internal/telephony/BaseCommands;->mSubscriptionStatusRegistrants:Landroid/os/RegistrantList;
-Lcom/android/internal/telephony/BaseCommands;->mUnsolOemHookRawRegistrant:Landroid/os/Registrant;
-Lcom/android/internal/telephony/BaseCommands;->mUSSDRegistrant:Landroid/os/Registrant;
-Lcom/android/internal/telephony/BaseCommands;->mVoiceRadioTechChangedRegistrants:Landroid/os/RegistrantList;
-Lcom/android/internal/telephony/Call$State;->ACTIVE:Lcom/android/internal/telephony/Call$State;
 Lcom/android/internal/telephony/Call$State;->ALERTING:Lcom/android/internal/telephony/Call$State;
 Lcom/android/internal/telephony/Call$State;->DIALING:Lcom/android/internal/telephony/Call$State;
 Lcom/android/internal/telephony/Call$State;->DISCONNECTED:Lcom/android/internal/telephony/Call$State;
@@ -1805,232 +1763,22 @@
 Lcom/android/internal/telephony/Call$State;->HOLDING:Lcom/android/internal/telephony/Call$State;
 Lcom/android/internal/telephony/Call$State;->IDLE:Lcom/android/internal/telephony/Call$State;
 Lcom/android/internal/telephony/Call$State;->INCOMING:Lcom/android/internal/telephony/Call$State;
-Lcom/android/internal/telephony/Call$State;->isAlive()Z
-Lcom/android/internal/telephony/Call$State;->isRinging()Z
 Lcom/android/internal/telephony/Call$State;->values()[Lcom/android/internal/telephony/Call$State;
 Lcom/android/internal/telephony/Call$State;->WAITING:Lcom/android/internal/telephony/Call$State;
 Lcom/android/internal/telephony/Call;-><init>()V
-Lcom/android/internal/telephony/Call;->getConnections()Ljava/util/List;
-Lcom/android/internal/telephony/Call;->getEarliestConnection()Lcom/android/internal/telephony/Connection;
-Lcom/android/internal/telephony/Call;->getLatestConnection()Lcom/android/internal/telephony/Connection;
-Lcom/android/internal/telephony/Call;->getPhone()Lcom/android/internal/telephony/Phone;
-Lcom/android/internal/telephony/Call;->getState()Lcom/android/internal/telephony/Call$State;
-Lcom/android/internal/telephony/Call;->hangup()V
-Lcom/android/internal/telephony/Call;->isIdle()Z
-Lcom/android/internal/telephony/Call;->isMultiparty()Z
-Lcom/android/internal/telephony/Call;->mConnections:Ljava/util/ArrayList;
-Lcom/android/internal/telephony/Call;->mState:Lcom/android/internal/telephony/Call$State;
 Lcom/android/internal/telephony/CallerInfoAsyncQuery$CallerInfoAsyncQueryHandler;-><init>(Lcom/android/internal/telephony/CallerInfoAsyncQuery;Landroid/content/Context;)V
 Lcom/android/internal/telephony/CallerInfoAsyncQuery$CookieWrapper;-><init>()V
 Lcom/android/internal/telephony/CallerInfoAsyncQuery;->release()V
 Lcom/android/internal/telephony/CallForwardInfo;-><init>()V
-Lcom/android/internal/telephony/CallForwardInfo;->number:Ljava/lang/String;
-Lcom/android/internal/telephony/CallForwardInfo;->reason:I
-Lcom/android/internal/telephony/CallForwardInfo;->serviceClass:I
-Lcom/android/internal/telephony/CallForwardInfo;->status:I
-Lcom/android/internal/telephony/CallForwardInfo;->timeSeconds:I
-Lcom/android/internal/telephony/CallForwardInfo;->toa:I
-Lcom/android/internal/telephony/CallManager;->canConference(Lcom/android/internal/telephony/Call;I)Z
-Lcom/android/internal/telephony/CallManager;->canDial(Lcom/android/internal/telephony/Phone;)Z
-Lcom/android/internal/telephony/CallManager;->conference(Lcom/android/internal/telephony/Call;)V
-Lcom/android/internal/telephony/CallManager;->getActiveFgCall(I)Lcom/android/internal/telephony/Call;
-Lcom/android/internal/telephony/CallManager;->getActiveFgCallState(I)Lcom/android/internal/telephony/Call$State;
-Lcom/android/internal/telephony/CallManager;->getBackgroundCalls()Ljava/util/List;
-Lcom/android/internal/telephony/CallManager;->getBgCallConnections()Ljava/util/List;
-Lcom/android/internal/telephony/CallManager;->getBgPhone()Lcom/android/internal/telephony/Phone;
-Lcom/android/internal/telephony/CallManager;->getContext()Landroid/content/Context;
-Lcom/android/internal/telephony/CallManager;->getDefaultPhone()Lcom/android/internal/telephony/Phone;
-Lcom/android/internal/telephony/CallManager;->getFgCallConnections()Ljava/util/List;
-Lcom/android/internal/telephony/CallManager;->getFgPhone()Lcom/android/internal/telephony/Phone;
-Lcom/android/internal/telephony/CallManager;->getFgPhone(I)Lcom/android/internal/telephony/Phone;
-Lcom/android/internal/telephony/CallManager;->getFirstActiveBgCall()Lcom/android/internal/telephony/Call;
-Lcom/android/internal/telephony/CallManager;->getFirstActiveBgCall(I)Lcom/android/internal/telephony/Call;
-Lcom/android/internal/telephony/CallManager;->getFirstActiveRingingCall()Lcom/android/internal/telephony/Call;
-Lcom/android/internal/telephony/CallManager;->getFirstActiveRingingCall(I)Lcom/android/internal/telephony/Call;
-Lcom/android/internal/telephony/CallManager;->getInstance()Lcom/android/internal/telephony/CallManager;
-Lcom/android/internal/telephony/CallManager;->getPhoneInCall()Lcom/android/internal/telephony/Phone;
-Lcom/android/internal/telephony/CallManager;->getRingingCalls()Ljava/util/List;
-Lcom/android/internal/telephony/CallManager;->getRingingPhone()Lcom/android/internal/telephony/Phone;
-Lcom/android/internal/telephony/CallManager;->getState()Lcom/android/internal/telephony/PhoneConstants$State;
-Lcom/android/internal/telephony/CallManager;->getState(I)Lcom/android/internal/telephony/PhoneConstants$State;
-Lcom/android/internal/telephony/CallManager;->hasActiveBgCall()Z
-Lcom/android/internal/telephony/CallManager;->hasActiveBgCall(I)Z
-Lcom/android/internal/telephony/CallManager;->hasActiveFgCall()Z
-Lcom/android/internal/telephony/CallManager;->hasActiveFgCall(I)Z
-Lcom/android/internal/telephony/CallManager;->hasActiveRingingCall(I)Z
-Lcom/android/internal/telephony/CallManager;->hasMoreThanOneRingingCall()Z
-Lcom/android/internal/telephony/CallManager;->hasMoreThanOneRingingCall(I)Z
-Lcom/android/internal/telephony/CallManager;->mBackgroundCalls:Ljava/util/ArrayList;
-Lcom/android/internal/telephony/CallManager;->mEmptyConnections:Ljava/util/ArrayList;
-Lcom/android/internal/telephony/CallManager;->mForegroundCalls:Ljava/util/ArrayList;
-Lcom/android/internal/telephony/CallManager;->mPhones:Ljava/util/ArrayList;
-Lcom/android/internal/telephony/CallManager;->mRingingCalls:Ljava/util/ArrayList;
-Lcom/android/internal/telephony/CallManager;->registerForDisconnect(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CallManager;->registerForNewRingingConnection(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CallManager;->registerForPreciseCallStateChanged(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CallManager;->registerPhone(Lcom/android/internal/telephony/Phone;)Z
-Lcom/android/internal/telephony/CallManager;->unregisterForDisconnect(Landroid/os/Handler;)V
-Lcom/android/internal/telephony/CallManager;->unregisterForNewRingingConnection(Landroid/os/Handler;)V
-Lcom/android/internal/telephony/CallManager;->unregisterForPreciseCallStateChanged(Landroid/os/Handler;)V
-Lcom/android/internal/telephony/CallManager;->unregisterPhone(Lcom/android/internal/telephony/Phone;)V
-Lcom/android/internal/telephony/CallStateException;-><init>(Ljava/lang/String;)V
 Lcom/android/internal/telephony/CallTracker;-><init>()V
-Lcom/android/internal/telephony/CallTracker;->getState()Lcom/android/internal/telephony/PhoneConstants$State;
-Lcom/android/internal/telephony/CallTracker;->log(Ljava/lang/String;)V
-Lcom/android/internal/telephony/CallTracker;->mCi:Lcom/android/internal/telephony/CommandsInterface;
-Lcom/android/internal/telephony/CallTracker;->mNeedsPoll:Z
-Lcom/android/internal/telephony/CallTracker;->mNumberConverted:Z
-Lcom/android/internal/telephony/CallTracker;->mPendingOperations:I
-Lcom/android/internal/telephony/CallTracker;->registerForVoiceCallEnded(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CarrierServiceBindHelper;->mContext:Landroid/content/Context;
-Lcom/android/internal/telephony/CarrierServiceBindHelper;->mHandler:Landroid/os/Handler;
-Lcom/android/internal/telephony/cat/AppInterface$CommandType;->CLOSE_CHANNEL:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
-Lcom/android/internal/telephony/cat/AppInterface$CommandType;->DISPLAY_TEXT:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
-Lcom/android/internal/telephony/cat/AppInterface$CommandType;->fromInt(I)Lcom/android/internal/telephony/cat/AppInterface$CommandType;
-Lcom/android/internal/telephony/cat/AppInterface$CommandType;->GET_CHANNEL_STATUS:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
-Lcom/android/internal/telephony/cat/AppInterface$CommandType;->GET_INKEY:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
-Lcom/android/internal/telephony/cat/AppInterface$CommandType;->GET_INPUT:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
-Lcom/android/internal/telephony/cat/AppInterface$CommandType;->LANGUAGE_NOTIFICATION:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
-Lcom/android/internal/telephony/cat/AppInterface$CommandType;->LAUNCH_BROWSER:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
-Lcom/android/internal/telephony/cat/AppInterface$CommandType;->OPEN_CHANNEL:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
-Lcom/android/internal/telephony/cat/AppInterface$CommandType;->PLAY_TONE:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
-Lcom/android/internal/telephony/cat/AppInterface$CommandType;->PROVIDE_LOCAL_INFORMATION:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
-Lcom/android/internal/telephony/cat/AppInterface$CommandType;->RECEIVE_DATA:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
-Lcom/android/internal/telephony/cat/AppInterface$CommandType;->REFRESH:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
-Lcom/android/internal/telephony/cat/AppInterface$CommandType;->SELECT_ITEM:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
-Lcom/android/internal/telephony/cat/AppInterface$CommandType;->SEND_DATA:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
-Lcom/android/internal/telephony/cat/AppInterface$CommandType;->SEND_DTMF:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
-Lcom/android/internal/telephony/cat/AppInterface$CommandType;->SEND_SMS:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
-Lcom/android/internal/telephony/cat/AppInterface$CommandType;->SEND_SS:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
-Lcom/android/internal/telephony/cat/AppInterface$CommandType;->SEND_USSD:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
-Lcom/android/internal/telephony/cat/AppInterface$CommandType;->SET_UP_CALL:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
-Lcom/android/internal/telephony/cat/AppInterface$CommandType;->SET_UP_EVENT_LIST:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
-Lcom/android/internal/telephony/cat/AppInterface$CommandType;->SET_UP_IDLE_MODE_TEXT:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
-Lcom/android/internal/telephony/cat/AppInterface$CommandType;->SET_UP_MENU:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
 Lcom/android/internal/telephony/cat/AppInterface$CommandType;->values()[Lcom/android/internal/telephony/cat/AppInterface$CommandType;
-Lcom/android/internal/telephony/cat/CatCmdMessage$CallSettings;->callMsg:Lcom/android/internal/telephony/cat/TextMessage;
-Lcom/android/internal/telephony/cat/CatCmdMessage$CallSettings;->confirmMsg:Lcom/android/internal/telephony/cat/TextMessage;
-Lcom/android/internal/telephony/cat/CatCmdMessage$SetupEventListSettings;->eventList:[I
-Lcom/android/internal/telephony/cat/CatCmdMessage;->getCallSettings()Lcom/android/internal/telephony/cat/CatCmdMessage$CallSettings;
-Lcom/android/internal/telephony/cat/CatCmdMessage;->getCmdType()Lcom/android/internal/telephony/cat/AppInterface$CommandType;
-Lcom/android/internal/telephony/cat/CatCmdMessage;->geTextMessage()Lcom/android/internal/telephony/cat/TextMessage;
-Lcom/android/internal/telephony/cat/CatCmdMessage;->getSetEventList()Lcom/android/internal/telephony/cat/CatCmdMessage$SetupEventListSettings;
-Lcom/android/internal/telephony/cat/CatCmdMessage;->hasIconLoadFailed()Z
-Lcom/android/internal/telephony/cat/CatCmdMessage;->mCallSettings:Lcom/android/internal/telephony/cat/CatCmdMessage$CallSettings;
-Lcom/android/internal/telephony/cat/CatCmdMessage;->mCmdDet:Lcom/android/internal/telephony/cat/CommandDetails;
-Lcom/android/internal/telephony/cat/CatCmdMessage;->mInput:Lcom/android/internal/telephony/cat/Input;
-Lcom/android/internal/telephony/cat/CatCmdMessage;->mMenu:Lcom/android/internal/telephony/cat/Menu;
-Lcom/android/internal/telephony/cat/CatCmdMessage;->mTextMsg:Lcom/android/internal/telephony/cat/TextMessage;
-Lcom/android/internal/telephony/cat/CatLog;->d(Ljava/lang/Object;Ljava/lang/String;)V
-Lcom/android/internal/telephony/cat/CatLog;->d(Ljava/lang/String;Ljava/lang/String;)V
-Lcom/android/internal/telephony/cat/CatLog;->e(Ljava/lang/Object;Ljava/lang/String;)V
-Lcom/android/internal/telephony/cat/CatResponseMessage;->setEventDownload(I[B)V
-Lcom/android/internal/telephony/cat/CatService;->dispose()V
-Lcom/android/internal/telephony/cat/CatService;->isStkAppInstalled()Z
-Lcom/android/internal/telephony/cat/CatService;->mCmdIf:Lcom/android/internal/telephony/CommandsInterface;
-Lcom/android/internal/telephony/cat/CatService;->mContext:Landroid/content/Context;
-Lcom/android/internal/telephony/cat/CatService;->mCurrntCmd:Lcom/android/internal/telephony/cat/CatCmdMessage;
-Lcom/android/internal/telephony/cat/CatService;->mMenuCmd:Lcom/android/internal/telephony/cat/CatCmdMessage;
-Lcom/android/internal/telephony/cat/CatService;->mMsgDecoder:Lcom/android/internal/telephony/cat/RilMessageDecoder;
-Lcom/android/internal/telephony/cat/CatService;->mSlotId:I
-Lcom/android/internal/telephony/cat/CatService;->mStkAppInstalled:Z
-Lcom/android/internal/telephony/cat/CatService;->mUiccController:Lcom/android/internal/telephony/uicc/UiccController;
-Lcom/android/internal/telephony/cat/CatService;->sendTerminalResponse(Lcom/android/internal/telephony/cat/CommandDetails;Lcom/android/internal/telephony/cat/ResultCode;ZILcom/android/internal/telephony/cat/ResponseData;)V
-Lcom/android/internal/telephony/cat/CatService;->sInstance:[Lcom/android/internal/telephony/cat/CatService;
-Lcom/android/internal/telephony/cat/CatService;->sInstanceLock:Ljava/lang/Object;
-Lcom/android/internal/telephony/cat/CommandDetails;->commandNumber:I
-Lcom/android/internal/telephony/cat/CommandDetails;->commandQualifier:I
-Lcom/android/internal/telephony/cat/CommandDetails;->compRequired:Z
-Lcom/android/internal/telephony/cat/CommandDetails;->typeOfCommand:I
-Lcom/android/internal/telephony/cat/CommandParams;-><init>(Lcom/android/internal/telephony/cat/CommandDetails;)V
-Lcom/android/internal/telephony/cat/CommandParams;->getCommandType()Lcom/android/internal/telephony/cat/AppInterface$CommandType;
-Lcom/android/internal/telephony/cat/CommandParams;->mCmdDet:Lcom/android/internal/telephony/cat/CommandDetails;
-Lcom/android/internal/telephony/cat/CommandParamsFactory;->dispose()V
-Lcom/android/internal/telephony/cat/CommandParamsFactory;->mIconLoader:Lcom/android/internal/telephony/cat/IconLoader;
-Lcom/android/internal/telephony/cat/CommandParamsFactory;->searchForNextTag(Lcom/android/internal/telephony/cat/ComprehensionTlvTag;Ljava/util/Iterator;)Lcom/android/internal/telephony/cat/ComprehensionTlv;
-Lcom/android/internal/telephony/cat/CommandParamsFactory;->searchForTag(Lcom/android/internal/telephony/cat/ComprehensionTlvTag;Ljava/util/List;)Lcom/android/internal/telephony/cat/ComprehensionTlv;
-Lcom/android/internal/telephony/cat/ComprehensionTlv;->getLength()I
-Lcom/android/internal/telephony/cat/ComprehensionTlv;->getRawValue()[B
-Lcom/android/internal/telephony/cat/ComprehensionTlv;->getTag()I
-Lcom/android/internal/telephony/cat/ComprehensionTlv;->getValueIndex()I
-Lcom/android/internal/telephony/cat/ComprehensionTlvTag;->ADDRESS:Lcom/android/internal/telephony/cat/ComprehensionTlvTag;
-Lcom/android/internal/telephony/cat/ComprehensionTlvTag;->ALPHA_ID:Lcom/android/internal/telephony/cat/ComprehensionTlvTag;
-Lcom/android/internal/telephony/cat/ComprehensionTlvTag;->COMMAND_DETAILS:Lcom/android/internal/telephony/cat/ComprehensionTlvTag;
-Lcom/android/internal/telephony/cat/ComprehensionTlvTag;->DEVICE_IDENTITIES:Lcom/android/internal/telephony/cat/ComprehensionTlvTag;
-Lcom/android/internal/telephony/cat/ComprehensionTlvTag;->ICON_ID:Lcom/android/internal/telephony/cat/ComprehensionTlvTag;
-Lcom/android/internal/telephony/cat/ComprehensionTlvTag;->RESULT:Lcom/android/internal/telephony/cat/ComprehensionTlvTag;
-Lcom/android/internal/telephony/cat/ComprehensionTlvTag;->SMS_TPDU:Lcom/android/internal/telephony/cat/ComprehensionTlvTag;
-Lcom/android/internal/telephony/cat/ComprehensionTlvTag;->TEXT_ATTRIBUTE:Lcom/android/internal/telephony/cat/ComprehensionTlvTag;
-Lcom/android/internal/telephony/cat/ComprehensionTlvTag;->TEXT_STRING:Lcom/android/internal/telephony/cat/ComprehensionTlvTag;
-Lcom/android/internal/telephony/cat/ComprehensionTlvTag;->USSD_STRING:Lcom/android/internal/telephony/cat/ComprehensionTlvTag;
-Lcom/android/internal/telephony/cat/ComprehensionTlvTag;->value()I
-Lcom/android/internal/telephony/cat/DeviceIdentities;->destinationId:I
-Lcom/android/internal/telephony/cat/DisplayTextParams;-><init>(Lcom/android/internal/telephony/cat/CommandDetails;Lcom/android/internal/telephony/cat/TextMessage;)V
-Lcom/android/internal/telephony/cat/DisplayTextParams;->mTextMsg:Lcom/android/internal/telephony/cat/TextMessage;
-Lcom/android/internal/telephony/cat/Duration$TimeUnit;->value()I
-Lcom/android/internal/telephony/cat/Duration;->timeInterval:I
-Lcom/android/internal/telephony/cat/Duration;->timeUnit:Lcom/android/internal/telephony/cat/Duration$TimeUnit;
-Lcom/android/internal/telephony/cat/GetInputParams;-><init>(Lcom/android/internal/telephony/cat/CommandDetails;Lcom/android/internal/telephony/cat/Input;)V
-Lcom/android/internal/telephony/cat/IconId;->recordNumber:I
-Lcom/android/internal/telephony/cat/IconLoader;->loadIcon(ILandroid/os/Message;)V
-Lcom/android/internal/telephony/cat/Menu;->titleAttrs:Ljava/util/List;
-Lcom/android/internal/telephony/cat/PlayToneParams;-><init>(Lcom/android/internal/telephony/cat/CommandDetails;Lcom/android/internal/telephony/cat/TextMessage;Lcom/android/internal/telephony/cat/Tone;Lcom/android/internal/telephony/cat/Duration;Z)V
 Lcom/android/internal/telephony/cat/ResponseData;-><init>()V
-Lcom/android/internal/telephony/cat/ResponseData;->format(Ljava/io/ByteArrayOutputStream;)V
-Lcom/android/internal/telephony/cat/ResultCode;->BACKWARD_MOVE_BY_USER:Lcom/android/internal/telephony/cat/ResultCode;
-Lcom/android/internal/telephony/cat/ResultCode;->BEYOND_TERMINAL_CAPABILITY:Lcom/android/internal/telephony/cat/ResultCode;
-Lcom/android/internal/telephony/cat/ResultCode;->BIP_ERROR:Lcom/android/internal/telephony/cat/ResultCode;
-Lcom/android/internal/telephony/cat/ResultCode;->CMD_DATA_NOT_UNDERSTOOD:Lcom/android/internal/telephony/cat/ResultCode;
-Lcom/android/internal/telephony/cat/ResultCode;->HELP_INFO_REQUIRED:Lcom/android/internal/telephony/cat/ResultCode;
-Lcom/android/internal/telephony/cat/ResultCode;->LAUNCH_BROWSER_ERROR:Lcom/android/internal/telephony/cat/ResultCode;
-Lcom/android/internal/telephony/cat/ResultCode;->NETWORK_CRNTLY_UNABLE_TO_PROCESS:Lcom/android/internal/telephony/cat/ResultCode;
-Lcom/android/internal/telephony/cat/ResultCode;->NO_RESPONSE_FROM_USER:Lcom/android/internal/telephony/cat/ResultCode;
-Lcom/android/internal/telephony/cat/ResultCode;->OK:Lcom/android/internal/telephony/cat/ResultCode;
-Lcom/android/internal/telephony/cat/ResultCode;->PRFRMD_ICON_NOT_DISPLAYED:Lcom/android/internal/telephony/cat/ResultCode;
-Lcom/android/internal/telephony/cat/ResultCode;->PRFRMD_LIMITED_SERVICE:Lcom/android/internal/telephony/cat/ResultCode;
-Lcom/android/internal/telephony/cat/ResultCode;->PRFRMD_MODIFIED_BY_NAA:Lcom/android/internal/telephony/cat/ResultCode;
-Lcom/android/internal/telephony/cat/ResultCode;->PRFRMD_NAA_NOT_ACTIVE:Lcom/android/internal/telephony/cat/ResultCode;
-Lcom/android/internal/telephony/cat/ResultCode;->PRFRMD_TONE_NOT_PLAYED:Lcom/android/internal/telephony/cat/ResultCode;
-Lcom/android/internal/telephony/cat/ResultCode;->PRFRMD_WITH_ADDITIONAL_EFS_READ:Lcom/android/internal/telephony/cat/ResultCode;
-Lcom/android/internal/telephony/cat/ResultCode;->PRFRMD_WITH_MISSING_INFO:Lcom/android/internal/telephony/cat/ResultCode;
-Lcom/android/internal/telephony/cat/ResultCode;->PRFRMD_WITH_MODIFICATION:Lcom/android/internal/telephony/cat/ResultCode;
-Lcom/android/internal/telephony/cat/ResultCode;->PRFRMD_WITH_PARTIAL_COMPREHENSION:Lcom/android/internal/telephony/cat/ResultCode;
-Lcom/android/internal/telephony/cat/ResultCode;->REQUIRED_VALUES_MISSING:Lcom/android/internal/telephony/cat/ResultCode;
-Lcom/android/internal/telephony/cat/ResultCode;->TERMINAL_CRNTLY_UNABLE_TO_PROCESS:Lcom/android/internal/telephony/cat/ResultCode;
-Lcom/android/internal/telephony/cat/ResultCode;->UICC_SESSION_TERM_BY_USER:Lcom/android/internal/telephony/cat/ResultCode;
-Lcom/android/internal/telephony/cat/ResultCode;->USER_NOT_ACCEPT:Lcom/android/internal/telephony/cat/ResultCode;
-Lcom/android/internal/telephony/cat/ResultCode;->USIM_CALL_CONTROL_PERMANENT:Lcom/android/internal/telephony/cat/ResultCode;
-Lcom/android/internal/telephony/cat/ResultCode;->value()I
 Lcom/android/internal/telephony/cat/ResultCode;->values()[Lcom/android/internal/telephony/cat/ResultCode;
-Lcom/android/internal/telephony/cat/ResultException;-><init>(Lcom/android/internal/telephony/cat/ResultCode;)V
-Lcom/android/internal/telephony/cat/RilMessage;-><init>(ILjava/lang/String;)V
-Lcom/android/internal/telephony/cat/RilMessage;->mData:Ljava/lang/Object;
-Lcom/android/internal/telephony/cat/RilMessage;->mId:I
-Lcom/android/internal/telephony/cat/RilMessageDecoder;->getInstance(Landroid/os/Handler;Lcom/android/internal/telephony/uicc/IccFileHandler;I)Lcom/android/internal/telephony/cat/RilMessageDecoder;
-Lcom/android/internal/telephony/cat/RilMessageDecoder;->mCmdParamsFactory:Lcom/android/internal/telephony/cat/CommandParamsFactory;
 Lcom/android/internal/telephony/cat/RilMessageDecoder;->mCurrentRilMessage:Lcom/android/internal/telephony/cat/RilMessage;
-Lcom/android/internal/telephony/cat/RilMessageDecoder;->mInstance:[Lcom/android/internal/telephony/cat/RilMessageDecoder;
-Lcom/android/internal/telephony/cat/RilMessageDecoder;->mStateStart:Lcom/android/internal/telephony/cat/RilMessageDecoder$StateStart;
 Lcom/android/internal/telephony/cat/RilMessageDecoder;->sendCmdForExecution(Lcom/android/internal/telephony/cat/RilMessage;)V
 Lcom/android/internal/telephony/cat/RilMessageDecoder;->sendStartDecodingMessageParams(Lcom/android/internal/telephony/cat/RilMessage;)V
-Lcom/android/internal/telephony/cat/SelectItemParams;-><init>(Lcom/android/internal/telephony/cat/CommandDetails;Lcom/android/internal/telephony/cat/Menu;Z)V
-Lcom/android/internal/telephony/cat/TextMessage;-><init>()V
-Lcom/android/internal/telephony/cat/TextMessage;->iconSelfExplanatory:Z
-Lcom/android/internal/telephony/cat/TextMessage;->text:Ljava/lang/String;
 Lcom/android/internal/telephony/cat/ValueObject;-><init>()V
-Lcom/android/internal/telephony/cat/ValueParser;->retrieveAlphaId(Lcom/android/internal/telephony/cat/ComprehensionTlv;)Ljava/lang/String;
 Lcom/android/internal/telephony/cat/ValueParser;->retrieveDeviceIdentities(Lcom/android/internal/telephony/cat/ComprehensionTlv;)Lcom/android/internal/telephony/cat/DeviceIdentities;
-Lcom/android/internal/telephony/cat/ValueParser;->retrieveTextAttribute(Lcom/android/internal/telephony/cat/ComprehensionTlv;)Ljava/util/List;
-Lcom/android/internal/telephony/cat/ValueParser;->retrieveTextString(Lcom/android/internal/telephony/cat/ComprehensionTlv;)Ljava/lang/String;
-Lcom/android/internal/telephony/cdma/CdmaCallWaitingNotification;->number:Ljava/lang/String;
-Lcom/android/internal/telephony/cdma/CdmaMmiCode;->makeEmptyNull(Ljava/lang/String;)Ljava/lang/String;
-Lcom/android/internal/telephony/cdma/CdmaMmiCode;->mSc:Ljava/lang/String;
-Lcom/android/internal/telephony/cdma/CdmaSMSDispatcher;->getFormat()Ljava/lang/String;
-Lcom/android/internal/telephony/cdma/CdmaSMSDispatcher;->handleCdmaStatusReport(Lcom/android/internal/telephony/cdma/SmsMessage;)V
-Lcom/android/internal/telephony/cdma/CdmaSubscriptionSourceManager;->getCdmaSubscriptionSource()I
-Lcom/android/internal/telephony/cdma/CdmaSubscriptionSourceManager;->getInstance(Landroid/content/Context;Lcom/android/internal/telephony/CommandsInterface;Landroid/os/Handler;ILjava/lang/Object;)Lcom/android/internal/telephony/cdma/CdmaSubscriptionSourceManager;
-Lcom/android/internal/telephony/cdma/EriManager$EriDisplayInformation;->mEriIconText:Ljava/lang/String;
-Lcom/android/internal/telephony/cdma/EriManager;->getEriDisplayInformation(II)Lcom/android/internal/telephony/cdma/EriManager$EriDisplayInformation;
 Lcom/android/internal/telephony/cdma/sms/BearerData$CodingException;-><init>(Ljava/lang/String;)V
 Lcom/android/internal/telephony/cdma/sms/BearerData$TimeStamp;-><init>()V
 Lcom/android/internal/telephony/cdma/sms/BearerData;-><init>()V
@@ -2084,130 +1832,6 @@
 Lcom/android/internal/telephony/cdma/SmsMessage;->mEnvelope:Lcom/android/internal/telephony/cdma/sms/SmsEnvelope;
 Lcom/android/internal/telephony/cdma/SmsMessage;->parseSms()V
 Lcom/android/internal/telephony/cdma/SmsMessage;->privateGetSubmitPdu(Ljava/lang/String;ZLcom/android/internal/telephony/cdma/sms/UserData;)Lcom/android/internal/telephony/cdma/SmsMessage$SubmitPdu;
-Lcom/android/internal/telephony/CommandException$Error;->GENERIC_FAILURE:Lcom/android/internal/telephony/CommandException$Error;
-Lcom/android/internal/telephony/CommandException$Error;->PASSWORD_INCORRECT:Lcom/android/internal/telephony/CommandException$Error;
-Lcom/android/internal/telephony/CommandException$Error;->RADIO_NOT_AVAILABLE:Lcom/android/internal/telephony/CommandException$Error;
-Lcom/android/internal/telephony/CommandException$Error;->REQUEST_NOT_SUPPORTED:Lcom/android/internal/telephony/CommandException$Error;
-Lcom/android/internal/telephony/CommandException$Error;->SIM_PUK2:Lcom/android/internal/telephony/CommandException$Error;
-Lcom/android/internal/telephony/CommandException$Error;->SMS_FAIL_RETRY:Lcom/android/internal/telephony/CommandException$Error;
-Lcom/android/internal/telephony/CommandException;-><init>(Lcom/android/internal/telephony/CommandException$Error;)V
-Lcom/android/internal/telephony/CommandException;->fromRilErrno(I)Lcom/android/internal/telephony/CommandException;
-Lcom/android/internal/telephony/CommandException;->getCommandError()Lcom/android/internal/telephony/CommandException$Error;
-Lcom/android/internal/telephony/CommandException;->mError:Lcom/android/internal/telephony/CommandException$Error;
-Lcom/android/internal/telephony/CommandsInterface;->acceptCall(Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->acknowledgeLastIncomingCdmaSms(ZILandroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->acknowledgeLastIncomingGsmSms(ZILandroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->changeBarringPassword(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->deleteSmsOnRuim(ILandroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->deleteSmsOnSim(ILandroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->exitEmergencyCallbackMode(Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->getBasebandVersion(Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->getCdmaBroadcastConfig(Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->getCDMASubscription(Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->getDataCallList(Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->getIccCardStatus(Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->getIMEISV(Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->getIMSI(Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->getLastDataCallFailCause(Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->getLastPdpFailCause(Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->getNetworkSelectionMode(Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->getOperator(Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->getPDPContextList(Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->getPreferredNetworkType(Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->getSignalStrength(Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->getSmscAddress(Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->getVoiceRegistrationState(Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->handleCallSetupRequestFromSim(ZLandroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->iccIO(IILjava/lang/String;IIILjava/lang/String;Ljava/lang/String;Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->iccIOForApp(IILjava/lang/String;IIILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->invokeOemRilRequestRaw([BLandroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->queryCallForwardStatus(IILjava/lang/String;Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->queryCallWaiting(ILandroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->queryFacilityLock(Ljava/lang/String;Ljava/lang/String;ILandroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->queryTTYMode(Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->registerForAvailable(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CommandsInterface;->registerForCdmaOtaProvision(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CommandsInterface;->registerForCellInfoList(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CommandsInterface;->registerForIccRefresh(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CommandsInterface;->registerForImsNetworkStateChanged(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CommandsInterface;->registerForNotAvailable(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CommandsInterface;->registerForOffOrNotAvailable(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CommandsInterface;->registerForOn(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CommandsInterface;->registerForRadioStateChanged(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CommandsInterface;->registerForRilConnected(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CommandsInterface;->reportSmsMemoryStatus(ZLandroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->reportStkServiceIsRunning(Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->requestIccSimAuthentication(ILjava/lang/String;Ljava/lang/String;Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->requestShutdown(Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->sendDtmf(CLandroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->sendEnvelope(Ljava/lang/String;Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->sendTerminalResponse(Ljava/lang/String;Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->setCallForward(IIILjava/lang/String;ILandroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->setCallWaiting(ZILandroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->setCdmaBroadcastActivation(ZLandroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->setDataAllowed(ZLandroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->setEmergencyCallbackMode(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CommandsInterface;->setFacilityLock(Ljava/lang/String;ZLjava/lang/String;ILandroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->setNetworkSelectionModeAutomatic(Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->setNetworkSelectionModeManual(Ljava/lang/String;Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->setOnCallRing(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CommandsInterface;->setOnCatCallSetUp(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CommandsInterface;->setOnCatCcAlphaNotify(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CommandsInterface;->setOnCatEvent(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CommandsInterface;->setOnCatProactiveCmd(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CommandsInterface;->setOnCatSessionEnd(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CommandsInterface;->setOnIccRefresh(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CommandsInterface;->setOnIccSmsFull(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CommandsInterface;->setOnNewGsmBroadcastSms(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CommandsInterface;->setOnNITZTime(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CommandsInterface;->setOnSignalStrengthUpdate(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CommandsInterface;->setOnSmsOnSim(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CommandsInterface;->setOnSmsStatus(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CommandsInterface;->setOnSuppServiceNotification(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/CommandsInterface;->setPhoneType(I)V
-Lcom/android/internal/telephony/CommandsInterface;->setPreferredNetworkType(ILandroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->setRadioPower(ZLandroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->setSmscAddress(Ljava/lang/String;Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->setTTYMode(ILandroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->setUiccSubscription(IIIILandroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->supplyIccPin(Ljava/lang/String;Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->switchWaitingOrHoldingAndActive(Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->unregisterForAvailable(Landroid/os/Handler;)V
-Lcom/android/internal/telephony/CommandsInterface;->unregisterForCdmaOtaProvision(Landroid/os/Handler;)V
-Lcom/android/internal/telephony/CommandsInterface;->unregisterForOffOrNotAvailable(Landroid/os/Handler;)V
-Lcom/android/internal/telephony/CommandsInterface;->unregisterForOn(Landroid/os/Handler;)V
-Lcom/android/internal/telephony/CommandsInterface;->unregisterForRilConnected(Landroid/os/Handler;)V
-Lcom/android/internal/telephony/CommandsInterface;->unregisterForVoiceRadioTechChanged(Landroid/os/Handler;)V
-Lcom/android/internal/telephony/CommandsInterface;->writeSmsToRuim(ILjava/lang/String;Landroid/os/Message;)V
-Lcom/android/internal/telephony/CommandsInterface;->writeSmsToSim(ILjava/lang/String;Ljava/lang/String;Landroid/os/Message;)V
-Lcom/android/internal/telephony/Connection$PostDialState;->CANCELLED:Lcom/android/internal/telephony/Connection$PostDialState;
-Lcom/android/internal/telephony/Connection$PostDialState;->COMPLETE:Lcom/android/internal/telephony/Connection$PostDialState;
-Lcom/android/internal/telephony/Connection$PostDialState;->NOT_STARTED:Lcom/android/internal/telephony/Connection$PostDialState;
-Lcom/android/internal/telephony/Connection$PostDialState;->STARTED:Lcom/android/internal/telephony/Connection$PostDialState;
-Lcom/android/internal/telephony/Connection$PostDialState;->WAIT:Lcom/android/internal/telephony/Connection$PostDialState;
-Lcom/android/internal/telephony/Connection$PostDialState;->WILD:Lcom/android/internal/telephony/Connection$PostDialState;
-Lcom/android/internal/telephony/Connection;-><init>(I)V
-Lcom/android/internal/telephony/Connection;->getAddress()Ljava/lang/String;
-Lcom/android/internal/telephony/Connection;->getCall()Lcom/android/internal/telephony/Call;
-Lcom/android/internal/telephony/Connection;->getConnectTime()J
-Lcom/android/internal/telephony/Connection;->getCreateTime()J
-Lcom/android/internal/telephony/Connection;->getDisconnectCause()I
-Lcom/android/internal/telephony/Connection;->getDisconnectTime()J
-Lcom/android/internal/telephony/Connection;->getDurationMillis()J
-Lcom/android/internal/telephony/Connection;->getState()Lcom/android/internal/telephony/Call$State;
-Lcom/android/internal/telephony/Connection;->getUserData()Ljava/lang/Object;
-Lcom/android/internal/telephony/Connection;->hangup()V
-Lcom/android/internal/telephony/Connection;->isAlive()Z
-Lcom/android/internal/telephony/Connection;->isIncoming()Z
-Lcom/android/internal/telephony/Connection;->LOG_TAG:Ljava/lang/String;
-Lcom/android/internal/telephony/Connection;->mAddress:Ljava/lang/String;
-Lcom/android/internal/telephony/Connection;->mCnapName:Ljava/lang/String;
-Lcom/android/internal/telephony/Connection;->mCnapNamePresentation:I
-Lcom/android/internal/telephony/Connection;->mDialString:Ljava/lang/String;
-Lcom/android/internal/telephony/Connection;->mDuration:J
-Lcom/android/internal/telephony/Connection;->mIsIncoming:Z
-Lcom/android/internal/telephony/Connection;->mNumberPresentation:I
-Lcom/android/internal/telephony/Connection;->setVideoState(I)V
 Lcom/android/internal/telephony/DctConstants$Activity;->DATAIN:Lcom/android/internal/telephony/DctConstants$Activity;
 Lcom/android/internal/telephony/DctConstants$Activity;->DATAINANDOUT:Lcom/android/internal/telephony/DctConstants$Activity;
 Lcom/android/internal/telephony/DctConstants$Activity;->DATAOUT:Lcom/android/internal/telephony/DctConstants$Activity;
@@ -2220,22 +1844,7 @@
 Lcom/android/internal/telephony/DctConstants$State;->IDLE:Lcom/android/internal/telephony/DctConstants$State;
 Lcom/android/internal/telephony/DctConstants$State;->RETRYING:Lcom/android/internal/telephony/DctConstants$State;
 Lcom/android/internal/telephony/DctConstants$State;->values()[Lcom/android/internal/telephony/DctConstants$State;
-Lcom/android/internal/telephony/DefaultPhoneNotifier;->mRegistry:Lcom/android/internal/telephony/ITelephonyRegistry;
-Lcom/android/internal/telephony/DriverCall$State;->ACTIVE:Lcom/android/internal/telephony/DriverCall$State;
-Lcom/android/internal/telephony/DriverCall$State;->ALERTING:Lcom/android/internal/telephony/DriverCall$State;
-Lcom/android/internal/telephony/DriverCall$State;->DIALING:Lcom/android/internal/telephony/DriverCall$State;
-Lcom/android/internal/telephony/DriverCall$State;->HOLDING:Lcom/android/internal/telephony/DriverCall$State;
-Lcom/android/internal/telephony/DriverCall$State;->INCOMING:Lcom/android/internal/telephony/DriverCall$State;
 Lcom/android/internal/telephony/DriverCall$State;->values()[Lcom/android/internal/telephony/DriverCall$State;
-Lcom/android/internal/telephony/DriverCall$State;->WAITING:Lcom/android/internal/telephony/DriverCall$State;
-Lcom/android/internal/telephony/DriverCall;-><init>()V
-Lcom/android/internal/telephony/DriverCall;->index:I
-Lcom/android/internal/telephony/DriverCall;->isMT:Z
-Lcom/android/internal/telephony/DriverCall;->isVoice:Z
-Lcom/android/internal/telephony/DriverCall;->name:Ljava/lang/String;
-Lcom/android/internal/telephony/DriverCall;->number:Ljava/lang/String;
-Lcom/android/internal/telephony/DriverCall;->numberPresentation:I
-Lcom/android/internal/telephony/DriverCall;->state:Lcom/android/internal/telephony/DriverCall$State;
 Lcom/android/internal/telephony/gsm/GsmCellBroadcastHandler$SmsCbConcatInfo;-><init>(Lcom/android/internal/telephony/gsm/SmsCbHeader;Landroid/telephony/SmsCbLocation;)V
 Lcom/android/internal/telephony/gsm/GsmCellBroadcastHandler$SmsCbConcatInfo;->matchesLocation(Ljava/lang/String;II)Z
 Lcom/android/internal/telephony/gsm/GsmCellBroadcastHandler;->mSmsCbPageMap:Ljava/util/HashMap;
@@ -2314,79 +1923,7 @@
 Lcom/android/internal/telephony/gsm/UsimPhoneBookManager;->mPhoneBookRecords:Ljava/util/ArrayList;
 Lcom/android/internal/telephony/gsm/UsimPhoneBookManager;->reset()V
 Lcom/android/internal/telephony/GsmAlphabet$TextEncodingDetails;-><init>()V
-Lcom/android/internal/telephony/GsmCdmaCall;->attachFake(Lcom/android/internal/telephony/Connection;Lcom/android/internal/telephony/Call$State;)V
-Lcom/android/internal/telephony/GsmCdmaCallTracker;->clearDisconnected()V
-Lcom/android/internal/telephony/GsmCdmaCallTracker;->disableDataCallInEmergencyCall(Ljava/lang/String;)V
-Lcom/android/internal/telephony/GsmCdmaCallTracker;->fakeHoldForegroundBeforeDial()V
-Lcom/android/internal/telephony/GsmCdmaCallTracker;->getPhone()Lcom/android/internal/telephony/GsmCdmaPhone;
-Lcom/android/internal/telephony/GsmCdmaCallTracker;->handleEcmTimer(I)V
-Lcom/android/internal/telephony/GsmCdmaCallTracker;->isPhoneTypeGsm()Z
-Lcom/android/internal/telephony/GsmCdmaCallTracker;->log(Ljava/lang/String;)V
-Lcom/android/internal/telephony/GsmCdmaCallTracker;->mBackgroundCall:Lcom/android/internal/telephony/GsmCdmaCall;
-Lcom/android/internal/telephony/GsmCdmaCallTracker;->mForegroundCall:Lcom/android/internal/telephony/GsmCdmaCall;
-Lcom/android/internal/telephony/GsmCdmaCallTracker;->mPendingMO:Lcom/android/internal/telephony/GsmCdmaConnection;
-Lcom/android/internal/telephony/GsmCdmaCallTracker;->mPhone:Lcom/android/internal/telephony/GsmCdmaPhone;
-Lcom/android/internal/telephony/GsmCdmaCallTracker;->mRingingCall:Lcom/android/internal/telephony/GsmCdmaCall;
-Lcom/android/internal/telephony/GsmCdmaCallTracker;->mState:Lcom/android/internal/telephony/PhoneConstants$State;
-Lcom/android/internal/telephony/GsmCdmaCallTracker;->obtainCompleteMessage()Landroid/os/Message;
-Lcom/android/internal/telephony/GsmCdmaCallTracker;->obtainCompleteMessage(I)Landroid/os/Message;
-Lcom/android/internal/telephony/GsmCdmaCallTracker;->setMute(Z)V
-Lcom/android/internal/telephony/GsmCdmaCallTracker;->switchWaitingOrHoldingAndActive()V
-Lcom/android/internal/telephony/GsmCdmaCallTracker;->updatePhoneState()V
 Lcom/android/internal/telephony/GsmCdmaConnection$MyHandler;-><init>(Lcom/android/internal/telephony/GsmCdmaConnection;Landroid/os/Looper;)V
-Lcom/android/internal/telephony/GsmCdmaConnection;->acquireWakeLock()V
-Lcom/android/internal/telephony/GsmCdmaConnection;->createWakeLock(Landroid/content/Context;)V
-Lcom/android/internal/telephony/GsmCdmaConnection;->disconnectCauseFromCode(I)I
-Lcom/android/internal/telephony/GsmCdmaConnection;->fetchDtmfToneDelay(Lcom/android/internal/telephony/GsmCdmaPhone;)V
-Lcom/android/internal/telephony/GsmCdmaConnection;->findNextPCharOrNonPOrNonWCharIndex(Ljava/lang/String;I)I
-Lcom/android/internal/telephony/GsmCdmaConnection;->findPOrWCharToAppend(Ljava/lang/String;II)C
-Lcom/android/internal/telephony/GsmCdmaConnection;->formatDialString(Ljava/lang/String;)Ljava/lang/String;
-Lcom/android/internal/telephony/GsmCdmaConnection;->getState()Lcom/android/internal/telephony/Call$State;
-Lcom/android/internal/telephony/GsmCdmaConnection;->isPause(C)Z
-Lcom/android/internal/telephony/GsmCdmaConnection;->isPhoneTypeGsm()Z
-Lcom/android/internal/telephony/GsmCdmaConnection;->isWait(C)Z
-Lcom/android/internal/telephony/GsmCdmaConnection;->log(Ljava/lang/String;)V
-Lcom/android/internal/telephony/GsmCdmaConnection;->maskDialString(Ljava/lang/String;)Ljava/lang/String;
-Lcom/android/internal/telephony/GsmCdmaConnection;->mIndex:I
-Lcom/android/internal/telephony/GsmCdmaConnection;->mOwner:Lcom/android/internal/telephony/GsmCdmaCallTracker;
-Lcom/android/internal/telephony/GsmCdmaConnection;->onConnectedInOrOut()V
-Lcom/android/internal/telephony/GsmCdmaConnection;->updateParent(Lcom/android/internal/telephony/GsmCdmaCall;Lcom/android/internal/telephony/GsmCdmaCall;)V
-Lcom/android/internal/telephony/GsmCdmaPhone$Cfu;-><init>(Ljava/lang/String;Landroid/os/Message;)V
-Lcom/android/internal/telephony/GsmCdmaPhone;->exitEmergencyCallbackMode()V
-Lcom/android/internal/telephony/GsmCdmaPhone;->getCallTracker()Lcom/android/internal/telephony/CallTracker;
-Lcom/android/internal/telephony/GsmCdmaPhone;->getCdmaEriText()Ljava/lang/String;
-Lcom/android/internal/telephony/GsmCdmaPhone;->getEsn()Ljava/lang/String;
-Lcom/android/internal/telephony/GsmCdmaPhone;->getLine1Number()Ljava/lang/String;
-Lcom/android/internal/telephony/GsmCdmaPhone;->getPhoneType()I
-Lcom/android/internal/telephony/GsmCdmaPhone;->getServiceState()Landroid/telephony/ServiceState;
-Lcom/android/internal/telephony/GsmCdmaPhone;->getState()Lcom/android/internal/telephony/PhoneConstants$State;
-Lcom/android/internal/telephony/GsmCdmaPhone;->getSystemProperty(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
-Lcom/android/internal/telephony/GsmCdmaPhone;->handleInCallMmiCommands(Ljava/lang/String;)Z
-Lcom/android/internal/telephony/GsmCdmaPhone;->isCfEnable(I)Z
-Lcom/android/internal/telephony/GsmCdmaPhone;->isEriFileLoaded()Z
-Lcom/android/internal/telephony/GsmCdmaPhone;->isInCall()Z
-Lcom/android/internal/telephony/GsmCdmaPhone;->isManualSelProhibitedInGlobalMode()Z
-Lcom/android/internal/telephony/GsmCdmaPhone;->isPhoneTypeGsm()Z
-Lcom/android/internal/telephony/GsmCdmaPhone;->isValidCommandInterfaceCFAction(I)Z
-Lcom/android/internal/telephony/GsmCdmaPhone;->isValidCommandInterfaceCFReason(I)Z
-Lcom/android/internal/telephony/GsmCdmaPhone;->logd(Ljava/lang/String;)V
-Lcom/android/internal/telephony/GsmCdmaPhone;->loge(Ljava/lang/String;)V
-Lcom/android/internal/telephony/GsmCdmaPhone;->mCT:Lcom/android/internal/telephony/GsmCdmaCallTracker;
-Lcom/android/internal/telephony/GsmCdmaPhone;->mEcmExitRespRegistrant:Landroid/os/Registrant;
-Lcom/android/internal/telephony/GsmCdmaPhone;->mEriManager:Lcom/android/internal/telephony/cdma/EriManager;
-Lcom/android/internal/telephony/GsmCdmaPhone;->mIccSmsInterfaceManager:Lcom/android/internal/telephony/IccSmsInterfaceManager;
-Lcom/android/internal/telephony/GsmCdmaPhone;->mIsimUiccRecords:Lcom/android/internal/telephony/uicc/IsimUiccRecords;
-Lcom/android/internal/telephony/GsmCdmaPhone;->mPendingMMIs:Ljava/util/ArrayList;
-Lcom/android/internal/telephony/GsmCdmaPhone;->mSST:Lcom/android/internal/telephony/ServiceStateTracker;
-Lcom/android/internal/telephony/GsmCdmaPhone;->notifyPreciseCallStateChanged()V
-Lcom/android/internal/telephony/GsmCdmaPhone;->notifyServiceStateChanged(Landroid/telephony/ServiceState;)V
-Lcom/android/internal/telephony/GsmCdmaPhone;->setOnEcbModeExitResponse(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/GsmCdmaPhone;->syncClirSetting()V
-Lcom/android/internal/telephony/IccCard;->getState()Lcom/android/internal/telephony/IccCardConstants$State;
-Lcom/android/internal/telephony/IccCard;->registerForNetworkLocked(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/IccCard;->supplyNetworkDepersonalization(Ljava/lang/String;Landroid/os/Message;)V
-Lcom/android/internal/telephony/IccCard;->supplyPin(Ljava/lang/String;Landroid/os/Message;)V
-Lcom/android/internal/telephony/IccCard;->supplyPuk(Ljava/lang/String;Ljava/lang/String;Landroid/os/Message;)V
 Lcom/android/internal/telephony/IccCardConstants$State;->ABSENT:Lcom/android/internal/telephony/IccCardConstants$State;
 Lcom/android/internal/telephony/IccCardConstants$State;->CARD_IO_ERROR:Lcom/android/internal/telephony/IccCardConstants$State;
 Lcom/android/internal/telephony/IccCardConstants$State;->NETWORK_LOCKED:Lcom/android/internal/telephony/IccCardConstants$State;
@@ -2397,47 +1934,7 @@
 Lcom/android/internal/telephony/IccCardConstants$State;->READY:Lcom/android/internal/telephony/IccCardConstants$State;
 Lcom/android/internal/telephony/IccCardConstants$State;->UNKNOWN:Lcom/android/internal/telephony/IccCardConstants$State;
 Lcom/android/internal/telephony/IccCardConstants$State;->values()[Lcom/android/internal/telephony/IccCardConstants$State;
-Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;->checkThread()V
-Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;->DBG:Z
-Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;->logd(Ljava/lang/String;)V
-Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;->loge(Ljava/lang/String;)V
-Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;->mAdnCache:Lcom/android/internal/telephony/uicc/AdnRecordCache;
-Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;->mBaseHandler:Landroid/os/Handler;
-Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;->mPhone:Lcom/android/internal/telephony/Phone;
-Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;->updateEfForIccType(I)I
 Lcom/android/internal/telephony/IccProvider;-><init>()V
-Lcom/android/internal/telephony/IccProvider;->ADDRESS_BOOK_COLUMN_NAMES:[Ljava/lang/String;
-Lcom/android/internal/telephony/IccProvider;->DBG:Z
-Lcom/android/internal/telephony/IccProvider;->loadRecord(Lcom/android/internal/telephony/uicc/AdnRecord;Landroid/database/MatrixCursor;I)V
-Lcom/android/internal/telephony/IccProvider;->log(Ljava/lang/String;)V
-Lcom/android/internal/telephony/IccSmsInterfaceManager;->copyMessageToIccEf(Ljava/lang/String;I[B[B)Z
-Lcom/android/internal/telephony/IccSmsInterfaceManager;->disableCdmaBroadcastRange(II)Z
-Lcom/android/internal/telephony/IccSmsInterfaceManager;->disableGsmBroadcastRange(II)Z
-Lcom/android/internal/telephony/IccSmsInterfaceManager;->enableCdmaBroadcastRange(II)Z
-Lcom/android/internal/telephony/IccSmsInterfaceManager;->enableGsmBroadcastRange(II)Z
-Lcom/android/internal/telephony/IccSmsInterfaceManager;->enforceReceiveAndSend(Ljava/lang/String;)V
-Lcom/android/internal/telephony/IccSmsInterfaceManager;->filterDestAddress(Ljava/lang/String;)Ljava/lang/String;
-Lcom/android/internal/telephony/IccSmsInterfaceManager;->getAllMessagesFromIccEf(Ljava/lang/String;)Ljava/util/List;
-Lcom/android/internal/telephony/IccSmsInterfaceManager;->getImsSmsFormat()Ljava/lang/String;
-Lcom/android/internal/telephony/IccSmsInterfaceManager;->getPremiumSmsPermission(Ljava/lang/String;)I
-Lcom/android/internal/telephony/IccSmsInterfaceManager;->injectSmsPdu([BLjava/lang/String;Landroid/app/PendingIntent;)V
-Lcom/android/internal/telephony/IccSmsInterfaceManager;->isImsSmsSupported()Z
-Lcom/android/internal/telephony/IccSmsInterfaceManager;->log(Ljava/lang/String;)V
-Lcom/android/internal/telephony/IccSmsInterfaceManager;->mAppOps:Landroid/app/AppOpsManager;
-Lcom/android/internal/telephony/IccSmsInterfaceManager;->mCellBroadcastRangeManager:Lcom/android/internal/telephony/IccSmsInterfaceManager$CellBroadcastRangeManager;
-Lcom/android/internal/telephony/IccSmsInterfaceManager;->mContext:Landroid/content/Context;
-Lcom/android/internal/telephony/IccSmsInterfaceManager;->mHandler:Landroid/os/Handler;
-Lcom/android/internal/telephony/IccSmsInterfaceManager;->mLock:Ljava/lang/Object;
-Lcom/android/internal/telephony/IccSmsInterfaceManager;->mPhone:Lcom/android/internal/telephony/Phone;
-Lcom/android/internal/telephony/IccSmsInterfaceManager;->mSms:Ljava/util/List;
-Lcom/android/internal/telephony/IccSmsInterfaceManager;->mSuccess:Z
-Lcom/android/internal/telephony/IccSmsInterfaceManager;->sendData(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I[BLandroid/app/PendingIntent;Landroid/app/PendingIntent;)V
-Lcom/android/internal/telephony/IccSmsInterfaceManager;->sendStoredMultipartText(Ljava/lang/String;Landroid/net/Uri;Ljava/lang/String;Ljava/util/List;Ljava/util/List;)V
-Lcom/android/internal/telephony/IccSmsInterfaceManager;->sendStoredText(Ljava/lang/String;Landroid/net/Uri;Ljava/lang/String;Landroid/app/PendingIntent;Landroid/app/PendingIntent;)V
-Lcom/android/internal/telephony/IccSmsInterfaceManager;->setCdmaBroadcastConfig([Lcom/android/internal/telephony/cdma/CdmaSmsBroadcastConfigInfo;)Z
-Lcom/android/internal/telephony/IccSmsInterfaceManager;->setCellBroadcastConfig([Lcom/android/internal/telephony/gsm/SmsBroadcastConfigInfo;)Z
-Lcom/android/internal/telephony/IccSmsInterfaceManager;->setPremiumSmsPermission(Ljava/lang/String;I)V
-Lcom/android/internal/telephony/IccSmsInterfaceManager;->updateMessageOnIccEf(Ljava/lang/String;II[B)Z
 Lcom/android/internal/telephony/IIccPhoneBook$Stub$Proxy;->mRemote:Landroid/os/IBinder;
 Lcom/android/internal/telephony/IIccPhoneBook$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/IIccPhoneBook;
 Lcom/android/internal/telephony/IIccPhoneBook;->getAdnRecordsInEf(I)Ljava/util/List;
@@ -2446,142 +1943,24 @@
 Lcom/android/internal/telephony/IIccPhoneBook;->getAdnRecordsSizeForSubscriber(II)[I
 Lcom/android/internal/telephony/IIccPhoneBook;->updateAdnRecordsInEfBySearch(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z
 Lcom/android/internal/telephony/IMms$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/IMms;
-Lcom/android/internal/telephony/imsphone/ImsExternalCall;-><init>(Lcom/android/internal/telephony/Phone;Lcom/android/internal/telephony/imsphone/ImsExternalConnection;)V
 Lcom/android/internal/telephony/imsphone/ImsExternalCallTracker$ExternalCallStateListener;-><init>(Lcom/android/internal/telephony/imsphone/ImsExternalCallTracker;)V
 Lcom/android/internal/telephony/imsphone/ImsExternalCallTracker$ExternalConnectionListener;-><init>(Lcom/android/internal/telephony/imsphone/ImsExternalCallTracker;)V
-Lcom/android/internal/telephony/imsphone/ImsExternalConnection;->rebuildCapabilities()V
-Lcom/android/internal/telephony/imsphone/ImsExternalConnection;->setActive()V
-Lcom/android/internal/telephony/imsphone/ImsPhone$Cf;-><init>(Ljava/lang/String;ZLandroid/os/Message;)V
-Lcom/android/internal/telephony/imsphone/ImsPhone;->getActionFromCFAction(I)I
-Lcom/android/internal/telephony/imsphone/ImsPhone;->getBackgroundCall()Lcom/android/internal/telephony/imsphone/ImsPhoneCall;
-Lcom/android/internal/telephony/imsphone/ImsPhone;->getCallForwardingOption(ILandroid/os/Message;)V
-Lcom/android/internal/telephony/imsphone/ImsPhone;->getCallWaiting(Landroid/os/Message;)V
-Lcom/android/internal/telephony/imsphone/ImsPhone;->getConditionFromCFReason(I)I
-Lcom/android/internal/telephony/imsphone/ImsPhone;->getForegroundCall()Lcom/android/internal/telephony/imsphone/ImsPhoneCall;
-Lcom/android/internal/telephony/imsphone/ImsPhone;->getRingingCall()Lcom/android/internal/telephony/imsphone/ImsPhoneCall;
-Lcom/android/internal/telephony/imsphone/ImsPhone;->getServiceState()Landroid/telephony/ServiceState;
-Lcom/android/internal/telephony/imsphone/ImsPhone;->getState()Lcom/android/internal/telephony/PhoneConstants$State;
-Lcom/android/internal/telephony/imsphone/ImsPhone;->handleEnterEmergencyCallbackMode()V
-Lcom/android/internal/telephony/imsphone/ImsPhone;->handleExitEmergencyCallbackMode()V
-Lcom/android/internal/telephony/imsphone/ImsPhone;->handleInCallMmiCommands(Ljava/lang/String;)Z
-Lcom/android/internal/telephony/imsphone/ImsPhone;->isCfEnable(I)Z
-Lcom/android/internal/telephony/imsphone/ImsPhone;->isUtEnabled()Z
-Lcom/android/internal/telephony/imsphone/ImsPhone;->isValidCommandInterfaceCFAction(I)Z
-Lcom/android/internal/telephony/imsphone/ImsPhone;->isValidCommandInterfaceCFReason(I)Z
-Lcom/android/internal/telephony/imsphone/ImsPhone;->isVolteEnabled()Z
-Lcom/android/internal/telephony/imsphone/ImsPhone;->mCT:Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;
-Lcom/android/internal/telephony/imsphone/ImsPhone;->mPendingMMIs:Ljava/util/ArrayList;
-Lcom/android/internal/telephony/imsphone/ImsPhone;->mSS:Landroid/telephony/ServiceState;
 Lcom/android/internal/telephony/imsphone/ImsPhone;->notifyCallForwardingIndicator()V
 Lcom/android/internal/telephony/imsphone/ImsPhone;->notifyPreciseCallStateChanged()V
-Lcom/android/internal/telephony/imsphone/ImsPhone;->notifyUnknownConnection(Lcom/android/internal/telephony/Connection;)V
-Lcom/android/internal/telephony/imsphone/ImsPhone;->onMMIDone(Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;)V
-Lcom/android/internal/telephony/imsphone/ImsPhone;->sendErrorResponse(Landroid/os/Message;)V
-Lcom/android/internal/telephony/imsphone/ImsPhone;->sendErrorResponse(Landroid/os/Message;Ljava/lang/Throwable;)V
-Lcom/android/internal/telephony/imsphone/ImsPhone;->setCallForwardingOption(IILjava/lang/String;IILandroid/os/Message;)V
-Lcom/android/internal/telephony/imsphone/ImsPhone;->setCallWaiting(ZLandroid/os/Message;)V
-Lcom/android/internal/telephony/imsphone/ImsPhone;->setImsRegistered(Z)V
-Lcom/android/internal/telephony/imsphone/ImsPhone;->setOnEcbModeExitResponse(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/imsphone/ImsPhone;->setServiceState(I)V
-Lcom/android/internal/telephony/imsphone/ImsPhoneCall;->attach(Lcom/android/internal/telephony/Connection;Lcom/android/internal/telephony/Call$State;)V
-Lcom/android/internal/telephony/imsphone/ImsPhoneCall;->attachFake(Lcom/android/internal/telephony/Connection;Lcom/android/internal/telephony/Call$State;)V
-Lcom/android/internal/telephony/imsphone/ImsPhoneCall;->getConnections()Ljava/util/List;
 Lcom/android/internal/telephony/imsphone/ImsPhoneCall;->getImsCall()Lcom/android/ims/ImsCall;
-Lcom/android/internal/telephony/imsphone/ImsPhoneCall;->hangup()V
-Lcom/android/internal/telephony/imsphone/ImsPhoneCall;->merge(Lcom/android/internal/telephony/imsphone/ImsPhoneCall;Lcom/android/internal/telephony/Call$State;)V
-Lcom/android/internal/telephony/imsphone/ImsPhoneCall;->onHangupLocal()V
-Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->addConnection(Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;)V
-Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->clearDisconnected()V
-Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->dial(Ljava/lang/String;ILandroid/os/Bundle;)Lcom/android/internal/telephony/Connection;
-Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->dialPendingMO()V
 Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->findConnection(Lcom/android/ims/ImsCall;)Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;
 Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->getEcbmInterface()Lcom/android/ims/ImsEcbm;
-Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->getUtInterface()Lcom/android/ims/ImsUtInterface;
-Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->handleEcmTimer(I)V
-Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->log(Ljava/lang/String;)V
-Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->loge(Ljava/lang/String;)V
-Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mAllowEmergencyVideoCalls:Z
-Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mBackgroundCall:Lcom/android/internal/telephony/imsphone/ImsPhoneCall;
 Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mCallExpectedToResume:Lcom/android/ims/ImsCall;
-Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mConnections:Ljava/util/ArrayList;
-Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mForegroundCall:Lcom/android/internal/telephony/imsphone/ImsPhoneCall;
-Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mHandoverCall:Lcom/android/internal/telephony/imsphone/ImsPhoneCall;
 Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mImsCallListener:Lcom/android/ims/ImsCall$Listener;
 Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mImsManager:Lcom/android/ims/ImsManager;
-Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mOnHoldToneId:I
-Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mOnHoldToneStarted:Z
-Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mPendingMO:Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;
-Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mPendingUssd:Landroid/os/Message;
-Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mPhone:Lcom/android/internal/telephony/imsphone/ImsPhone;
-Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mRingingCall:Lcom/android/internal/telephony/imsphone/ImsPhoneCall;
-Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mSwitchingFgAndBgCalls:Z
-Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mSyncHold:Ljava/lang/Object;
 Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mUssdSession:Lcom/android/ims/ImsCall;
 Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->processCallStateChange(Lcom/android/ims/ImsCall;Lcom/android/internal/telephony/Call$State;I)V
 Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->processCallStateChange(Lcom/android/ims/ImsCall;Lcom/android/internal/telephony/Call$State;IZ)V
-Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->removeConnection(Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;)V
 Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->setVideoCallProvider(Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;Lcom/android/ims/ImsCall;)V
-Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->switchAfterConferenceSuccess()V
-Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->updatePhoneState()V
 Lcom/android/internal/telephony/imsphone/ImsPhoneConnection$MyHandler;-><init>(Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;Landroid/os/Looper;)V
-Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;->acquireWakeLock()V
-Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;->createWakeLock(Landroid/content/Context;)V
-Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;->getCall()Lcom/android/internal/telephony/imsphone/ImsPhoneCall;
-Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;->getOwner()Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;
-Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;->isMultiparty()Z
-Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;->mDisconnected:Z
 Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;->mImsCall:Lcom/android/ims/ImsCall;
-Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;->mOwner:Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;
-Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;->mParent:Lcom/android/internal/telephony/imsphone/ImsPhoneCall;
-Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;->onDisconnect()Z
 Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;->update(Lcom/android/ims/ImsCall;Lcom/android/internal/telephony/Call$State;)Z
-Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->getCLIRMode()I
-Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->getDialingNumber()Ljava/lang/String;
-Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->getErrorMessage(Landroid/os/AsyncResult;)Ljava/lang/CharSequence;
-Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->getScString()Ljava/lang/CharSequence;
-Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->isActivate()Z
-Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->isDeactivate()Z
-Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->isEmptyOrNull(Ljava/lang/CharSequence;)Z
-Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->isErasure()Z
-Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->isRegister()Z
-Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->isSupportedOverImsPhone()Z
-Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->isTemporaryModeCLIR()Z
-Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->mContext:Landroid/content/Context;
-Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->mPhone:Lcom/android/internal/telephony/imsphone/ImsPhone;
-Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->newFromDialString(Ljava/lang/String;Lcom/android/internal/telephony/imsphone/ImsPhone;)Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;
-Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->processCode()V
-Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->serviceClassToCFString(I)Ljava/lang/CharSequence;
 Lcom/android/internal/telephony/InboundSmsHandler$SmsBroadcastReceiver;-><init>(Lcom/android/internal/telephony/InboundSmsHandler;Lcom/android/internal/telephony/InboundSmsTracker;)V
-Lcom/android/internal/telephony/InboundSmsHandler$SmsBroadcastReceiver;->mDeleteWhere:Ljava/lang/String;
-Lcom/android/internal/telephony/InboundSmsHandler$SmsBroadcastReceiver;->mDeleteWhereArgs:[Ljava/lang/String;
-Lcom/android/internal/telephony/InboundSmsHandler;->acknowledgeLastIncomingSms(ZILandroid/os/Message;)V
-Lcom/android/internal/telephony/InboundSmsHandler;->deleteFromRawTable(Ljava/lang/String;[Ljava/lang/String;I)V
-Lcom/android/internal/telephony/InboundSmsHandler;->dispatchIntent(Landroid/content/Intent;Ljava/lang/String;ILandroid/os/Bundle;Landroid/content/BroadcastReceiver;Landroid/os/UserHandle;)V
-Lcom/android/internal/telephony/InboundSmsHandler;->dispatchNormalMessage(Lcom/android/internal/telephony/SmsMessageBase;)I
-Lcom/android/internal/telephony/InboundSmsHandler;->getPhone()Lcom/android/internal/telephony/Phone;
-Lcom/android/internal/telephony/InboundSmsHandler;->handleInjectSms(Landroid/os/AsyncResult;)V
-Lcom/android/internal/telephony/InboundSmsHandler;->handleNewSms(Landroid/os/AsyncResult;)V
-Lcom/android/internal/telephony/InboundSmsHandler;->handleSmsWhitelisting(Landroid/content/ComponentName;)Landroid/os/Bundle;
-Lcom/android/internal/telephony/InboundSmsHandler;->isSkipNotifyFlagSet(I)Z
-Lcom/android/internal/telephony/InboundSmsHandler;->log(Ljava/lang/String;)V
-Lcom/android/internal/telephony/InboundSmsHandler;->loge(Ljava/lang/String;)V
-Lcom/android/internal/telephony/InboundSmsHandler;->mCellBroadcastHandler:Lcom/android/internal/telephony/CellBroadcastHandler;
-Lcom/android/internal/telephony/InboundSmsHandler;->mContext:Landroid/content/Context;
-Lcom/android/internal/telephony/InboundSmsHandler;->mDeliveringState:Lcom/android/internal/telephony/InboundSmsHandler$DeliveringState;
-Lcom/android/internal/telephony/InboundSmsHandler;->mDeviceIdleController:Landroid/os/IDeviceIdleController;
-Lcom/android/internal/telephony/InboundSmsHandler;->mIdleState:Lcom/android/internal/telephony/InboundSmsHandler$IdleState;
-Lcom/android/internal/telephony/InboundSmsHandler;->mPhone:Lcom/android/internal/telephony/Phone;
-Lcom/android/internal/telephony/InboundSmsHandler;->mResolver:Landroid/content/ContentResolver;
-Lcom/android/internal/telephony/InboundSmsHandler;->mUserManager:Landroid/os/UserManager;
-Lcom/android/internal/telephony/InboundSmsHandler;->mWaitingState:Lcom/android/internal/telephony/InboundSmsHandler$WaitingState;
-Lcom/android/internal/telephony/InboundSmsHandler;->mWakeLock:Landroid/os/PowerManager$WakeLock;
-Lcom/android/internal/telephony/InboundSmsHandler;->mWapPush:Lcom/android/internal/telephony/WapPushOverSms;
-Lcom/android/internal/telephony/InboundSmsHandler;->processMessagePart(Lcom/android/internal/telephony/InboundSmsTracker;)Z
-Lcom/android/internal/telephony/InboundSmsHandler;->showNewMessageNotification()V
-Lcom/android/internal/telephony/InboundSmsHandler;->writeInboxMessage(Landroid/content/Intent;)Landroid/net/Uri;
-Lcom/android/internal/telephony/InboundSmsTracker;->getFormat()Ljava/lang/String;
-Lcom/android/internal/telephony/InboundSmsTracker;->getIndexOffset()I
-Lcom/android/internal/telephony/IntRangeManager;->mRanges:Ljava/util/ArrayList;
 Lcom/android/internal/telephony/IPhoneStateListener$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/IPhoneStateListener;
 Lcom/android/internal/telephony/IPhoneSubInfo$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Lcom/android/internal/telephony/IPhoneSubInfo$Stub$Proxy;->getDeviceId(Ljava/lang/String;)Ljava/lang/String;
@@ -2603,91 +1982,6 @@
 Lcom/android/internal/telephony/ITelephonyRegistry$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Lcom/android/internal/telephony/ITelephonyRegistry$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/ITelephonyRegistry;
 Lcom/android/internal/telephony/IWapPushManager$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/IWapPushManager;
-Lcom/android/internal/telephony/MccTable$MccEntry;->mIso:Ljava/lang/String;
-Lcom/android/internal/telephony/MccTable;->countryCodeForMcc(I)Ljava/lang/String;
-Lcom/android/internal/telephony/MccTable;->defaultLanguageForMcc(I)Ljava/lang/String;
-Lcom/android/internal/telephony/MccTable;->defaultTimeZoneForMcc(I)Ljava/lang/String;
-Lcom/android/internal/telephony/MccTable;->entryForMcc(I)Lcom/android/internal/telephony/MccTable$MccEntry;
-Lcom/android/internal/telephony/MccTable;->getLocaleForLanguageCountry(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)Ljava/util/Locale;
-Lcom/android/internal/telephony/MccTable;->smallestDigitsMccForMnc(I)I
-Lcom/android/internal/telephony/MmiCode$State;->CANCELLED:Lcom/android/internal/telephony/MmiCode$State;
-Lcom/android/internal/telephony/MmiCode$State;->COMPLETE:Lcom/android/internal/telephony/MmiCode$State;
-Lcom/android/internal/telephony/MmiCode$State;->FAILED:Lcom/android/internal/telephony/MmiCode$State;
-Lcom/android/internal/telephony/MmiCode$State;->PENDING:Lcom/android/internal/telephony/MmiCode$State;
-Lcom/android/internal/telephony/MmiCode;->getPhone()Lcom/android/internal/telephony/Phone;
-Lcom/android/internal/telephony/Phone;->dispose()V
-Lcom/android/internal/telephony/Phone;->exitEmergencyCallbackMode()V
-Lcom/android/internal/telephony/Phone;->getActiveApnTypes()[Ljava/lang/String;
-Lcom/android/internal/telephony/Phone;->getCallTracker()Lcom/android/internal/telephony/CallTracker;
-Lcom/android/internal/telephony/Phone;->getCellLocation()Landroid/telephony/CellLocation;
-Lcom/android/internal/telephony/Phone;->getContext()Landroid/content/Context;
-Lcom/android/internal/telephony/Phone;->getDataConnectionState()Lcom/android/internal/telephony/PhoneConstants$DataState;
-Lcom/android/internal/telephony/Phone;->getIccCard()Lcom/android/internal/telephony/IccCard;
-Lcom/android/internal/telephony/Phone;->getIccFileHandler()Lcom/android/internal/telephony/uicc/IccFileHandler;
-Lcom/android/internal/telephony/Phone;->getIccSerialNumber()Ljava/lang/String;
-Lcom/android/internal/telephony/Phone;->getIccSmsInterfaceManager()Lcom/android/internal/telephony/IccSmsInterfaceManager;
-Lcom/android/internal/telephony/Phone;->getImsPhone()Lcom/android/internal/telephony/Phone;
-Lcom/android/internal/telephony/Phone;->getIsimRecords()Lcom/android/internal/telephony/uicc/IsimRecords;
-Lcom/android/internal/telephony/Phone;->getMsisdn()Ljava/lang/String;
-Lcom/android/internal/telephony/Phone;->getNai()Ljava/lang/String;
-Lcom/android/internal/telephony/Phone;->getPhoneId()I
-Lcom/android/internal/telephony/Phone;->getPhoneName()Ljava/lang/String;
-Lcom/android/internal/telephony/Phone;->getPhoneType()I
-Lcom/android/internal/telephony/Phone;->getServiceStateTracker()Lcom/android/internal/telephony/ServiceStateTracker;
-Lcom/android/internal/telephony/Phone;->getSmscAddress(Landroid/os/Message;)V
-Lcom/android/internal/telephony/Phone;->getState()Lcom/android/internal/telephony/PhoneConstants$State;
-Lcom/android/internal/telephony/Phone;->getSubId()I
-Lcom/android/internal/telephony/Phone;->getSystemProperty(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
-Lcom/android/internal/telephony/Phone;->getUiccCard()Lcom/android/internal/telephony/uicc/UiccCard;
-Lcom/android/internal/telephony/Phone;->getVideoState(Lcom/android/internal/telephony/Call;)I
-Lcom/android/internal/telephony/Phone;->invokeOemRilRequestRaw([BLandroid/os/Message;)V
-Lcom/android/internal/telephony/Phone;->invokeOemRilRequestStrings([Ljava/lang/String;Landroid/os/Message;)V
-Lcom/android/internal/telephony/Phone;->isCspPlmnEnabled()Z
-Lcom/android/internal/telephony/Phone;->isUtEnabled()Z
-Lcom/android/internal/telephony/Phone;->isVideoEnabled()Z
-Lcom/android/internal/telephony/Phone;->isVolteEnabled()Z
-Lcom/android/internal/telephony/Phone;->isWifiCallingEnabled()Z
-Lcom/android/internal/telephony/Phone;->mCi:Lcom/android/internal/telephony/CommandsInterface;
-Lcom/android/internal/telephony/Phone;->mContext:Landroid/content/Context;
-Lcom/android/internal/telephony/Phone;->mIccRecords:Ljava/util/concurrent/atomic/AtomicReference;
-Lcom/android/internal/telephony/Phone;->mImsPhone:Lcom/android/internal/telephony/Phone;
-Lcom/android/internal/telephony/Phone;->mMmiRegistrants:Landroid/os/RegistrantList;
-Lcom/android/internal/telephony/Phone;->mNotifier:Lcom/android/internal/telephony/PhoneNotifier;
-Lcom/android/internal/telephony/Phone;->mPhoneId:I
-Lcom/android/internal/telephony/Phone;->mSmsStorageMonitor:Lcom/android/internal/telephony/SmsStorageMonitor;
-Lcom/android/internal/telephony/Phone;->mUiccApplication:Ljava/util/concurrent/atomic/AtomicReference;
-Lcom/android/internal/telephony/Phone;->mUiccController:Lcom/android/internal/telephony/uicc/UiccController;
-Lcom/android/internal/telephony/Phone;->needsOtaServiceProvisioning()Z
-Lcom/android/internal/telephony/Phone;->notifyOtaspChanged(I)V
-Lcom/android/internal/telephony/Phone;->registerForDisconnect(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/Phone;->registerForEcmTimerReset(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/Phone;->registerForIncomingRing(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/Phone;->registerForMmiComplete(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/Phone;->registerForMmiInitiate(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/Phone;->registerForNewRingingConnection(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/Phone;->registerForPreciseCallStateChanged(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/Phone;->registerForRingbackTone(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/Phone;->registerForServiceStateChanged(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/Phone;->registerForSimRecordsLoaded(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/Phone;->registerForUnknownConnection(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/Phone;->selectNetworkManually(Lcom/android/internal/telephony/OperatorInfo;ZLandroid/os/Message;)V
-Lcom/android/internal/telephony/Phone;->setNetworkSelectionModeAutomatic(Landroid/os/Message;)V
-Lcom/android/internal/telephony/Phone;->setOnEcbModeExitResponse(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/Phone;->setOnPostDialCharacter(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/Phone;->setPreferredNetworkType(ILandroid/os/Message;)V
-Lcom/android/internal/telephony/Phone;->setSmscAddress(Ljava/lang/String;Landroid/os/Message;)V
-Lcom/android/internal/telephony/Phone;->unregisterForDisconnect(Landroid/os/Handler;)V
-Lcom/android/internal/telephony/Phone;->unregisterForEcmTimerReset(Landroid/os/Handler;)V
-Lcom/android/internal/telephony/Phone;->unregisterForIncomingRing(Landroid/os/Handler;)V
-Lcom/android/internal/telephony/Phone;->unregisterForMmiComplete(Landroid/os/Handler;)V
-Lcom/android/internal/telephony/Phone;->unregisterForMmiInitiate(Landroid/os/Handler;)V
-Lcom/android/internal/telephony/Phone;->unregisterForNewRingingConnection(Landroid/os/Handler;)V
-Lcom/android/internal/telephony/Phone;->unregisterForPreciseCallStateChanged(Landroid/os/Handler;)V
-Lcom/android/internal/telephony/Phone;->unregisterForRingbackTone(Landroid/os/Handler;)V
-Lcom/android/internal/telephony/Phone;->unregisterForServiceStateChanged(Landroid/os/Handler;)V
-Lcom/android/internal/telephony/Phone;->unregisterForSimRecordsLoaded(Landroid/os/Handler;)V
-Lcom/android/internal/telephony/Phone;->unregisterForUnknownConnection(Landroid/os/Handler;)V
-Lcom/android/internal/telephony/Phone;->unsetOnEcbModeExitResponse(Landroid/os/Handler;)V
 Lcom/android/internal/telephony/PhoneConstants$DataState;->CONNECTED:Lcom/android/internal/telephony/PhoneConstants$DataState;
 Lcom/android/internal/telephony/PhoneConstants$DataState;->CONNECTING:Lcom/android/internal/telephony/PhoneConstants$DataState;
 Lcom/android/internal/telephony/PhoneConstants$DataState;->DISCONNECTED:Lcom/android/internal/telephony/PhoneConstants$DataState;
@@ -2701,152 +1995,7 @@
 Lcom/android/internal/telephony/PhoneConstants;->PRESENTATION_PAYPHONE:I
 Lcom/android/internal/telephony/PhoneConstants;->PRESENTATION_RESTRICTED:I
 Lcom/android/internal/telephony/PhoneConstants;->PRESENTATION_UNKNOWN:I
-Lcom/android/internal/telephony/PhoneFactory;->calculatePreferredNetworkType(Landroid/content/Context;I)I
-Lcom/android/internal/telephony/PhoneFactory;->getDefaultPhone()Lcom/android/internal/telephony/Phone;
-Lcom/android/internal/telephony/PhoneFactory;->getDefaultSubscription()I
-Lcom/android/internal/telephony/PhoneFactory;->getPhone(I)Lcom/android/internal/telephony/Phone;
-Lcom/android/internal/telephony/PhoneFactory;->getPhones()[Lcom/android/internal/telephony/Phone;
-Lcom/android/internal/telephony/PhoneFactory;->makeDefaultPhone(Landroid/content/Context;)V
-Lcom/android/internal/telephony/PhoneFactory;->sCommandsInterface:Lcom/android/internal/telephony/CommandsInterface;
-Lcom/android/internal/telephony/PhoneFactory;->sContext:Landroid/content/Context;
-Lcom/android/internal/telephony/PhoneFactory;->sMadeDefaults:Z
-Lcom/android/internal/telephony/PhoneFactory;->sPhoneNotifier:Lcom/android/internal/telephony/PhoneNotifier;
-Lcom/android/internal/telephony/PhoneInternalInterface$DataActivityState;->NONE:Lcom/android/internal/telephony/PhoneInternalInterface$DataActivityState;
-Lcom/android/internal/telephony/PhoneInternalInterface;->PREFERRED_NT_MODE:I
-Lcom/android/internal/telephony/PhoneNotifier;->notifyMessageWaitingChanged(Lcom/android/internal/telephony/Phone;)V
-Lcom/android/internal/telephony/PhoneNotifier;->notifySignalStrength(Lcom/android/internal/telephony/Phone;)V
-Lcom/android/internal/telephony/PhoneStateIntentReceiver;-><init>(Landroid/content/Context;Landroid/os/Handler;)V
-Lcom/android/internal/telephony/PhoneStateIntentReceiver;->getSignalStrengthDbm()I
-Lcom/android/internal/telephony/PhoneStateIntentReceiver;->mSignalStrength:Landroid/telephony/SignalStrength;
-Lcom/android/internal/telephony/PhoneStateIntentReceiver;->mWants:I
-Lcom/android/internal/telephony/PhoneStateIntentReceiver;->notifyServiceState(I)V
-Lcom/android/internal/telephony/PhoneStateIntentReceiver;->notifySignalStrength(I)V
-Lcom/android/internal/telephony/PhoneStateIntentReceiver;->registerIntent()V
-Lcom/android/internal/telephony/PhoneStateIntentReceiver;->unregisterIntent()V
-Lcom/android/internal/telephony/PhoneSubInfoController;->getDefaultSubscription()I
-Lcom/android/internal/telephony/PhoneSubInfoController;->getPhone(I)Lcom/android/internal/telephony/Phone;
-Lcom/android/internal/telephony/PhoneSubInfoController;->loge(Ljava/lang/String;)V
-Lcom/android/internal/telephony/PhoneSubInfoController;->mContext:Landroid/content/Context;
-Lcom/android/internal/telephony/PhoneSubInfoController;->mPhone:[Lcom/android/internal/telephony/Phone;
-Lcom/android/internal/telephony/PhoneSwitcher;->activate(I)V
-Lcom/android/internal/telephony/PhoneSwitcher;->deactivate(I)V
-Lcom/android/internal/telephony/PhoneSwitcher;->log(Ljava/lang/String;)V
-Lcom/android/internal/telephony/PhoneSwitcher;->mMaxActivePhones:I
-Lcom/android/internal/telephony/PhoneSwitcher;->mNumPhones:I
-Lcom/android/internal/telephony/PhoneSwitcher;->mPhones:[Lcom/android/internal/telephony/Phone;
-Lcom/android/internal/telephony/ProxyController;->completeRadioCapabilityTransaction()V
-Lcom/android/internal/telephony/ProxyController;->getInstance()Lcom/android/internal/telephony/ProxyController;
-Lcom/android/internal/telephony/ProxyController;->logd(Ljava/lang/String;)V
-Lcom/android/internal/telephony/ProxyController;->mOldRadioAccessFamily:[I
-Lcom/android/internal/telephony/ProxyController;->mRadioCapabilitySessionId:I
-Lcom/android/internal/telephony/ProxyController;->mSetRadioAccessFamilyStatus:[I
-Lcom/android/internal/telephony/ProxyController;->mUniqueIdGenerator:Ljava/util/concurrent/atomic/AtomicInteger;
-Lcom/android/internal/telephony/ProxyController;->sendRadioCapabilityRequest(IIIILjava/lang/String;II)V
-Lcom/android/internal/telephony/ProxyController;->sProxyController:Lcom/android/internal/telephony/ProxyController;
-Lcom/android/internal/telephony/RadioCapability;->getRadioAccessFamily()I
-Lcom/android/internal/telephony/RetryManager;->configure(Ljava/lang/String;)Z
-Lcom/android/internal/telephony/RetryManager;->getRetryTimer()I
-Lcom/android/internal/telephony/RetryManager;->log(Ljava/lang/String;)V
-Lcom/android/internal/telephony/RetryManager;->mApnType:Ljava/lang/String;
-Lcom/android/internal/telephony/RetryManager;->mFailFastInterApnDelay:J
-Lcom/android/internal/telephony/RetryManager;->mInterApnDelay:J
-Lcom/android/internal/telephony/RetryManager;->mPhone:Lcom/android/internal/telephony/Phone;
-Lcom/android/internal/telephony/RIL;-><init>(Landroid/content/Context;II)V
-Lcom/android/internal/telephony/RIL;-><init>(Landroid/content/Context;IILjava/lang/Integer;)V
-Lcom/android/internal/telephony/RIL;->acquireWakeLock(Lcom/android/internal/telephony/RILRequest;I)V
-Lcom/android/internal/telephony/RIL;->clearRequestList(IZ)V
-Lcom/android/internal/telephony/RIL;->clearWakeLock(I)Z
-Lcom/android/internal/telephony/RIL;->decrementWakeLock(Lcom/android/internal/telephony/RILRequest;)V
-Lcom/android/internal/telephony/RIL;->findAndRemoveRequestFromList(I)Lcom/android/internal/telephony/RILRequest;
-Lcom/android/internal/telephony/RIL;->getResponseForTimedOutRILRequest(Lcom/android/internal/telephony/RILRequest;)Ljava/lang/Object;
-Lcom/android/internal/telephony/RIL;->hangupForegroundResumeBackground(Landroid/os/Message;)V
-Lcom/android/internal/telephony/RIL;->hangupWaitingOrBackground(Landroid/os/Message;)V
-Lcom/android/internal/telephony/RIL;->invokeOemRilRequestRaw([BLandroid/os/Message;)V
-Lcom/android/internal/telephony/RIL;->makeStaticRadioCapability()Lcom/android/internal/telephony/RadioCapability;
-Lcom/android/internal/telephony/RIL;->mRequestList:Landroid/util/SparseArray;
-Lcom/android/internal/telephony/RIL;->mTestingEmergencyCall:Ljava/util/concurrent/atomic/AtomicBoolean;
-Lcom/android/internal/telephony/RIL;->mWakeLock:Landroid/os/PowerManager$WakeLock;
-Lcom/android/internal/telephony/RIL;->notifyRegistrantsCdmaInfoRec(Lcom/android/internal/telephony/cdma/CdmaInformationRecords;)V
-Lcom/android/internal/telephony/RIL;->notifyRegistrantsRilConnectionChanged(I)V
-Lcom/android/internal/telephony/RIL;->requestToString(I)Ljava/lang/String;
-Lcom/android/internal/telephony/RIL;->responseToString(I)Ljava/lang/String;
-Lcom/android/internal/telephony/RIL;->retToString(ILjava/lang/Object;)Ljava/lang/String;
-Lcom/android/internal/telephony/RIL;->riljLog(Ljava/lang/String;)V
-Lcom/android/internal/telephony/RIL;->setRadioPower(ZLandroid/os/Message;)V
-Lcom/android/internal/telephony/RIL;->unsljLog(I)V
-Lcom/android/internal/telephony/RIL;->unsljLogMore(ILjava/lang/String;)V
-Lcom/android/internal/telephony/RIL;->unsljLogRet(ILjava/lang/Object;)V
-Lcom/android/internal/telephony/RIL;->unsljLogvRet(ILjava/lang/Object;)V
 Lcom/android/internal/telephony/RILConstants;->PREFERRED_NETWORK_MODE:I
-Lcom/android/internal/telephony/RILRequest;->mRequest:I
-Lcom/android/internal/telephony/RILRequest;->mResult:Landroid/os/Message;
-Lcom/android/internal/telephony/RILRequest;->mSerial:I
-Lcom/android/internal/telephony/RILRequest;->obtain(ILandroid/os/Message;)Lcom/android/internal/telephony/RILRequest;
-Lcom/android/internal/telephony/RILRequest;->onError(ILjava/lang/Object;)V
-Lcom/android/internal/telephony/RILRequest;->release()V
-Lcom/android/internal/telephony/RILRequest;->serialString()Ljava/lang/String;
-Lcom/android/internal/telephony/ServiceStateTracker;->fixUnknownMcc(Ljava/lang/String;I)Ljava/lang/String;
-Lcom/android/internal/telephony/ServiceStateTracker;->getCurrentDataConnectionState()I
-Lcom/android/internal/telephony/ServiceStateTracker;->getDesiredPowerState()Z
-Lcom/android/internal/telephony/ServiceStateTracker;->getPhoneId()I
-Lcom/android/internal/telephony/ServiceStateTracker;->getSystemProperty(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
-Lcom/android/internal/telephony/ServiceStateTracker;->isConcurrentVoiceAndDataAllowed()Z
-Lcom/android/internal/telephony/ServiceStateTracker;->isGprsConsistent(II)Z
-Lcom/android/internal/telephony/ServiceStateTracker;->isImsRegistered()Z
-Lcom/android/internal/telephony/ServiceStateTracker;->isInHomeSidNid(II)Z
-Lcom/android/internal/telephony/ServiceStateTracker;->isInvalidOperatorNumeric(Ljava/lang/String;)Z
-Lcom/android/internal/telephony/ServiceStateTracker;->log(Ljava/lang/String;)V
-Lcom/android/internal/telephony/ServiceStateTracker;->loge(Ljava/lang/String;)V
-Lcom/android/internal/telephony/ServiceStateTracker;->mCi:Lcom/android/internal/telephony/CommandsInterface;
-Lcom/android/internal/telephony/ServiceStateTracker;->mCr:Landroid/content/ContentResolver;
-Lcom/android/internal/telephony/ServiceStateTracker;->mCurDataSpn:Ljava/lang/String;
-Lcom/android/internal/telephony/ServiceStateTracker;->mCurPlmn:Ljava/lang/String;
-Lcom/android/internal/telephony/ServiceStateTracker;->mCurShowPlmn:Z
-Lcom/android/internal/telephony/ServiceStateTracker;->mCurShowSpn:Z
-Lcom/android/internal/telephony/ServiceStateTracker;->mCurSpn:Ljava/lang/String;
-Lcom/android/internal/telephony/ServiceStateTracker;->mDataRoamingOffRegistrants:Landroid/os/RegistrantList;
-Lcom/android/internal/telephony/ServiceStateTracker;->mDataRoamingOnRegistrants:Landroid/os/RegistrantList;
-Lcom/android/internal/telephony/ServiceStateTracker;->mDefaultRoamingIndicator:I
-Lcom/android/internal/telephony/ServiceStateTracker;->mDesiredPowerState:Z
-Lcom/android/internal/telephony/ServiceStateTracker;->mDeviceShuttingDown:Z
-Lcom/android/internal/telephony/ServiceStateTracker;->mEmergencyOnly:Z
-Lcom/android/internal/telephony/ServiceStateTracker;->mIccRecords:Lcom/android/internal/telephony/uicc/IccRecords;
-Lcom/android/internal/telephony/ServiceStateTracker;->mIntentReceiver:Landroid/content/BroadcastReceiver;
-Lcom/android/internal/telephony/ServiceStateTracker;->mIsSubscriptionFromRuim:Z
-Lcom/android/internal/telephony/ServiceStateTracker;->mMaxDataCalls:I
-Lcom/android/internal/telephony/ServiceStateTracker;->mNetworkAttachedRegistrants:Landroid/os/RegistrantList;
-Lcom/android/internal/telephony/ServiceStateTracker;->mNewMaxDataCalls:I
-Lcom/android/internal/telephony/ServiceStateTracker;->mNewReasonDataDenied:I
-Lcom/android/internal/telephony/ServiceStateTracker;->mNewSS:Landroid/telephony/ServiceState;
-Lcom/android/internal/telephony/ServiceStateTracker;->mOnSubscriptionsChangedListener:Lcom/android/internal/telephony/ServiceStateTracker$SstSubscriptionsChangedListener;
-Lcom/android/internal/telephony/ServiceStateTracker;->mPhone:Lcom/android/internal/telephony/GsmCdmaPhone;
-Lcom/android/internal/telephony/ServiceStateTracker;->mPreferredNetworkType:I
-Lcom/android/internal/telephony/ServiceStateTracker;->mReasonDataDenied:I
-Lcom/android/internal/telephony/ServiceStateTracker;->mReportedGprsNoReg:Z
-Lcom/android/internal/telephony/ServiceStateTracker;->mRoamingIndicator:I
-Lcom/android/internal/telephony/ServiceStateTracker;->mSignalStrength:Landroid/telephony/SignalStrength;
-Lcom/android/internal/telephony/ServiceStateTracker;->mSpnUpdatePending:Z
-Lcom/android/internal/telephony/ServiceStateTracker;->mSS:Landroid/telephony/ServiceState;
-Lcom/android/internal/telephony/ServiceStateTracker;->mStartedGprsRegCheck:Z
-Lcom/android/internal/telephony/ServiceStateTracker;->mSubId:I
-Lcom/android/internal/telephony/ServiceStateTracker;->mSubscriptionController:Lcom/android/internal/telephony/SubscriptionController;
-Lcom/android/internal/telephony/ServiceStateTracker;->mSubscriptionManager:Landroid/telephony/SubscriptionManager;
-Lcom/android/internal/telephony/ServiceStateTracker;->mUiccApplcation:Lcom/android/internal/telephony/uicc/UiccCardApplication;
-Lcom/android/internal/telephony/ServiceStateTracker;->mUiccController:Lcom/android/internal/telephony/uicc/UiccController;
-Lcom/android/internal/telephony/ServiceStateTracker;->mVoiceRoamingOffRegistrants:Landroid/os/RegistrantList;
-Lcom/android/internal/telephony/ServiceStateTracker;->mVoiceRoamingOnRegistrants:Landroid/os/RegistrantList;
-Lcom/android/internal/telephony/ServiceStateTracker;->notifySignalStrength()Z
-Lcom/android/internal/telephony/ServiceStateTracker;->pollState()V
-Lcom/android/internal/telephony/ServiceStateTracker;->reRegisterNetwork(Landroid/os/Message;)V
-Lcom/android/internal/telephony/ServiceStateTracker;->resetServiceStateInIwlanMode()V
-Lcom/android/internal/telephony/ServiceStateTracker;->setOperatorIdd(Ljava/lang/String;)V
-Lcom/android/internal/telephony/ServiceStateTracker;->setRoamingType(Landroid/telephony/ServiceState;)V
-Lcom/android/internal/telephony/ServiceStateTracker;->setSignalStrengthDefaultValues()V
-Lcom/android/internal/telephony/ServiceStateTracker;->updateOtaspState()V
-Lcom/android/internal/telephony/ServiceStateTracker;->updatePhoneObject()V
-Lcom/android/internal/telephony/ServiceStateTracker;->updateRoamingState()V
-Lcom/android/internal/telephony/ServiceStateTracker;->updateSpnDisplay()V
-Lcom/android/internal/telephony/ServiceStateTracker;->useDataRegStateForDataOnlyDevices()V
 Lcom/android/internal/telephony/sip/SipPhone$SipCall;->hold()V
 Lcom/android/internal/telephony/sip/SipPhone$SipCall;->switchWith(Lcom/android/internal/telephony/sip/SipPhone$SipCall;)V
 Lcom/android/internal/telephony/sip/SipPhone$SipCall;->unhold()V
@@ -2870,100 +2019,14 @@
 Lcom/android/internal/telephony/SmsApplication;->isDefaultSmsApplication(Landroid/content/Context;Ljava/lang/String;)Z
 Lcom/android/internal/telephony/SmsApplication;->setDefaultApplication(Ljava/lang/String;Landroid/content/Context;)V
 Lcom/android/internal/telephony/SmsApplication;->shouldWriteMessageForPackage(Ljava/lang/String;Landroid/content/Context;)Z
-Lcom/android/internal/telephony/SmsBroadcastUndelivered;-><init>(Landroid/content/Context;Lcom/android/internal/telephony/gsm/GsmInboundSmsHandler;Lcom/android/internal/telephony/cdma/CdmaInboundSmsHandler;)V
-Lcom/android/internal/telephony/SMSDispatcher$ConfirmDialogListener;->mNegativeButton:Landroid/widget/Button;
-Lcom/android/internal/telephony/SMSDispatcher$ConfirmDialogListener;->mPositiveButton:Landroid/widget/Button;
-Lcom/android/internal/telephony/SMSDispatcher$ConfirmDialogListener;->mRememberUndoInstruction:Landroid/widget/TextView;
 Lcom/android/internal/telephony/SMSDispatcher$DataSmsSender;-><init>(Lcom/android/internal/telephony/SMSDispatcher;Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;)V
 Lcom/android/internal/telephony/SMSDispatcher$MultipartSmsSender;-><init>(Lcom/android/internal/telephony/SMSDispatcher;Ljava/util/ArrayList;[Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;)V
-Lcom/android/internal/telephony/SMSDispatcher$MultipartSmsSender;->sendSmsByCarrierApp(Ljava/lang/String;Lcom/android/internal/telephony/SMSDispatcher$MultipartSmsSenderCallback;)V
 Lcom/android/internal/telephony/SMSDispatcher$MultipartSmsSenderCallback;-><init>(Lcom/android/internal/telephony/SMSDispatcher;Lcom/android/internal/telephony/SMSDispatcher$MultipartSmsSender;)V
 Lcom/android/internal/telephony/SMSDispatcher$SmsSenderCallback;-><init>(Lcom/android/internal/telephony/SMSDispatcher;Lcom/android/internal/telephony/SMSDispatcher$SmsSender;)V
-Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;->isMultipart()Z
-Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;->mAppInfo:Landroid/content/pm/PackageInfo;
-Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;->mData:Ljava/util/HashMap;
-Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;->mDeliveryIntent:Landroid/app/PendingIntent;
-Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;->mDestAddress:Ljava/lang/String;
-Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;->mMessageRef:I
-Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;->mMessageUri:Landroid/net/Uri;
-Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;->mPersistMessage:Z
-Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;->mSentIntent:Landroid/app/PendingIntent;
-Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;->mTimestamp:J
-Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;->onFailed(Landroid/content/Context;II)V
-Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;->onSent(Landroid/content/Context;)V
-Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;->updateSentMessageStatus(Landroid/content/Context;I)V
 Lcom/android/internal/telephony/SMSDispatcher$TextSmsSender;-><init>(Lcom/android/internal/telephony/SMSDispatcher;Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;)V
-Lcom/android/internal/telephony/SMSDispatcher;->calculateLength(Ljava/lang/CharSequence;Z)Lcom/android/internal/telephony/GsmAlphabet$TextEncodingDetails;
-Lcom/android/internal/telephony/SMSDispatcher;->checkCallerIsPhoneOrCarrierApp()V
-Lcom/android/internal/telephony/SMSDispatcher;->deliveryPendingList:Ljava/util/ArrayList;
-Lcom/android/internal/telephony/SMSDispatcher;->dispose()V
-Lcom/android/internal/telephony/SMSDispatcher;->getCarrierAppPackageName()Ljava/lang/String;
-Lcom/android/internal/telephony/SMSDispatcher;->getMultipartMessageText(Ljava/util/ArrayList;)Ljava/lang/String;
-Lcom/android/internal/telephony/SMSDispatcher;->getNextConcatenatedRef()I
-Lcom/android/internal/telephony/SMSDispatcher;->getSubId()I
-Lcom/android/internal/telephony/SMSDispatcher;->handleConfirmShortCode(ZLcom/android/internal/telephony/SMSDispatcher$SmsTracker;)V
-Lcom/android/internal/telephony/SMSDispatcher;->mCi:Lcom/android/internal/telephony/CommandsInterface;
-Lcom/android/internal/telephony/SMSDispatcher;->mContext:Landroid/content/Context;
-Lcom/android/internal/telephony/SMSDispatcher;->mPhone:Lcom/android/internal/telephony/Phone;
-Lcom/android/internal/telephony/SMSDispatcher;->mResolver:Landroid/content/ContentResolver;
-Lcom/android/internal/telephony/SMSDispatcher;->mTelephonyManager:Landroid/telephony/TelephonyManager;
-Lcom/android/internal/telephony/SMSDispatcher;->processSendSmsResponse(Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;II)V
-Lcom/android/internal/telephony/SMSDispatcher;->sendData(Ljava/lang/String;Ljava/lang/String;I[BLandroid/app/PendingIntent;Landroid/app/PendingIntent;)V
-Lcom/android/internal/telephony/SMSDispatcher;->sendMultipartSms(Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;)V
-Lcom/android/internal/telephony/SMSDispatcher;->sendSms(Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;)V
-Lcom/android/internal/telephony/SMSDispatcher;->sendSubmitPdu(Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;)V
 Lcom/android/internal/telephony/SmsHeader$ConcatRef;-><init>()V
 Lcom/android/internal/telephony/SmsHeader$PortAddrs;-><init>()V
 Lcom/android/internal/telephony/SmsMessageBase;-><init>()V
-Lcom/android/internal/telephony/SmsResponse;-><init>(ILjava/lang/String;I)V
-Lcom/android/internal/telephony/SmsResponse;->mAckPdu:Ljava/lang/String;
-Lcom/android/internal/telephony/SmsResponse;->mErrorCode:I
-Lcom/android/internal/telephony/SmsResponse;->mMessageRef:I
-Lcom/android/internal/telephony/SmsStorageMonitor;->mCi:Lcom/android/internal/telephony/CommandsInterface;
-Lcom/android/internal/telephony/SmsUsageMonitor;-><init>(Landroid/content/Context;)V
-Lcom/android/internal/telephony/SmsUsageMonitor;->check(Ljava/lang/String;I)Z
-Lcom/android/internal/telephony/SubscriptionController;->broadcastDefaultDataSubIdChanged(I)V
-Lcom/android/internal/telephony/SubscriptionController;->colorArr:[I
-Lcom/android/internal/telephony/SubscriptionController;->enforceModifyPhoneState(Ljava/lang/String;)V
-Lcom/android/internal/telephony/SubscriptionController;->getActiveSubInfoCount(Ljava/lang/String;)I
-Lcom/android/internal/telephony/SubscriptionController;->getActiveSubscriptionInfo(ILjava/lang/String;)Landroid/telephony/SubscriptionInfo;
-Lcom/android/internal/telephony/SubscriptionController;->getActiveSubscriptionInfoList(Ljava/lang/String;)Ljava/util/List;
-Lcom/android/internal/telephony/SubscriptionController;->getDefaultDataSubId()I
-Lcom/android/internal/telephony/SubscriptionController;->getDefaultSmsSubId()I
-Lcom/android/internal/telephony/SubscriptionController;->getDefaultSubId()I
-Lcom/android/internal/telephony/SubscriptionController;->getDefaultVoiceSubId()I
-Lcom/android/internal/telephony/SubscriptionController;->getInstance()Lcom/android/internal/telephony/SubscriptionController;
-Lcom/android/internal/telephony/SubscriptionController;->getPhoneId(I)I
-Lcom/android/internal/telephony/SubscriptionController;->getSubId(I)[I
-Lcom/android/internal/telephony/SubscriptionController;->getSubIdUsingPhoneId(I)I
-Lcom/android/internal/telephony/SubscriptionController;->getSubInfo(Ljava/lang/String;Ljava/lang/Object;)Ljava/util/List;
-Lcom/android/internal/telephony/SubscriptionController;->getSubInfoRecord(Landroid/database/Cursor;)Landroid/telephony/SubscriptionInfo;
-Lcom/android/internal/telephony/SubscriptionController;->isActiveSubId(I)Z
-Lcom/android/internal/telephony/SubscriptionController;->isSubInfoReady()Z
-Lcom/android/internal/telephony/SubscriptionController;->logd(Ljava/lang/String;)V
-Lcom/android/internal/telephony/SubscriptionController;->logdl(Ljava/lang/String;)V
-Lcom/android/internal/telephony/SubscriptionController;->loge(Ljava/lang/String;)V
-Lcom/android/internal/telephony/SubscriptionController;->mContext:Landroid/content/Context;
-Lcom/android/internal/telephony/SubscriptionController;->mDefaultPhoneId:I
-Lcom/android/internal/telephony/SubscriptionController;->mLock:Ljava/lang/Object;
-Lcom/android/internal/telephony/SubscriptionController;->notifySubscriptionInfoChanged()V
-Lcom/android/internal/telephony/SubscriptionController;->setDefaultDataSubId(I)V
-Lcom/android/internal/telephony/SubscriptionController;->setDefaultFallbackSubId(II)V
-Lcom/android/internal/telephony/SubscriptionController;->setDefaultSmsSubId(I)V
-Lcom/android/internal/telephony/SubscriptionController;->setDefaultVoiceSubId(I)V
-Lcom/android/internal/telephony/SubscriptionController;->setPlmnSpn(IZLjava/lang/String;ZLjava/lang/String;)Z
-Lcom/android/internal/telephony/SubscriptionController;->updateAllDataConnectionTrackers()V
-Lcom/android/internal/telephony/SubscriptionController;->validateSubId(I)V
-Lcom/android/internal/telephony/SubscriptionInfoUpdater;->broadcastSimStateChanged(ILjava/lang/String;Ljava/lang/String;)V
-Lcom/android/internal/telephony/SubscriptionInfoUpdater;->isAllIccIdQueryDone()Z
-Lcom/android/internal/telephony/SubscriptionInfoUpdater;->logd(Ljava/lang/String;)V
-Lcom/android/internal/telephony/SubscriptionInfoUpdater;->mContext:Landroid/content/Context;
-Lcom/android/internal/telephony/SubscriptionInfoUpdater;->mCurrentlyActiveUserId:I
-Lcom/android/internal/telephony/SubscriptionInfoUpdater;->mIccId:[Ljava/lang/String;
-Lcom/android/internal/telephony/SubscriptionInfoUpdater;->mPackageManager:Landroid/content/pm/IPackageManager;
-Lcom/android/internal/telephony/SubscriptionInfoUpdater;->mPhone:[Lcom/android/internal/telephony/Phone;
-Lcom/android/internal/telephony/SubscriptionInfoUpdater;->PROJECT_SIM_NUM:I
-Lcom/android/internal/telephony/TelephonyCapabilities;->supportsAdn(I)Z
 Lcom/android/internal/telephony/TelephonyProperties;->PROPERTY_ICC_OPERATOR_NUMERIC:Ljava/lang/String;
 Lcom/android/internal/telephony/test/InterpreterEx;-><init>(Ljava/lang/String;)V
 Lcom/android/internal/telephony/test/SimulatedCommands;->acceptCall(Landroid/os/Message;)V
@@ -2980,143 +2043,11 @@
 Lcom/android/internal/telephony/test/SimulatedGsmCallState;->releaseHeldOrUDUB()Z
 Lcom/android/internal/telephony/test/SimulatedGsmCallState;->separateCall(I)Z
 Lcom/android/internal/telephony/test/SimulatedGsmCallState;->switchActiveAndHeldOrWaiting()Z
-Lcom/android/internal/telephony/uicc/AdnRecord;-><init>(IILjava/lang/String;Ljava/lang/String;)V
-Lcom/android/internal/telephony/uicc/AdnRecord;-><init>(IILjava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V
-Lcom/android/internal/telephony/uicc/AdnRecord;-><init>(II[B)V
-Lcom/android/internal/telephony/uicc/AdnRecord;-><init>(Ljava/lang/String;Ljava/lang/String;)V
-Lcom/android/internal/telephony/uicc/AdnRecord;-><init>(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V
-Lcom/android/internal/telephony/uicc/AdnRecord;-><init>([B)V
-Lcom/android/internal/telephony/uicc/AdnRecord;->buildAdnString(I)[B
-Lcom/android/internal/telephony/uicc/AdnRecord;->CREATOR:Landroid/os/Parcelable$Creator;
-Lcom/android/internal/telephony/uicc/AdnRecord;->getEmails()[Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/AdnRecord;->getNumber()Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/AdnRecord;->isEmpty()Z
-Lcom/android/internal/telephony/uicc/AdnRecord;->mAlphaTag:Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/AdnRecord;->mEfid:I
-Lcom/android/internal/telephony/uicc/AdnRecord;->mEmails:[Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/AdnRecord;->mExtRecord:I
-Lcom/android/internal/telephony/uicc/AdnRecord;->mNumber:Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/AdnRecord;->mRecordNumber:I
-Lcom/android/internal/telephony/uicc/AdnRecord;->setEmails([Ljava/lang/String;)V
-Lcom/android/internal/telephony/uicc/AdnRecordCache;->extensionEfForEf(I)I
-Lcom/android/internal/telephony/uicc/AdnRecordCache;->getRecordsIfLoaded(I)Ljava/util/ArrayList;
-Lcom/android/internal/telephony/uicc/AdnRecordCache;->mAdnLikeWaiters:Landroid/util/SparseArray;
-Lcom/android/internal/telephony/uicc/AdnRecordCache;->mFh:Lcom/android/internal/telephony/uicc/IccFileHandler;
-Lcom/android/internal/telephony/uicc/AdnRecordCache;->mUserWriteResponse:Landroid/util/SparseArray;
-Lcom/android/internal/telephony/uicc/AdnRecordCache;->mUsimPhoneBookManager:Lcom/android/internal/telephony/gsm/UsimPhoneBookManager;
-Lcom/android/internal/telephony/uicc/AdnRecordCache;->reset()V
-Lcom/android/internal/telephony/uicc/AdnRecordCache;->sendErrorResponse(Landroid/os/Message;Ljava/lang/String;)V
-Lcom/android/internal/telephony/uicc/AdnRecordCache;->updateAdnByIndex(ILcom/android/internal/telephony/uicc/AdnRecord;ILjava/lang/String;Landroid/os/Message;)V
-Lcom/android/internal/telephony/uicc/AdnRecordLoader;-><init>(Lcom/android/internal/telephony/uicc/IccFileHandler;)V
-Lcom/android/internal/telephony/uicc/AdnRecordLoader;->getEFPath(I)Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/AdnRecordLoader;->loadFromEF(IIILandroid/os/Message;)V
-Lcom/android/internal/telephony/uicc/AdnRecordLoader;->mFh:Lcom/android/internal/telephony/uicc/IccFileHandler;
-Lcom/android/internal/telephony/uicc/AdnRecordLoader;->updateEF(Lcom/android/internal/telephony/uicc/AdnRecord;IIILjava/lang/String;Landroid/os/Message;)V
-Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;->APPSTATE_DETECTED:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;
-Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;->APPSTATE_PIN:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;
-Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;->APPSTATE_PUK:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;
-Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;->APPSTATE_READY:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;
-Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;->APPSTATE_SUBSCRIPTION_PERSO:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;
-Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;->APPSTATE_UNKNOWN:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;
 Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;->values()[Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;
-Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;->APPTYPE_CSIM:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;
-Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;->APPTYPE_ISIM:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;
-Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;->APPTYPE_RUIM:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;
-Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;->APPTYPE_SIM:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;
-Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;->APPTYPE_UNKNOWN:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;
-Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;->APPTYPE_USIM:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;
 Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;->values()[Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;
-Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;->PERSOSUBSTATE_SIM_NETWORK:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;
-Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;->PERSOSUBSTATE_SIM_NETWORK_SUBSET:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;
-Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;->PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;
-Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;->PERSOSUBSTATE_SIM_SERVICE_PROVIDER:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;
-Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;->PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;
-Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;->PERSOSUBSTATE_UNKNOWN:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;
 Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;->values()[Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;
 Lcom/android/internal/telephony/uicc/IccCardApplicationStatus;-><init>()V
-Lcom/android/internal/telephony/uicc/IccCardApplicationStatus;->AppTypeFromRILInt(I)Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;
-Lcom/android/internal/telephony/uicc/IccCardApplicationStatus;->app_type:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;
-Lcom/android/internal/telephony/uicc/IccCardStatus$CardState;->CARDSTATE_ABSENT:Lcom/android/internal/telephony/uicc/IccCardStatus$CardState;
-Lcom/android/internal/telephony/uicc/IccCardStatus$CardState;->CARDSTATE_ERROR:Lcom/android/internal/telephony/uicc/IccCardStatus$CardState;
-Lcom/android/internal/telephony/uicc/IccCardStatus$CardState;->CARDSTATE_PRESENT:Lcom/android/internal/telephony/uicc/IccCardStatus$CardState;
-Lcom/android/internal/telephony/uicc/IccCardStatus$CardState;->isCardPresent()Z
-Lcom/android/internal/telephony/uicc/IccCardStatus$PinState;->PINSTATE_DISABLED:Lcom/android/internal/telephony/uicc/IccCardStatus$PinState;
-Lcom/android/internal/telephony/uicc/IccCardStatus$PinState;->PINSTATE_ENABLED_BLOCKED:Lcom/android/internal/telephony/uicc/IccCardStatus$PinState;
-Lcom/android/internal/telephony/uicc/IccCardStatus$PinState;->PINSTATE_ENABLED_PERM_BLOCKED:Lcom/android/internal/telephony/uicc/IccCardStatus$PinState;
-Lcom/android/internal/telephony/uicc/IccCardStatus;->mApplications:[Lcom/android/internal/telephony/uicc/IccCardApplicationStatus;
-Lcom/android/internal/telephony/uicc/IccCardStatus;->mCardState:Lcom/android/internal/telephony/uicc/IccCardStatus$CardState;
-Lcom/android/internal/telephony/uicc/IccCardStatus;->mCdmaSubscriptionAppIndex:I
-Lcom/android/internal/telephony/uicc/IccCardStatus;->mGsmUmtsSubscriptionAppIndex:I
-Lcom/android/internal/telephony/uicc/IccCardStatus;->mImsSubscriptionAppIndex:I
-Lcom/android/internal/telephony/uicc/IccCardStatus;->mUniversalPinState:Lcom/android/internal/telephony/uicc/IccCardStatus$PinState;
-Lcom/android/internal/telephony/uicc/IccFileHandler$LoadLinearFixedContext;-><init>(IILandroid/os/Message;)V
-Lcom/android/internal/telephony/uicc/IccFileHandler$LoadLinearFixedContext;->mRecordSize:I
-Lcom/android/internal/telephony/uicc/IccFileHandler$LoadLinearFixedContext;->results:Ljava/util/ArrayList;
-Lcom/android/internal/telephony/uicc/IccFileHandler;->getEFLinearRecordSize(ILandroid/os/Message;)V
-Lcom/android/internal/telephony/uicc/IccFileHandler;->getEFLinearRecordSize(ILjava/lang/String;Landroid/os/Message;)V
-Lcom/android/internal/telephony/uicc/IccFileHandler;->getEFPath(I)Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/IccFileHandler;->loadEFLinearFixed(IILandroid/os/Message;)V
-Lcom/android/internal/telephony/uicc/IccFileHandler;->loadEFLinearFixed(ILjava/lang/String;ILandroid/os/Message;)V
-Lcom/android/internal/telephony/uicc/IccFileHandler;->loadEFLinearFixedAll(ILandroid/os/Message;)V
-Lcom/android/internal/telephony/uicc/IccFileHandler;->loadEFLinearFixedAll(ILjava/lang/String;Landroid/os/Message;)V
-Lcom/android/internal/telephony/uicc/IccFileHandler;->loadEFTransparent(ILandroid/os/Message;)V
-Lcom/android/internal/telephony/uicc/IccFileHandler;->mAid:Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/IccFileHandler;->mCi:Lcom/android/internal/telephony/CommandsInterface;
-Lcom/android/internal/telephony/uicc/IccFileHandler;->mParentApp:Lcom/android/internal/telephony/uicc/UiccCardApplication;
-Lcom/android/internal/telephony/uicc/IccFileHandler;->updateEFLinearFixed(II[BLjava/lang/String;Landroid/os/Message;)V
-Lcom/android/internal/telephony/uicc/IccFileHandler;->updateEFLinearFixed(ILjava/lang/String;I[BLjava/lang/String;Landroid/os/Message;)V
-Lcom/android/internal/telephony/uicc/IccFileHandler;->updateEFTransparent(I[BLandroid/os/Message;)V
-Lcom/android/internal/telephony/uicc/IccIoResult;-><init>(IILjava/lang/String;)V
-Lcom/android/internal/telephony/uicc/IccIoResult;-><init>(II[B)V
-Lcom/android/internal/telephony/uicc/IccIoResult;->payload:[B
-Lcom/android/internal/telephony/uicc/IccIoResult;->success()Z
-Lcom/android/internal/telephony/uicc/IccIoResult;->sw1:I
-Lcom/android/internal/telephony/uicc/IccIoResult;->sw2:I
-Lcom/android/internal/telephony/uicc/IccRecords;->auth_rsp:Lcom/android/internal/telephony/uicc/IccIoResult;
-Lcom/android/internal/telephony/uicc/IccRecords;->getGid1()Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/IccRecords;->getIccId()Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/IccRecords;->getIccSimChallengeResponse(ILjava/lang/String;)Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/IccRecords;->getIMSI()Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/IccRecords;->getMsisdnNumber()Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/IccRecords;->getOperatorNumeric()Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/IccRecords;->getRecordsLoaded()Z
-Lcom/android/internal/telephony/uicc/IccRecords;->getServiceProviderName()Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/IccRecords;->getUsimServiceTable()Lcom/android/internal/telephony/uicc/UsimServiceTable;
-Lcom/android/internal/telephony/uicc/IccRecords;->handleRefresh(Lcom/android/internal/telephony/uicc/IccRefreshResponse;)V
-Lcom/android/internal/telephony/uicc/IccRecords;->log(Ljava/lang/String;)V
-Lcom/android/internal/telephony/uicc/IccRecords;->mAdnCache:Lcom/android/internal/telephony/uicc/AdnRecordCache;
-Lcom/android/internal/telephony/uicc/IccRecords;->mCi:Lcom/android/internal/telephony/CommandsInterface;
-Lcom/android/internal/telephony/uicc/IccRecords;->mContext:Landroid/content/Context;
-Lcom/android/internal/telephony/uicc/IccRecords;->mDestroyed:Ljava/util/concurrent/atomic/AtomicBoolean;
-Lcom/android/internal/telephony/uicc/IccRecords;->mFh:Lcom/android/internal/telephony/uicc/IccFileHandler;
-Lcom/android/internal/telephony/uicc/IccRecords;->mGid1:Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/IccRecords;->mIccId:Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/IccRecords;->mImsi:Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/IccRecords;->mIsVoiceMailFixed:Z
-Lcom/android/internal/telephony/uicc/IccRecords;->mLock:Ljava/lang/Object;
-Lcom/android/internal/telephony/uicc/IccRecords;->mMncLength:I
-Lcom/android/internal/telephony/uicc/IccRecords;->mParentApp:Lcom/android/internal/telephony/uicc/UiccCardApplication;
-Lcom/android/internal/telephony/uicc/IccRecords;->mRecordsEventsRegistrants:Landroid/os/RegistrantList;
-Lcom/android/internal/telephony/uicc/IccRecords;->mRecordsToLoad:I
-Lcom/android/internal/telephony/uicc/IccRecords;->mSpn:Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/IccRecords;->mTelephonyManager:Landroid/telephony/TelephonyManager;
-Lcom/android/internal/telephony/uicc/IccRecords;->mVoiceMailNum:Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/IccRecords;->registerForNetworkSelectionModeAutomatic(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/uicc/IccRecords;->registerForNewSms(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/uicc/IccRecords;->registerForRecordsEvents(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/uicc/IccRecords;->registerForRecordsLoaded(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/uicc/IccRecords;->setMsisdnNumber(Ljava/lang/String;Ljava/lang/String;Landroid/os/Message;)V
-Lcom/android/internal/telephony/uicc/IccRecords;->setVoiceCallForwardingFlag(IZLjava/lang/String;)V
-Lcom/android/internal/telephony/uicc/IccRecords;->unregisterForNetworkSelectionModeAutomatic(Landroid/os/Handler;)V
-Lcom/android/internal/telephony/uicc/IccRecords;->unregisterForNewSms(Landroid/os/Handler;)V
-Lcom/android/internal/telephony/uicc/IccRecords;->unregisterForRecordsEvents(Landroid/os/Handler;)V
-Lcom/android/internal/telephony/uicc/IccRecords;->unregisterForRecordsLoaded(Landroid/os/Handler;)V
 Lcom/android/internal/telephony/uicc/IccRefreshResponse;-><init>()V
-Lcom/android/internal/telephony/uicc/IccRefreshResponse;->aid:Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/IccRefreshResponse;->efId:I
-Lcom/android/internal/telephony/uicc/IccRefreshResponse;->refreshResult:I
-Lcom/android/internal/telephony/uicc/IccServiceTable;->getTag()Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/IccServiceTable;->mServiceTable:[B
 Lcom/android/internal/telephony/uicc/IccUtils;->adnStringFieldToString([BII)Ljava/lang/String;
 Lcom/android/internal/telephony/uicc/IccUtils;->bcdToString([BII)Ljava/lang/String;
 Lcom/android/internal/telephony/uicc/IccUtils;->bytesToHexString([B)Ljava/lang/String;
@@ -3128,175 +2059,7 @@
 Lcom/android/internal/telephony/uicc/IccUtils;->networkNameToString([BII)Ljava/lang/String;
 Lcom/android/internal/telephony/uicc/IccUtils;->parseToBnW([BI)Landroid/graphics/Bitmap;
 Lcom/android/internal/telephony/uicc/IccUtils;->parseToRGB([BIZ)Landroid/graphics/Bitmap;
-Lcom/android/internal/telephony/uicc/IsimRecords;->getIsimDomain()Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/IsimRecords;->getIsimImpi()Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/IsimRecords;->getIsimImpu()[Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/IsimUiccRecords;->auth_rsp:Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/IsimUiccRecords;->fetchIsimRecords()V
-Lcom/android/internal/telephony/uicc/IsimUiccRecords;->isimTlvToString([B)Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/IsimUiccRecords;->log(Ljava/lang/String;)V
-Lcom/android/internal/telephony/uicc/IsimUiccRecords;->mIsimDomain:Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/IsimUiccRecords;->mIsimImpi:Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/IsimUiccRecords;->mIsimImpu:[Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/IsimUiccRecords;->mIsimIst:Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/IsimUiccRecords;->mIsimPcscf:[Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/IsimUiccRecords;->mLock:Ljava/lang/Object;
-Lcom/android/internal/telephony/uicc/RuimRecords;->adjstMinDigits(I)I
-Lcom/android/internal/telephony/uicc/RuimRecords;->fetchRuimRecords()V
-Lcom/android/internal/telephony/uicc/RuimRecords;->getAssetLanguages(Landroid/content/Context;)[Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/RuimRecords;->getCsimSpnDisplayCondition()Z
-Lcom/android/internal/telephony/uicc/RuimRecords;->getMdn()Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/RuimRecords;->getMdnNumber()Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/RuimRecords;->getRUIMOperatorNumeric()Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/RuimRecords;->log(Ljava/lang/String;)V
-Lcom/android/internal/telephony/uicc/RuimRecords;->loge(Ljava/lang/String;)V
-Lcom/android/internal/telephony/uicc/RuimRecords;->mEFli:[B
-Lcom/android/internal/telephony/uicc/RuimRecords;->mEFpl:[B
-Lcom/android/internal/telephony/uicc/RuimRecords;->mMin:Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/RuimRecords;->mNai:Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/RuimRecords;->onGetCSimEprlDone(Landroid/os/AsyncResult;)V
-Lcom/android/internal/telephony/uicc/SIMRecords$GetSpnFsmState;->INIT:Lcom/android/internal/telephony/uicc/SIMRecords$GetSpnFsmState;
-Lcom/android/internal/telephony/uicc/SIMRecords$GetSpnFsmState;->READ_SPN_3GPP:Lcom/android/internal/telephony/uicc/SIMRecords$GetSpnFsmState;
-Lcom/android/internal/telephony/uicc/SIMRecords$GetSpnFsmState;->READ_SPN_CPHS:Lcom/android/internal/telephony/uicc/SIMRecords$GetSpnFsmState;
-Lcom/android/internal/telephony/uicc/SIMRecords$GetSpnFsmState;->READ_SPN_SHORT_CPHS:Lcom/android/internal/telephony/uicc/SIMRecords$GetSpnFsmState;
 Lcom/android/internal/telephony/uicc/SIMRecords$GetSpnFsmState;->values()[Lcom/android/internal/telephony/uicc/SIMRecords$GetSpnFsmState;
-Lcom/android/internal/telephony/uicc/SIMRecords;->fetchSimRecords()V
-Lcom/android/internal/telephony/uicc/SIMRecords;->getExtFromEf(I)I
-Lcom/android/internal/telephony/uicc/SIMRecords;->getMsisdnNumber()Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/SIMRecords;->getOperatorNumeric()Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/SIMRecords;->getSpnFsm(ZLandroid/os/AsyncResult;)V
-Lcom/android/internal/telephony/uicc/SIMRecords;->getVoiceMailNumber()Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/SIMRecords;->isCphsMailboxEnabled()Z
-Lcom/android/internal/telephony/uicc/SIMRecords;->log(Ljava/lang/String;)V
-Lcom/android/internal/telephony/uicc/SIMRecords;->loge(Ljava/lang/String;)V
-Lcom/android/internal/telephony/uicc/SIMRecords;->logv(Ljava/lang/String;)V
-Lcom/android/internal/telephony/uicc/SIMRecords;->mEfCff:[B
-Lcom/android/internal/telephony/uicc/SIMRecords;->mEfCfis:[B
-Lcom/android/internal/telephony/uicc/SIMRecords;->mEfCPHS_MWI:[B
-Lcom/android/internal/telephony/uicc/SIMRecords;->mEfLi:[B
-Lcom/android/internal/telephony/uicc/SIMRecords;->mEfMWIS:[B
-Lcom/android/internal/telephony/uicc/SIMRecords;->mEfPl:[B
-Lcom/android/internal/telephony/uicc/SIMRecords;->mSpnDisplayCondition:I
-Lcom/android/internal/telephony/uicc/SIMRecords;->mUsimServiceTable:Lcom/android/internal/telephony/uicc/UsimServiceTable;
-Lcom/android/internal/telephony/uicc/SIMRecords;->mVmConfig:Lcom/android/internal/telephony/uicc/VoiceMailConstants;
-Lcom/android/internal/telephony/uicc/SIMRecords;->setVoiceCallForwardingFlag(IZLjava/lang/String;)V
-Lcom/android/internal/telephony/uicc/UiccCard;->getApplication(I)Lcom/android/internal/telephony/uicc/UiccCardApplication;
-Lcom/android/internal/telephony/uicc/UiccCard;->getApplicationByType(I)Lcom/android/internal/telephony/uicc/UiccCardApplication;
-Lcom/android/internal/telephony/uicc/UiccCard;->getApplicationIndex(I)Lcom/android/internal/telephony/uicc/UiccCardApplication;
-Lcom/android/internal/telephony/uicc/UiccCard;->getCardState()Lcom/android/internal/telephony/uicc/IccCardStatus$CardState;
-Lcom/android/internal/telephony/uicc/UiccCard;->getCarrierPackageNamesForIntent(Landroid/content/pm/PackageManager;Landroid/content/Intent;)Ljava/util/List;
-Lcom/android/internal/telephony/uicc/UiccCard;->getIccId()Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/UiccCard;->getNumApplications()I
-Lcom/android/internal/telephony/uicc/UiccCard;->getOperatorBrandOverride()Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/UiccCard;->isApplicationOnIcc(Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;)Z
-Lcom/android/internal/telephony/uicc/UiccCard;->log(Ljava/lang/String;)V
-Lcom/android/internal/telephony/uicc/UiccCard;->loge(Ljava/lang/String;)V
-Lcom/android/internal/telephony/uicc/UiccCard;->mCardState:Lcom/android/internal/telephony/uicc/IccCardStatus$CardState;
-Lcom/android/internal/telephony/uicc/UiccCard;->mCi:Lcom/android/internal/telephony/CommandsInterface;
-Lcom/android/internal/telephony/uicc/UiccCard;->mContext:Landroid/content/Context;
-Lcom/android/internal/telephony/uicc/UiccCard;->mLock:Ljava/lang/Object;
-Lcom/android/internal/telephony/uicc/UiccCard;->mPhoneId:I
-Lcom/android/internal/telephony/uicc/UiccCardApplication;->dispose()V
-Lcom/android/internal/telephony/uicc/UiccCardApplication;->getAid()Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/UiccCardApplication;->getAuthContext()I
-Lcom/android/internal/telephony/uicc/UiccCardApplication;->getIccFileHandler()Lcom/android/internal/telephony/uicc/IccFileHandler;
-Lcom/android/internal/telephony/uicc/UiccCardApplication;->getIccRecords()Lcom/android/internal/telephony/uicc/IccRecords;
-Lcom/android/internal/telephony/uicc/UiccCardApplication;->getPersoSubState()Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;
-Lcom/android/internal/telephony/uicc/UiccCardApplication;->getPhoneId()I
-Lcom/android/internal/telephony/uicc/UiccCardApplication;->getPin1State()Lcom/android/internal/telephony/uicc/IccCardStatus$PinState;
-Lcom/android/internal/telephony/uicc/UiccCardApplication;->getState()Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;
-Lcom/android/internal/telephony/uicc/UiccCardApplication;->getType()Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;
-Lcom/android/internal/telephony/uicc/UiccCardApplication;->log(Ljava/lang/String;)V
-Lcom/android/internal/telephony/uicc/UiccCardApplication;->loge(Ljava/lang/String;)V
-Lcom/android/internal/telephony/uicc/UiccCardApplication;->mAid:Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/UiccCardApplication;->mAppState:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;
-Lcom/android/internal/telephony/uicc/UiccCardApplication;->mAppType:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;
-Lcom/android/internal/telephony/uicc/UiccCardApplication;->mCi:Lcom/android/internal/telephony/CommandsInterface;
-Lcom/android/internal/telephony/uicc/UiccCardApplication;->mDestroyed:Z
-Lcom/android/internal/telephony/uicc/UiccCardApplication;->mLock:Ljava/lang/Object;
-Lcom/android/internal/telephony/uicc/UiccCardApplication;->mPersoSubState:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;
-Lcom/android/internal/telephony/uicc/UiccCardApplication;->mPin1State:Lcom/android/internal/telephony/uicc/IccCardStatus$PinState;
-Lcom/android/internal/telephony/uicc/UiccCardApplication;->registerForReady(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/uicc/UiccCardApplication;->unregisterForReady(Landroid/os/Handler;)V
-Lcom/android/internal/telephony/uicc/UiccCardApplication;->update(Lcom/android/internal/telephony/uicc/IccCardApplicationStatus;Landroid/content/Context;Lcom/android/internal/telephony/CommandsInterface;)V
-Lcom/android/internal/telephony/uicc/UiccCarrierPrivilegeRules$TLV;->length:Ljava/lang/Integer;
-Lcom/android/internal/telephony/uicc/UiccCarrierPrivilegeRules$TLV;->value:Ljava/lang/String;
-Lcom/android/internal/telephony/uicc/UiccCarrierPrivilegeRules;->mLoadedCallback:Landroid/os/Message;
-Lcom/android/internal/telephony/uicc/UiccCarrierPrivilegeRules;->mState:Ljava/util/concurrent/atomic/AtomicInteger;
-Lcom/android/internal/telephony/uicc/UiccController;->getIccFileHandler(II)Lcom/android/internal/telephony/uicc/IccFileHandler;
-Lcom/android/internal/telephony/uicc/UiccController;->getIccRecords(II)Lcom/android/internal/telephony/uicc/IccRecords;
-Lcom/android/internal/telephony/uicc/UiccController;->getInstance()Lcom/android/internal/telephony/uicc/UiccController;
-Lcom/android/internal/telephony/uicc/UiccController;->getUiccCard(I)Lcom/android/internal/telephony/uicc/UiccCard;
-Lcom/android/internal/telephony/uicc/UiccController;->getUiccCardApplication(II)Lcom/android/internal/telephony/uicc/UiccCardApplication;
-Lcom/android/internal/telephony/uicc/UiccController;->log(Ljava/lang/String;)V
-Lcom/android/internal/telephony/uicc/UiccController;->mCis:[Lcom/android/internal/telephony/CommandsInterface;
-Lcom/android/internal/telephony/uicc/UiccController;->mContext:Landroid/content/Context;
-Lcom/android/internal/telephony/uicc/UiccController;->mInstance:Lcom/android/internal/telephony/uicc/UiccController;
-Lcom/android/internal/telephony/uicc/UiccController;->mLock:Ljava/lang/Object;
-Lcom/android/internal/telephony/uicc/UiccController;->registerForIccChanged(Landroid/os/Handler;ILjava/lang/Object;)V
-Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->ALLOWED_CSG_LISTS_AND_INDICATIONS:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
-Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->CFI_STATUS:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
-Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->CSG_DISPLAY_CONTROL:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
-Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->FDN:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
-Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->MBDN:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
-Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->MSISDN:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
-Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->MWI_STATUS:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
-Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->OPERATOR_CSG_LISTS_AND_INDICATIONS:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
-Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->OPERATOR_PLMN_LIST:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
-Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->PLMN_NETWORK_NAME:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
-Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->SDN:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
-Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->SM_OVER_IP:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
-Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->SM_SERVICE_PARAMS:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
-Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->SM_STORAGE:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
-Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->SPN:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
-Lcom/android/internal/telephony/uicc/UsimServiceTable;->isAvailable(Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;)Z
-Lcom/android/internal/telephony/uicc/VoiceMailConstants;-><init>()V
-Lcom/android/internal/telephony/UiccPhoneBookController;-><init>([Lcom/android/internal/telephony/Phone;)V
-Lcom/android/internal/telephony/UiccPhoneBookController;->getDefaultSubscription()I
-Lcom/android/internal/telephony/UiccPhoneBookController;->getIccPhoneBookInterfaceManager(I)Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;
-Lcom/android/internal/telephony/UiccPhoneBookController;->mPhone:[Lcom/android/internal/telephony/Phone;
-Lcom/android/internal/telephony/UiccSmsController;->copyMessageToIccEfForSubscriber(ILjava/lang/String;I[B[B)Z
-Lcom/android/internal/telephony/UiccSmsController;->disableCellBroadcastForSubscriber(III)Z
-Lcom/android/internal/telephony/UiccSmsController;->disableCellBroadcastRangeForSubscriber(IIII)Z
-Lcom/android/internal/telephony/UiccSmsController;->enableCellBroadcastForSubscriber(III)Z
-Lcom/android/internal/telephony/UiccSmsController;->enableCellBroadcastRangeForSubscriber(IIII)Z
-Lcom/android/internal/telephony/UiccSmsController;->getAllMessagesFromIccEfForSubscriber(ILjava/lang/String;)Ljava/util/List;
-Lcom/android/internal/telephony/UiccSmsController;->getIccSmsInterfaceManager(I)Lcom/android/internal/telephony/IccSmsInterfaceManager;
-Lcom/android/internal/telephony/UiccSmsController;->getImsSmsFormatForSubscriber(I)Ljava/lang/String;
-Lcom/android/internal/telephony/UiccSmsController;->getPreferredSmsSubscription()I
-Lcom/android/internal/telephony/UiccSmsController;->isImsSmsSupportedForSubscriber(I)Z
-Lcom/android/internal/telephony/UiccSmsController;->sendDataForSubscriber(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;I[BLandroid/app/PendingIntent;Landroid/app/PendingIntent;)V
-Lcom/android/internal/telephony/UiccSmsController;->sendErrorInPendingIntent(Landroid/app/PendingIntent;I)V
-Lcom/android/internal/telephony/UiccSmsController;->sendErrorInPendingIntents(Ljava/util/List;I)V
-Lcom/android/internal/telephony/UiccSmsController;->updateMessageOnIccEfForSubscriber(ILjava/lang/String;II[B)Z
-Lcom/android/internal/telephony/UUSInfo;->getDcs()I
-Lcom/android/internal/telephony/UUSInfo;->getType()I
-Lcom/android/internal/telephony/UUSInfo;->getUserData()[B
-Lcom/android/internal/telephony/WakeLockStateMachine;->log(Ljava/lang/String;)V
-Lcom/android/internal/telephony/WakeLockStateMachine;->mContext:Landroid/content/Context;
-Lcom/android/internal/telephony/WakeLockStateMachine;->mIdleState:Lcom/android/internal/telephony/WakeLockStateMachine$IdleState;
-Lcom/android/internal/telephony/WakeLockStateMachine;->mPhone:Lcom/android/internal/telephony/Phone;
-Lcom/android/internal/telephony/WapPushOverSms;->dispatchWapPdu([BLandroid/content/BroadcastReceiver;Lcom/android/internal/telephony/InboundSmsHandler;)I
-Lcom/android/internal/telephony/WapPushOverSms;->getDeliveryOrReadReportThreadId(Landroid/content/Context;Lcom/google/android/mms/pdu/GenericPdu;)J
-Lcom/android/internal/telephony/WapPushOverSms;->isDuplicateNotification(Landroid/content/Context;Lcom/google/android/mms/pdu/NotificationInd;)Z
-Lcom/android/internal/telephony/WapPushOverSms;->isWapPushForMms([BLcom/android/internal/telephony/InboundSmsHandler;)Z
-Lcom/android/internal/telephony/WapPushOverSms;->mContext:Landroid/content/Context;
-Lcom/android/internal/telephony/WapPushOverSms;->mDeviceIdleController:Landroid/os/IDeviceIdleController;
-Lcom/android/internal/telephony/WapPushOverSms;->mWapPushManager:Lcom/android/internal/telephony/IWapPushManager;
-Lcom/android/internal/telephony/WspTypeDecoder;-><init>([B)V
-Lcom/android/internal/telephony/WspTypeDecoder;->decodeContentType(I)Z
-Lcom/android/internal/telephony/WspTypeDecoder;->decodeIntegerValue(I)Z
-Lcom/android/internal/telephony/WspTypeDecoder;->decodeShortInteger(I)Z
-Lcom/android/internal/telephony/WspTypeDecoder;->decodeTextString(I)Z
-Lcom/android/internal/telephony/WspTypeDecoder;->decodeUintvarInteger(I)Z
-Lcom/android/internal/telephony/WspTypeDecoder;->decodeValueLength(I)Z
-Lcom/android/internal/telephony/WspTypeDecoder;->decodeXWapApplicationId(I)Z
-Lcom/android/internal/telephony/WspTypeDecoder;->getContentParameters()Ljava/util/HashMap;
-Lcom/android/internal/telephony/WspTypeDecoder;->getDecodedDataLength()I
-Lcom/android/internal/telephony/WspTypeDecoder;->getValue32()J
-Lcom/android/internal/telephony/WspTypeDecoder;->getValueString()Ljava/lang/String;
-Lcom/android/internal/telephony/WspTypeDecoder;->mWspData:[B
-Lcom/android/internal/telephony/WspTypeDecoder;->seekXWapApplicationId(II)Z
 Lcom/android/internal/textservice/ITextServicesManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Lcom/android/internal/util/ArrayUtils;->appendElement(Ljava/lang/Class;[Ljava/lang/Object;Ljava/lang/Object;)[Ljava/lang/Object;
 Lcom/android/internal/util/ArrayUtils;->appendInt([II)[I
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 56bf8fa..694f6b0 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -139,6 +139,8 @@
 import com.android.internal.app.WindowDecorActionBar;
 import com.android.internal.policy.PhoneWindow;
 
+import dalvik.system.VMRuntime;
+
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
@@ -2491,6 +2493,7 @@
             try {
                 ActivityTaskManager.getService().reportActivityFullyDrawn(
                         mToken, mRestoredFromBundle);
+                VMRuntime.getRuntime().notifyStartupCompleted();
             } catch (RemoteException e) {
             }
         }
diff --git a/core/java/android/app/AppOpsManagerInternal.java b/core/java/android/app/AppOpsManagerInternal.java
index da45054..08cad04 100644
--- a/core/java/android/app/AppOpsManagerInternal.java
+++ b/core/java/android/app/AppOpsManagerInternal.java
@@ -16,6 +16,7 @@
 
 package android.app;
 
+import android.annotation.NonNull;
 import android.util.SparseIntArray;
 
 import com.android.internal.util.function.QuadFunction;
@@ -96,4 +97,18 @@
      * @param uid The uid
      */
     public abstract void setAllPkgModesToDefault(int code, int uid);
+
+    /**
+     * Get the (raw) mode of an app-op.
+     *
+     * <p>Does <u>not</u> verify that package belongs to uid. The caller needs to do that.
+     *
+     * @param code The code of the op
+     * @param uid The uid of the package the op belongs to
+     * @param packageName The package the op belongs to
+     *
+     * @return The mode of the op
+     */
+    public abstract @AppOpsManager.Mode int checkOperationUnchecked(int code, int uid,
+            @NonNull String packageName);
 }
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 90bc0a6..6103818 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -104,11 +104,13 @@
 import android.net.IIpMemoryStore;
 import android.net.IIpSecService;
 import android.net.INetworkPolicyManager;
+import android.net.ITestNetworkManager;
 import android.net.IpMemoryStore;
 import android.net.IpSecManager;
 import android.net.NetworkPolicyManager;
 import android.net.NetworkScoreManager;
 import android.net.NetworkWatchlistManager;
+import android.net.TestNetworkManager;
 import android.net.lowpan.ILowpanManager;
 import android.net.lowpan.LowpanManager;
 import android.net.nsd.INsdManager;
@@ -146,6 +148,7 @@
 import android.os.IncidentManager;
 import android.os.PowerManager;
 import android.os.RecoverySystem;
+import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.ServiceManager.ServiceNotFoundException;
 import android.os.SystemUpdateManager;
@@ -357,6 +360,29 @@
                 return new IpSecManager(ctx, service);
             }});
 
+        registerService(
+                Context.TEST_NETWORK_SERVICE,
+                TestNetworkManager.class,
+                new StaticApplicationContextServiceFetcher<TestNetworkManager>() {
+                    @Override
+                    public TestNetworkManager createService(Context context)
+                            throws ServiceNotFoundException {
+                        IBinder csBinder =
+                                ServiceManager.getServiceOrThrow(Context.CONNECTIVITY_SERVICE);
+                        IConnectivityManager csMgr =
+                                IConnectivityManager.Stub.asInterface(csBinder);
+
+                        final IBinder tnBinder;
+                        try {
+                            tnBinder = csMgr.startOrGetTestNetworkService();
+                        } catch (RemoteException e) {
+                            throw new ServiceNotFoundException(Context.TEST_NETWORK_SERVICE);
+                        }
+                        ITestNetworkManager tnMgr = ITestNetworkManager.Stub.asInterface(tnBinder);
+                        return new TestNetworkManager(context, tnMgr);
+                    }
+                });
+
         registerService(Context.COUNTRY_DETECTOR, CountryDetector.class,
                 new StaticServiceFetcher<CountryDetector>() {
             @Override
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index f8ccb13..9a4e215 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -3393,9 +3393,6 @@
      * explicitly querying the parent profile screen lock complexity via {@link
      * #getParentProfileInstance}.
      *
-     * <p>On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the
-     * password is always empty and this method returns {@link #PASSWORD_COMPLEXITY_NONE}.
-     *
      * @throws IllegalStateException if the user is not unlocked.
      * @throws SecurityException if the calling application does not have the permission
      *                           {@link permission#REQUEST_PASSWORD_COMPLEXITY}
@@ -10628,10 +10625,10 @@
      * Returns the system-wide Private DNS host.
      *
      * @param admin which {@link DeviceAdminReceiver} this request is associated with.
-     * @return The hostname used for Private DNS queries.
+     * @return The hostname used for Private DNS queries, null if none is set.
      * @throws SecurityException if the caller is not the device owner.
      */
-    public String getGlobalPrivateDnsHost(@NonNull ComponentName admin) {
+    public @Nullable String getGlobalPrivateDnsHost(@NonNull ComponentName admin) {
         throwIfParentInstance("setGlobalPrivateDns");
         if (mService == null) {
             return null;
@@ -10661,13 +10658,12 @@
     @SystemApi
     @RequiresPermission(value = android.Manifest.permission.GRANT_PROFILE_OWNER_DEVICE_IDS_ACCESS,
             conditional = true)
-    public void setProfileOwnerCanAccessDeviceIdsForUser(
-            @NonNull ComponentName who, @NonNull UserHandle userHandle) {
+    public void setProfileOwnerCanAccessDeviceIds(@NonNull ComponentName who) {
         if (mService == null) {
             return;
         }
         try {
-            mService.grantDeviceIdsAccessToProfileOwner(who, userHandle.getIdentifier());
+            mService.grantDeviceIdsAccessToProfileOwner(who, myUserId());
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
         }
diff --git a/core/java/android/app/usage/IUsageStatsManager.aidl b/core/java/android/app/usage/IUsageStatsManager.aidl
index 62b24e9..83c1d61 100644
--- a/core/java/android/app/usage/IUsageStatsManager.aidl
+++ b/core/java/android/app/usage/IUsageStatsManager.aidl
@@ -60,7 +60,7 @@
             in PendingIntent sessionEndCallbackIntent, String callingPackage);
     void unregisterUsageSessionObserver(int sessionObserverId, String callingPackage);
     void registerAppUsageLimitObserver(int observerId, in String[] packages, long timeLimitMs,
-            long timeRemainingMs, in PendingIntent callback, String callingPackage);
+            long timeUsedMs, in PendingIntent callback, String callingPackage);
     void unregisterAppUsageLimitObserver(int observerId, String callingPackage);
     void reportUsageStart(in IBinder activity, String token, String callingPackage);
     void reportPastUsageStart(in IBinder activity, String token, long timeAgoMs,
diff --git a/core/java/android/app/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java
index b3d01fd..b564c31 100644
--- a/core/java/android/app/usage/UsageEvents.java
+++ b/core/java/android/app/usage/UsageEvents.java
@@ -428,7 +428,6 @@
 
         /**
          * Indicates whether it is an instant app.
-         * STOPSHIP b/111407095: Add GTS tests for the newly added API method.
          * @hide
          */
         @SystemApi
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
index cee6b87..b5224c7 100644
--- a/core/java/android/app/usage/UsageStatsManager.java
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -660,6 +660,30 @@
         }
     }
 
+
+    /**
+     * @deprecated use {@link #registerUsageSessionObserver(int, String[], Duration, Duration,
+     *                                                      PendingIntent, PendingIntent)}.
+     *
+     * @removed
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE)
+    // STOPSHIP b/128455269: remove this method
+    public void registerUsageSessionObserver(int sessionObserverId,
+            @NonNull String[] observedEntities, long timeLimit, @NonNull TimeUnit timeUnit,
+            long sessionThresholdTime,  @NonNull TimeUnit sessionThresholdTimeUnit,
+            @NonNull PendingIntent limitReachedCallbackIntent,
+            @Nullable PendingIntent sessionEndCallbackIntent) {
+        final Duration timeLimitDuration = Duration.ofMillis(timeUnit.toMillis(timeLimit));
+        final Duration sessionThresholdDuration =
+                Duration.ofMillis(sessionThresholdTimeUnit.toMillis(sessionThresholdTime));
+        registerUsageSessionObserver(sessionObserverId, observedEntities, timeLimitDuration,
+                sessionThresholdDuration, limitReachedCallbackIntent, sessionEndCallbackIntent);
+    }
+
     /**
      * Register a usage session observer that receives a callback on the provided {@code
      * limitReachedCallbackIntent} when the sum of usages of apps and tokens in the {@code
@@ -679,11 +703,8 @@
      *                         null and must include at least one package or token.
      * @param timeLimit The total time the set of apps can be used continuously before the {@code
      *                  limitReachedCallbackIntent} is delivered. Must be at least one minute.
-     * @param timeUnit The unit for time specified in {@code timeLimit}. Cannot be null.
      * @param sessionThresholdTime The time that can take place between usage sessions before the
      *                             next session is considered a new session. Must be non-negative.
-     * @param sessionThresholdTimeUnit The unit for time specified in {@code sessionThreshold}.
-     *                                 Cannot be null.
      * @param limitReachedCallbackIntent The {@link PendingIntent} that will be dispatched when the
      *                                   usage limit is exceeded by the group of apps. The
      *                                   delivered Intent will also contain the extras {@link
@@ -703,14 +724,13 @@
     @SystemApi
     @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE)
     public void registerUsageSessionObserver(int sessionObserverId,
-            @NonNull String[] observedEntities, long timeLimit, @NonNull TimeUnit timeUnit,
-            long sessionThresholdTime,  @NonNull TimeUnit sessionThresholdTimeUnit,
+            @NonNull String[] observedEntities, @NonNull Duration timeLimit,
+            @NonNull Duration sessionThresholdTime,
             @NonNull PendingIntent limitReachedCallbackIntent,
             @Nullable PendingIntent sessionEndCallbackIntent) {
         try {
             mService.registerUsageSessionObserver(sessionObserverId, observedEntities,
-                    timeUnit.toMillis(timeLimit),
-                    sessionThresholdTimeUnit.toMillis(sessionThresholdTime),
+                    timeLimit.toMillis(), sessionThresholdTime.toMillis(),
                     limitReachedCallbackIntent, sessionEndCallbackIntent,
                     mContext.getOpPackageName());
         } catch (RemoteException e) {
@@ -747,7 +767,7 @@
      */
     @Deprecated
     @UnsupportedAppUsage
-    // STOPSHIP b/126917290: remove this method once ag/6591106 is merged and it's not being used.
+    // STOPSHIP b/126917290: remove this method once b/126926550 is fixed.
     public void registerAppUsageLimitObserver(int observerId, @NonNull String[] observedEntities,
             long timeLimit, @NonNull TimeUnit timeUnit, @Nullable PendingIntent callbackIntent) {
         final Duration timeLimitDuration = Duration.ofMillis(timeUnit.toMillis(timeLimit));
@@ -782,16 +802,17 @@
      *                         null and must include at least one package or token.
      * @param timeLimit The total time the set of apps can be in the foreground before the
      *                  {@code callbackIntent} is delivered. Must be at least one minute.
-     * @param timeRemaining The remaining time the set of apps can be in the foreground before the
-     *                      {@code callbackIntent} is delivered. Must be greater than
-     *                      {@code timeLimit}. Note: a limit of 0 can be set to indicate that the
-     *                      user has already exhausted the limit for a group, in which case,
-     *                      the given {@code callbackIntent} will be ignored.
+     * @param timeUsed The time that has already been used by the set of apps in
+     *                 {@code observedEntities}. Note: a time used equal to or greater than
+     *                 {@code timeLimit} can be set to indicate that the user has already exhausted
+     *                 the limit for a group, in which case, the given {@code callbackIntent} will
+     *                 be ignored.
      * @param callbackIntent The PendingIntent that will be dispatched when the usage limit is
      *                       exceeded by the group of apps. The delivered Intent will also contain
      *                       the extras {@link #EXTRA_OBSERVER_ID}, {@link #EXTRA_TIME_LIMIT} and
      *                       {@link #EXTRA_TIME_USED}. Cannot be {@code null} unless the observer is
-     *                       being registered with a {@code timeRemaining} of 0.
+     *                       being registered with a {@code timeUsed} equal to or greater than
+     *                       {@code timeLimit}.
      * @throws SecurityException if the caller doesn't have both SUSPEND_APPS and OBSERVE_APP_USAGE
      *                           permissions.
      * @hide
@@ -801,11 +822,11 @@
             android.Manifest.permission.SUSPEND_APPS,
             android.Manifest.permission.OBSERVE_APP_USAGE})
     public void registerAppUsageLimitObserver(int observerId, @NonNull String[] observedEntities,
-            @NonNull Duration timeLimit, @NonNull Duration timeRemaining,
+            @NonNull Duration timeLimit, @NonNull Duration timeUsed,
             @Nullable PendingIntent callbackIntent) {
         try {
             mService.registerAppUsageLimitObserver(observerId, observedEntities,
-                    timeLimit.toMillis(), timeRemaining.toMillis(), callbackIntent,
+                    timeLimit.toMillis(), timeUsed.toMillis(), callbackIntent,
                     mContext.getOpPackageName());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index ab8c196..b8a741a 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -19,6 +19,7 @@
 
 import android.Manifest;
 import android.annotation.IntDef;
+import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
@@ -3057,7 +3058,7 @@
      * permissions, or unable to start this CoC
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH)
-    public BluetoothServerSocket listenUsingL2capChannel()
+    public @NonNull BluetoothServerSocket listenUsingL2capChannel()
             throws IOException {
         BluetoothServerSocket socket =
                             new BluetoothServerSocket(BluetoothSocket.TYPE_L2CAP_LE, true, true,
@@ -3115,7 +3116,7 @@
      * permissions, or unable to start this CoC
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH)
-    public BluetoothServerSocket listenUsingInsecureL2capChannel()
+    public @NonNull BluetoothServerSocket listenUsingInsecureL2capChannel()
             throws IOException {
         BluetoothServerSocket socket =
                             new BluetoothServerSocket(BluetoothSocket.TYPE_L2CAP_LE, false, false,
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index f718415..fa2c9f8 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -17,6 +17,7 @@
 package android.bluetooth;
 
 import android.Manifest;
+import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
@@ -2182,7 +2183,7 @@
      * permissions
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH)
-    public BluetoothSocket createL2capChannel(int psm) throws IOException {
+    public @NonNull BluetoothSocket createL2capChannel(int psm) throws IOException {
         if (!isBluetoothEnabled()) {
             Log.e(TAG, "createL2capChannel: Bluetooth is not enabled");
             throw new IOException();
@@ -2221,7 +2222,7 @@
      * permissions
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH)
-    public BluetoothSocket createInsecureL2capChannel(int psm) throws IOException {
+    public @NonNull BluetoothSocket createInsecureL2capChannel(int psm) throws IOException {
         if (!isBluetoothEnabled()) {
             Log.e(TAG, "createInsecureL2capChannel: Bluetooth is not enabled");
             throw new IOException();
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 0c76f3f..efb3bfc1 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -338,6 +338,15 @@
     public static final int BIND_ADJUST_BELOW_PERCEPTIBLE = 0x0100;
 
     /**
+     * Flag for {@link #bindService}: allow background activity starts from the bound service's
+     * process.
+     * This flag is only respected if the caller is holding
+     * {@link android.Manifest.permission#START_ACTIVITIES_FROM_BACKGROUND}.
+     * @hide
+     */
+    public static final int BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS = 0x00100000;
+
+    /**
      * @hide Flag for {@link #bindService}: the service being bound to represents a
      * protected system component, so must have association restrictions applied to it.
      * That is, a system config must have one or more allow-association tags limiting
@@ -3127,6 +3136,7 @@
             CONNECTIVITY_SERVICE,
             //@hide: IP_MEMORY_STORE_SERVICE,
             IPSEC_SERVICE,
+            TEST_NETWORK_SERVICE,
             //@hide: UPDATE_LOCK_SERVICE,
             //@hide: NETWORKMANAGEMENT_SERVICE,
             NETWORK_STATS_SERVICE,
@@ -3289,11 +3299,16 @@
      * {@link #USB_SERVICE}, {@link #WALLPAPER_SERVICE}, {@link #WIFI_P2P_SERVICE},
      * {@link #WIFI_SERVICE}, {@link #WIFI_AWARE_SERVICE}. For these services this method will
      * return <code>null</code>.  Generally, if you are running as an instant app you should always
-     * check whether the result of this method is null.
+     * check whether the result of this method is {@code null}.
+     *
+     * <p>Note: When implementing this method, keep in mind that new services can be added on newer
+     * Android releases, so if you're looking for just the explicit names mentioned above, make sure
+     * to return {@code null} when you don't recognize the name &mdash; if you throw a
+     * {@link RuntimeException} exception instead, you're app might break on new Android releases.
      *
      * @param name The name of the desired service.
      *
-     * @return The service or null if the name does not exist.
+     * @return The service or {@code null} if the name does not exist.
      *
      * @see #WINDOW_SERVICE
      * @see android.view.WindowManager
@@ -3367,7 +3382,9 @@
      * {@link android.app.UiModeManager}, {@link android.app.DownloadManager},
      * {@link android.os.BatteryManager}, {@link android.app.job.JobScheduler},
      * {@link android.app.usage.NetworkStatsManager}.
-     * </p><p>
+     * </p>
+     *
+     * <p>
      * Note: System services obtained via this API may be closely associated with
      * the Context in which they are obtained from.  In general, do not share the
      * service objects between various different contexts (Activities, Applications,
@@ -3379,11 +3396,13 @@
      * {@link #FINGERPRINT_SERVICE}, {@link #KEYGUARD_SERVICE}, {@link #SHORTCUT_SERVICE},
      * {@link #USB_SERVICE}, {@link #WALLPAPER_SERVICE}, {@link #WIFI_P2P_SERVICE},
      * {@link #WIFI_SERVICE}, {@link #WIFI_AWARE_SERVICE}. For these services this method will
-     * return <code>null</code>.  Generally, if you are running as an instant app you should always
-     * check whether the result of this method is null.
+     * return {@code null}. Generally, if you are running as an instant app you should always
+     * check whether the result of this method is {@code null}.
+     * </p>
      *
      * @param serviceClass The class of the desired service.
-     * @return The service or null if the class is not a supported system service.
+     * @return The service or {@code null} if the class is not a supported system service. Note:
+     * <b>never</b> throw a {@link RuntimeException} if the name is not supported.
      */
     @SuppressWarnings("unchecked")
     public final @Nullable <T> T getSystemService(@NonNull Class<T> serviceClass) {
@@ -3691,6 +3710,15 @@
 
     /**
      * Use with {@link #getSystemService(String)} to retrieve a {@link
+     * android.net.TestNetworkManager} for building TUNs and limited-use Networks
+     *
+     * @see #getSystemService(String)
+     * @hide
+     */
+    @TestApi public static final String TEST_NETWORK_SERVICE = "test_network";
+
+    /**
+     * Use with {@link #getSystemService(String)} to retrieve a {@link
      * android.os.IUpdateLock} for managing runtime sequences that
      * must not be interrupted by headless OTA application or similar.
      *
diff --git a/core/java/android/content/pm/AndroidHidlUpdater.java b/core/java/android/content/pm/AndroidHidlUpdater.java
index b7ae8f4..d0657e5 100644
--- a/core/java/android/content/pm/AndroidHidlUpdater.java
+++ b/core/java/android/content/pm/AndroidHidlUpdater.java
@@ -34,8 +34,14 @@
 
     @Override
     public void updatePackage(Package pkg) {
+        ApplicationInfo info = pkg.applicationInfo;
+
         // This was the default <= P and is maintained for backwards compatibility.
-        if (pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.P) {
+        boolean isLegacy = info.targetSdkVersion <= Build.VERSION_CODES.P;
+        // Only system apps use these libraries
+        boolean isSystem = info.isSystemApp() || info.isUpdatedSystemApp();
+
+        if (isLegacy && isSystem) {
             prefixRequiredLibrary(pkg, ANDROID_HIDL_BASE);
             prefixRequiredLibrary(pkg, ANDROID_HIDL_MANAGER);
         } else {
diff --git a/core/java/android/content/pm/PackageList.java b/core/java/android/content/pm/PackageList.java
index cfd99ab..f781758 100644
--- a/core/java/android/content/pm/PackageList.java
+++ b/core/java/android/content/pm/PackageList.java
@@ -45,16 +45,16 @@
     }
 
     @Override
-    public void onPackageAdded(String packageName) {
+    public void onPackageAdded(String packageName, int uid) {
         if (mWrappedObserver != null) {
-            mWrappedObserver.onPackageAdded(packageName);
+            mWrappedObserver.onPackageAdded(packageName, uid);
         }
     }
 
     @Override
-    public void onPackageRemoved(String packageName) {
+    public void onPackageRemoved(String packageName, int uid) {
         if (mWrappedObserver != null) {
-            mWrappedObserver.onPackageRemoved(packageName);
+            mWrappedObserver.onPackageRemoved(packageName, uid);
         }
     }
 
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index d1ebcfd..9037759 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1389,6 +1389,14 @@
      */
     public static final int INSTALL_FAILED_BAD_SIGNATURE = -118;
 
+    /**
+     * Installation failed return code: a new staged session was attempted to be committed while
+     * there is already one in-progress.
+     *
+     * @hide
+     */
+    public static final int INSTALL_FAILED_OTHER_STAGED_SESSION_IN_PROGRESS = -119;
+
     /** @hide */
     @IntDef(flag = true, prefix = { "DELETE_" }, value = {
             DELETE_KEEP_DATA,
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index 2c1842c..b3cc627 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -22,6 +22,7 @@
 import android.annotation.UserIdInt;
 import android.content.ComponentName;
 import android.content.Intent;
+import android.content.IntentSender;
 import android.content.pm.PackageManager.ApplicationInfoFlags;
 import android.content.pm.PackageManager.ComponentInfoFlags;
 import android.content.pm.PackageManager.PackageInfoFlags;
@@ -78,9 +79,9 @@
     /** Observer called whenever the list of packages changes */
     public interface PackageListObserver {
         /** A package was added to the system. */
-        void onPackageAdded(@NonNull String packageName);
+        void onPackageAdded(@NonNull String packageName, int uid);
         /** A package was removed from the system. */
-        void onPackageRemoved(@NonNull String packageName);
+        void onPackageRemoved(@NonNull String packageName, int uid);
     }
 
     /** Interface to override permission checks via composition */
@@ -925,4 +926,21 @@
      * @param provider the provider
      */
     public abstract void setDefaultHomeProvider(@NonNull DefaultHomeProvider provider);
+
+    /**
+     * Returns {@code true} if given {@code packageName} is an apex package.
+     */
+    public abstract boolean isApexPackage(String packageName);
+
+    /**
+     * Uninstalls given {@code packageName}.
+     *
+     * @param packageName apex package to uninstall.
+     * @param versionCode version of a package to uninstall.
+     * @param userId user to uninstall apex package for. Must be
+     *               {@link android.os.UserHandle#USER_ALL}, otherwise failure will be reported.
+     * @param intentSender a {@link IntentSender} to send result of an uninstall to.
+     */
+    public abstract void uninstallApex(String packageName, long versionCode, int userId,
+            IntentSender intentSender);
 }
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 89c0690..9d0ece0 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1618,7 +1618,7 @@
             }
 
             final AttributeSet attrs = parser;
-            return parseApkLite(apkPath, parser, attrs, signingDetails, flags);
+            return parseApkLite(apkPath, parser, attrs, signingDetails);
 
         } catch (XmlPullParserException | IOException | RuntimeException e) {
             Slog.w(TAG, "Failed to parse " + apkPath, e);
@@ -1705,7 +1705,7 @@
     }
 
     private static ApkLite parseApkLite(String codePath, XmlPullParser parser, AttributeSet attrs,
-            SigningDetails signingDetails, int flags)
+            SigningDetails signingDetails)
             throws IOException, XmlPullParserException, PackageParserException {
         final Pair<String, String> packageSplit = parsePackageSplitNames(parser, attrs);
 
@@ -1713,12 +1713,11 @@
         int versionCode = 0;
         int versionCodeMajor = 0;
         int revisionCode = 0;
-        int targetSdkVersion = 0;
         boolean coreApp = false;
         boolean debuggable = false;
         boolean multiArch = false;
         boolean use32bitAbi = false;
-        Boolean extractNativeLibsProvided = null;
+        boolean extractNativeLibs = true;
         boolean isolatedSplits = false;
         boolean isFeatureSplit = false;
         boolean isSplitRequired = false;
@@ -1783,8 +1782,7 @@
                         use32bitAbi = attrs.getAttributeBooleanValue(i, false);
                     }
                     if ("extractNativeLibs".equals(attr)) {
-                        extractNativeLibsProvided = Boolean.valueOf(
-                                attrs.getAttributeBooleanValue(i, true));
+                        extractNativeLibs = attrs.getAttributeBooleanValue(i, true);
                     }
                     if ("useEmbeddedDex".equals(attr)) {
                         useEmbeddedDex = attrs.getAttributeBooleanValue(i, false);
@@ -1802,52 +1800,9 @@
                             PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
                             "<uses-split> tag requires 'android:name' attribute");
                 }
-            } else if (TAG_USES_SDK.equals(parser.getName())) {
-                final String[] errorMsg = new String[1];
-                Pair<Integer, Integer> versions = deriveSdkVersions(new AbstractVersionsAccessor() {
-                    @Override public String getMinSdkVersionCode() {
-                        return getAttributeAsString("minSdkVersion");
-                    }
-
-                    @Override public int getMinSdkVersion() {
-                        return getAttributeAsInt("minSdkVersion");
-                    }
-
-                    @Override public String getTargetSdkVersionCode() {
-                        return getAttributeAsString("targetSdkVersion");
-                    }
-
-                    @Override public int getTargetSdkVersion() {
-                        return getAttributeAsInt("targetSdkVersion");
-                    }
-
-                    private String getAttributeAsString(String name) {
-                        return attrs.getAttributeValue(ANDROID_RESOURCES, name);
-                    }
-
-                    private int getAttributeAsInt(String name) {
-                        try {
-                            return attrs.getAttributeIntValue(ANDROID_RESOURCES, name, -1);
-                        } catch (NumberFormatException e) {
-                            return -1;
-                        }
-                    }
-                }, flags, errorMsg);
-
-                if (versions == null) {
-                    throw new PackageParserException(
-                            PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, errorMsg[0]);
-                }
-
-                targetSdkVersion = versions.second;
             }
         }
 
-        // TODO: flip the default based on targetSdkVersion when possible.  See b/128335904.
-        final boolean extractNativeLibsDefault = true;
-        final boolean extractNativeLibs = (extractNativeLibsProvided != null)
-                ? extractNativeLibsProvided : extractNativeLibsDefault;
-
         return new ApkLite(codePath, packageSplit.first, packageSplit.second, isFeatureSplit,
                 configForSplit, usesSplitName, isSplitRequired, versionCode, versionCodeMajor,
                 revisionCode, installLocation, verifiers, signingDetails, coreApp, debuggable,
@@ -2253,60 +2208,64 @@
 
             } else if (tagName.equals(TAG_USES_SDK)) {
                 if (SDK_VERSION > 0) {
-                    sa = res.obtainAttributes(parser, R.styleable.AndroidManifestUsesSdk);
-                    final TypedArray saFinal = sa;
-                    Pair<Integer, Integer> versions = deriveSdkVersions(
-                            new AbstractVersionsAccessor() {
-                                @Override public String getMinSdkVersionCode() {
-                                    return getAttributeAsString(
-                                            R.styleable.AndroidManifestUsesSdk_minSdkVersion);
-                                }
+                    sa = res.obtainAttributes(parser,
+                            com.android.internal.R.styleable.AndroidManifestUsesSdk);
 
-                                @Override public int getMinSdkVersion() {
-                                    return getAttributeAsInt(
-                                            R.styleable.AndroidManifestUsesSdk_minSdkVersion);
-                                }
+                    int minVers = 1;
+                    String minCode = null;
+                    int targetVers = 0;
+                    String targetCode = null;
 
-                                @Override public String getTargetSdkVersionCode() {
-                                    return getAttributeAsString(
-                                            R.styleable.AndroidManifestUsesSdk_targetSdkVersion);
-                                }
+                    TypedValue val = sa.peekValue(
+                            com.android.internal.R.styleable.AndroidManifestUsesSdk_minSdkVersion);
+                    if (val != null) {
+                        if (val.type == TypedValue.TYPE_STRING && val.string != null) {
+                            minCode = val.string.toString();
+                        } else {
+                            // If it's not a string, it's an integer.
+                            minVers = val.data;
+                        }
+                    }
 
-                                @Override public int getTargetSdkVersion() {
-                                    return getAttributeAsInt(
-                                            R.styleable.AndroidManifestUsesSdk_targetSdkVersion);
-                                }
+                    val = sa.peekValue(
+                            com.android.internal.R.styleable.AndroidManifestUsesSdk_targetSdkVersion);
+                    if (val != null) {
+                        if (val.type == TypedValue.TYPE_STRING && val.string != null) {
+                            targetCode = val.string.toString();
+                            if (minCode == null) {
+                                minCode = targetCode;
+                            }
+                        } else {
+                            // If it's not a string, it's an integer.
+                            targetVers = val.data;
+                        }
+                    } else {
+                        targetVers = minVers;
+                        targetCode = minCode;
+                    }
 
-                                private String getAttributeAsString(int index) {
-                                    TypedValue val = saFinal.peekValue(index);
-                                    if (val != null && val.type == TypedValue.TYPE_STRING
-                                            && val.string != null) {
-                                        return val.string.toString();
-                                    }
-                                    return null;
-                                }
+                    sa.recycle();
 
-                                private int getAttributeAsInt(int index) {
-                                    TypedValue val = saFinal.peekValue(index);
-                                    if (val != null && val.type != TypedValue.TYPE_STRING) {
-                                        // If it's not a string, it's an integer.
-                                        return val.data;
-                                    }
-                                    return -1;
-                                }
-                            }, flags, outError);
-
-                    if (versions == null) {
+                    final int minSdkVersion = PackageParser.computeMinSdkVersion(minVers, minCode,
+                            SDK_VERSION, SDK_CODENAMES, outError);
+                    if (minSdkVersion < 0) {
                         mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK;
                         return null;
                     }
 
-                    pkg.applicationInfo.minSdkVersion = versions.first;
-                    pkg.applicationInfo.targetSdkVersion = versions.second;
+                    final int targetSdkVersion = PackageParser.computeTargetSdkVersion(targetVers,
+                            targetCode, SDK_CODENAMES, outError);
+                    if (targetSdkVersion < 0) {
+                        mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK;
+                        return null;
+                    }
 
-                    sa.recycle();
+                    pkg.applicationInfo.minSdkVersion = minSdkVersion;
+                    pkg.applicationInfo.targetSdkVersion = targetSdkVersion;
                 }
+
                 XmlUtils.skipCurrentTag(parser);
+
             } else if (tagName.equals(TAG_SUPPORT_SCREENS)) {
                 sa = res.obtainAttributes(parser,
                         com.android.internal.R.styleable.AndroidManifestSupportsScreens);
@@ -2717,66 +2676,6 @@
         return -1;
     }
 
-    private interface AbstractVersionsAccessor {
-        /** Returns minimum SDK version code string, or null if absent. */
-        String getMinSdkVersionCode();
-
-        /** Returns minimum SDK version code, or -1 if absent. */
-        int getMinSdkVersion();
-
-        /** Returns target SDK version code string, or null if absent. */
-        String getTargetSdkVersionCode();
-
-        /** Returns target SDK version code, or -1 if absent. */
-        int getTargetSdkVersion();
-    }
-
-    private static @Nullable Pair<Integer, Integer> deriveSdkVersions(
-            @NonNull AbstractVersionsAccessor accessor, int flags, String[] outError) {
-        int minVers = 1;
-        String minCode = null;
-        int targetVers = 0;
-        String targetCode = null;
-
-        String code = accessor.getMinSdkVersionCode();
-        int version = accessor.getMinSdkVersion();
-        // Check integer first since code is almost never a null string (e.g. "28").
-        if (version >= 0) {
-            minVers = version;
-        } else if (code != null) {
-            minCode = code;
-        }
-
-        code = accessor.getTargetSdkVersionCode();
-        version = accessor.getTargetSdkVersion();
-        // Check integer first since code is almost never a null string (e.g. "28").
-        if (version >= 0) {
-            targetVers = version;
-        } else if (code != null) {
-            targetCode = code;
-            if (minCode == null) {
-                minCode = targetCode;
-            }
-        } else {
-            targetVers = minVers;
-            targetCode = minCode;
-        }
-
-        final int minSdkVersion = computeMinSdkVersion(minVers, minCode,
-                SDK_VERSION, SDK_CODENAMES, outError);
-        if (minSdkVersion < 0) {
-            return null;
-        }
-
-        final int targetSdkVersion = computeTargetSdkVersion(targetVers,
-                targetCode, SDK_CODENAMES, outError);
-        if (targetSdkVersion < 0) {
-            return null;
-        }
-
-        return Pair.create(minSdkVersion, targetSdkVersion);
-    }
-
     /**
      * Computes the minSdkVersion to use at runtime. If the package is not
      * compatible with this platform, populates {@code outError[0]} with an
@@ -3719,7 +3618,6 @@
             ai.flags |= ApplicationInfo.FLAG_MULTIARCH;
         }
 
-        // TODO: flip the default based on targetSdkVersion when possible.  See b/128335904.
         if (sa.getBoolean(
                 com.android.internal.R.styleable.AndroidManifestApplication_extractNativeLibs,
                 true)) {
@@ -4095,8 +3993,6 @@
         setMaxAspectRatio(owner);
         setMinAspectRatio(owner);
 
-        PackageBackwardCompatibility.modifySharedLibraries(owner);
-
         if (hasDomainURLs(owner)) {
             owner.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS;
         } else {
diff --git a/core/java/android/hardware/OWNERS b/core/java/android/hardware/OWNERS
index 29a339a..47dbf2d 100644
--- a/core/java/android/hardware/OWNERS
+++ b/core/java/android/hardware/OWNERS
@@ -1,2 +1,2 @@
 # Camera
-per-file *Camera* = cychen@google.com,epeev@google.com,etalvala@google.com,shuzhenwang@google.com,yinchiayeh@google.com,zhijunhe@google.com
+per-file *Camera*=cychen@google.com,epeev@google.com,etalvala@google.com,shuzhenwang@google.com,yinchiayeh@google.com,zhijunhe@google.com,jchowdhary@google.com
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index f8b2a5b..7ae673c 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -85,8 +85,7 @@
          *
          * @hide
          */
-        @UnsupportedAppUsage
-        public Key(@NonNull String name, @NonNull String fallbackName, @NonNull Class<T> type) {
+        public Key(String name, String fallbackName, Class<T> type) {
             mKey = new CameraMetadataNative.Key<T>(name,  fallbackName, type);
         }
 
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 23401432..d5d25c5 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -680,7 +680,7 @@
         }
 
         /**
-         * Notify registered clients about a change in the camera access priorities.
+         * Called whenever camera access priorities change.
          *
          * <p>Notification that camera access priorities have changed and the camera may
          * now be openable. An application that was previously denied camera access due to
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 7382ac4..ba451e5 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -89,8 +89,7 @@
          *
          * @hide
          */
-        @UnsupportedAppUsage
-        public Key(@NonNull String name, @NonNull String fallbackName, @NonNull Class<T> type) {
+        public Key(String name, String fallbackName, Class<T> type) {
             mKey = new CameraMetadataNative.Key<T>(name, fallbackName, type);
         }
 
@@ -4252,7 +4251,6 @@
      * @see CaptureResult#SENSOR_TIMESTAMP
      * @hide
      */
-    @UnsupportedAppUsage
     public static final Key<long[]> STATISTICS_OIS_TIMESTAMPS =
             new Key<long[]>("android.statistics.oisTimestamps", long[].class);
 
@@ -4272,7 +4270,6 @@
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
      * @hide
      */
-    @UnsupportedAppUsage
     public static final Key<float[]> STATISTICS_OIS_X_SHIFTS =
             new Key<float[]>("android.statistics.oisXShifts", float[].class);
 
@@ -4292,7 +4289,6 @@
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
      * @hide
      */
-    @UnsupportedAppUsage
     public static final Key<float[]> STATISTICS_OIS_Y_SHIFTS =
             new Key<float[]>("android.statistics.oisYShifts", float[].class);
 
diff --git a/core/java/android/hardware/camera2/OWNERS b/core/java/android/hardware/camera2/OWNERS
index 18acfee..f48a95c 100644
--- a/core/java/android/hardware/camera2/OWNERS
+++ b/core/java/android/hardware/camera2/OWNERS
@@ -1,6 +1 @@
-cychen@google.com
-epeev@google.com
-etalvala@google.com
-shuzhenwang@google.com
-yinchiayeh@google.com
-zhijunhe@google.com
+include platform/frameworks/av:/camera/OWNERS
diff --git a/core/java/android/hardware/radio/RadioManager.java b/core/java/android/hardware/radio/RadioManager.java
index 92653d18..a7ff644 100644
--- a/core/java/android/hardware/radio/RadioManager.java
+++ b/core/java/android/hardware/radio/RadioManager.java
@@ -1761,7 +1761,7 @@
         TunerCallbackAdapter halCallback = new TunerCallbackAdapter(callback, handler);
         try {
             tuner = mService.openTuner(moduleId, config, withAudio, halCallback);
-        } catch (RemoteException | IllegalArgumentException ex) {
+        } catch (RemoteException | IllegalArgumentException | IllegalStateException ex) {
             Log.e(TAG, "Failed to open tuner", ex);
             return null;
         }
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 3f8410f..2a357ff 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -2805,7 +2805,7 @@
          *         {@link #TETHER_ERROR_PROVISION_FAILED}, or
          *         {@link #TETHER_ERROR_ENTITLEMENT_UNKONWN}.
          */
-        void onEntitlementResult(@EntitlementResultCode int resultCode);
+        void onTetheringEntitlementResult(@EntitlementResultCode int resultCode);
     }
 
     /**
@@ -2855,7 +2855,7 @@
             protected void onReceiveResult(int resultCode, Bundle resultData) {
                 Binder.withCleanCallingIdentity(() ->
                             executor.execute(() -> {
-                                listener.onEntitlementResult(resultCode);
+                                listener.onTetheringEntitlementResult(resultCode);
                             }));
             }
         };
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 403b44d..f1e4f64 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -219,4 +219,6 @@
 
     void registerTetheringEventCallback(ITetheringEventCallback callback, String callerPkg);
     void unregisterTetheringEventCallback(ITetheringEventCallback callback, String callerPkg);
+
+    IBinder startOrGetTestNetworkService();
 }
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index 60f4f06..b6bc95d 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -120,10 +120,6 @@
         mUsapPoolSecondarySocketAddress =
                 new LocalSocketAddress(Zygote.USAP_POOL_SECONDARY_SOCKET_NAME,
                                        LocalSocketAddress.Namespace.RESERVED);
-
-        if (fetchUsapPoolEnabledProp()) {
-            informZygotesOfUsapPoolStatus();
-        }
     }
 
     public ZygoteProcess(LocalSocketAddress primarySocketAddress,
@@ -151,7 +147,7 @@
         final DataInputStream mZygoteInputStream;
         final BufferedWriter mZygoteOutputWriter;
 
-        private final List<String> mABIList;
+        private final List<String> mAbiList;
 
         private boolean mClosed;
 
@@ -166,7 +162,7 @@
             this.mZygoteSessionSocket = zygoteSessionSocket;
             this.mZygoteInputStream = zygoteInputStream;
             this.mZygoteOutputWriter = zygoteOutputWriter;
-            this.mABIList = abiList;
+            this.mAbiList = abiList;
         }
 
         /**
@@ -179,14 +175,18 @@
          * address
          * @throws IOException
          */
-        public static ZygoteState connect(LocalSocketAddress zygoteSocketAddress,
-                                          LocalSocketAddress usapSocketAddress)
+        public static ZygoteState connect(@NonNull LocalSocketAddress zygoteSocketAddress,
+                                          @Nullable LocalSocketAddress usapSocketAddress)
                 throws IOException {
 
             DataInputStream zygoteInputStream = null;
             BufferedWriter zygoteOutputWriter = null;
             final LocalSocket zygoteSessionSocket = new LocalSocket();
 
+            if (zygoteSocketAddress == null) {
+                throw new IllegalArgumentException("zygoteSocketAddress can't be null");
+            }
+
             try {
                 zygoteSessionSocket.connect(zygoteSocketAddress);
                 zygoteInputStream = new DataInputStream(zygoteSessionSocket.getInputStream());
@@ -215,7 +215,7 @@
         }
 
         boolean matches(String abi) {
-            return mABIList.contains(abi);
+            return mAbiList.contains(abi);
         }
 
         public void close() {
@@ -338,7 +338,7 @@
         try {
             return startViaZygote(processClass, niceName, uid, gid, gids,
                     runtimeFlags, mountExternal, targetSdkVersion, seInfo,
-                    abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/false,
+                    abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
                     packageName, packagesForUid, sandboxId,
                     useUsapPool, zygoteArgs);
         } catch (ZygoteStartFailedEx ex) {
@@ -374,7 +374,7 @@
         byte[] bytes = new byte[numBytes];
         inputStream.readFully(bytes);
 
-        String rawList = new String(bytes, StandardCharsets.US_ASCII);
+        final String rawList = new String(bytes, StandardCharsets.US_ASCII);
 
         return Arrays.asList(rawList.split(","));
     }
@@ -660,13 +660,13 @@
         boolean origVal = mUsapPoolEnabled;
 
         final String propertyString =
-                Zygote.getSystemProperty(
+                Zygote.getConfigurationProperty(
                         DeviceConfig.RuntimeNative.USAP_POOL_ENABLED,
                         USAP_POOL_ENABLED_DEFAULT);
 
         if (!propertyString.isEmpty()) {
             mUsapPoolEnabled =
-                    Zygote.getSystemPropertyBoolean(
+                    Zygote.getConfigurationPropertyBoolean(
                             DeviceConfig.RuntimeNative.USAP_POOL_ENABLED,
                             Boolean.parseBoolean(USAP_POOL_ENABLED_DEFAULT));
         }
@@ -678,12 +678,15 @@
         return origVal != mUsapPoolEnabled;
     }
 
+    private boolean mIsFirstPropCheck = true;
     private long mLastPropCheckTimestamp = 0;
 
     private boolean fetchUsapPoolEnabledPropWithMinInterval() {
         final long currentTimestamp = SystemClock.elapsedRealtime();
 
-        if (currentTimestamp - mLastPropCheckTimestamp >= Zygote.PROPERTY_CHECK_INTERVAL) {
+        if (mIsFirstPropCheck
+                || (currentTimestamp - mLastPropCheckTimestamp >= Zygote.PROPERTY_CHECK_INTERVAL)) {
+            mIsFirstPropCheck = false;
             mLastPropCheckTimestamp = currentTimestamp;
             return fetchUsapPoolEnabledProp();
         }
@@ -919,11 +922,13 @@
                 return primaryZygoteState;
             }
 
-            // The primary zygote didn't match. Try the secondary.
-            attemptConnectionToSecondaryZygote();
+            if (mZygoteSecondarySocketAddress != null) {
+                // The primary zygote didn't match. Try the secondary.
+                attemptConnectionToSecondaryZygote();
 
-            if (secondaryZygoteState.matches(abi)) {
-                return secondaryZygoteState;
+                if (secondaryZygoteState.matches(abi)) {
+                    return secondaryZygoteState;
+                }
             }
         } catch (IOException ioe) {
             throw new ZygoteStartFailedEx("Error connecting to zygote", ioe);
@@ -1071,22 +1076,24 @@
                 return;
             }
 
-            try {
-                attemptConnectionToSecondaryZygote();
-
+            if (mZygoteSecondarySocketAddress != null) {
                 try {
-                    secondaryZygoteState.mZygoteOutputWriter.write(command);
-                    secondaryZygoteState.mZygoteOutputWriter.flush();
+                    attemptConnectionToSecondaryZygote();
 
-                    // Wait for the secondary Zygote to finish its work.
-                    secondaryZygoteState.mZygoteInputStream.readInt();
+                    try {
+                        secondaryZygoteState.mZygoteOutputWriter.write(command);
+                        secondaryZygoteState.mZygoteOutputWriter.flush();
+
+                        // Wait for the secondary Zygote to finish its work.
+                        secondaryZygoteState.mZygoteInputStream.readInt();
+                    } catch (IOException ioe) {
+                        throw new IllegalStateException(
+                                "USAP pool state change cause an irrecoverable error",
+                                ioe);
+                    }
                 } catch (IOException ioe) {
-                    throw new IllegalStateException(
-                            "USAP pool state change cause an irrecoverable error",
-                            ioe);
+                    // No secondary zygote present.  This is expected on some devices.
                 }
-            } catch (IOException ioe) {
-                // No secondary zygote present.  This is expected on some devices.
             }
 
             // Wait for the response from the primary zygote here so the primary/secondary zygotes
diff --git a/core/java/android/os/storage/IStorageManager.aidl b/core/java/android/os/storage/IStorageManager.aidl
index f114b12..25f67f8 100644
--- a/core/java/android/os/storage/IStorageManager.aidl
+++ b/core/java/android/os/storage/IStorageManager.aidl
@@ -191,4 +191,6 @@
     String translateAppToSystem(String path, int pid, int uid) = 81;
     String translateSystemToApp(String path, int pid, int uid) = 82;
     void commitChanges() = 83;
+    boolean supportsCheckpoint() = 84;
+    void startCheckpoint(int numTries) = 85;
 }
diff --git a/core/java/android/preference/DialogPreference.java b/core/java/android/preference/DialogPreference.java
index e656466..32511e9 100644
--- a/core/java/android/preference/DialogPreference.java
+++ b/core/java/android/preference/DialogPreference.java
@@ -19,6 +19,7 @@
 
 import android.annotation.CallSuper;
 import android.annotation.DrawableRes;
+import android.annotation.Nullable;
 import android.annotation.StringRes;
 import android.annotation.UnsupportedAppUsage;
 import android.app.AlertDialog;
@@ -354,6 +355,7 @@
      * @return the DecorView for the current dialog window, if it exists.
      * If the window does not exist, null is returned.
      */
+    @Nullable
     private View getDecorView() {
         if (mDialog != null && mDialog.getWindow() != null) {
             return mDialog.getWindow().getDecorView();
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 261e5db..038d455 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -31,6 +31,7 @@
 import android.net.Uri;
 import android.provider.Settings.ResetMode;
 import android.util.ArrayMap;
+import android.util.Log;
 import android.util.Pair;
 
 import com.android.internal.annotations.GuardedBy;
@@ -105,6 +106,14 @@
     public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture";
 
     /**
+     * Namespace for how dex runs. The feature requires a reboot to reach a clean state.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String NAMESPACE_DEX_BOOT = "dex_boot";
+
+    /**
      * Namespace for all Game Driver features.
      *
      * @hide
@@ -122,6 +131,14 @@
     public static final String NAMESPACE_INPUT_NATIVE_BOOT = "input_native_boot";
 
     /**
+     * Namespace for attention-based features provided by on-device machine intelligence.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String NAMESPACE_INTELLIGENCE_ATTENTION = "intelligence_attention";
+
+    /**
      * Namespace for all media native related features.
      *
      * @hide
@@ -220,22 +237,6 @@
     }
 
     /**
-     * Namespace for attention-based features provided by on-device machine intelligence.
-     *
-     * @hide
-     */
-    @SystemApi
-    public interface IntelligenceAttention {
-        String NAMESPACE = "intelligence_attention";
-
-        /** If {@code true}, enables the attention features. */
-        String ATTENTION_ENABLED = "attention_enabled";
-
-        /** Settings for the attention features. */
-        String ATTENTION_SETTINGS = "attention_settings";
-    }
-
-    /**
      * Privacy related properties definitions.
      *
      * @hide
@@ -290,18 +291,6 @@
     }
 
     /**
-     * Namespace for how dex runs.  The feature may requires reboot to a clean state.
-     *
-     * @hide
-     */
-    @SystemApi
-    public interface DexBoot {
-        String NAMESPACE = "dex_boot";
-        String PRIV_APPS_OOB_ENABLED = "priv_apps_oob_enabled";
-        String PRIV_APPS_OOB_WHITELIST = "priv_apps_oob_whitelist";
-    }
-
-    /**
      * Namespace for {@link AttentionManagerService} related features.
      *
      * @hide
@@ -406,6 +395,7 @@
             new ArrayMap<>();
     @GuardedBy("sLock")
     private static Map<String, Pair<ContentObserver, Integer>> sNamespaces = new HashMap<>();
+    private static final String TAG = "DeviceConfig";
 
     // Should never be invoked
     private DeviceConfig() {
@@ -422,7 +412,7 @@
     @SystemApi
     @TestApi
     @RequiresPermission(READ_DEVICE_CONFIG)
-    public static String getProperty(String namespace, String name) {
+    public static String getProperty(@NonNull String namespace, @NonNull String name) {
         ContentResolver contentResolver = ActivityThread.currentApplication().getContentResolver();
         String compositeName = createCompositeName(namespace, name);
         return Settings.Config.getString(contentResolver, compositeName);
@@ -441,7 +431,8 @@
     @SystemApi
     @TestApi
     @RequiresPermission(READ_DEVICE_CONFIG)
-    public static String getString(String namespace, String name, String defaultValue) {
+    public static String getString(@NonNull String namespace, @NonNull String name,
+            @Nullable String defaultValue) {
         String value = getProperty(namespace, name);
         return value != null ? value : defaultValue;
     }
@@ -459,7 +450,8 @@
     @SystemApi
     @TestApi
     @RequiresPermission(READ_DEVICE_CONFIG)
-    public static boolean getBoolean(String namespace, String name, boolean defaultValue) {
+    public static boolean getBoolean(@NonNull String namespace, @NonNull String name,
+            boolean defaultValue) {
         String value = getProperty(namespace, name);
         return value != null ? Boolean.parseBoolean(value) : defaultValue;
     }
@@ -477,11 +469,15 @@
     @SystemApi
     @TestApi
     @RequiresPermission(READ_DEVICE_CONFIG)
-    public static int getInt(String namespace, String name, int defaultValue) {
+    public static int getInt(@NonNull String namespace, @NonNull String name, int defaultValue) {
         String value = getProperty(namespace, name);
+        if (value == null) {
+            return defaultValue;
+        }
         try {
             return Integer.parseInt(value);
         } catch (NumberFormatException e) {
+            Log.e(TAG, "Parsing integer failed for " + namespace + ":" + name);
             return defaultValue;
         }
     }
@@ -499,11 +495,15 @@
     @SystemApi
     @TestApi
     @RequiresPermission(READ_DEVICE_CONFIG)
-    public static long getLong(String namespace, String name, long defaultValue) {
+    public static long getLong(@NonNull String namespace, @NonNull String name, long defaultValue) {
         String value = getProperty(namespace, name);
+        if (value == null) {
+            return defaultValue;
+        }
         try {
             return Long.parseLong(value);
         } catch (NumberFormatException e) {
+            Log.e(TAG, "Parsing long failed for " + namespace + ":" + name);
             return defaultValue;
         }
     }
@@ -521,13 +521,16 @@
     @SystemApi
     @TestApi
     @RequiresPermission(READ_DEVICE_CONFIG)
-    public static float getFloat(String namespace, String name, float defaultValue) {
+    public static float getFloat(@NonNull String namespace, @NonNull String name,
+            float defaultValue) {
         String value = getProperty(namespace, name);
+        if (value == null) {
+            return defaultValue;
+        }
         try {
             return Float.parseFloat(value);
         } catch (NumberFormatException e) {
-            return defaultValue;
-        } catch (NullPointerException e) {
+            Log.e(TAG, "Parsing float failed for " + namespace + ":" + name);
             return defaultValue;
         }
     }
@@ -554,10 +557,10 @@
     @SystemApi
     @TestApi
     @RequiresPermission(WRITE_DEVICE_CONFIG)
-    public static boolean setProperty(
-            String namespace, String name, String value, boolean makeDefault) {
-        ContentResolver contentResolver = ActivityThread.currentApplication().getContentResolver();
+    public static boolean setProperty(@NonNull String namespace, @NonNull String name,
+            @Nullable String value, boolean makeDefault) {
         String compositeName = createCompositeName(namespace, name);
+        ContentResolver contentResolver = ActivityThread.currentApplication().getContentResolver();
         return Settings.Config.putString(contentResolver, compositeName, value, makeDefault);
     }
 
@@ -700,11 +703,14 @@
         }
     }
 
-    private static String createCompositeName(String namespace, String name) {
+    private static String createCompositeName(@NonNull String namespace, @NonNull String name) {
+        Preconditions.checkNotNull(namespace);
+        Preconditions.checkNotNull(name);
         return namespace + "/" + name;
     }
 
-    private static Uri createNamespaceUri(String namespace) {
+    private static Uri createNamespaceUri(@NonNull String namespace) {
+        Preconditions.checkNotNull(namespace);
         return CONTENT_URI.buildUpon().appendPath(namespace).build();
     }
 
@@ -716,7 +722,8 @@
      * @param namespace The namespace to increment the count for.
      */
     @GuardedBy("sLock")
-    private static void incrementNamespace(String namespace) {
+    private static void incrementNamespace(@NonNull String namespace) {
+        Preconditions.checkNotNull(namespace);
         Pair<ContentObserver, Integer> namespaceCount = sNamespaces.get(namespace);
         if (namespaceCount != null) {
             sNamespaces.put(namespace, new Pair<>(namespaceCount.first, namespaceCount.second + 1));
@@ -725,7 +732,9 @@
             ContentObserver contentObserver = new ContentObserver(null) {
                 @Override
                 public void onChange(boolean selfChange, Uri uri) {
-                    handleChange(uri);
+                    if (uri != null) {
+                        handleChange(uri);
+                    }
                 }
             };
             ActivityThread.currentApplication().getContentResolver()
@@ -742,7 +751,8 @@
      * @param namespace The namespace to decrement the count for.
      */
     @GuardedBy("sLock")
-    private static void decrementNamespace(String namespace) {
+    private static void decrementNamespace(@NonNull String namespace) {
+        Preconditions.checkNotNull(namespace);
         Pair<ContentObserver, Integer> namespaceCount = sNamespaces.get(namespace);
         if (namespaceCount == null) {
             // This namespace is not registered and does not need to be decremented
@@ -757,7 +767,8 @@
         }
     }
 
-    private static void handleChange(Uri uri) {
+    private static void handleChange(@NonNull Uri uri) {
+        Preconditions.checkNotNull(uri);
         List<String> pathSegments = uri.getPathSegments();
         // pathSegments(0) is "config"
         final String namespace = pathSegments.get(1);
@@ -813,7 +824,8 @@
          * @param name      The name of the property which has changed.
          * @param value     The new value of the property which has changed.
          */
-        void onPropertyChanged(String namespace, String name, String value);
+        void onPropertyChanged(@NonNull String namespace, @NonNull String name,
+                @Nullable String value);
     }
 
     /**
@@ -915,9 +927,13 @@
         public int getInt(@NonNull String name, int defaultValue) {
             Preconditions.checkNotNull(name);
             String value = mMap.get(name);
+            if (value == null) {
+                return defaultValue;
+            }
             try {
                 return Integer.parseInt(value);
             } catch (NumberFormatException e) {
+                Log.e(TAG, "Parsing int failed for " + name);
                 return defaultValue;
             }
         }
@@ -933,9 +949,13 @@
         public long getLong(@NonNull String name, long defaultValue) {
             Preconditions.checkNotNull(name);
             String value = mMap.get(name);
+            if (value == null) {
+                return defaultValue;
+            }
             try {
                 return Long.parseLong(value);
             } catch (NumberFormatException e) {
+                Log.e(TAG, "Parsing long failed for " + name);
                 return defaultValue;
             }
         }
@@ -951,11 +971,13 @@
         public float getFloat(@NonNull String name, float defaultValue) {
             Preconditions.checkNotNull(name);
             String value = mMap.get(name);
+            if (value == null) {
+                return defaultValue;
+            }
             try {
                 return Float.parseFloat(value);
             } catch (NumberFormatException e) {
-                return defaultValue;
-            } catch (NullPointerException e) {
+                Log.e(TAG, "Parsing float failed for " + name);
                 return defaultValue;
             }
         }
diff --git a/core/java/android/provider/FontsContract.java b/core/java/android/provider/FontsContract.java
index e931826..2814474 100644
--- a/core/java/android/provider/FontsContract.java
+++ b/core/java/android/provider/FontsContract.java
@@ -34,7 +34,6 @@
 import android.graphics.fonts.FontStyle;
 import android.graphics.fonts.FontVariationAxis;
 import android.net.Uri;
-import android.os.Build.VERSION_CODES;
 import android.os.CancellationSignal;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -642,25 +641,35 @@
                 continue;
             }
             try {
-                final Font font = new Font.Builder(buffer)
+                Font font = null;
+                try {
+                    font = new Font.Builder(buffer)
                         .setWeight(fontInfo.getWeight())
                         .setSlant(fontInfo.isItalic()
                                 ? FontStyle.FONT_SLANT_ITALIC : FontStyle.FONT_SLANT_UPRIGHT)
                         .setTtcIndex(fontInfo.getTtcIndex())
                         .setFontVariationSettings(fontInfo.getAxes())
                         .build();
+                } catch (IllegalArgumentException e) {
+                    // The exception happens if the unsupported font is passed. We suppress this
+                    // exception and just ignore this font here since there is no way of
+                    // resolving this issue by users during inflating layout.
+                    Log.w(TAG, "Ignoring font file since failed to create font object."
+                            + " The font file is not supported on this platform.");
+                    continue;
+                }
                 if (familyBuilder == null) {
                     familyBuilder = new FontFamily.Builder(font);
                 } else {
                     try {
                         familyBuilder.addFont(font);
                     } catch (IllegalArgumentException e) {
-                        if (context.getApplicationInfo().targetSdkVersion <= VERSION_CODES.P) {
-                            // Surpress the IllegalArgumentException for keeping the backward
-                            // compatibility.
-                            continue;
-                        }
-                        throw e;
+                        // The exception happens if the same style font is added to the family.
+                        // We suppress this exception and just ignore this font here since there is
+                        // no way of resolving this issue by users during inflating layout.
+                        Log.w(TAG,
+                                "Ignoring font file since the same style font is already added.");
+                        continue;
                     }
                 }
             } catch (IOException e) {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 4836e6c..df5da6c 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5590,6 +5590,15 @@
         private static final Validator ALLOW_MOCK_LOCATION_VALIDATOR = BOOLEAN_VALIDATOR;
 
         /**
+         * Setting to indicate that on device captions are enabled.
+         *
+         * @hide
+         */
+        public static final String ODI_CAPTIONS_ENABLED = "odi_captions_enabled";
+
+        private static final Validator ODI_CAPTIONS_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
+
+        /**
          * On Android 8.0 (API level 26) and higher versions of the platform,
          * a 64-bit number (expressed as a hexadecimal string), unique to
          * each combination of app-signing key, user, and device.
@@ -6335,7 +6344,6 @@
          * Number of times the user has manually clicked the ringer toggle
          * @hide
          */
-        @SystemApi
         public static final String MANUAL_RINGER_TOGGLE_COUNT = "manual_ringer_toggle_count";
 
         private static final Validator MANUAL_RINGER_TOGGLE_COUNT_VALIDATOR =
@@ -8508,9 +8516,15 @@
         @SystemApi
         public static final String VOLUME_HUSH_GESTURE = "volume_hush_gesture";
 
-        /** @hide */ public static final int VOLUME_HUSH_OFF = 0;
-        /** @hide */ public static final int VOLUME_HUSH_VIBRATE = 1;
-        /** @hide */ public static final int VOLUME_HUSH_MUTE = 2;
+        /** @hide */
+        @SystemApi
+        public static final int VOLUME_HUSH_OFF = 0;
+        /** @hide */
+        @SystemApi
+        public static final int VOLUME_HUSH_VIBRATE = 1;
+        /** @hide */
+        @SystemApi
+        public static final int VOLUME_HUSH_MUTE = 2;
 
         private static final Validator VOLUME_HUSH_GESTURE_VALIDATOR =
                 NON_NEGATIVE_INTEGER_VALIDATOR;
@@ -8950,6 +8964,7 @@
             VALIDATORS.put(SILENCE_TIMER_GESTURE_COUNT, SILENCE_GESTURE_COUNT_VALIDATOR);
             VALIDATORS.put(SILENCE_CALL_GESTURE_COUNT, SILENCE_GESTURE_COUNT_VALIDATOR);
             VALIDATORS.put(SILENCE_NOTIFICATION_GESTURE_COUNT, SILENCE_GESTURE_COUNT_VALIDATOR);
+            VALIDATORS.put(ODI_CAPTIONS_ENABLED, ODI_CAPTIONS_ENABLED_VALIDATOR);
         }
 
         /**
@@ -9038,27 +9053,12 @@
          * @return true if the provider is enabled
          *
          * @deprecated use {@link LocationManager#isProviderEnabled(String)}
+         * @removed no longer supported
          */
         @Deprecated
-        public static final boolean isLocationProviderEnabled(ContentResolver cr, String provider) {
-            return isLocationProviderEnabledForUser(cr, provider, cr.getUserId());
-        }
-
-        /**
-         * Helper method for determining if a location provider is enabled.
-         * @param cr the content resolver to use
-         * @param provider the location provider to query
-         * @param userId the userId to query
-         * @return true if the provider is enabled
-         *
-         * @deprecated use {@link LocationManager#isProviderEnabled(String)}
-         * @hide
-         */
-        @Deprecated
-        public static final boolean isLocationProviderEnabledForUser(
-                ContentResolver cr, String provider, int userId) {
+        public static boolean isLocationProviderEnabled(ContentResolver cr, String provider) {
             String allowedProviders = Settings.Secure.getStringForUser(cr,
-                    LOCATION_PROVIDERS_ALLOWED, userId);
+                    LOCATION_PROVIDERS_ALLOWED, cr.getUserId());
             return TextUtils.delimitedStringContains(allowedProviders, ',', provider);
         }
 
@@ -9067,42 +9067,12 @@
          * @param cr the content resolver to use
          * @param provider the location provider to enable or disable
          * @param enabled true if the provider should be enabled
-         * @deprecated This API is deprecated. It requires WRITE_SECURE_SETTINGS permission to
-         *             change location settings.
+         * @deprecated This API is deprecated
+         * @removed no longer supported
          */
         @Deprecated
-        public static final void setLocationProviderEnabled(ContentResolver cr,
+        public static void setLocationProviderEnabled(ContentResolver cr,
                 String provider, boolean enabled) {
-            setLocationProviderEnabledForUser(cr, provider, enabled, cr.getUserId());
-        }
-
-        /**
-         * Thread-safe method for enabling or disabling a single location provider.
-         *
-         * @param cr the content resolver to use
-         * @param provider the location provider to enable or disable
-         * @param enabled true if the provider should be enabled
-         * @param userId the userId for which to enable/disable providers
-         * @return true if the value was set, false on database errors
-         *
-         * @deprecated use {@link LocationManager#setProviderEnabledForUser(String, boolean, int)}
-         * @hide
-         */
-        @Deprecated
-        public static final boolean setLocationProviderEnabledForUser(ContentResolver cr,
-                String provider, boolean enabled, int userId) {
-            synchronized (mLocationSettingsLock) {
-                // to ensure thread safety, we write the provider name with a '+' or '-'
-                // and let the SettingsProvider handle it rather than reading and modifying
-                // the list of enabled providers.
-                if (enabled) {
-                    provider = "+" + provider;
-                } else {
-                    provider = "-" + provider;
-                }
-                return putStringForUser(cr, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, provider,
-                        userId);
-            }
         }
     }
 
@@ -11508,6 +11478,7 @@
          * service_min_restart_time_between     (long)
          * service_max_inactivity               (long)
          * service_bg_start_timeout             (long)
+         * service_bg_activity_start_timeout    (long)
          * process_start_async                  (boolean)
          * </pre>
          *
@@ -12007,6 +11978,8 @@
          * notification_conversation_action_types_default   (String[])
          * lang_id_threshold_override                       (float)
          * template_intent_factory_enabled                  (boolean)
+         * translate_in_classification_enabled              (boolean)
+         * detect_language_from_text_enabled                (boolean)
          * </pre>
          *
          * <p>
diff --git a/core/java/android/service/attention/AttentionService.java b/core/java/android/service/attention/AttentionService.java
index 24d74ff..32f4ea9 100644
--- a/core/java/android/service/attention/AttentionService.java
+++ b/core/java/android/service/attention/AttentionService.java
@@ -18,6 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.app.Service;
 import android.content.Intent;
@@ -111,8 +112,9 @@
         }
     };
 
+    @Nullable
     @Override
-    public final IBinder onBind(Intent intent) {
+    public final IBinder onBind(@NonNull Intent intent) {
         if (SERVICE_INTERFACE.equals(intent.getAction())) {
             return mBinder;
         }
diff --git a/core/java/android/service/contentcapture/ContentCaptureService.java b/core/java/android/service/contentcapture/ContentCaptureService.java
index 192abd5..6f4114d 100644
--- a/core/java/android/service/contentcapture/ContentCaptureService.java
+++ b/core/java/android/service/contentcapture/ContentCaptureService.java
@@ -102,9 +102,10 @@
 
         @Override
         public void onSessionStarted(ContentCaptureContext context, String sessionId, int uid,
-                IResultReceiver clientReceiver) {
+                IResultReceiver clientReceiver, int initialState) {
             mHandler.sendMessage(obtainMessage(ContentCaptureService::handleOnCreateSession,
-                    ContentCaptureService.this, context, sessionId, uid, clientReceiver));
+                    ContentCaptureService.this, context, sessionId, uid, clientReceiver,
+                    initialState));
         }
 
         @Override
@@ -335,7 +336,7 @@
     // so we don't need to create a temporary InteractionSessionId for each event.
 
     private void handleOnCreateSession(@NonNull ContentCaptureContext context,
-            @NonNull String sessionId, int uid, IResultReceiver clientReceiver) {
+            @NonNull String sessionId, int uid, IResultReceiver clientReceiver, int initialState) {
         mSessionUids.put(sessionId, uid);
         onCreateContentCaptureSession(context, new ContentCaptureSessionId(sessionId));
 
@@ -348,7 +349,7 @@
             stateFlags |= ContentCaptureSession.STATE_BY_APP;
         }
         if (stateFlags == 0) {
-            stateFlags = ContentCaptureSession.STATE_ACTIVE;
+            stateFlags = initialState;
         } else {
             stateFlags |= ContentCaptureSession.STATE_DISABLED;
 
diff --git a/core/java/android/service/contentcapture/IContentCaptureService.aidl b/core/java/android/service/contentcapture/IContentCaptureService.aidl
index f32432f..6be7a80 100644
--- a/core/java/android/service/contentcapture/IContentCaptureService.aidl
+++ b/core/java/android/service/contentcapture/IContentCaptureService.aidl
@@ -36,7 +36,7 @@
     void onConnected(IBinder callback, boolean verbose, boolean debug);
     void onDisconnected();
     void onSessionStarted(in ContentCaptureContext context, String sessionId, int uid,
-                          in IResultReceiver clientReceiver);
+                          in IResultReceiver clientReceiver, int initialState);
     void onSessionFinished(String sessionId);
     void onActivitySnapshot(String sessionId, in SnapshotData snapshotData);
     void onUserDataRemovalRequest(in UserDataRemovalRequest request);
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index fb6dc22..bf0ef94 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -2192,26 +2192,26 @@
      */
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
     public static class TabStops {
-        private int[] mStops;
+        private float[] mStops;
         private int mNumStops;
-        private int mIncrement;
+        private float mIncrement;
 
-        public TabStops(int increment, Object[] spans) {
+        public TabStops(float increment, Object[] spans) {
             reset(increment, spans);
         }
 
-        void reset(int increment, Object[] spans) {
+        void reset(float increment, Object[] spans) {
             this.mIncrement = increment;
 
             int ns = 0;
             if (spans != null) {
-                int[] stops = this.mStops;
+                float[] stops = this.mStops;
                 for (Object o : spans) {
                     if (o instanceof TabStopSpan) {
                         if (stops == null) {
-                            stops = new int[10];
+                            stops = new float[10];
                         } else if (ns == stops.length) {
-                            int[] nstops = new int[ns * 2];
+                            float[] nstops = new float[ns * 2];
                             for (int i = 0; i < ns; ++i) {
                                 nstops[i] = stops[i];
                             }
@@ -2233,9 +2233,9 @@
         float nextTab(float h) {
             int ns = this.mNumStops;
             if (ns > 0) {
-                int[] stops = this.mStops;
+                float[] stops = this.mStops;
                 for (int i = 0; i < ns; ++i) {
-                    int stop = stops[i];
+                    float stop = stops[i];
                     if (stop > h) {
                         return stop;
                     }
@@ -2244,7 +2244,10 @@
             return nextDefaultStop(h, mIncrement);
         }
 
-        public static float nextDefaultStop(float h, int inc) {
+        /**
+         * Returns the position of next tab stop.
+         */
+        public static float nextDefaultStop(float h, float inc) {
             return ((int) ((h + inc) / inc)) * inc;
         }
     }
@@ -2582,7 +2585,7 @@
         ALIGN_RIGHT,
     }
 
-    private static final int TAB_INCREMENT = 20;
+    private static final float TAB_INCREMENT = 20;
 
     /** @hide */
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 9fefc83..69cfc03 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -737,14 +737,14 @@
                 }
             }
             // tab stop locations
-            int[] variableTabStops = null;
+            float[] variableTabStops = null;
             if (spanned != null) {
                 TabStopSpan[] spans = getParagraphSpans(spanned, paraStart,
                         paraEnd, TabStopSpan.class);
                 if (spans.length > 0) {
-                    int[] stops = new int[spans.length];
+                    float[] stops = new float[spans.length];
                     for (int i = 0; i < spans.length; i++) {
-                        stops[i] = spans[i].getTabStop();
+                        stops[i] = (float) spans[i].getTabStop();
                     }
                     Arrays.sort(stops, 0, stops.length);
                     variableTabStops = stops;
@@ -1422,7 +1422,7 @@
     private static final int START_HYPHEN_MASK = 0x18; // 0b11000
     private static final int END_HYPHEN_MASK = 0x7;  // 0b00111
 
-    private static final int TAB_INCREMENT = 20; // same as Layout, but that's private
+    private static final float TAB_INCREMENT = 20; // same as Layout, but that's private
 
     private static final char CHAR_NEW_LINE = '\n';
 
diff --git a/core/java/android/text/style/ImageSpan.java b/core/java/android/text/style/ImageSpan.java
index 13ac9ff..98f58be 100644
--- a/core/java/android/text/style/ImageSpan.java
+++ b/core/java/android/text/style/ImageSpan.java
@@ -46,10 +46,10 @@
  * <p>
  * For example, an <code>ImagedSpan</code> can be used like this:
  * <pre>
- * SpannableString string = SpannableString("Bottom: span.\nBaseline: span.");
+ * SpannableString string = new SpannableString("Bottom: span.\nBaseline: span.");
  * // using the default alignment: ALIGN_BOTTOM
- * string.setSpan(ImageSpan(this, R.mipmap.ic_launcher), 7, 8, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- * string.setSpan(ImageSpan(this, R.mipmap.ic_launcher, DynamicDrawableSpan.ALIGN_BASELINE),
+ * string.setSpan(new ImageSpan(this, R.mipmap.ic_launcher), 7, 8, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ * string.setSpan(new ImageSpan(this, R.mipmap.ic_launcher, DynamicDrawableSpan.ALIGN_BASELINE),
  * 22, 23, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
  * </pre>
  * <img src="{@docRoot}reference/android/images/text/style/imagespan.png" />
diff --git a/core/java/android/util/ArrayMap.java b/core/java/android/util/ArrayMap.java
index e2af6f5..436cb4f 100644
--- a/core/java/android/util/ArrayMap.java
+++ b/core/java/android/util/ArrayMap.java
@@ -16,12 +16,12 @@
 
 package android.util;
 
+import libcore.util.EmptyArray;
+
 import android.annotation.UnsupportedAppUsage;
 
 import com.android.internal.util.ArrayUtils;
 
-import libcore.util.EmptyArray;
-
 import java.util.Collection;
 import java.util.ConcurrentModificationException;
 import java.util.Map;
@@ -453,10 +453,6 @@
      * @return Returns the key stored at the given index.
      */
     public K keyAt(int index) {
-        if (index >= mSize) {
-            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
-            throw new ArrayIndexOutOfBoundsException(index);
-        }
         return (K)mArray[index << 1];
     }
 
@@ -466,10 +462,6 @@
      * @return Returns the value stored at the given index.
      */
     public V valueAt(int index) {
-        if (index >= mSize) {
-            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
-            throw new ArrayIndexOutOfBoundsException(index);
-        }
         return (V)mArray[(index << 1) + 1];
     }
 
@@ -480,10 +472,6 @@
      * @return Returns the previous value at the given index.
      */
     public V setValueAt(int index, V value) {
-        if (index >= mSize) {
-            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
-            throw new ArrayIndexOutOfBoundsException(index);
-        }
         index = (index << 1) + 1;
         V old = (V)mArray[index];
         mArray[index] = value;
@@ -677,11 +665,6 @@
      * @return Returns the value that was stored at this index.
      */
     public V removeAt(int index) {
-        if (index >= mSize) {
-            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
-            throw new ArrayIndexOutOfBoundsException(index);
-        }
-
         final Object old = mArray[(index << 1) + 1];
         final int osize = mSize;
         final int nsize;
diff --git a/core/java/android/util/LongSparseArray.java b/core/java/android/util/LongSparseArray.java
index e4de704..cf49803 100644
--- a/core/java/android/util/LongSparseArray.java
+++ b/core/java/android/util/LongSparseArray.java
@@ -21,6 +21,9 @@
 
 import libcore.util.EmptyArray;
 
+import java.util.Arrays;
+import java.util.Objects;
+
 /**
  * SparseArray mapping longs to Objects.  Unlike a normal array of Objects,
  * there can be gaps in the indices.  It is intended to be more memory efficient
@@ -144,10 +147,6 @@
      * Removes the mapping at the specified index.
      */
     public void removeAt(int index) {
-        if (index >= mSize) {
-            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
-            throw new ArrayIndexOutOfBoundsException(index);
-        }
         if (mValues[index] != DELETED) {
             mValues[index] = DELETED;
             mGarbage = true;
@@ -237,10 +236,6 @@
      * key.</p>
      */
     public long keyAt(int index) {
-        if (index >= mSize) {
-            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
-            throw new ArrayIndexOutOfBoundsException(index);
-        }
         if (mGarbage) {
             gc();
         }
@@ -261,10 +256,6 @@
      */
     @SuppressWarnings("unchecked")
     public E valueAt(int index) {
-        if (index >= mSize) {
-            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
-            throw new ArrayIndexOutOfBoundsException(index);
-        }
         if (mGarbage) {
             gc();
         }
@@ -278,10 +269,6 @@
      * LongSparseArray stores.
      */
     public void setValueAt(int index, E value) {
-        if (index >= mSize) {
-            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
-            throw new ArrayIndexOutOfBoundsException(index);
-        }
         if (mGarbage) {
             gc();
         }
diff --git a/core/java/android/util/LongSparseLongArray.java b/core/java/android/util/LongSparseLongArray.java
index f167f00..8dcdb40 100644
--- a/core/java/android/util/LongSparseLongArray.java
+++ b/core/java/android/util/LongSparseLongArray.java
@@ -16,13 +16,14 @@
 
 package android.util;
 
-import android.annotation.UnsupportedAppUsage;
-
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.GrowingArrayUtils;
 
+import android.annotation.UnsupportedAppUsage;
 import libcore.util.EmptyArray;
 
+import java.util.Arrays;
+
 /**
  * Map of {@code long} to {@code long}. Unlike a normal array of longs, there
  * can be gaps in the indices. It is intended to be more memory efficient than using a
@@ -172,10 +173,6 @@
      * key.</p>
      */
     public long keyAt(int index) {
-        if (index >= mSize) {
-            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
-            throw new ArrayIndexOutOfBoundsException(index);
-        }
         return mKeys[index];
     }
 
@@ -191,10 +188,6 @@
      * associated with the largest key.</p>
      */
     public long valueAt(int index) {
-        if (index >= mSize) {
-            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
-            throw new ArrayIndexOutOfBoundsException(index);
-        }
         return mValues[index];
     }
 
diff --git a/core/java/android/util/SparseArray.java b/core/java/android/util/SparseArray.java
index 67dfb02..89ea2d3 100644
--- a/core/java/android/util/SparseArray.java
+++ b/core/java/android/util/SparseArray.java
@@ -16,11 +16,10 @@
 
 package android.util;
 
-import android.annotation.UnsupportedAppUsage;
-
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.GrowingArrayUtils;
 
+import android.annotation.UnsupportedAppUsage;
 import libcore.util.EmptyArray;
 
 /**
@@ -172,10 +171,6 @@
      * the behavior is undefined.</p>
      */
     public void removeAt(int index) {
-        if (index >= mSize) {
-            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
-            throw new ArrayIndexOutOfBoundsException(index);
-        }
         if (mValues[index] != DELETED) {
             mValues[index] = DELETED;
             mGarbage = true;
@@ -284,10 +279,6 @@
      * the behavior is undefined.</p>
      */
     public int keyAt(int index) {
-        if (index >= mSize) {
-            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
-            throw new ArrayIndexOutOfBoundsException(index);
-        }
         if (mGarbage) {
             gc();
         }
@@ -311,10 +302,6 @@
      */
     @SuppressWarnings("unchecked")
     public E valueAt(int index) {
-        if (index >= mSize) {
-            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
-            throw new ArrayIndexOutOfBoundsException(index);
-        }
         if (mGarbage) {
             gc();
         }
@@ -330,10 +317,6 @@
      * <p>For indices outside of the range <code>0...size()-1</code>, the behavior is undefined.</p>
      */
     public void setValueAt(int index, E value) {
-        if (index >= mSize) {
-            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
-            throw new ArrayIndexOutOfBoundsException(index);
-        }
         if (mGarbage) {
             gc();
         }
diff --git a/core/java/android/util/SparseBooleanArray.java b/core/java/android/util/SparseBooleanArray.java
index 03fa1c9..d4c4095 100644
--- a/core/java/android/util/SparseBooleanArray.java
+++ b/core/java/android/util/SparseBooleanArray.java
@@ -16,11 +16,10 @@
 
 package android.util;
 
-import android.annotation.UnsupportedAppUsage;
-
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.GrowingArrayUtils;
 
+import android.annotation.UnsupportedAppUsage;
 import libcore.util.EmptyArray;
 
 /**
@@ -168,10 +167,6 @@
      * key.</p>
      */
     public int keyAt(int index) {
-        if (index >= mSize) {
-            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
-            throw new ArrayIndexOutOfBoundsException(index);
-        }
         return mKeys[index];
     }
 
@@ -187,10 +182,6 @@
      * associated with the largest key.</p>
      */
     public boolean valueAt(int index) {
-        if (index >= mSize) {
-            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
-            throw new ArrayIndexOutOfBoundsException(index);
-        }
         return mValues[index];
     }
 
@@ -198,19 +189,11 @@
      * Directly set the value at a particular index.
      */
     public void setValueAt(int index, boolean value) {
-        if (index >= mSize) {
-            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
-            throw new ArrayIndexOutOfBoundsException(index);
-        }
         mValues[index] = value;
     }
 
     /** @hide */
     public void setKeyAt(int index, int key) {
-        if (index >= mSize) {
-            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
-            throw new ArrayIndexOutOfBoundsException(index);
-        }
         mKeys[index] = key;
     }
 
diff --git a/core/java/android/util/SparseIntArray.java b/core/java/android/util/SparseIntArray.java
index c68dc4e..9e6bad1 100644
--- a/core/java/android/util/SparseIntArray.java
+++ b/core/java/android/util/SparseIntArray.java
@@ -16,15 +16,14 @@
 
 package android.util;
 
-import android.annotation.UnsupportedAppUsage;
-
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.GrowingArrayUtils;
 
-import libcore.util.EmptyArray;
-
 import java.util.Arrays;
 
+import android.annotation.UnsupportedAppUsage;
+import libcore.util.EmptyArray;
+
 /**
  * SparseIntArrays map integers to integers.  Unlike a normal array of integers,
  * there can be gaps in the indices.  It is intended to be more memory efficient
@@ -172,10 +171,6 @@
      * key.</p>
      */
     public int keyAt(int index) {
-        if (index >= mSize) {
-            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
-            throw new ArrayIndexOutOfBoundsException(index);
-        }
         return mKeys[index];
     }
 
@@ -191,10 +186,6 @@
      * associated with the largest key.</p>
      */
     public int valueAt(int index) {
-        if (index >= mSize) {
-            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
-            throw new ArrayIndexOutOfBoundsException(index);
-        }
         return mValues[index];
     }
 
@@ -202,10 +193,6 @@
      * Directly set the value at a particular index.
      */
     public void setValueAt(int index, int value) {
-        if (index >= mSize) {
-            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
-            throw new ArrayIndexOutOfBoundsException(index);
-        }
         mValues[index] = value;
     }
 
diff --git a/core/java/android/util/SparseLongArray.java b/core/java/android/util/SparseLongArray.java
index 37a9202..81db2b7 100644
--- a/core/java/android/util/SparseLongArray.java
+++ b/core/java/android/util/SparseLongArray.java
@@ -182,10 +182,6 @@
      * key.</p>
      */
     public int keyAt(int index) {
-        if (index >= mSize) {
-            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
-            throw new ArrayIndexOutOfBoundsException(index);
-        }
         return mKeys[index];
     }
 
@@ -201,10 +197,6 @@
      * associated with the largest key.</p>
      */
     public long valueAt(int index) {
-        if (index >= mSize) {
-            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
-            throw new ArrayIndexOutOfBoundsException(index);
-        }
         return mValues[index];
     }
 
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 998ad2a..cd075bf 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -63,6 +63,7 @@
 import java.io.Closeable;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
+import java.util.Objects;
 
 /**
  * Handle to an on-screen Surface managed by the system compositor. The SurfaceControl is
@@ -196,6 +197,9 @@
     private static native boolean nativeGetProtectedContentSupport();
     private static native void nativeSetMetadata(long transactionObj, int key, Parcel data);
     private static native void nativeSyncInputWindows(long transactionObj);
+    private static native boolean nativeGetDisplayBrightnessSupport(IBinder displayToken);
+    private static native boolean nativeSetDisplayBrightness(IBinder displayToken,
+            float brightness);
 
     private final CloseGuard mCloseGuard = CloseGuard.get();
     private String mName;
@@ -1961,6 +1965,47 @@
     }
 
     /**
+     * Returns whether brightness operations are supported on a display.
+     *
+     * @param displayToken
+     *      The token for the display.
+     *
+     * @return Whether brightness operations are supported on the display.
+     *
+     * @hide
+     */
+    public static boolean getDisplayBrightnessSupport(IBinder displayToken) {
+        return nativeGetDisplayBrightnessSupport(displayToken);
+    }
+
+    /**
+     * Sets the brightness of a display.
+     *
+     * @param displayToken
+     *      The token for the display whose brightness is set.
+     * @param brightness
+     *      A number between 0.0f (minimum brightness) and 1.0f (maximum brightness), or -1.0f to
+     *      turn the backlight off.
+     *
+     * @return Whether the method succeeded or not.
+     *
+     * @throws IllegalArgumentException if:
+     *      - displayToken is null;
+     *      - brightness is NaN or greater than 1.0f.
+     *
+     * @hide
+     */
+    public static boolean setDisplayBrightness(IBinder displayToken, float brightness) {
+        Objects.requireNonNull(displayToken);
+        if (Float.isNaN(brightness) || brightness > 1.0f
+                || (brightness < 0.0f && brightness != -1.0f)) {
+            throw new IllegalArgumentException("brightness must be a number between 0.0f and 1.0f,"
+                    + " or -1 to turn the backlight off.");
+        }
+        return nativeSetDisplayBrightness(displayToken, brightness);
+    }
+
+    /**
      * An atomic set of changes to a set of SurfaceControl.
      */
     public static class Transaction implements Closeable {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 7fcce6d..b857f1e 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -17197,6 +17197,7 @@
      * and {@link #setTranslationY(float)} (float)}} instead.
      *
      * @param matrix The matrix, null indicates that the matrix should be cleared.
+     * @see #getAnimationMatrix()
      */
     public void setAnimationMatrix(@Nullable Matrix matrix) {
         invalidateViewProperty(true, false);
@@ -17207,6 +17208,22 @@
     }
 
     /**
+     * Return the current transformation matrix of the view. This is used in animation frameworks,
+     * such as {@link android.transition.Transition}. Returns <code>null</code> when there is no
+     * transformation provided by {@link #setAnimationMatrix(Matrix)}.
+     * Application developers should use transformation methods like {@link #setRotation(float)},
+     * {@link #setScaleX(float)}, {@link #setScaleX(float)}, {@link #setTranslationX(float)}}
+     * and {@link #setTranslationY(float)} (float)}} instead.
+     *
+     * @return the Matrix, null indicates there is no transformation
+     * @see #setAnimationMatrix(Matrix)
+     */
+    @Nullable
+    public Matrix getAnimationMatrix() {
+        return mRenderNode.getAnimationMatrix();
+    }
+
+    /**
      * Returns the current StateListAnimator if exists.
      *
      * @return StateListAnimator or null if it does not exists
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 4dc20d4..4964ee1 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -4284,35 +4284,38 @@
     }
 
     /**
-     * Returns the index of the child to draw for this iteration. Override this
+     * Converts drawing order position to container position. Override this
      * if you want to change the drawing order of children. By default, it
-     * returns i.
+     * returns drawingPosition.
      * <p>
      * NOTE: In order for this method to be called, you must enable child ordering
      * first by calling {@link #setChildrenDrawingOrderEnabled(boolean)}.
      *
-     * @param i The current iteration.
-     * @return The index of the child to draw this iteration.
+     * @param drawingPosition the drawing order position.
+     * @return the container position of a child for this drawing order position.
      *
      * @see #setChildrenDrawingOrderEnabled(boolean)
      * @see #isChildrenDrawingOrderEnabled()
      */
-    protected int getChildDrawingOrder(int childCount, int i) {
-        return i;
+    protected int getChildDrawingOrder(int childCount, int drawingPosition) {
+        return drawingPosition;
     }
 
     /**
-     * The public version of getChildDrawingOrder().
+     * Converts drawing order position to container position.
+     * <p>
+     * Children are not necessarily drawn in the order in which they appear in the container.
+     * ViewGroups can enable a custom ordering via {@link #setChildrenDrawingOrderEnabled(boolean)}.
+     * This method returns the container position of a child that appears in the given position
+     * in the current drawing order.
      *
-     * Returns the index of the child to draw for this iteration.
-     *
-     * @param i The current iteration.
-     * @return The index of the child to draw this iteration.
+     * @param drawingPosition the drawing order position.
+     * @return the container position of a child for this drawing order position.
      *
      * @see #getChildDrawingOrder(int, int)}
      */
-    public final int getChildDrawingOrder(int i) {
-        return getChildDrawingOrder(getChildCount(), i);
+    public final int getChildDrawingOrder(int drawingPosition) {
+        return getChildDrawingOrder(getChildCount(), drawingPosition);
     }
 
     private boolean hasChildWithZ() {
diff --git a/core/java/android/view/contentcapture/ContentCaptureContext.java b/core/java/android/view/contentcapture/ContentCaptureContext.java
index b9dc0dd..019ebff 100644
--- a/core/java/android/view/contentcapture/ContentCaptureContext.java
+++ b/core/java/android/view/contentcapture/ContentCaptureContext.java
@@ -71,10 +71,21 @@
     @TestApi
     public static final int FLAG_DISABLED_BY_FLAG_SECURE = 0x2;
 
+    /**
+     * Flag used when the event is sent because the Android System reconnected to the service (for
+     * example, after its process died).
+     *
+     * @hide
+     */
+    @SystemApi
+    @TestApi
+    public static final int FLAG_RECONNECTED = 0x4;
+
     /** @hide */
     @IntDef(flag = true, prefix = { "FLAG_" }, value = {
             FLAG_DISABLED_BY_APP,
-            FLAG_DISABLED_BY_FLAG_SECURE
+            FLAG_DISABLED_BY_FLAG_SECURE,
+            FLAG_RECONNECTED
     })
     @Retention(RetentionPolicy.SOURCE)
     @interface ContextCreationFlags{}
@@ -126,6 +137,17 @@
         mDisplayId = Display.INVALID_DISPLAY;
     }
 
+    /** @hide */
+    public ContentCaptureContext(@Nullable ContentCaptureContext original, int extraFlags) {
+        mHasClientContext = original.mHasClientContext;
+        mExtras = original.mExtras;
+        mId = original.mId;
+        mComponentName = original.mComponentName;
+        mTaskId = original.mTaskId;
+        mFlags = original.mFlags | extraFlags;
+        mDisplayId = original.mDisplayId;
+    }
+
     /**
      * Gets the (optional) extras set by the app (through {@link Builder#setExtras(Bundle)}).
      *
@@ -199,8 +221,8 @@
     /**
      * Gets the flags associated with this context.
      *
-     * @return any combination of {@link #FLAG_DISABLED_BY_FLAG_SECURE} and
-     * {@link #FLAG_DISABLED_BY_APP}.
+     * @return any combination of {@link #FLAG_DISABLED_BY_FLAG_SECURE},
+     * {@link #FLAG_DISABLED_BY_APP} and {@link #FLAG_RECONNECTED}.
      *
      * @hide
      */
diff --git a/core/java/android/view/contentcapture/ContentCaptureEvent.java b/core/java/android/view/contentcapture/ContentCaptureEvent.java
index 67d3629..8188e05 100644
--- a/core/java/android/view/contentcapture/ContentCaptureEvent.java
+++ b/core/java/android/view/contentcapture/ContentCaptureEvent.java
@@ -303,6 +303,47 @@
         return mText;
     }
 
+    /**
+     * Merges event of the same type, either {@link #TYPE_VIEW_TEXT_CHANGED}
+     * or {@link #TYPE_VIEW_DISAPPEARED}.
+     *
+     * @hide
+     */
+    public void mergeEvent(@NonNull ContentCaptureEvent event) {
+        Preconditions.checkNotNull(event);
+        final int eventType = event.getType();
+        if (mType != eventType) {
+            Log.e(TAG, "mergeEvent(" + getTypeAsString(eventType) + ") cannot be merged "
+                    + "with different eventType=" + getTypeAsString(mType));
+            return;
+        }
+
+        if (eventType == TYPE_VIEW_DISAPPEARED) {
+            final List<AutofillId> ids = event.getIds();
+            final AutofillId id = event.getId();
+            if (ids != null) {
+                if (id != null) {
+                    Log.w(TAG, "got TYPE_VIEW_DISAPPEARED event with both id and ids: " + event);
+                }
+                for (int i = 0; i < ids.size(); i++) {
+                    addAutofillId(ids.get(i));
+                }
+                return;
+            }
+            if (id != null) {
+                addAutofillId(id);
+                return;
+            }
+            throw new IllegalArgumentException("mergeEvent(): got "
+                    + "TYPE_VIEW_DISAPPEARED event with neither id or ids: " + event);
+        } else if (eventType == TYPE_VIEW_TEXT_CHANGED) {
+            setText(event.getText());
+        } else {
+            Log.e(TAG, "mergeEvent(" + getTypeAsString(eventType)
+                    + ") does not support this event type.");
+        }
+    }
+
     /** @hide */
     public void dump(@NonNull PrintWriter pw) {
         pw.print("type="); pw.print(getTypeAsString(mType));
diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java
index 1f0971e..ebac629 100644
--- a/core/java/android/view/contentcapture/ContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/ContentCaptureSession.java
@@ -127,6 +127,20 @@
      */
     public static final int STATE_NOT_WHITELISTED = 0x200;
 
+    /**
+     * Session is disabled because the service died.
+     *
+     * @hide
+     */
+    public static final int STATE_SERVICE_DIED = 0x400;
+
+    /**
+     * Session is enabled, after the service died and came back to live.
+     *
+     * @hide
+     */
+    public static final int STATE_SERVICE_RESURRECTED = 0x800;
+
     private static final int INITIAL_CHILDREN_CAPACITY = 5;
 
     /** @hide */
diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java
index dce8ebe..f9fd0c6 100644
--- a/core/java/android/view/contentcapture/MainContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java
@@ -128,6 +128,12 @@
     @Nullable
     private final LocalLog mFlushHistory;
 
+    /**
+     * Binder object used to update the session state.
+     */
+    @NonNull
+    private final IResultReceiver.Stub mSessionStateReceiver;
+
     protected MainContentCaptureSession(@NonNull Context context,
             @NonNull ContentCaptureManager manager, @NonNull Handler handler,
             @NonNull IContentCaptureManager systemServerInterface) {
@@ -138,6 +144,26 @@
 
         final int logHistorySize = mManager.mOptions.logHistorySize;
         mFlushHistory = logHistorySize > 0 ? new LocalLog(logHistorySize) : null;
+
+        mSessionStateReceiver = new IResultReceiver.Stub() {
+            @Override
+            public void send(int resultCode, Bundle resultData) {
+                final IBinder binder;
+                if (resultData != null) {
+                    binder = resultData.getBinder(EXTRA_BINDER);
+                    if (binder == null) {
+                        Log.wtf(TAG, "No " + EXTRA_BINDER + " extra result");
+                        mHandler.post(() -> resetSession(
+                                STATE_DISABLED | STATE_INTERNAL_ERROR));
+                        return;
+                    }
+                } else {
+                    binder = null;
+                }
+                mHandler.post(() -> onSessionStarted(resultCode, binder));
+            }
+        };
+
     }
 
     @Override
@@ -185,24 +211,7 @@
 
         try {
             mSystemServerInterface.startSession(mApplicationToken, component, mId, flags,
-                    new IResultReceiver.Stub() {
-                        @Override
-                        public void send(int resultCode, Bundle resultData) {
-                            final IBinder binder;
-                            if (resultData != null) {
-                                binder = resultData.getBinder(EXTRA_BINDER);
-                                if (binder == null) {
-                                    Log.wtf(TAG, "No " + EXTRA_BINDER + " extra result");
-                                    mHandler.post(() -> resetSession(
-                                            STATE_DISABLED | STATE_INTERNAL_ERROR));
-                                    return;
-                                }
-                            } else {
-                                binder = null;
-                            }
-                            mHandler.post(() -> onSessionStarted(resultCode, binder));
-                        }
-                    });
+                    mSessionStateReceiver);
         } catch (RemoteException e) {
             Log.w(TAG, "Error starting session for " + component.flattenToShortString() + ": " + e);
         }
@@ -216,8 +225,7 @@
 
     /**
      * Callback from {@code system_server} after call to
-     * {@link IContentCaptureManager#startSession(IBinder, ComponentName, String, int,
-     * IResultReceiver)}
+     * {@link IContentCaptureManager#startSession(IBinder, ComponentName, String, int, IBinder)}
      *
      * @param resultCode session state
      * @param binder handle to {@code IContentCaptureDirectManager}
@@ -227,8 +235,9 @@
         if (binder != null) {
             mDirectServiceInterface = IContentCaptureDirectManager.Stub.asInterface(binder);
             mDirectServiceVulture = () -> {
-                Log.w(TAG, "Destroying session " + mId + " because service died");
-                destroy();
+                Log.w(TAG, "Keeping session " + mId + " when service died");
+                mState = STATE_SERVICE_DIED;
+                mDisabled.set(true);
             };
             try {
                 binder.linkToDeath(mDirectServiceVulture, 0);
@@ -295,8 +304,7 @@
                     Log.v(TAG, "Buffering VIEW_TEXT_CHANGED event, updated text="
                             + getSanitizedString(event.getText()));
                 }
-                // TODO(b/124107816): should call lastEvent.merge(event) instead
-                lastEvent.setText(event.getText());
+                lastEvent.mergeEvent(event);
                 addEvent = false;
             }
         }
@@ -309,7 +317,7 @@
                     Log.v(TAG, "Buffering TYPE_VIEW_DISAPPEARED events for session "
                             + lastEvent.getSessionId());
                 }
-                mergeViewsDisappearedEvent(lastEvent, event);
+                lastEvent.mergeEvent(event);
                 addEvent = false;
             }
         }
@@ -357,30 +365,6 @@
         flush(flushReason);
     }
 
-    // TODO(b/124107816): should be ContentCaptureEvent Event.merge(event) instead (which would
-    // replace the addAutofillId() method - we would also need unit tests on ContentCaptureEventTest
-    // to check these scenarios)
-    private void mergeViewsDisappearedEvent(@NonNull ContentCaptureEvent lastEvent,
-            @NonNull ContentCaptureEvent event) {
-        final List<AutofillId> ids = event.getIds();
-        final AutofillId id = event.getId();
-        if (ids != null) {
-            if (id != null) {
-                Log.w(TAG, "got TYPE_VIEW_DISAPPEARED event with both id and ids: " + event);
-            }
-            for (int i = 0; i < ids.size(); i++) {
-                lastEvent.addAutofillId(ids.get(i));
-            }
-            return;
-        }
-        if (id != null) {
-            lastEvent.addAutofillId(id);
-            return;
-        }
-        throw new IllegalArgumentException(
-                "got TYPE_VIEW_DISAPPEARED event with neither id or ids: " + event);
-    }
-
     @UiThread
     private boolean hasStarted() {
         return mState != UNKNOWN_STATE;
diff --git a/core/java/android/view/textclassifier/ActionsSuggestionsHelper.java b/core/java/android/view/textclassifier/ActionsSuggestionsHelper.java
index ddbff7b..17edf5c 100644
--- a/core/java/android/view/textclassifier/ActionsSuggestionsHelper.java
+++ b/core/java/android/view/textclassifier/ActionsSuggestionsHelper.java
@@ -82,9 +82,12 @@
             long referenceTime = message.getReferenceTime() == null
                     ? 0
                     : message.getReferenceTime().toInstant().toEpochMilli();
+            String timeZone = message.getReferenceTime() == null
+                    ? null
+                    : message.getReferenceTime().getZone().getId();
             nativeMessages.push(new ActionsSuggestionsModel.ConversationMessage(
                     personEncoder.encode(message.getAuthor()),
-                    message.getText().toString(), referenceTime,
+                    message.getText().toString(), referenceTime, timeZone,
                     languageDetector.apply(message.getText())));
         }
         return nativeMessages.toArray(
diff --git a/core/java/android/view/textclassifier/TextClassificationConstants.java b/core/java/android/view/textclassifier/TextClassificationConstants.java
index 125b0d3..38e72e3 100644
--- a/core/java/android/view/textclassifier/TextClassificationConstants.java
+++ b/core/java/android/view/textclassifier/TextClassificationConstants.java
@@ -48,6 +48,8 @@
  * notification_conversation_action_types_default   (String[])
  * lang_id_threshold_override                       (float)
  * template_intent_factory_enabled                  (boolean)
+ * translate_in_classification_enabled              (boolean)
+ * detect_languages_from_text_enabled               (boolean)
  * </pre>
  *
  * <p>
@@ -139,7 +141,7 @@
     private static final String NOTIFICATION_CONVERSATION_ACTION_TYPES_DEFAULT =
             "notification_conversation_action_types_default";
     /**
-     * Threshold in classifyText to consider a text is in a foreign language.
+     * Threshold to accept a suggested language from LangID model.
      */
     private static final String LANG_ID_THRESHOLD_OVERRIDE = "lang_id_threshold_override";
     /**
@@ -147,6 +149,18 @@
      */
     private static final String TEMPLATE_INTENT_FACTORY_ENABLED = "template_intent_factory_enabled";
 
+    /**
+     * Whether to enable "translate" action in classifyText.
+     */
+    private static final String TRANSLATE_IN_CLASSIFICATION_ENABLED =
+            "translate_in_classification_enabled";
+    /**
+     * Whether to detect the languages of the text in request by using langId for the native
+     * model.
+     */
+    private static final String DETECT_LANGUAGES_FROM_TEXT_ENABLED =
+            "detect_languages_from_text_enabled";
+
     private static final boolean LOCAL_TEXT_CLASSIFIER_ENABLED_DEFAULT = true;
     private static final boolean SYSTEM_TEXT_CLASSIFIER_ENABLED_DEFAULT = true;
     private static final boolean MODEL_DARK_LAUNCH_ENABLED_DEFAULT = false;
@@ -183,11 +197,13 @@
     /**
      * < 0  : Not set. Use value from LangId model.
      * 0 - 1: Override value in LangId model.
-     * > 1  : Effectively turns off the foreign language detection. Scores should never be > 1.
+     *
      * @see EntityConfidence
      */
     private static final float LANG_ID_THRESHOLD_OVERRIDE_DEFAULT = -1f;
     private static final boolean TEMPLATE_INTENT_FACTORY_ENABLED_DEFAULT = true;
+    private static final boolean TRANSLATE_IN_CLASSIFICATION_ENABLED_DEFAULT = true;
+    private static final boolean DETECT_LANGUAGES_FROM_TEXT_ENABLED_DEFAULT = true;
 
     private final boolean mSystemTextClassifierEnabled;
     private final boolean mLocalTextClassifierEnabled;
@@ -207,6 +223,8 @@
     private final List<String> mNotificationConversationActionTypesDefault;
     private final float mLangIdThresholdOverride;
     private final boolean mTemplateIntentFactoryEnabled;
+    private final boolean mTranslateInClassificationEnabled;
+    private final boolean mDetectLanguagesFromTextEnabled;
 
     private TextClassificationConstants(@Nullable String settings) {
         ConfigParser configParser = new ConfigParser(settings);
@@ -280,6 +298,10 @@
         mTemplateIntentFactoryEnabled = configParser.getBoolean(
                 TEMPLATE_INTENT_FACTORY_ENABLED,
                 TEMPLATE_INTENT_FACTORY_ENABLED_DEFAULT);
+        mTranslateInClassificationEnabled = configParser.getBoolean(
+                TRANSLATE_IN_CLASSIFICATION_ENABLED, TRANSLATE_IN_CLASSIFICATION_ENABLED_DEFAULT);
+        mDetectLanguagesFromTextEnabled = configParser.getBoolean(
+                DETECT_LANGUAGES_FROM_TEXT_ENABLED, DETECT_LANGUAGES_FROM_TEXT_ENABLED_DEFAULT);
     }
 
     /** Load from a settings string. */
@@ -359,6 +381,14 @@
         return mTemplateIntentFactoryEnabled;
     }
 
+    public boolean isTranslateInClassificationEnabled() {
+        return mTranslateInClassificationEnabled;
+    }
+
+    public boolean isDetectLanguagesFromTextEnabled() {
+        return mDetectLanguagesFromTextEnabled;
+    }
+
     private static List<String> parseStringList(String listStr) {
         return Collections.unmodifiableList(Arrays.asList(listStr.split(STRING_LIST_DELIMITER)));
     }
@@ -385,6 +415,8 @@
                 mNotificationConversationActionTypesDefault);
         pw.printPair("getLangIdThresholdOverride", mLangIdThresholdOverride);
         pw.printPair("isTemplateIntentFactoryEnabled", mTemplateIntentFactoryEnabled);
+        pw.printPair("isTranslateInClassificationEnabled", mTranslateInClassificationEnabled);
+        pw.printPair("isDetectLanguageFromTextEnabled", mDetectLanguagesFromTextEnabled);
         pw.decreaseIndent();
         pw.println();
     }
diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java
index 35cd678..0f3a8cf 100644
--- a/core/java/android/view/textclassifier/TextClassifierImpl.java
+++ b/core/java/android/view/textclassifier/TextClassifierImpl.java
@@ -164,6 +164,7 @@
             if (string.length() > 0
                     && rangeLength <= mSettings.getSuggestSelectionMaxRangeLength()) {
                 final String localesString = concatenateLocales(request.getDefaultLocales());
+                final String detectLanguageTags = detectLanguageTagsFromText(request.getText());
                 final ZonedDateTime refTime = ZonedDateTime.now();
                 final AnnotatorModel annotatorImpl =
                         getAnnotatorImpl(request.getDefaultLocales());
@@ -175,7 +176,7 @@
                 } else {
                     final int[] startEnd = annotatorImpl.suggestSelection(
                             string, request.getStartIndex(), request.getEndIndex(),
-                            new AnnotatorModel.SelectionOptions(localesString));
+                            new AnnotatorModel.SelectionOptions(localesString, detectLanguageTags));
                     start = startEnd[0];
                     end = startEnd[1];
                 }
@@ -189,7 +190,8 @@
                                     new AnnotatorModel.ClassificationOptions(
                                             refTime.toInstant().toEpochMilli(),
                                             refTime.getZone().getId(),
-                                            localesString),
+                                            localesString,
+                                            detectLanguageTags),
                                     // Passing null here to suppress intent generation
                                     // TODO: Use an explicit flag to suppress it.
                                     /* appContext */ null,
@@ -227,6 +229,7 @@
             final String string = request.getText().toString();
             if (string.length() > 0 && rangeLength <= mSettings.getClassifyTextMaxRangeLength()) {
                 final String localesString = concatenateLocales(request.getDefaultLocales());
+                final String detectLanguageTags = detectLanguageTagsFromText(request.getText());
                 final ZonedDateTime refTime = request.getReferenceTime() != null
                         ? request.getReferenceTime() : ZonedDateTime.now();
                 final AnnotatorModel.ClassificationResult[] results =
@@ -236,9 +239,10 @@
                                         new AnnotatorModel.ClassificationOptions(
                                                 refTime.toInstant().toEpochMilli(),
                                                 refTime.getZone().getId(),
-                                                localesString),
+                                                localesString,
+                                                detectLanguageTags),
                                         mContext,
-                                        getResourceLocaleString()
+                                        getResourceLocalesString()
                                 );
                 if (results.length > 0) {
                     return createClassificationResult(
@@ -276,6 +280,8 @@
                     ? request.getEntityConfig().resolveEntityListModifications(
                     getEntitiesForHints(request.getEntityConfig().getHints()))
                     : mSettings.getEntityListDefault();
+            final String localesString = concatenateLocales(request.getDefaultLocales());
+            final String detectLanguageTags = detectLanguageTagsFromText(request.getText());
             final AnnotatorModel annotatorImpl =
                     getAnnotatorImpl(request.getDefaultLocales());
             final AnnotatorModel.AnnotatedSpan[] annotations =
@@ -284,7 +290,8 @@
                             new AnnotatorModel.AnnotationOptions(
                                     refTime.toInstant().toEpochMilli(),
                                     refTime.getZone().getId(),
-                                    concatenateLocales(request.getDefaultLocales())));
+                                    localesString,
+                                    detectLanguageTags));
             for (AnnotatorModel.AnnotatedSpan span : annotations) {
                 final AnnotatorModel.ClassificationResult[] results =
                         span.getClassification();
@@ -386,8 +393,8 @@
                 return mFallback.suggestConversationActions(request);
             }
             ActionsSuggestionsModel.ConversationMessage[] nativeMessages =
-                    ActionsSuggestionsHelper.toNativeMessages(request.getConversation(),
-                            this::detectLanguageTagsFromText);
+                    ActionsSuggestionsHelper.toNativeMessages(
+                            request.getConversation(), this::detectLanguageTagsFromText);
             if (nativeMessages.length == 0) {
                 return mFallback.suggestConversationActions(request);
             }
@@ -399,7 +406,7 @@
                             nativeConversation,
                             null,
                             mContext,
-                            getResourceLocaleString());
+                            getResourceLocalesString());
             return createConversationActionResult(request, nativeSuggestions);
         } catch (Throwable t) {
             // Avoid throwing from this method. Log the error.
@@ -463,19 +470,28 @@
 
     @Nullable
     private String detectLanguageTagsFromText(CharSequence text) {
+        if (!mSettings.isDetectLanguagesFromTextEnabled()) {
+            return null;
+        }
+        final float threshold = getLangIdThreshold();
+        if (threshold < 0 || threshold > 1) {
+            Log.w(LOG_TAG,
+                    "[detectLanguageTagsFromText] unexpected threshold is found: " + threshold);
+            return null;
+        }
         TextLanguage.Request request = new TextLanguage.Request.Builder(text).build();
         TextLanguage textLanguage = detectLanguage(request);
         int localeHypothesisCount = textLanguage.getLocaleHypothesisCount();
         List<String> languageTags = new ArrayList<>();
         for (int i = 0; i < localeHypothesisCount; i++) {
             ULocale locale = textLanguage.getLocale(i);
-            if (textLanguage.getConfidenceScore(locale) < getForeignLanguageThreshold()) {
+            if (textLanguage.getConfidenceScore(locale) < threshold) {
                 break;
             }
             languageTags.add(locale.toLanguageTag());
         }
         if (languageTags.isEmpty()) {
-            return LocaleList.getDefault().toLanguageTags();
+            return null;
         }
         return String.join(",", languageTags);
     }
@@ -644,10 +660,14 @@
     // TODO: Consider making this public API.
     @Nullable
     private Bundle detectForeignLanguage(String text) {
+        if (!mSettings.isTranslateInClassificationEnabled()) {
+            return null;
+        }
         try {
-            final float threshold = getForeignLanguageThreshold();
-            if (threshold > 1) {
-                Log.v(LOG_TAG, "Foreign language detection disabled.");
+            final float threshold = getLangIdThreshold();
+            if (threshold < 0 || threshold > 1) {
+                Log.w(LOG_TAG,
+                        "[detectForeignLanguage] unexpected threshold is found: " + threshold);
                 return null;
             }
 
@@ -686,11 +706,11 @@
         return null;
     }
 
-    private float getForeignLanguageThreshold() {
+    private float getLangIdThreshold() {
         try {
             return mSettings.getLangIdThresholdOverride() >= 0
                     ? mSettings.getLangIdThresholdOverride()
-                    : getLangIdImpl().getTranslateThreshold();
+                    : getLangIdImpl().getLangIdThreshold();
         } catch (FileNotFoundException e) {
             final float defaultThreshold = 0.5f;
             Log.v(LOG_TAG, "Using default foreign language threshold: " + defaultThreshold);
@@ -746,15 +766,14 @@
     }
 
     /**
-     * Returns the locale string for the current resources configuration.
+     * Returns the locales string for the current resources configuration.
      */
-    private String getResourceLocaleString() {
-        // TODO: Pass the locale list once it is supported in native side.
+    private String getResourceLocalesString() {
         try {
-            return mContext.getResources().getConfiguration().getLocales().get(0).toLanguageTag();
+            return mContext.getResources().getConfiguration().getLocales().toLanguageTags();
         } catch (NullPointerException e) {
             // NPE is unexpected. Erring on the side of caution.
-            return LocaleList.getDefault().get(0).toLanguageTag();
+            return LocaleList.getDefault().toLanguageTags();
         }
     }
 }
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index 528a6a8..6d88530 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -448,7 +448,8 @@
 
             Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.getChromiumProviderClass()");
             try {
-                new WebViewDelegate().addWebViewAssetPath(initialApplication);
+                initialApplication.getAssets().addAssetPathAsSharedLibrary(
+                        webViewContext.getApplicationInfo().sourceDir);
                 ClassLoader clazzLoader = webViewContext.getClassLoader();
 
                 Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.loadNativeLibrary()");
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index 89e205c..8785251 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -17,6 +17,7 @@
 package android.widget;
 
 import android.annotation.DrawableRes;
+import android.annotation.IntDef;
 import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.Resources.Theme;
@@ -44,6 +45,8 @@
 
 import com.android.internal.R;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.lang.ref.WeakReference;
 
 /**
@@ -1259,9 +1262,20 @@
     }
 
     /**
+     * The valid input method modes for the {@link AutoCompleteTextView}:
+     *
+     * {@hide}
+     */
+    @IntDef({ListPopupWindow.INPUT_METHOD_FROM_FOCUSABLE,
+            ListPopupWindow.INPUT_METHOD_NEEDED,
+            ListPopupWindow.INPUT_METHOD_NOT_NEEDED})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface InputMethodMode {}
+
+    /**
      * Returns the input method mode used by the auto complete dropdown.
      */
-    public int getInputMethodMode() {
+    public @InputMethodMode int getInputMethodMode() {
         return mPopup.getInputMethodMode();
     }
 
@@ -1277,7 +1291,7 @@
      * {@link ListPopupWindow#INPUT_METHOD_NOT_NEEDED}. The auto-complete suggestions are always
      * displayed, even if the suggestions cover/hide the input method.
      */
-    public void setInputMethodMode(int mode) {
+    public void setInputMethodMode(@InputMethodMode int mode) {
         mPopup.setInputMethodMode(mode);
     }
 
diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java
index 25e5dd3..16b903d 100644
--- a/core/java/android/widget/ListPopupWindow.java
+++ b/core/java/android/widget/ListPopupWindow.java
@@ -702,7 +702,7 @@
 
             mPopup.setWidth(widthSpec);
             mPopup.setHeight(heightSpec);
-            mPopup.setClipToScreenEnabled(true);
+            mPopup.setIsClippedToScreen(true);
 
             // use outside touchable to dismiss drop down when touching outside of it, so
             // only set this if the dropdown is not always visible
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 2798296..20fc0b1 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -886,9 +886,9 @@
      * containing window<p/>
      *
      * @return true if popup will be clipped to the screen instead of the window, false otherwise
-     *
-     * @see #setClipToScreenEnabled(boolean)
+     * @deprecated Use {@link #isClippedToScreen()} instead
      */
+    @Deprecated
     public boolean isClipToScreenEnabled() {
         return mClipToScreen;
     }
@@ -900,11 +900,37 @@
      * the next time the popup is shown or through a manual call to one of
      * the {@link #update()} methods.</p>
      *
+     * @deprecated Use {@link #setIsClippedToScreen(boolean)} instead
+     */
+    @Deprecated
+    public void setClipToScreenEnabled(boolean enabled) {
+        mClipToScreen = enabled;
+    }
+
+    /**
+     * <p>Indicates whether this popup will be clipped to the screen and not to the
+     * containing window<p/>
+     *
+     * @return true if popup will be clipped to the screen instead of the window, false otherwise
+     *
+     * @see #setIsClippedToScreen(boolean)
+     */
+    public boolean isClippedToScreen() {
+        return mClipToScreen;
+    }
+
+    /**
+     * <p>Clip this popup window to the screen, but not to the containing window.</p>
+     *
+     * <p>If the popup is showing, calling this method will take effect only
+     * the next time the popup is shown or through a manual call to one of
+     * the {@link #update()} methods.</p>
+     *
      * @param enabled true to clip to the screen.
      *
-     * @see #isClipToScreenEnabled()
+     * @see #isClippedToScreen()
      */
-    public void setClipToScreenEnabled(boolean enabled) {
+    public void setIsClippedToScreen(boolean enabled) {
         mClipToScreen = enabled;
     }
 
@@ -961,8 +987,9 @@
      *
      * @return true if the window will always be positioned in screen coordinates.
      *
-     * @see #setLayoutInScreenEnabled(boolean)
+     * @deprecated Use {@link #isLaidOutInScreen()} instead
      */
+    @Deprecated
     public boolean isLayoutInScreenEnabled() {
         return mLayoutInScreen;
     }
@@ -973,14 +1000,39 @@
      * This will cause the popup to be positioned in absolute screen coordinates.</p>
      *
      * @param enabled true if the popup should always be positioned in screen coordinates
-     *
-     * @see #isLayoutInScreenEnabled()
+     * @deprecated Use {@link #setIsLaidOutInScreen(boolean)} instead
      */
+    @Deprecated
     public void setLayoutInScreenEnabled(boolean enabled) {
         mLayoutInScreen = enabled;
     }
 
     /**
+     * <p>Indicates whether the popup window will be forced into using absolute screen coordinates
+     * for positioning.</p>
+     *
+     * @return true if the window will always be positioned in screen coordinates.
+     *
+     * @see #setIsLaidOutInScreen(boolean)
+     */
+    public boolean isLaidOutInScreen() {
+        return mLayoutInScreen;
+    }
+
+    /**
+     * <p>Allows the popup window to force the flag
+     * {@link WindowManager.LayoutParams#FLAG_LAYOUT_IN_SCREEN}, overriding default behavior.
+     * This will cause the popup to be positioned in absolute screen coordinates.</p>
+     *
+     * @param enabled true if the popup should always be positioned in screen coordinates
+     *
+     * @see #isLaidOutInScreen()
+     */
+    public void setIsLaidOutInScreen(boolean enabled) {
+        mLayoutInScreen = enabled;
+    }
+
+    /**
      * <p>Indicates whether the popup window will be attached in the decor frame of its parent
      * window.
      *
@@ -1016,7 +1068,7 @@
      * This will cause the popup to inset its content to account for system windows overlaying
      * the screen, such as the status bar.
      *
-     * <p>This will often be combined with {@link #setLayoutInScreenEnabled(boolean)}.
+     * <p>This will often be combined with {@link #setIsLaidOutInScreen(boolean)}.
      *
      * @param enabled true if the popup's views should inset content to account for system windows,
      *                the way that decor views behave for full-screen windows.
@@ -2114,7 +2166,7 @@
      *     <li>{@link #setTouchable(boolean)}</li>
      *     <li>{@link #setAnimationStyle(int)}</li>
      *     <li>{@link #setTouchModal(boolean)} (boolean)}</li>
-     *     <li>{@link #setClipToScreenEnabled(boolean)}</li>
+     *     <li>{@link #setIsClippedToScreen(boolean)}</li>
      * </ul>
      */
     public void update() {
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 91928b5..f250666 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -42,7 +42,6 @@
 import android.content.IntentSender;
 import android.content.IntentSender.SendIntentException;
 import android.content.ServiceConnection;
-import android.content.SharedPreferences;
 import android.content.pm.ActivityInfo;
 import android.content.pm.LabeledIntent;
 import android.content.pm.LauncherApps;
@@ -65,7 +64,6 @@
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Bundle;
-import android.os.Environment;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
@@ -75,7 +73,6 @@
 import android.os.ResultReceiver;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.os.storage.StorageManager;
 import android.provider.DocumentsContract;
 import android.provider.Downloads;
 import android.provider.OpenableColumns;
@@ -114,7 +111,6 @@
 
 import com.google.android.collect.Lists;
 
-import java.io.File;
 import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.util.ArrayList;
@@ -188,10 +184,7 @@
     private Drawable mChooserRowLayer;
     private int mChooserRowServiceSpacing;
 
-    private SharedPreferences mPinnedSharedPrefs;
-    private static final float PINNED_TARGET_SCORE_BOOST = 1000.f;
     private static final float CALLER_TARGET_SCORE_BOOST = 900.f;
-    private static final String PINNED_SHARED_PREFS_NAME = "chooser_pin_settings";
     private static final String TARGET_DETAILS_FRAGMENT_TAG = "targetDetailsFragment";
 
     private final List<ChooserTargetServiceConnection> mServiceConnections = new ArrayList<>();
@@ -236,7 +229,6 @@
                     mServiceConnections.remove(sri.connection);
                     if (mServiceConnections.isEmpty()) {
                         sendVoiceChoicesIfNeeded();
-                        mChooserListAdapter.setShowServiceTargets(true);
                     }
                     break;
 
@@ -250,7 +242,6 @@
                     unbindRemainingServices();
                     sendVoiceChoicesIfNeeded();
                     mChooserListAdapter.completeServiceTargetLoading();
-                    mChooserListAdapter.setShowServiceTargets(true);
                     break;
 
                 case SHORTCUT_MANAGER_SHARE_TARGET_RESULT:
@@ -265,7 +256,6 @@
 
                 case SHORTCUT_MANAGER_SHARE_TARGET_RESULT_COMPLETED:
                     sendVoiceChoicesIfNeeded();
-                    mChooserListAdapter.setShowServiceTargets(true);
                     break;
 
                 default:
@@ -321,9 +311,7 @@
         // Do not allow the title to be changed when sharing content
         CharSequence title = null;
         if (target != null) {
-            String targetAction = target.getAction();
-            if (!(Intent.ACTION_SEND.equals(targetAction) || Intent.ACTION_SEND_MULTIPLE.equals(
-                    targetAction))) {
+            if (!isSendAction(target)) {
                 title = intent.getCharSequenceExtra(Intent.EXTRA_TITLE);
             } else {
                 Log.w(TAG, "Ignoring intent's EXTRA_TITLE, deprecated in P. You may wish to set a"
@@ -390,7 +378,6 @@
             mCallerChooserTargets = targets;
         }
 
-        mPinnedSharedPrefs = getPinnedSharedPrefs(this);
         setRetainInOnStop(intent.getBooleanExtra(EXTRA_PRIVATE_RETAIN_IN_ON_STOP, false));
         super.onCreate(savedInstanceState, target, title, defaultTitleRes, initialIntents,
                 null, false);
@@ -446,6 +433,11 @@
         mChooserRowServiceSpacing = getResources()
                                         .getDimensionPixelSize(R.dimen.chooser_service_spacing);
 
+        // expand/shrink direct share 4 -> 8 viewgroup
+        if (mResolverDrawerLayout != null && isSendAction(target)) {
+            mResolverDrawerLayout.setOnScrollChangeListener(this::handleScroll);
+        }
+
         if (DEBUG) {
             Log.d(TAG, "System Time Cost is " + systemCost);
         }
@@ -461,34 +453,6 @@
                 .getUserInfo(UserHandle.myUserId()).isManagedProfile();
     }
 
-    /**
-     * Override method to add content preview area, specific to the chooser activity.
-     */
-    @Override
-    public void setHeader() {
-        super.setHeader();
-
-        Intent targetIntent = getTargetIntent();
-        if (targetIntent == null) {
-            return;
-        }
-
-        String action = targetIntent.getAction();
-        if (!(Intent.ACTION_SEND.equals(action) || Intent.ACTION_SEND_MULTIPLE.equals(action))) {
-            return;
-        }
-
-        if (mChooserListAdapter == null || mChooserListAdapter.getCount() == 0) {
-            return;
-        }
-
-        int previewType = findPreferredContentPreview(targetIntent, getContentResolver());
-
-        getMetricsLogger().write(new LogMaker(MetricsEvent.ACTION_SHARE_WITH_PREVIEW)
-                .setSubtype(previewType));
-        displayContentPreview(previewType, targetIntent);
-    }
-
     private void onCopyButtonClicked(View v) {
         Intent targetIntent = getTargetIntent();
         if (targetIntent == null) {
@@ -548,46 +512,56 @@
 
     private void updateLayoutWidth(int layoutResourceId, int width) {
         View view = findViewById(layoutResourceId);
-        LayoutParams params = view.getLayoutParams();
-        params.width = width;
-        view.setLayoutParams(params);
-    }
-
-    private void displayContentPreview(@ContentPreviewType int previewType, Intent targetIntent) {
-        switch (previewType) {
-            case CONTENT_PREVIEW_TEXT:
-                displayTextContentPreview(targetIntent);
-                break;
-            case CONTENT_PREVIEW_IMAGE:
-                displayImageContentPreview(targetIntent);
-                break;
-            case CONTENT_PREVIEW_FILE:
-                displayFileContentPreview(targetIntent);
-                break;
-            default:
-                Log.e(TAG, "Unexpected content preview type: " + previewType);
+        if (view != null && view.getLayoutParams() != null) {
+            LayoutParams params = view.getLayoutParams();
+            params.width = width;
+            view.setLayoutParams(params);
         }
     }
 
-    private void displayTextContentPreview(Intent targetIntent) {
-        ViewGroup contentPreviewLayout = findViewById(R.id.content_preview_text_area);
-        contentPreviewLayout.setVisibility(View.VISIBLE);
+    private ViewGroup displayContentPreview(@ContentPreviewType int previewType,
+            Intent targetIntent, LayoutInflater layoutInflater, ViewGroup convertView,
+            ViewGroup parent) {
+        switch (previewType) {
+            case CONTENT_PREVIEW_TEXT:
+                return displayTextContentPreview(targetIntent, layoutInflater, convertView, parent);
+            case CONTENT_PREVIEW_IMAGE:
+                return displayImageContentPreview(targetIntent, layoutInflater, convertView,
+                        parent);
+            case CONTENT_PREVIEW_FILE:
+                return displayFileContentPreview(targetIntent, layoutInflater, convertView, parent);
+            default:
+                Log.e(TAG, "Unexpected content preview type: " + previewType);
+        }
 
-        findViewById(R.id.copy_button).setOnClickListener(this::onCopyButtonClicked);
+        return null;
+    }
+
+    private ViewGroup displayTextContentPreview(Intent targetIntent, LayoutInflater layoutInflater,
+            ViewGroup convertView, ViewGroup parent) {
+        ViewGroup contentPreviewLayout =
+                convertView != null ? convertView : (ViewGroup) layoutInflater.inflate(
+                        R.layout.chooser_grid_preview_text, parent, false);
+
+        contentPreviewLayout.findViewById(R.id.copy_button).setOnClickListener(
+                this::onCopyButtonClicked);
 
         CharSequence sharingText = targetIntent.getCharSequenceExtra(Intent.EXTRA_TEXT);
         if (sharingText == null) {
-            findViewById(R.id.content_preview_text_layout).setVisibility(View.GONE);
+            contentPreviewLayout.findViewById(R.id.content_preview_text_layout).setVisibility(
+                    View.GONE);
         } else {
-            TextView textView = findViewById(R.id.content_preview_text);
+            TextView textView = contentPreviewLayout.findViewById(R.id.content_preview_text);
             textView.setText(sharingText);
         }
 
         String previewTitle = targetIntent.getStringExtra(Intent.EXTRA_TITLE);
         if (TextUtils.isEmpty(previewTitle)) {
-            findViewById(R.id.content_preview_title_layout).setVisibility(View.GONE);
+            contentPreviewLayout.findViewById(R.id.content_preview_title_layout).setVisibility(
+                    View.GONE);
         } else {
-            TextView previewTitleView = findViewById(R.id.content_preview_title);
+            TextView previewTitleView = contentPreviewLayout.findViewById(
+                    R.id.content_preview_title);
             previewTitleView.setText(previewTitle);
 
             ClipData previewData = targetIntent.getClipData();
@@ -599,7 +573,8 @@
                 }
             }
 
-            ImageView previewThumbnailView = findViewById(R.id.content_preview_thumbnail);
+            ImageView previewThumbnailView = contentPreviewLayout.findViewById(
+                    R.id.content_preview_thumbnail);
             if (previewThumbnail == null) {
                 previewThumbnailView.setVisibility(View.GONE);
             } else {
@@ -611,16 +586,20 @@
                 }
             }
         }
+
+        return contentPreviewLayout;
     }
 
-    private void displayImageContentPreview(Intent targetIntent) {
-        ViewGroup contentPreviewLayout = findViewById(R.id.content_preview_image_area);
-        contentPreviewLayout.setVisibility(View.VISIBLE);
+    private ViewGroup displayImageContentPreview(Intent targetIntent, LayoutInflater layoutInflater,
+            ViewGroup convertView, ViewGroup parent) {
+        ViewGroup contentPreviewLayout =
+                convertView != null ? convertView : (ViewGroup) layoutInflater.inflate(
+                        R.layout.chooser_grid_preview_image, parent, false);
 
         String action = targetIntent.getAction();
         if (Intent.ACTION_SEND.equals(action)) {
             Uri uri = targetIntent.getParcelableExtra(Intent.EXTRA_STREAM);
-            loadUriIntoView(R.id.content_preview_image_1_large, uri);
+            loadUriIntoView(R.id.content_preview_image_1_large, uri, contentPreviewLayout);
         } else {
             ContentResolver resolver = getContentResolver();
 
@@ -636,23 +615,28 @@
                 Log.i(TAG, "Attempted to display image preview area with zero"
                         + " available images detected in EXTRA_STREAM list");
                 contentPreviewLayout.setVisibility(View.GONE);
-                return;
+                return contentPreviewLayout;
             }
 
-            loadUriIntoView(R.id.content_preview_image_1_large, imageUris.get(0));
+            loadUriIntoView(R.id.content_preview_image_1_large, imageUris.get(0),
+                    contentPreviewLayout);
 
             if (imageUris.size() == 2) {
-                loadUriIntoView(R.id.content_preview_image_2_large, imageUris.get(1));
+                loadUriIntoView(R.id.content_preview_image_2_large, imageUris.get(1),
+                        contentPreviewLayout);
             } else if (imageUris.size() > 2) {
-                loadUriIntoView(R.id.content_preview_image_2_small, imageUris.get(1));
+                loadUriIntoView(R.id.content_preview_image_2_small, imageUris.get(1),
+                        contentPreviewLayout);
                 RoundedRectImageView imageView = loadUriIntoView(
-                        R.id.content_preview_image_3_small, imageUris.get(2));
+                        R.id.content_preview_image_3_small, imageUris.get(2), contentPreviewLayout);
 
                 if (imageUris.size() > 3) {
                     imageView.setExtraImageCount(imageUris.size() - 3);
                 }
             }
         }
+
+        return contentPreviewLayout;
     }
 
     private static class FileInfo {
@@ -711,18 +695,21 @@
         return new FileInfo(fileName, hasThumbnail);
     }
 
-    private void displayFileContentPreview(Intent targetIntent) {
-        ViewGroup contentPreviewLayout = findViewById(R.id.content_preview_file_area);
-        contentPreviewLayout.setVisibility(View.VISIBLE);
+    private ViewGroup displayFileContentPreview(Intent targetIntent, LayoutInflater layoutInflater,
+            ViewGroup convertView, ViewGroup parent) {
+
+        ViewGroup contentPreviewLayout =
+                convertView != null ? convertView : (ViewGroup) layoutInflater.inflate(
+                        R.layout.chooser_grid_preview_file, parent, false);
 
         // TODO(b/120417119): Disable file copy until after moving to sysui,
         // due to permissions issues
-        findViewById(R.id.file_copy_button).setVisibility(View.GONE);
+        contentPreviewLayout.findViewById(R.id.file_copy_button).setVisibility(View.GONE);
 
         String action = targetIntent.getAction();
         if (Intent.ACTION_SEND.equals(action)) {
             Uri uri = targetIntent.getParcelableExtra(Intent.EXTRA_STREAM);
-            loadFileUriIntoView(uri);
+            loadFileUriIntoView(uri, contentPreviewLayout);
         } else {
             List<Uri> uris = targetIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
             int uriCount = uris.size();
@@ -732,42 +719,46 @@
                 Log.i(TAG,
                         "Appears to be no uris available in EXTRA_STREAM, removing "
                                 + "preview area");
-                return;
+                return contentPreviewLayout;
             } else if (uriCount == 1) {
-                loadFileUriIntoView(uris.get(0));
+                loadFileUriIntoView(uris.get(0), contentPreviewLayout);
             } else {
                 FileInfo fileInfo = extractFileInfo(uris.get(0), getContentResolver());
                 int remUriCount = uriCount - 1;
                 String fileName = getResources().getQuantityString(R.plurals.file_count,
                         remUriCount, fileInfo.name, remUriCount);
 
-                TextView fileNameView = findViewById(R.id.content_preview_filename);
+                TextView fileNameView = contentPreviewLayout.findViewById(
+                        R.id.content_preview_filename);
                 fileNameView.setText(fileName);
 
-                ImageView fileIconView = findViewById(R.id.content_preview_file_icon);
+                ImageView fileIconView = contentPreviewLayout.findViewById(
+                        R.id.content_preview_file_icon);
                 fileIconView.setVisibility(View.VISIBLE);
                 fileIconView.setImageResource(R.drawable.ic_file_copy);
             }
         }
+
+        return contentPreviewLayout;
     }
 
-    private void loadFileUriIntoView(Uri uri) {
+    private void loadFileUriIntoView(Uri uri, View parent) {
         FileInfo fileInfo = extractFileInfo(uri, getContentResolver());
 
-        TextView fileNameView = findViewById(R.id.content_preview_filename);
+        TextView fileNameView = parent.findViewById(R.id.content_preview_filename);
         fileNameView.setText(fileInfo.name);
 
         if (fileInfo.hasThumbnail) {
-            loadUriIntoView(R.id.content_preview_file_thumbnail, uri);
+            loadUriIntoView(R.id.content_preview_file_thumbnail, uri, parent);
         } else {
-            ImageView fileIconView = findViewById(R.id.content_preview_file_icon);
+            ImageView fileIconView = parent.findViewById(R.id.content_preview_file_icon);
             fileIconView.setVisibility(View.VISIBLE);
             fileIconView.setImageResource(R.drawable.ic_doc_generic);
         }
     }
 
-    private RoundedRectImageView loadUriIntoView(int imageResourceId, Uri uri) {
-        RoundedRectImageView imageView = findViewById(imageResourceId);
+    private RoundedRectImageView loadUriIntoView(int imageResourceId, Uri uri, View parent) {
+        RoundedRectImageView imageView = parent.findViewById(imageResourceId);
         Bitmap bmp = loadThumbnail(uri, new Size(200, 200));
         if (bmp != null) {
             imageView.setVisibility(View.VISIBLE);
@@ -822,22 +813,6 @@
         return CONTENT_PREVIEW_TEXT;
     }
 
-    static SharedPreferences getPinnedSharedPrefs(Context context) {
-        // The code below is because in the android:ui process, no one can hear you scream.
-        // The package info in the context isn't initialized in the way it is for normal apps,
-        // so the standard, name-based context.getSharedPreferences doesn't work. Instead, we
-        // build the path manually below using the same policy that appears in ContextImpl.
-        // This fails silently under the hood if there's a problem, so if we find ourselves in
-        // the case where we don't have access to credential encrypted storage we just won't
-        // have our pinned target info.
-        final File prefsFile = new File(new File(
-                Environment.getDataUserCePackageDirectory(StorageManager.UUID_PRIVATE_INTERNAL,
-                        context.getUserId(), context.getPackageName()),
-                "shared_prefs"),
-                PINNED_SHARED_PREFS_NAME + ".xml");
-        return context.getSharedPreferences(prefsFile, MODE_PRIVATE);
-    }
-
     @Override
     protected void onDestroy() {
         super.onDestroy();
@@ -933,17 +908,14 @@
         }
 
         ComponentName name = ri.activityInfo.getComponentName();
-        boolean pinned = mPinnedSharedPrefs.getBoolean(name.flattenToString(), false);
         ResolverTargetActionsDialogFragment f =
                 new ResolverTargetActionsDialogFragment(ri.loadLabel(getPackageManager()),
-                        name, pinned);
+                        name);
         f.show(getFragmentManager(), TARGET_DETAILS_FRAGMENT_TAG);
     }
 
     private void modifyTargetIntent(Intent in) {
-        final String action = in.getAction();
-        if (Intent.ACTION_SEND.equals(action) ||
-                Intent.ACTION_SEND_MULTIPLE.equals(action)) {
+        if (isSendAction(in)) {
             in.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT |
                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
         }
@@ -998,15 +970,15 @@
             switch (mChooserListAdapter.getPositionTargetType(which)) {
                 case ChooserListAdapter.TARGET_CALLER:
                     cat = MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_APP_TARGET;
+                    value -= mChooserListAdapter.getSelectableServiceTargetCount();
                     break;
                 case ChooserListAdapter.TARGET_SERVICE:
                     cat = MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET;
-                    value -= mChooserListAdapter.getCallerTargetCount();
                     break;
                 case ChooserListAdapter.TARGET_STANDARD:
                     cat = MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_STANDARD_TARGET;
                     value -= mChooserListAdapter.getCallerTargetCount()
-                            + mChooserListAdapter.getServiceTargetCount();
+                            + mChooserListAdapter.getSelectableServiceTargetCount();
                     break;
             }
 
@@ -1392,11 +1364,6 @@
         }
 
         @Override
-        boolean isComponentPinned(ComponentName name) {
-            return mPinnedSharedPrefs.getBoolean(name.flattenToString(), false);
-        }
-
-        @Override
         boolean isComponentFiltered(ComponentName name) {
             if (mFilteredComponentNames == null) {
                 return false;
@@ -1414,11 +1381,8 @@
             if (target == null) {
                 return CALLER_TARGET_SCORE_BOOST;
             }
-            float score = super.getScore(target);
-            if (target.isPinned()) {
-                score += PINNED_TARGET_SCORE_BOOST;
-            }
-            return score;
+
+            return super.getScore(target);
         }
     }
 
@@ -1515,10 +1479,6 @@
             return null;
         }
 
-        public boolean isPinned() {
-            return false;
-        }
-
         public float getModifiedScore() {
             return 0.1f;
         }
@@ -1749,10 +1709,11 @@
             }
             return results;
         }
+    }
 
-        @Override
-        public boolean isPinned() {
-            return mSourceInfo != null ? mSourceInfo.isPinned() : false;
+    private void handleScroll(View view, int x, int y, int oldx, int oldy) {
+        if (mChooserRowAdapter != null) {
+            mChooserRowAdapter.handleScroll(view, y, oldy);
         }
     }
 
@@ -1762,12 +1723,14 @@
         public static final int TARGET_SERVICE = 1;
         public static final int TARGET_STANDARD = 2;
 
-        private static final int MAX_SERVICE_TARGETS = 4;
+        private static final int MAX_SUGGESTED_APP_TARGETS = 4;
         private static final int MAX_TARGETS_PER_SERVICE = 2;
 
+        private static final int MAX_SERVICE_TARGETS = 8;
+
         // Reserve spots for incoming direct share targets by adding placeholders
         private ChooserTargetInfo mPlaceHolderTargetInfo = new PlaceHolderTargetInfo();
-        private List<ChooserTargetInfo> mServiceTargets;
+        private final List<ChooserTargetInfo> mServiceTargets = new ArrayList<>();
         private final List<TargetInfo> mCallerTargets = new ArrayList<>();
         private boolean mShowServiceTargets;
 
@@ -1786,7 +1749,7 @@
             super(context, payloadIntents, null, rList, launchedFromUid, filterLastUsed,
                     resolverListController);
 
-            mServiceTargets = createPlaceHolders();
+            createPlaceHolders();
 
             if (initialIntents != null) {
                 final PackageManager pm = getPackageManager();
@@ -1840,12 +1803,11 @@
             }
         }
 
-        private List<ChooserTargetInfo> createPlaceHolders() {
-            List<ChooserTargetInfo> list = new ArrayList<>();
+        private void createPlaceHolders() {
+            mServiceTargets.clear();
             for (int i = 0; i < MAX_SERVICE_TARGETS; i++) {
-                list.add(mPlaceHolderTargetInfo);
+                mServiceTargets.add(mPlaceHolderTargetInfo);
             }
-            return list;
         }
 
         @Override
@@ -1855,11 +1817,6 @@
         }
 
         @Override
-        public boolean isComponentPinned(ComponentName name) {
-            return mPinnedSharedPrefs.getBoolean(name.flattenToString(), false);
-        }
-
-        @Override
         public View onCreateView(ViewGroup parent) {
             return mInflater.inflate(
                     com.android.internal.R.layout.resolve_grid_item, parent, false);
@@ -1913,7 +1870,7 @@
         }
 
         public int getCallerTargetCount() {
-            return mCallerTargets.size();
+            return Math.min(mCallerTargets.size(), MAX_SUGGESTED_APP_TARGETS);
         }
 
         /**
@@ -1930,7 +1887,11 @@
         }
 
         public int getServiceTargetCount() {
-            return Math.min(mServiceTargets.size(), MAX_SERVICE_TARGETS);
+            if (isSendAction(getTargetIntent())) {
+                return Math.min(mServiceTargets.size(), MAX_SERVICE_TARGETS);
+            }
+
+            return 0;
         }
 
         public int getStandardTargetCount() {
@@ -1940,18 +1901,18 @@
         public int getPositionTargetType(int position) {
             int offset = 0;
 
-            final int callerTargetCount = getCallerTargetCount();
-            if (position < callerTargetCount) {
-                return TARGET_CALLER;
-            }
-            offset += callerTargetCount;
-
             final int serviceTargetCount = getServiceTargetCount();
-            if (position - offset < serviceTargetCount) {
+            if (position < serviceTargetCount) {
                 return TARGET_SERVICE;
             }
             offset += serviceTargetCount;
 
+            final int callerTargetCount = getCallerTargetCount();
+            if (position - offset < callerTargetCount) {
+                return TARGET_CALLER;
+            }
+            offset += callerTargetCount;
+
             final int standardTargetCount = super.getCount();
             if (position - offset < standardTargetCount) {
                 return TARGET_STANDARD;
@@ -1969,19 +1930,19 @@
         public TargetInfo targetInfoForPosition(int position, boolean filtered) {
             int offset = 0;
 
-            final int callerTargetCount = getCallerTargetCount();
-            if (position < callerTargetCount) {
-                return mCallerTargets.get(position);
-            }
-            offset += callerTargetCount;
-
             final int serviceTargetCount = filtered ? getServiceTargetCount() :
                                                getSelectableServiceTargetCount();
-            if (position - offset < serviceTargetCount) {
-                return mServiceTargets.get(position - offset);
+            if (position < serviceTargetCount) {
+                return mServiceTargets.get(position);
             }
             offset += serviceTargetCount;
 
+            final int callerTargetCount = getCallerTargetCount();
+            if (position - offset < callerTargetCount) {
+                return mCallerTargets.get(position - offset);
+            }
+            offset += callerTargetCount;
+
             return filtered ? super.getItem(position - offset)
                     : getDisplayInfoAt(position - offset);
         }
@@ -1995,7 +1956,7 @@
             if (mTargetsNeedPruning && targets.size() > 0) {
                 // First proper update since we got an onListRebuilt() with (transient) 0 items.
                 // Clear out the target list and rebuild.
-                mServiceTargets = createPlaceHolders();
+                createPlaceHolders();
                 mTargetsNeedPruning = false;
 
                 // Add back any app-supplied direct share targets that may have been
@@ -2037,26 +1998,6 @@
         }
 
         /**
-         * Set to true to reveal all service targets at once.
-         */
-        public void setShowServiceTargets(boolean show) {
-            // mShowServiceTargets is only flipped once to show direct share targets. But after the
-            // initial display the list can be re-sorted and the user will see the target list
-            // change. This will log the initial show and the subsequent shuffle to help us get
-            // accurate timing of the UX.
-            if (show) {
-                getMetricsLogger().write(
-                        new LogMaker(MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN_DIRECT_TARGET)
-                                .setSubtype(mShowServiceTargets ? MetricsEvent.PREVIOUSLY_VISIBLE
-                                        : MetricsEvent.PREVIOUSLY_HIDDEN));
-            }
-            if (show != mShowServiceTargets) {
-                mShowServiceTargets = show;
-                notifyDataSetChanged();
-            }
-        }
-
-        /**
          * Calling this marks service target loading complete, and will attempt to no longer
          * update the direct share area.
          */
@@ -2099,12 +2040,34 @@
         }
     }
 
+    private boolean isSendAction(Intent targetIntent) {
+        if (targetIntent == null) {
+            return false;
+        }
+
+        String action = targetIntent.getAction();
+        if (action == null) {
+            return false;
+        }
+
+        if (Intent.ACTION_SEND.equals(action) || Intent.ACTION_SEND_MULTIPLE.equals(action)) {
+            return true;
+        }
+
+        return false;
+    }
+
     class ChooserRowAdapter extends BaseAdapter {
         private ChooserListAdapter mChooserListAdapter;
         private final LayoutInflater mLayoutInflater;
-        private final int mColumnCount = 4;
         private int mAnimationCount = 0;
 
+        private DirectShareViewHolder mDirectShareViewHolder;
+
+        private static final int VIEW_TYPE_DIRECT_SHARE = 0;
+        private static final int VIEW_TYPE_NORMAL = 1;
+        private static final int VIEW_TYPE_CONTENT_PREVIEW = 2;
+
         public ChooserRowAdapter(ChooserListAdapter wrappedAdapter) {
             mChooserListAdapter = wrappedAdapter;
             mLayoutInflater = LayoutInflater.from(ChooserActivity.this);
@@ -2124,24 +2087,47 @@
             });
         }
 
+        private int getMaxTargetsPerRow() {
+            // this will soon hold logic for portrait/landscape
+            return 4;
+        }
+
         @Override
         public int getCount() {
             return (int) (
-                    getCallerTargetRowCount()
+                    getContentPreviewRowCount()
+                            + getCallerTargetRowCount()
                             + getServiceTargetRowCount()
                             + Math.ceil(
-                            (float) mChooserListAdapter.getStandardTargetCount() / mColumnCount)
+                            (float) mChooserListAdapter.getStandardTargetCount()
+                                    / getMaxTargetsPerRow())
             );
         }
 
+        public int getContentPreviewRowCount() {
+            if (!isSendAction(getTargetIntent())) {
+                return 0;
+            }
+
+            if (mChooserListAdapter == null || mChooserListAdapter.getCount() == 0) {
+                return 0;
+            }
+
+            return 1;
+        }
+
         public int getCallerTargetRowCount() {
             return (int) Math.ceil(
-                    (float) mChooserListAdapter.getCallerTargetCount() / mColumnCount);
+                    (float) mChooserListAdapter.getCallerTargetCount() / getMaxTargetsPerRow());
         }
 
-        // There can be at most one row of service targets.
+        // There can be at most one row in the listview, that is internally
+        // a ViewGroup with 2 rows
         public int getServiceTargetRowCount() {
-            return 1;
+            if (isSendAction(getTargetIntent())) {
+                return 1;
+            }
+            return 0;
         }
 
         @Override
@@ -2158,29 +2144,70 @@
         @Override
         public View getView(int position, View convertView, ViewGroup parent) {
             final RowViewHolder holder;
+            int viewType = getItemViewType(position);
+
+            if (viewType == VIEW_TYPE_CONTENT_PREVIEW) {
+                return createContentPreviewView(convertView, parent);
+            }
+
             if (convertView == null) {
-                holder = createViewHolder(parent);
+                holder = createViewHolder(viewType, parent);
             } else {
                 holder = (RowViewHolder) convertView.getTag();
             }
-            bindViewHolder(position, holder);
 
-            return holder.row;
+            bindViewHolder(position, holder,
+                    viewType == VIEW_TYPE_DIRECT_SHARE
+                            ? ChooserListAdapter.MAX_SERVICE_TARGETS : getMaxTargetsPerRow());
+
+            return holder.getViewGroup();
         }
 
-        RowViewHolder createViewHolder(ViewGroup parent) {
-            final ViewGroup row = (ViewGroup) mLayoutInflater.inflate(R.layout.chooser_row,
-                    parent, false);
-            final RowViewHolder holder = new RowViewHolder(row, mColumnCount);
-            final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+        @Override
+        public int getItemViewType(int position) {
+            if (position == 0 && getContentPreviewRowCount() == 1) {
+                return VIEW_TYPE_CONTENT_PREVIEW;
+            }
 
-            for (int i = 0; i < mColumnCount; i++) {
-                final View v = mChooserListAdapter.createView(row);
+            final int start = getFirstRowPosition(position);
+            final int startType = mChooserListAdapter.getPositionTargetType(start);
+
+            if (startType == ChooserListAdapter.TARGET_SERVICE) {
+                return VIEW_TYPE_DIRECT_SHARE;
+            }
+
+            return VIEW_TYPE_NORMAL;
+        }
+
+        @Override
+        public int getViewTypeCount() {
+            return 3;
+        }
+
+        private ViewGroup createContentPreviewView(View convertView, ViewGroup parent) {
+            Intent targetIntent = getTargetIntent();
+            int previewType = findPreferredContentPreview(targetIntent, getContentResolver());
+
+            if (convertView == null) {
+                getMetricsLogger().write(new LogMaker(MetricsEvent.ACTION_SHARE_WITH_PREVIEW)
+                        .setSubtype(previewType));
+            }
+
+            return displayContentPreview(previewType, targetIntent, mLayoutInflater,
+                    (ViewGroup) convertView, parent);
+        }
+
+        private RowViewHolder loadViewsIntoRow(RowViewHolder holder) {
+            final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+            int columnCount = holder.getColumnCount();
+
+            for (int i = 0; i < columnCount; i++) {
+                final View v = mChooserListAdapter.createView(holder.getRow(i));
                 final int column = i;
                 v.setOnClickListener(new OnClickListener() {
                     @Override
                     public void onClick(View v) {
-                        startSelected(holder.itemIndices[column], false, true);
+                        startSelected(holder.getItemIndex(column), false, true);
                     }
                 });
                 v.setOnLongClickListener(new OnLongClickListener() {
@@ -2188,12 +2215,11 @@
                     public boolean onLongClick(View v) {
                         showTargetDetails(
                                 mChooserListAdapter.resolveInfoForPosition(
-                                        holder.itemIndices[column], true));
+                                        holder.getItemIndex(column), true));
                         return true;
                     }
                 });
-                row.addView(v);
-                holder.cells[i] = v;
+                ViewGroup row = holder.addView(i, v);
 
                 // Force height to be a given so we don't have visual disruption during scaling.
                 LayoutParams lp = v.getLayoutParams();
@@ -2204,47 +2230,75 @@
                 } else {
                     lp.height = v.getMeasuredHeight();
                 }
-                if (i != (mColumnCount - 1)) {
-                    row.addView(new Space(ChooserActivity.this),
-                            new LinearLayout.LayoutParams(0, 0, 1));
-                }
             }
 
+            final ViewGroup viewGroup = holder.getViewGroup();
+
             // Pre-measure so we can scale later.
             holder.measure();
-            LayoutParams lp = row.getLayoutParams();
+            LayoutParams lp = viewGroup.getLayoutParams();
             if (lp == null) {
-                lp = new LayoutParams(LayoutParams.MATCH_PARENT, holder.measuredRowHeight);
-                row.setLayoutParams(lp);
+                lp = new LayoutParams(LayoutParams.MATCH_PARENT, holder.getMeasuredRowHeight());
+                viewGroup.setLayoutParams(lp);
             } else {
-                lp.height = holder.measuredRowHeight;
+                lp.height = holder.getMeasuredRowHeight();
             }
-            row.setTag(holder);
+
+            viewGroup.setTag(holder);
+
             return holder;
         }
 
-        void bindViewHolder(int rowPosition, RowViewHolder holder) {
+        RowViewHolder createViewHolder(int viewType, ViewGroup parent) {
+            if (viewType == VIEW_TYPE_DIRECT_SHARE) {
+                ViewGroup parentGroup = (ViewGroup) mLayoutInflater.inflate(
+                        R.layout.chooser_row_direct_share, parent, false);
+                ViewGroup row1 = (ViewGroup) mLayoutInflater.inflate(R.layout.chooser_row,
+                        parentGroup, false);
+                ViewGroup row2 = (ViewGroup) mLayoutInflater.inflate(R.layout.chooser_row,
+                        parentGroup, false);
+                parentGroup.addView(row1);
+                parentGroup.addView(row2);
+
+                mDirectShareViewHolder = new DirectShareViewHolder(parentGroup,
+                        Lists.newArrayList(row1, row2), getMaxTargetsPerRow());
+                loadViewsIntoRow(mDirectShareViewHolder);
+
+                return mDirectShareViewHolder;
+            } else {
+                ViewGroup row = (ViewGroup) mLayoutInflater.inflate(R.layout.chooser_row, parent,
+                        false);
+                RowViewHolder holder = new SingleRowViewHolder(row, getMaxTargetsPerRow());
+                loadViewsIntoRow(holder);
+
+                return holder;
+            }
+        }
+
+        void bindViewHolder(int rowPosition, RowViewHolder holder, int columnCount) {
             final int start = getFirstRowPosition(rowPosition);
             final int startType = mChooserListAdapter.getPositionTargetType(start);
 
             final int lastStartType = mChooserListAdapter.getPositionTargetType(
                     getFirstRowPosition(rowPosition - 1));
 
-            if (startType != lastStartType || rowPosition == 0) {
-                holder.row.setBackground(mChooserRowLayer);
-                setVertPadding(holder, mChooserRowServiceSpacing, 0);
+            final ViewGroup row = holder.getViewGroup();
+
+            if (startType != lastStartType || rowPosition == getContentPreviewRowCount()) {
+                row.setBackground(mChooserRowLayer);
+                setVertPadding(row, mChooserRowServiceSpacing, 0);
             } else {
-                holder.row.setBackground(null);
-                setVertPadding(holder, 0, 0);
+                row.setBackground(null);
+                setVertPadding(row, 0, 0);
             }
 
-            int end = start + mColumnCount - 1;
+            int end = start + columnCount - 1;
             while (mChooserListAdapter.getPositionTargetType(end) != startType && end >= start) {
                 end--;
             }
 
             if (end == start && mChooserListAdapter.getItem(start) instanceof EmptyTargetInfo) {
-                final TextView textView = holder.row.findViewById(R.id.chooser_row_text_option);
+                final TextView textView = row.findViewById(R.id.chooser_row_text_option);
 
                 if (textView.getVisibility() != View.VISIBLE) {
                     textView.setAlpha(0.0f);
@@ -2269,12 +2323,12 @@
                 }
             }
 
-            for (int i = 0; i < mColumnCount; i++) {
-                final View v = holder.cells[i];
+            for (int i = 0; i < columnCount; i++) {
+                final View v = holder.getView(i);
                 if (start + i <= end) {
                     setCellVisibility(holder, i, View.VISIBLE);
-                    holder.itemIndices[i] = start + i;
-                    mChooserListAdapter.bindView(holder.itemIndices[i], v);
+                    holder.setItemIndex(i, start + i);
+                    mChooserListAdapter.bindView(holder.getItemIndex(i), v);
                 } else {
                     setCellVisibility(holder, i, View.INVISIBLE);
                 }
@@ -2282,13 +2336,13 @@
         }
 
         private void setCellVisibility(RowViewHolder holder, int i, int visibility) {
-            final View v = holder.cells[i];
+            final View v = holder.getView(i);
             if (visibility == View.VISIBLE) {
-                holder.cellVisibility[i] = true;
+                holder.setViewVisibility(i, true);
                 v.setVisibility(visibility);
                 v.setAlpha(1.0f);
-            } else if (visibility == View.INVISIBLE && holder.cellVisibility[i]) {
-                holder.cellVisibility[i] = false;
+            } else if (visibility == View.INVISIBLE && holder.getViewVisibility(i)) {
+                holder.setViewVisibility(i, false);
 
                 ValueAnimator fadeAnim = ObjectAnimator.ofFloat(v, "alpha", 1.0f, 0f);
                 fadeAnim.setDuration(NO_DIRECT_SHARE_ANIM_IN_MILLIS);
@@ -2302,49 +2356,222 @@
             }
         }
 
-        private void setVertPadding(RowViewHolder holder, int top, int bottom) {
-            holder.row.setPadding(holder.row.getPaddingLeft(), top,
-                    holder.row.getPaddingRight(), bottom);
+        private void setVertPadding(ViewGroup row, int top, int bottom) {
+            row.setPadding(row.getPaddingLeft(), top, row.getPaddingRight(), bottom);
         }
 
         int getFirstRowPosition(int row) {
-            final int callerCount = mChooserListAdapter.getCallerTargetCount();
-            final int callerRows = (int) Math.ceil((float) callerCount / mColumnCount);
-
-            if (row < callerRows) {
-                return row * mColumnCount;
-            }
+            row -= getContentPreviewRowCount();
 
             final int serviceCount = mChooserListAdapter.getServiceTargetCount();
-            final int serviceRows = (int) Math.ceil((float) serviceCount / mColumnCount);
+            final int serviceRows = (int) Math.ceil((float) serviceCount
+                    / ChooserListAdapter.MAX_SERVICE_TARGETS);
+            if (row < serviceRows) {
+                return row * getMaxTargetsPerRow();
+            }
 
+            final int callerCount = mChooserListAdapter.getCallerTargetCount();
+            final int callerRows = (int) Math.ceil((float) callerCount / getMaxTargetsPerRow());
             if (row < callerRows + serviceRows) {
-                return callerCount + (row - callerRows) * mColumnCount;
+                return serviceCount + (row - serviceRows) * getMaxTargetsPerRow();
             }
 
             return callerCount + serviceCount
-                    + (row - callerRows - serviceRows) * mColumnCount;
+                    + (row - callerRows - serviceRows) * getMaxTargetsPerRow();
+        }
+
+        public void handleScroll(View v, int y, int oldy) {
+            if (mDirectShareViewHolder != null) {
+                mDirectShareViewHolder.handleScroll(mAdapterView, y, oldy, getMaxTargetsPerRow());
+            }
         }
     }
 
-    static class RowViewHolder {
-        public final View[] cells;
-        public final boolean [] cellVisibility;
-        public final ViewGroup row;
-        int measuredRowHeight;
-        int[] itemIndices;
+    abstract class RowViewHolder {
+        protected int mMeasuredRowHeight;
+        private int[] mItemIndices;
+        protected final View[] mCells;
+        private final boolean[] mCellVisibility;
+        private final int mColumnCount;
 
-        public RowViewHolder(ViewGroup row, int cellCount) {
-            this.row = row;
-            this.cells = new View[cellCount];
-            this.cellVisibility = new boolean[cellCount];
-            this.itemIndices = new int[cellCount];
+        RowViewHolder(int cellCount) {
+            this.mCells = new View[cellCount];
+            this.mItemIndices = new int[cellCount];
+            this.mCellVisibility = new boolean[cellCount];
+            this.mColumnCount = cellCount;
+        }
+
+        abstract ViewGroup addView(int index, View v);
+
+        abstract ViewGroup getViewGroup();
+
+        abstract ViewGroup getRow(int index);
+
+        public int getColumnCount() {
+            return mColumnCount;
+        }
+
+        public void setViewVisibility(int index, boolean visibility) {
+            mCellVisibility[index] = visibility;
+        }
+
+        public boolean getViewVisibility(int index) {
+            return mCellVisibility[index];
         }
 
         public void measure() {
             final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-            row.measure(spec, spec);
-            measuredRowHeight = row.getMeasuredHeight();
+            getViewGroup().measure(spec, spec);
+            mMeasuredRowHeight = getViewGroup().getMeasuredHeight();
+        }
+
+        public int getMeasuredRowHeight() {
+            return mMeasuredRowHeight;
+        }
+
+        protected void addSpacer(ViewGroup row) {
+            row.addView(new Space(ChooserActivity.this),
+                    new LinearLayout.LayoutParams(0, 0, 1));
+        }
+
+        public void setItemIndex(int itemIndex, int listIndex) {
+            mItemIndices[itemIndex] = listIndex;
+        }
+
+        public int getItemIndex(int itemIndex) {
+            return mItemIndices[itemIndex];
+        }
+
+        public View getView(int index) {
+            return mCells[index];
+        }
+    }
+
+    class SingleRowViewHolder extends RowViewHolder {
+        private final ViewGroup mRow;
+
+        SingleRowViewHolder(ViewGroup row, int cellCount) {
+            super(cellCount);
+
+            this.mRow = row;
+        }
+
+        public ViewGroup getViewGroup() {
+            return mRow;
+        }
+
+        public ViewGroup getRow(int index) {
+            return mRow;
+        }
+
+        public ViewGroup addView(int index, View v) {
+            mRow.addView(v);
+            mCells[index] = v;
+
+            if (index != (mCells.length - 1)) {
+                addSpacer(mRow);
+            }
+
+            return mRow;
+        }
+    }
+
+    class DirectShareViewHolder extends RowViewHolder {
+        private final ViewGroup mParent;
+        private final List<ViewGroup> mRows;
+        private int mCellCountPerRow;
+
+        private boolean mHideDirectShareExpansion = false;
+        private int mDirectShareMinHeight = 0;
+        private int mDirectShareCurrHeight = 0;
+        private int mDirectShareMaxHeight = 0;
+
+        DirectShareViewHolder(ViewGroup parent, List<ViewGroup> rows, int cellCountPerRow) {
+            super(rows.size() * cellCountPerRow);
+
+            this.mParent = parent;
+            this.mRows = rows;
+            this.mCellCountPerRow = cellCountPerRow;
+        }
+
+        public ViewGroup addView(int index, View v) {
+            ViewGroup row = getRow(index);
+            row.addView(v);
+            mCells[index] = v;
+
+            if (index % mCellCountPerRow != (mCellCountPerRow - 1)) {
+                addSpacer(row);
+            }
+
+            return row;
+        }
+
+        public ViewGroup getViewGroup() {
+            return mParent;
+        }
+
+        public ViewGroup getRow(int index) {
+            return mRows.get(index / mCellCountPerRow);
+        }
+
+        public void measure() {
+            final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+            getRow(0).measure(spec, spec);
+            getRow(1).measure(spec, spec);
+
+            // uses ChooserActiivty state variables to track height
+            mDirectShareMinHeight = getRow(0).getMeasuredHeight();
+            mDirectShareCurrHeight = mDirectShareCurrHeight > 0
+                                         ? mDirectShareCurrHeight : mDirectShareMinHeight;
+            mDirectShareMaxHeight = 2 * mDirectShareMinHeight;
+        }
+
+        public int getMeasuredRowHeight() {
+            return mDirectShareCurrHeight;
+        }
+
+        public void handleScroll(AbsListView view, int y, int oldy, int maxTargetsPerRow) {
+            // only expand if we have more than 4 targets, and delay that decision until
+            // they start to scroll
+            if (mHideDirectShareExpansion) {
+                return;
+            }
+
+            if (mChooserListAdapter.getSelectableServiceTargetCount() <= maxTargetsPerRow) {
+                mHideDirectShareExpansion = true;
+                return;
+            }
+
+            int yDiff = (int) ((oldy - y) * 0.7f);
+
+            int prevHeight = mDirectShareCurrHeight;
+            mDirectShareCurrHeight = Math.min(mDirectShareCurrHeight + yDiff,
+                    mDirectShareMaxHeight);
+            mDirectShareCurrHeight = Math.max(mDirectShareCurrHeight, mDirectShareMinHeight);
+            yDiff = mDirectShareCurrHeight - prevHeight;
+
+            if (view == null || view.getChildCount() == 0) {
+                return;
+            }
+
+            int index = mChooserRowAdapter.getContentPreviewRowCount();
+
+            ViewGroup expansionGroup = (ViewGroup) view.getChildAt(index);
+            int widthSpec = MeasureSpec.makeMeasureSpec(expansionGroup.getWidth(),
+                    MeasureSpec.EXACTLY);
+            int heightSpec = MeasureSpec.makeMeasureSpec(mDirectShareCurrHeight,
+                    MeasureSpec.EXACTLY);
+            expansionGroup.measure(widthSpec, heightSpec);
+            expansionGroup.getLayoutParams().height = expansionGroup.getMeasuredHeight();
+            expansionGroup.layout(expansionGroup.getLeft(), expansionGroup.getTop(),
+                    expansionGroup.getRight(),
+                    expansionGroup.getTop() + expansionGroup.getMeasuredHeight());
+
+            // reposition list items
+            int items = view.getChildCount();
+            for (int i = index + 1; i < items; i++) {
+                view.getChildAt(i).offsetTopAndBottom(yDiff);
+            }
         }
     }
 
@@ -2519,13 +2746,13 @@
             final int chooserTargetRows = mChooserRowAdapter.getServiceTargetRowCount();
             int offset = 0;
             for (int i = 0; i < chooserTargetRows; i++) {
-                final int pos = mChooserRowAdapter.getCallerTargetRowCount() + i;
+                final int pos = mChooserRowAdapter.getContentPreviewRowCount() + i;
                 final int vt = mChooserRowAdapter.getItemViewType(pos);
                 if (vt != mCachedViewType) {
                     mCachedView = null;
                 }
                 final View v = mChooserRowAdapter.getView(pos, mCachedView, mListView);
-                int height = ((RowViewHolder) (v.getTag())).measuredRowHeight;
+                int height = ((RowViewHolder) (v.getTag())).getMeasuredRowHeight();
 
                 offset += (int) (height);
 
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 011cc04..b55700e 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -99,7 +99,7 @@
 
     protected ResolveListAdapter mAdapter;
     private boolean mSafeForwardingMode;
-    private AbsListView mAdapterView;
+    protected AbsListView mAdapterView;
     private Button mAlwaysButton;
     private Button mOnceButton;
     private Button mSettingsButton;
@@ -1177,7 +1177,6 @@
         private final CharSequence mExtendedInfo;
         private final Intent mResolvedIntent;
         private final List<Intent> mSourceIntents = new ArrayList<>();
-        private boolean mPinned;
 
         public DisplayResolveInfo(Intent originalIntent, ResolveInfo pri, CharSequence pLabel,
                 CharSequence pInfo, Intent pOrigIntent) {
@@ -1204,7 +1203,6 @@
             mExtendedInfo = other.mExtendedInfo;
             mResolvedIntent = new Intent(other.mResolvedIntent);
             mResolvedIntent.fillIn(fillInIntent, flags);
-            mPinned = other.mPinned;
         }
 
         public ResolveInfo getResolveInfo() {
@@ -1304,15 +1302,6 @@
             activity.startActivityAsUser(mResolvedIntent, options, user);
             return false;
         }
-
-        @Override
-        public boolean isPinned() {
-            return mPinned;
-        }
-
-        public void setPinned(boolean pinned) {
-            mPinned = pinned;
-        }
     }
 
     /**
@@ -1414,11 +1403,6 @@
          * @return the list of supported source intents deduped against this single target
          */
         List<Intent> getAllSourceIntents();
-
-        /**
-         * @return true if this target should be pinned to the front by the request of the user
-         */
-        boolean isPinned();
     }
 
     public class ResolveListAdapter extends BaseAdapter {
@@ -1776,7 +1760,6 @@
             final Intent replaceIntent = getReplacementIntent(add.activityInfo, intent);
             final DisplayResolveInfo dri = new DisplayResolveInfo(intent, add, roLabel,
                     extraInfo, replaceIntent);
-            dri.setPinned(rci.isPinned());
             addResolveInfo(dri);
             if (replaceIntent == intent) {
                 // Only add alternates if we didn't get a specific replacement from
@@ -1921,10 +1904,6 @@
             return !TextUtils.isEmpty(info.getExtendedInfo());
         }
 
-        public boolean isComponentPinned(ComponentName name) {
-            return false;
-        }
-
         public final void bindView(int position, View view) {
             onBindView(view, getItem(position));
         }
@@ -1967,7 +1946,6 @@
     @VisibleForTesting
     public static final class ResolvedComponentInfo {
         public final ComponentName name;
-        private boolean mPinned;
         private final List<Intent> mIntents = new ArrayList<>();
         private final List<ResolveInfo> mResolveInfos = new ArrayList<>();
 
@@ -2010,14 +1988,6 @@
             }
             return -1;
         }
-
-        public boolean isPinned() {
-            return mPinned;
-        }
-
-        public void setPinned(boolean pinned) {
-            mPinned = pinned;
-        }
     }
 
     static class ViewHolder {
diff --git a/core/java/com/android/internal/app/ResolverComparator.java b/core/java/com/android/internal/app/ResolverComparator.java
index f61a03b..b9f67e6 100644
--- a/core/java/com/android/internal/app/ResolverComparator.java
+++ b/core/java/com/android/internal/app/ResolverComparator.java
@@ -325,30 +325,18 @@
             }
         }
 
-        final boolean lPinned = lhsp.isPinned();
-        final boolean rPinned = rhsp.isPinned();
+        if (mStats != null) {
+            final ResolverTarget lhsTarget = mTargetsDict.get(new ComponentName(
+                    lhs.activityInfo.packageName, lhs.activityInfo.name));
+            final ResolverTarget rhsTarget = mTargetsDict.get(new ComponentName(
+                    rhs.activityInfo.packageName, rhs.activityInfo.name));
 
-        if (lPinned && !rPinned) {
-            return -1;
-        } else if (!lPinned && rPinned) {
-            return 1;
-        }
-
-        // Pinned items stay stable within a normal lexical sort and ignore scoring.
-        if (!lPinned && !rPinned) {
-            if (mStats != null) {
-                final ResolverTarget lhsTarget = mTargetsDict.get(new ComponentName(
-                        lhs.activityInfo.packageName, lhs.activityInfo.name));
-                final ResolverTarget rhsTarget = mTargetsDict.get(new ComponentName(
-                        rhs.activityInfo.packageName, rhs.activityInfo.name));
-
-                if (lhsTarget != null && rhsTarget != null) {
-                    final int selectProbabilityDiff = Float.compare(
+            if (lhsTarget != null && rhsTarget != null) {
+                final int selectProbabilityDiff = Float.compare(
                         rhsTarget.getSelectProbability(), lhsTarget.getSelectProbability());
 
-                    if (selectProbabilityDiff != 0) {
-                        return selectProbabilityDiff > 0 ? 1 : -1;
-                    }
+                if (selectProbabilityDiff != 0) {
+                    return selectProbabilityDiff > 0 ? 1 : -1;
                 }
             }
         }
diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java
index 61aeca6..f48102a 100644
--- a/core/java/com/android/internal/app/ResolverListController.java
+++ b/core/java/com/android/internal/app/ResolverListController.java
@@ -30,14 +30,13 @@
 import android.content.pm.ResolveInfo;
 import android.os.RemoteException;
 import android.util.Log;
-import com.android.internal.annotations.GuardedBy;
+
 import com.android.internal.annotations.VisibleForTesting;
 
-import java.lang.InterruptedException;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.concurrent.CountDownLatch;
 import java.util.List;
+import java.util.concurrent.CountDownLatch;
 
 /**
  * A helper for the ResolverActivity that exposes methods to retrieve, filter and sort its list of
@@ -147,7 +146,6 @@
                         newInfo.activityInfo.packageName, newInfo.activityInfo.name);
                 final ResolverActivity.ResolvedComponentInfo rci =
                         new ResolverActivity.ResolvedComponentInfo(name, intent, newInfo);
-                rci.setPinned(isComponentPinned(name));
                 into.add(rci);
             }
         }
@@ -270,10 +268,6 @@
                 && ai.name.equals(b.name.getClassName());
     }
 
-    boolean isComponentPinned(ComponentName name) {
-        return false;
-    }
-
     boolean isComponentFiltered(ComponentName componentName) {
         return false;
     }
diff --git a/core/java/com/android/internal/app/ResolverTargetActionsDialogFragment.java b/core/java/com/android/internal/app/ResolverTargetActionsDialogFragment.java
index 8156f79..a49240c 100644
--- a/core/java/com/android/internal/app/ResolverTargetActionsDialogFragment.java
+++ b/core/java/com/android/internal/app/ResolverTargetActionsDialogFragment.java
@@ -23,7 +23,6 @@
 import android.content.ComponentName;
 import android.content.DialogInterface;
 import android.content.Intent;
-import android.content.SharedPreferences;
 import android.net.Uri;
 import android.os.Bundle;
 import android.provider.Settings;
@@ -36,34 +35,27 @@
 public class ResolverTargetActionsDialogFragment extends DialogFragment
         implements DialogInterface.OnClickListener {
     private static final String NAME_KEY = "componentName";
-    private static final String PINNED_KEY = "pinned";
     private static final String TITLE_KEY = "title";
 
     // Sync with R.array.resolver_target_actions_* resources
-    private static final int TOGGLE_PIN_INDEX = 0;
-    private static final int APP_INFO_INDEX = 1;
+    private static final int APP_INFO_INDEX = 0;
 
     public ResolverTargetActionsDialogFragment() {
     }
 
-    public ResolverTargetActionsDialogFragment(CharSequence title, ComponentName name,
-            boolean pinned) {
+    public ResolverTargetActionsDialogFragment(CharSequence title, ComponentName name) {
         Bundle args = new Bundle();
         args.putCharSequence(TITLE_KEY, title);
         args.putParcelable(NAME_KEY, name);
-        args.putBoolean(PINNED_KEY, pinned);
         setArguments(args);
     }
 
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
         final Bundle args = getArguments();
-        final int itemRes = args.getBoolean(PINNED_KEY, false)
-                ? R.array.resolver_target_actions_unpin
-                : R.array.resolver_target_actions_pin;
         return new Builder(getContext())
                 .setCancelable(true)
-                .setItems(itemRes, this)
+                .setItems(R.array.resolver_target_actions, this)
                 .setTitle(args.getCharSequence(TITLE_KEY))
                 .create();
     }
@@ -73,19 +65,6 @@
         final Bundle args = getArguments();
         ComponentName name = args.getParcelable(NAME_KEY);
         switch (which) {
-            case TOGGLE_PIN_INDEX:
-                SharedPreferences sp = ChooserActivity.getPinnedSharedPrefs(getContext());
-                final String key = name.flattenToString();
-                boolean currentVal = sp.getBoolean(name.flattenToString(), false);
-                if (currentVal) {
-                    sp.edit().remove(key).apply();
-                } else {
-                    sp.edit().putBoolean(key, true).apply();
-                }
-
-                // Force the chooser to requery and resort things
-                getActivity().recreate();
-                break;
             case APP_INFO_INDEX:
                 Intent in = new Intent().setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                         .setData(Uri.fromParts("package", name.getPackageName(), null))
diff --git a/core/java/com/android/internal/infra/AbstractRemoteService.java b/core/java/com/android/internal/infra/AbstractRemoteService.java
index 2e709de..eb881de 100644
--- a/core/java/com/android/internal/infra/AbstractRemoteService.java
+++ b/core/java/com/android/internal/infra/AbstractRemoteService.java
@@ -614,6 +614,7 @@
                 if (remoteService != null) {
                     // TODO(b/117779333): we should probably ignore it if service is destroyed.
                     Slog.w(mTag, "timed out after " + service.getRemoteRequestMillis() + " ms");
+                    remoteService.finishRequest(this);
                     onTimeout(remoteService);
                 } else {
                     Slog.w(mTag, "timed out (no service)");
diff --git a/core/java/com/android/internal/os/KernelCpuThreadReader.java b/core/java/com/android/internal/os/KernelCpuThreadReader.java
index 6a9db10..248e026 100644
--- a/core/java/com/android/internal/os/KernelCpuThreadReader.java
+++ b/core/java/com/android/internal/os/KernelCpuThreadReader.java
@@ -198,8 +198,8 @@
      *
      * <p>This function will crawl through all process {@code proc} directories found by the pattern
      * {@code /proc/[0-9]*}, and then check the UID using {@code /proc/$PID/status}. This takes
-     * approximately 500ms on a Pixel 2. Therefore, this method can be computationally expensive,
-     * and should not be called more than once an hour.
+     * approximately 500ms on a 2017 device. Therefore, this method can be computationally
+     * expensive, and should not be called more than once an hour.
      *
      * <p>Data is only collected for UIDs passing the predicate supplied in {@link
      * #setUidPredicate}.
@@ -283,7 +283,7 @@
                 if (threadCpuUsage == null) {
                     continue;
                 }
-                if (mMinimumTotalCpuUsageMillis < totalCpuUsage(threadCpuUsage.usageTimesMillis)) {
+                if (mMinimumTotalCpuUsageMillis > totalCpuUsage(threadCpuUsage.usageTimesMillis)) {
                     if (filteredThreadsCpuUsage == null) {
                         filteredThreadsCpuUsage = new int[mFrequenciesKhz.length];
                     }
diff --git a/core/java/com/android/internal/os/KernelWakelockReader.java b/core/java/com/android/internal/os/KernelWakelockReader.java
index 2442d0b..8b25e2d 100644
--- a/core/java/com/android/internal/os/KernelWakelockReader.java
+++ b/core/java/com/android/internal/os/KernelWakelockReader.java
@@ -66,7 +66,7 @@
      */
     public final KernelWakelockStats readKernelWakelockStats(KernelWakelockStats staleStats) {
         byte[] buffer = new byte[32*1024];
-        int len;
+        int len = 0;
         boolean wakeup_sources;
         final long startTime = SystemClock.uptimeMillis();
 
@@ -87,7 +87,11 @@
                 }
             }
 
-            len = is.read(buffer);
+            int cnt;
+            while ((cnt = is.read(buffer, len, buffer.length - len)) > 0) {
+                len += cnt;
+            }
+
             is.close();
         } catch (java.io.IOException e) {
             Slog.wtf(TAG, "failed to read kernel wakelocks", e);
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 70d8b45..3655748 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -408,7 +408,7 @@
      * TODO (chriswailes): Cache the system property location in native code and then write a JNI
      *                     function to fetch it.
      */
-    public static String getSystemProperty(String propertyName, String defaultValue) {
+    public static String getConfigurationProperty(String propertyName, String defaultValue) {
         return SystemProperties.get(
                 String.join(".",
                         "persist.device_config",
@@ -433,8 +433,10 @@
      *
      * TODO (chriswailes): Cache the system property location in native code and then write a JNI
      *                     function to fetch it.
+     * TODO (chriswailes): Move into ZygoteConfig.java once the necessary CL lands (go/ag/6580627)
      */
-    public static boolean getSystemPropertyBoolean(String propertyName, Boolean defaultValue) {
+    public static boolean getConfigurationPropertyBoolean(
+            String propertyName, Boolean defaultValue) {
         return SystemProperties.getBoolean(
                 String.join(".",
                         "persist.device_config",
diff --git a/core/java/com/android/internal/os/ZygoteServer.java b/core/java/com/android/internal/os/ZygoteServer.java
index 6595317..7abfd85 100644
--- a/core/java/com/android/internal/os/ZygoteServer.java
+++ b/core/java/com/android/internal/os/ZygoteServer.java
@@ -243,7 +243,7 @@
     private void fetchUsapPoolPolicyProps() {
         if (mUsapPoolSupported) {
             final String usapPoolSizeMaxPropString =
-                    Zygote.getSystemProperty(
+                    Zygote.getConfigurationProperty(
                             DeviceConfig.RuntimeNative.USAP_POOL_SIZE_MAX,
                             USAP_POOL_SIZE_MAX_DEFAULT);
 
@@ -255,7 +255,7 @@
             }
 
             final String usapPoolSizeMinPropString =
-                    Zygote.getSystemProperty(
+                    Zygote.getConfigurationProperty(
                             DeviceConfig.RuntimeNative.USAP_POOL_SIZE_MIN,
                             USAP_POOL_SIZE_MIN_DEFAULT);
 
@@ -267,7 +267,7 @@
             }
 
             final String usapPoolRefillThresholdPropString =
-                    Zygote.getSystemProperty(
+                    Zygote.getConfigurationProperty(
                             DeviceConfig.RuntimeNative.USAP_POOL_REFILL_THRESHOLD,
                             Integer.toString(mUsapPoolSizeMax / 2));
 
@@ -277,17 +277,31 @@
                                 Integer.parseInt(usapPoolRefillThresholdPropString),
                                 mUsapPoolSizeMax);
             }
+
+            // Sanity check
+
+            if (mUsapPoolSizeMin >= mUsapPoolSizeMax) {
+                Log.w(TAG, "The max size of the USAP pool must be greater than the minimum size."
+                        + "  Restoring default values.");
+
+                mUsapPoolSizeMax = Integer.parseInt(USAP_POOL_SIZE_MAX_DEFAULT);
+                mUsapPoolSizeMin = Integer.parseInt(USAP_POOL_SIZE_MIN_DEFAULT);
+                mUsapPoolRefillThreshold = mUsapPoolSizeMax / 2;
+            }
         }
     }
 
+    private boolean mIsFirstPropertyCheck = true;
     private long mLastPropCheckTimestamp = 0;
 
     private void fetchUsapPoolPolicyPropsWithMinInterval() {
         final long currentTimestamp = SystemClock.elapsedRealtime();
 
-        if (currentTimestamp - mLastPropCheckTimestamp >= Zygote.PROPERTY_CHECK_INTERVAL) {
-            fetchUsapPoolPolicyProps();
+        if (mIsFirstPropertyCheck
+                || (currentTimestamp - mLastPropCheckTimestamp >= Zygote.PROPERTY_CHECK_INTERVAL)) {
+            mIsFirstPropertyCheck = false;
             mLastPropCheckTimestamp = currentTimestamp;
+            fetchUsapPoolPolicyProps();
         }
     }
 
@@ -304,6 +318,9 @@
     Runnable fillUsapPool(int[] sessionSocketRawFDs) {
         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Zygote:FillUsapPool");
 
+        // Ensure that the pool properties have been fetched.
+        fetchUsapPoolPolicyPropsWithMinInterval();
+
         int usapPoolCount = Zygote.getUsapPoolCount();
         int numUsapsToSpawn = mUsapPoolSizeMax - usapPoolCount;
 
diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java
index 42fb1f5..bb7423a 100644
--- a/core/java/com/android/internal/widget/FloatingToolbar.java
+++ b/core/java/com/android/internal/widget/FloatingToolbar.java
@@ -33,7 +33,6 @@
 import android.graphics.drawable.Drawable;
 import android.text.TextUtils;
 import android.util.Size;
-import android.util.TypedValue;
 import android.view.ContextThemeWrapper;
 import android.view.Gravity;
 import android.view.LayoutInflater;
@@ -593,7 +592,7 @@
             refreshCoordinatesAndOverflowDirection(contentRectOnScreen);
             preparePopupContent();
             // We need to specify the position in window coordinates.
-            // TODO: Consider to use PopupWindow.setLayoutInScreenEnabled(true) so that we can
+            // TODO: Consider to use PopupWindow.setIsLaidOutInScreen(true) so that we can
             // specify the popup position in screen coordinates.
             mPopupWindow.showAtLocation(
                     mParent, Gravity.NO_GRAVITY, mCoordsOnWindow.x, mCoordsOnWindow.y);
@@ -661,7 +660,7 @@
             refreshCoordinatesAndOverflowDirection(contentRectOnScreen);
             preparePopupContent();
             // We need to specify the position in window coordinates.
-            // TODO: Consider to use PopupWindow.setLayoutInScreenEnabled(true) so that we can
+            // TODO: Consider to use PopupWindow.setIsLaidOutInScreen(true) so that we can
             // specify the popup position in screen coordinates.
             mPopupWindow.update(
                     mCoordsOnWindow.x, mCoordsOnWindow.y,
@@ -755,7 +754,7 @@
             // and screen coordiantes, where the offset between them should be equal to the window
             // origin, and 2) we can use an arbitrary for this calculation while calculating the
             // location of the rootview is supposed to be least expensive.
-            // TODO: Consider to use PopupWindow.setLayoutInScreenEnabled(true) so that we can avoid
+            // TODO: Consider to use PopupWindow.setIsLaidOutInScreen(true) so that we can avoid
             // the following calculation.
             mParent.getRootView().getLocationOnScreen(mTmpCoords);
             int rootViewLeftOnScreen = mTmpCoords[0];
@@ -1722,7 +1721,7 @@
     private static PopupWindow createPopupWindow(ViewGroup content) {
         ViewGroup popupContentHolder = new LinearLayout(content.getContext());
         PopupWindow popupWindow = new PopupWindow(popupContentHolder);
-        // TODO: Use .setLayoutInScreenEnabled(true) instead of .setClippingEnabled(false)
+        // TODO: Use .setIsLaidOutInScreen(true) instead of .setClippingEnabled(false)
         // unless FLAG_LAYOUT_IN_SCREEN has any unintentional side-effects.
         popupWindow.setClippingEnabled(false);
         popupWindow.setWindowLayoutType(
diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
index ee8637d8..9722fcb 100644
--- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java
+++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
@@ -502,6 +502,7 @@
                         new LogMaker(MetricsEvent.ACTION_SHARESHEET_COLLAPSED_CHANGED)
                         .setSubtype(isCollapsedNew ? 1 : 0));
             }
+            onScrollChanged(0, (int) newPos, 0, (int) (newPos - dy));
             postInvalidateOnAnimation();
             return dy;
         }
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index 958bb18..561dcad 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -938,6 +938,7 @@
                         } else {
                             mBugreportWhitelistedPackages.add(pkgname);
                         }
+                        XmlUtils.skipCurrentTag(parser);
                     } break;
                     default: {
                         Slog.w(TAG, "Tag " + name + " is unknown in "
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 8f00759..e0b7629 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -206,13 +206,14 @@
     // The caller needs to have already set the alpha type properly, so the
     // native SkBitmap stays in sync with the Java Bitmap.
     assert_premultiplied(bitmap->info(), isPremultiplied);
+    bool fromMalloc = bitmap->pixelStorageType() == PixelStorageType::Heap;
     BitmapWrapper* bitmapWrapper = new BitmapWrapper(bitmap);
     if (!isMutable) {
         bitmapWrapper->bitmap().setImmutable();
     }
     jobject obj = env->NewObject(gBitmap_class, gBitmap_constructorMethodID,
             reinterpret_cast<jlong>(bitmapWrapper), bitmap->width(), bitmap->height(), density,
-            isPremultiplied, ninePatchChunk, ninePatchInsets);
+            isPremultiplied, ninePatchChunk, ninePatchInsets, fromMalloc);
 
     if (env->ExceptionCheck() != 0) {
         ALOGE("*** Uncaught exception returned from Java call!\n");
@@ -1224,7 +1225,7 @@
 {
     gBitmap_class = MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/graphics/Bitmap"));
     gBitmap_nativePtr = GetFieldIDOrDie(env, gBitmap_class, "mNativePtr", "J");
-    gBitmap_constructorMethodID = GetMethodIDOrDie(env, gBitmap_class, "<init>", "(JIIIZ[BLandroid/graphics/NinePatch$InsetStruct;)V");
+    gBitmap_constructorMethodID = GetMethodIDOrDie(env, gBitmap_class, "<init>", "(JIIIZ[BLandroid/graphics/NinePatch$InsetStruct;Z)V");
     gBitmap_reinitMethodID = GetMethodIDOrDie(env, gBitmap_class, "reinit", "(IIZ)V");
     gBitmap_getAllocationByteCountMethodID = GetMethodIDOrDie(env, gBitmap_class, "getAllocationByteCount", "()I");
     return android::RegisterMethodsOrDie(env, "android/graphics/Bitmap", gBitmapMethods,
diff --git a/core/jni/android/graphics/text/LineBreaker.cpp b/core/jni/android/graphics/text/LineBreaker.cpp
index c23f1e9..a23f99a 100644
--- a/core/jni/android/graphics/text/LineBreaker.cpp
+++ b/core/jni/android/graphics/text/LineBreaker.cpp
@@ -80,13 +80,13 @@
         jfloat firstWidth,
         jint firstWidthLineCount,
         jfloat restWidth,
-        jintArray variableTabStops,
-        jint defaultTabStop,
+        jfloatArray variableTabStops,
+        jfloat defaultTabStop,
         jint indentsOffset) {
     minikin::android::StaticLayoutNative* builder = toNative(nativePtr);
 
     ScopedCharArrayRO text(env, javaText);
-    ScopedNullableIntArrayRO tabStops(env, variableTabStops);
+    ScopedNullableFloatArrayRO tabStops(env, variableTabStops);
 
     minikin::U16StringPiece u16Text(text.get(), length);
     minikin::MeasuredText* measuredText = reinterpret_cast<minikin::MeasuredText*>(measuredTextPtr);
@@ -151,8 +151,8 @@
         "F"  // firstWidth
         "I"  // firstWidthLineCount
         "F"  // restWidth
-        "[I"  // variableTabStops
-        "I"  // defaultTabStop
+        "[F"  // variableTabStops
+        "F"  // defaultTabStop
         "I"  // indentsOffset
         ")J", (void*) nComputeLineBreaks},
 
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
index ce5512b..9f9fbf9 100644
--- a/core/jni/android_view_RenderNode.cpp
+++ b/core/jni/android_view_RenderNode.cpp
@@ -338,6 +338,19 @@
     return renderNode->stagingProperties().hasOverlappingRendering();
 }
 
+static jboolean android_view_RenderNode_getAnimationMatrix(jlong renderNodePtr, jlong outMatrixPtr) {
+    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+    SkMatrix* outMatrix = reinterpret_cast<SkMatrix*>(outMatrixPtr);
+
+    const SkMatrix* animationMatrix = renderNode->stagingProperties().getAnimationMatrix();
+
+    if (animationMatrix) {
+        *outMatrix = *animationMatrix;
+        return JNI_TRUE;
+    }
+    return JNI_FALSE;
+}
+
 static jboolean android_view_RenderNode_getClipToBounds(jlong renderNodePtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     return renderNode->stagingProperties().getClipToBounds();
@@ -649,6 +662,7 @@
     { "nSetLayerPaint",        "(JJ)Z",  (void*) android_view_RenderNode_setLayerPaint },
     { "nSetStaticMatrix",      "(JJ)Z",  (void*) android_view_RenderNode_setStaticMatrix },
     { "nSetAnimationMatrix",   "(JJ)Z",  (void*) android_view_RenderNode_setAnimationMatrix },
+    { "nGetAnimationMatrix",   "(JJ)Z",  (void*) android_view_RenderNode_getAnimationMatrix },
     { "nSetClipToBounds",      "(JZ)Z",  (void*) android_view_RenderNode_setClipToBounds },
     { "nGetClipToBounds",      "(J)Z",   (void*) android_view_RenderNode_getClipToBounds },
     { "nSetClipBounds",        "(JIIII)Z", (void*) android_view_RenderNode_setClipBounds },
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 89d908b..4a6c72b 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -1164,6 +1164,25 @@
     }
 }
 
+static jboolean nativeGetDisplayBrightnessSupport(JNIEnv* env, jclass clazz,
+        jobject displayTokenObject) {
+    sp<IBinder> displayToken(ibinderForJavaObject(env, displayTokenObject));
+    if (displayToken == nullptr) {
+        return JNI_FALSE;
+    }
+    return static_cast<jboolean>(SurfaceComposerClient::getDisplayBrightnessSupport(displayToken));
+}
+
+static jboolean nativeSetDisplayBrightness(JNIEnv* env, jclass clazz, jobject displayTokenObject,
+        jfloat brightness) {
+    sp<IBinder> displayToken(ibinderForJavaObject(env, displayTokenObject));
+    if (displayToken == nullptr) {
+        return JNI_FALSE;
+    }
+    status_t error = SurfaceComposerClient::setDisplayBrightness(displayToken, brightness);
+    return error == OK ? JNI_TRUE : JNI_FALSE;
+}
+
 // ----------------------------------------------------------------------------
 
 static const JNINativeMethod sSurfaceControlMethods[] = {
@@ -1308,7 +1327,11 @@
     {"nativeSetGeometry", "(JJLandroid/graphics/Rect;Landroid/graphics/Rect;J)V",
             (void*)nativeSetGeometry },
     {"nativeSyncInputWindows", "(J)V",
-            (void*)nativeSyncInputWindows }
+            (void*)nativeSyncInputWindows },
+    {"nativeGetDisplayBrightnessSupport", "(Landroid/os/IBinder;)Z",
+            (void*)nativeGetDisplayBrightnessSupport },
+    {"nativeSetDisplayBrightness", "(Landroid/os/IBinder;F)Z",
+            (void*)nativeSetDisplayBrightness },
 };
 
 int register_android_view_SurfaceControl(JNIEnv* env)
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index c6f62ca..009a6ca 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -352,7 +352,7 @@
   }
 
   if (usaps_removed > 0) {
-    if (write(gUsapPoolEventFD, &usaps_removed, sizeof(usaps_removed)) == -1) {
+    if (TEMP_FAILURE_RETRY(write(gUsapPoolEventFD, &usaps_removed, sizeof(usaps_removed))) == -1) {
       // If this write fails something went terribly wrong.  We will now kill
       // the zygote and let the system bring it back up.
       async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG,
diff --git a/core/proto/android/server/connectivity/data_stall_event.proto b/core/proto/android/server/connectivity/data_stall_event.proto
index 21717d8..a82326f 100644
--- a/core/proto/android/server/connectivity/data_stall_event.proto
+++ b/core/proto/android/server/connectivity/data_stall_event.proto
@@ -25,6 +25,7 @@
     VALID = 1;
     INVALID = 2;
     PORTAL = 3;
+    PARTIAL = 4;
 }
 
 enum ApBand {
@@ -86,4 +87,4 @@
     repeated int32 dns_return_code = 1;
     // Indicate the timestamp of the dns event.
     repeated int64 dns_time = 2;
-}
\ No newline at end of file
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index ea300aa..c7417bf 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -867,6 +867,7 @@
         android:label="@string/permgrouplab_visual"
         android:description="@string/permgroupdesc_visual"
         android:request="@string/permgrouprequest_visual"
+        android:requestDetail="@string/permgrouprequestdetail_visual"
         android:priority="920" />
 
     <!-- Allows an application to read the user's shared images collection. -->
@@ -1516,6 +1517,13 @@
     <permission android:name="android.permission.MANAGE_IPSEC_TUNNELS"
         android:protectionLevel="signature|appop" />
 
+    <!-- @hide Allows apps to create and manage Test Networks.
+         <p>Granted only to shell. CTS tests will use
+         UiAutomation.AdoptShellPermissionIdentity() to gain access.
+    -->
+    <permission android:name="android.permission.MANAGE_TEST_NETWORKS"
+        android:protectionLevel="signature" />
+
     <!-- @SystemApi @hide Allows applications to read Wi-Fi credential.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.READ_WIFI_CREDENTIAL"
diff --git a/core/res/res/layout/chooser_grid.xml b/core/res/res/layout/chooser_grid.xml
index 10798ad..2860ee4 100644
--- a/core/res/res/layout/chooser_grid.xml
+++ b/core/res/res/layout/chooser_grid.xml
@@ -70,209 +70,6 @@
                   android:layout_centerHorizontal="true"/>
     </RelativeLayout>
 
-    <!-- The following 3 layouts are mutually exclusive. One of them will be
-         set VISIBLE programatically, when the optimal preview type can be 
-         determined by inspecting the data being shared. This path was chosen
-         b/c inflating layouts in code had sizing problems with this widget. -->
-
-    <!-- Layout Option 1: Supporting up to 3 images for preview -->
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="vertical"
-        android:background="?attr/colorBackgroundFloating">
-        <RelativeLayout
-            android:id="@+id/content_preview_image_area"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center_horizontal"
-            android:paddingBottom="@dimen/chooser_view_spacing"
-            android:visibility="gone"
-            android:background="?attr/colorBackgroundFloating">
-
-            <view class="com.android.internal.app.ChooserActivity$RoundedRectImageView"
-                  android:id="@+id/content_preview_image_1_large"
-                  android:visibility="gone"
-                  android:layout_width="120dp"
-                  android:layout_height="140dp"
-                  android:layout_alignParentTop="true"
-                  android:adjustViewBounds="true"
-                  android:gravity="center"
-                  android:scaleType="centerCrop"/>
-
-            <view class="com.android.internal.app.ChooserActivity$RoundedRectImageView"
-                  android:id="@+id/content_preview_image_2_large"
-                  android:visibility="gone"
-                  android:layout_width="120dp"
-                  android:layout_height="140dp"
-                  android:layout_alignParentTop="true"
-                  android:layout_toRightOf="@id/content_preview_image_1_large"
-                  android:layout_marginLeft="10dp"
-                  android:adjustViewBounds="true"
-                  android:gravity="center"
-                  android:scaleType="centerCrop"/>
-
-            <view class="com.android.internal.app.ChooserActivity$RoundedRectImageView"
-                  android:id="@+id/content_preview_image_2_small"
-                  android:visibility="gone"
-                  android:layout_width="120dp"
-                  android:layout_height="65dp"
-                  android:layout_alignParentTop="true"
-                  android:layout_toRightOf="@id/content_preview_image_1_large"
-                  android:layout_marginLeft="10dp"
-                  android:adjustViewBounds="true"
-                  android:gravity="center"
-                  android:scaleType="centerCrop"/>
-
-            <view class="com.android.internal.app.ChooserActivity$RoundedRectImageView"
-                  android:id="@+id/content_preview_image_3_small"
-                  android:visibility="gone"
-                  android:layout_width="120dp"
-                  android:layout_height="65dp"
-                  android:layout_below="@id/content_preview_image_2_small"
-                  android:layout_toRightOf="@id/content_preview_image_1_large"
-                  android:layout_marginLeft="10dp"
-                  android:layout_marginTop="10dp"
-                  android:adjustViewBounds="true"
-                  android:gravity="center"
-                  android:scaleType="centerCrop"/>
-
-        </RelativeLayout>
-    </LinearLayout>
-
-    <!-- Layout Option 2: Text preview, with optional title and thumbnail -->
-    <LinearLayout
-        android:id="@+id/content_preview_text_area"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="vertical"
-        android:paddingBottom="@dimen/chooser_view_spacing"
-        android:visibility="gone"
-        android:background="?attr/colorBackgroundFloating">
-
-        <LinearLayout
-            android:layout_width="@dimen/chooser_preview_width"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:orientation="horizontal"
-            android:paddingLeft="@dimen/chooser_edge_margin_normal"
-            android:paddingRight="@dimen/chooser_edge_margin_normal"
-            android:layout_marginBottom="@dimen/chooser_view_spacing"
-            android:id="@+id/content_preview_text_layout">
-            <TextView
-                android:id="@+id/content_preview_text"
-                android:layout_width="0dp"
-                android:layout_weight="1"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center_vertical"
-                android:ellipsize="end"
-                android:gravity="start|top"
-                android:paddingRight="24dp"
-                android:maxLines="2"/>
-            <Button
-                android:id="@+id/copy_button"
-                android:layout_width="24dp"
-                android:layout_height="24dp"
-                android:gravity="center"
-                android:layout_gravity="center_vertical"
-                android:background="@drawable/ic_content_copy_gm2"/>
-        </LinearLayout>
-
-        <!-- Required sub-layout so we can get the nice rounded corners-->
-        <!-- around this section -->
-        <LinearLayout
-            android:layout_width="@dimen/chooser_preview_width"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:orientation="horizontal"
-            android:layout_marginLeft="@dimen/chooser_edge_margin_thin"
-            android:layout_marginRight="@dimen/chooser_edge_margin_thin"
-            android:minHeight="80dp"
-            android:background="@drawable/chooser_content_preview_rounded"
-            android:id="@+id/content_preview_title_layout">
-
-            <view class="com.android.internal.app.ChooserActivity$RoundedRectImageView"
-                  android:id="@+id/content_preview_thumbnail"
-                  android:layout_width="75dp"
-                  android:layout_height="75dp"
-                  android:layout_marginRight="16dp"
-                  android:adjustViewBounds="true"
-                  android:layout_gravity="center_vertical"
-                  android:gravity="center"
-                  android:scaleType="centerCrop"/>
-
-            <TextView
-                android:id="@+id/content_preview_title"
-                android:layout_width="0dp"
-                android:layout_weight="1"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center_vertical"
-                android:ellipsize="end"
-                android:maxLines="2"
-                android:textAppearance="?attr/textAppearanceMedium"/>
-        </LinearLayout>
-    </LinearLayout>
-
-    <!-- Layout Option 3: File preview, icon, filename, copy-->
-    <LinearLayout
-        android:id="@+id/content_preview_file_area"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="vertical"
-        android:paddingBottom="@dimen/chooser_view_spacing"
-        android:visibility="gone"
-        android:background="?attr/colorBackgroundFloating">
-
-        <LinearLayout
-            android:layout_width="@dimen/chooser_preview_width"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:orientation="horizontal"
-            android:paddingLeft="@dimen/chooser_edge_margin_normal"
-            android:paddingRight="@dimen/chooser_edge_margin_normal"
-            android:layout_marginBottom="@dimen/chooser_view_spacing"
-            android:id="@+id/content_preview_file_layout">
-
-            <view class="com.android.internal.app.ChooserActivity$RoundedRectImageView"
-                  android:id="@+id/content_preview_file_thumbnail"
-                  android:layout_width="75dp"
-                  android:layout_height="75dp"
-                  android:layout_marginRight="16dp"
-                  android:adjustViewBounds="true"
-                  android:layout_gravity="center_vertical"
-                  android:gravity="center"
-                  android:scaleType="centerCrop"
-                  android:visibility="gone"/>
-            <ImageView
-                  android:id="@+id/content_preview_file_icon"
-                  android:layout_width="36dp"
-                  android:layout_height="36dp"
-                  android:layout_marginRight="16dp"
-                  android:adjustViewBounds="true"
-                  android:layout_gravity="center_vertical"
-                  android:gravity="center"
-                  android:scaleType="fitCenter"
-                  android:visibility="gone"/>
-            <TextView
-                android:id="@+id/content_preview_filename"
-                android:layout_width="0dp"
-                android:layout_weight="1"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center_vertical"
-                android:ellipsize="middle"
-                android:gravity="start|top"
-                android:paddingRight="24dp"
-                android:singleLine="true"/>
-            <Button
-                android:id="@+id/file_copy_button"
-                android:layout_width="24dp"
-                android:layout_height="24dp"
-                android:gravity="center"
-                android:layout_gravity="center_vertical"
-                android:background="@drawable/ic_content_copy_gm2"/>
-        </LinearLayout>
-    </LinearLayout>
-
     <ListView
         android:layout_width="match_parent"
         android:layout_height="match_parent"
diff --git a/core/res/res/layout/chooser_grid_preview_file.xml b/core/res/res/layout/chooser_grid_preview_file.xml
new file mode 100644
index 0000000..27c6041
--- /dev/null
+++ b/core/res/res/layout/chooser_grid_preview_file.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* Copyright 2019, 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.
+*/
+-->
+<!-- Layout Option: File preview, icon, filename, copy-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/content_preview_file_area"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:paddingBottom="@dimen/chooser_view_spacing"
+    android:background="?attr/colorBackgroundFloating">
+
+  <LinearLayout
+      android:layout_width="@dimen/chooser_preview_width"
+      android:layout_height="wrap_content"
+      android:layout_gravity="center"
+      android:orientation="horizontal"
+      android:paddingLeft="@dimen/chooser_edge_margin_normal"
+      android:paddingRight="@dimen/chooser_edge_margin_normal"
+      android:layout_marginBottom="@dimen/chooser_view_spacing"
+      android:id="@+id/content_preview_file_layout">
+
+    <view class="com.android.internal.app.ChooserActivity$RoundedRectImageView"
+          android:id="@+id/content_preview_file_thumbnail"
+          android:layout_width="75dp"
+          android:layout_height="75dp"
+          android:layout_marginRight="16dp"
+          android:adjustViewBounds="true"
+          android:layout_gravity="center_vertical"
+          android:gravity="center"
+          android:scaleType="centerCrop"
+          android:visibility="gone"/>
+    <ImageView
+        android:id="@+id/content_preview_file_icon"
+        android:layout_width="36dp"
+        android:layout_height="36dp"
+        android:layout_marginRight="16dp"
+        android:adjustViewBounds="true"
+        android:layout_gravity="center_vertical"
+        android:gravity="center"
+        android:scaleType="fitCenter"
+        android:visibility="gone"/>
+    <TextView
+        android:id="@+id/content_preview_filename"
+        android:layout_width="0dp"
+        android:layout_weight="1"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
+        android:ellipsize="middle"
+        android:gravity="start|top"
+        android:paddingRight="24dp"
+        android:singleLine="true"/>
+    <Button
+        android:id="@+id/file_copy_button"
+        android:layout_width="24dp"
+        android:layout_height="24dp"
+        android:gravity="center"
+        android:layout_gravity="center_vertical"
+        android:background="@drawable/ic_content_copy_gm2"/>
+  </LinearLayout>
+</LinearLayout>
+
diff --git a/core/res/res/layout/chooser_grid_preview_image.xml b/core/res/res/layout/chooser_grid_preview_image.xml
new file mode 100644
index 0000000..ad31e0d
--- /dev/null
+++ b/core/res/res/layout/chooser_grid_preview_image.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* Copyright 2019, 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.
+*/
+-->
+<!-- Layout Option: Supporting up to 3 images for preview -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:background="?attr/colorBackgroundFloating">
+  <RelativeLayout
+      android:id="@+id/content_preview_image_area"
+      android:layout_width="wrap_content"
+      android:layout_height="wrap_content"
+      android:layout_gravity="center_horizontal"
+      android:paddingBottom="@dimen/chooser_view_spacing"
+      android:background="?attr/colorBackgroundFloating">
+
+    <view class="com.android.internal.app.ChooserActivity$RoundedRectImageView"
+          android:id="@+id/content_preview_image_1_large"
+          android:visibility="gone"
+          android:layout_width="120dp"
+          android:layout_height="140dp"
+          android:layout_alignParentTop="true"
+          android:adjustViewBounds="true"
+          android:gravity="center"
+          android:scaleType="centerCrop"/>
+
+    <view class="com.android.internal.app.ChooserActivity$RoundedRectImageView"
+          android:id="@+id/content_preview_image_2_large"
+          android:visibility="gone"
+          android:layout_width="120dp"
+          android:layout_height="140dp"
+          android:layout_alignParentTop="true"
+          android:layout_toRightOf="@id/content_preview_image_1_large"
+          android:layout_marginLeft="10dp"
+          android:adjustViewBounds="true"
+          android:gravity="center"
+          android:scaleType="centerCrop"/>
+
+    <view class="com.android.internal.app.ChooserActivity$RoundedRectImageView"
+          android:id="@+id/content_preview_image_2_small"
+          android:visibility="gone"
+          android:layout_width="120dp"
+          android:layout_height="65dp"
+          android:layout_alignParentTop="true"
+          android:layout_toRightOf="@id/content_preview_image_1_large"
+          android:layout_marginLeft="10dp"
+          android:adjustViewBounds="true"
+          android:gravity="center"
+          android:scaleType="centerCrop"/>
+
+    <view class="com.android.internal.app.ChooserActivity$RoundedRectImageView"
+          android:id="@+id/content_preview_image_3_small"
+          android:visibility="gone"
+          android:layout_width="120dp"
+          android:layout_height="65dp"
+          android:layout_below="@id/content_preview_image_2_small"
+          android:layout_toRightOf="@id/content_preview_image_1_large"
+          android:layout_marginLeft="10dp"
+          android:layout_marginTop="10dp"
+          android:adjustViewBounds="true"
+          android:gravity="center"
+          android:scaleType="centerCrop"/>
+
+  </RelativeLayout>
+</LinearLayout>
+
diff --git a/core/res/res/layout/chooser_grid_preview_text.xml b/core/res/res/layout/chooser_grid_preview_text.xml
new file mode 100644
index 0000000..7cfbb1b
--- /dev/null
+++ b/core/res/res/layout/chooser_grid_preview_text.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* Copyright 2019, 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.
+*/
+-->
+<!-- Layout Option: Text preview, with optional title and thumbnail -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/content_preview_text_area"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:paddingBottom="@dimen/chooser_view_spacing"
+    android:background="?attr/colorBackgroundFloating">
+
+  <LinearLayout
+      android:layout_width="@dimen/chooser_preview_width"
+      android:layout_height="wrap_content"
+      android:layout_gravity="center"
+      android:orientation="horizontal"
+      android:paddingLeft="@dimen/chooser_edge_margin_normal"
+      android:paddingRight="@dimen/chooser_edge_margin_normal"
+      android:layout_marginBottom="@dimen/chooser_view_spacing"
+      android:id="@+id/content_preview_text_layout">
+    <TextView
+        android:id="@+id/content_preview_text"
+        android:layout_width="0dp"
+        android:layout_weight="1"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
+        android:ellipsize="end"
+        android:gravity="start|top"
+        android:paddingRight="24dp"
+        android:maxLines="2"/>
+    <Button
+        android:id="@+id/copy_button"
+        android:layout_width="24dp"
+        android:layout_height="24dp"
+        android:gravity="center"
+        android:layout_gravity="center_vertical"
+        android:background="@drawable/ic_content_copy_gm2"/>
+  </LinearLayout>
+
+  <!-- Required sub-layout so we can get the nice rounded corners-->
+  <!-- around this section -->
+  <LinearLayout
+      android:layout_width="@dimen/chooser_preview_width"
+      android:layout_height="wrap_content"
+      android:layout_gravity="center"
+      android:orientation="horizontal"
+      android:layout_marginLeft="@dimen/chooser_edge_margin_thin"
+      android:layout_marginRight="@dimen/chooser_edge_margin_thin"
+      android:minHeight="80dp"
+      android:background="@drawable/chooser_content_preview_rounded"
+      android:id="@+id/content_preview_title_layout">
+
+    <view class="com.android.internal.app.ChooserActivity$RoundedRectImageView"
+          android:id="@+id/content_preview_thumbnail"
+          android:layout_width="75dp"
+          android:layout_height="75dp"
+          android:layout_marginRight="16dp"
+          android:adjustViewBounds="true"
+          android:layout_gravity="center_vertical"
+          android:gravity="center"
+          android:scaleType="centerCrop"/>
+
+    <TextView
+        android:id="@+id/content_preview_title"
+        android:layout_width="0dp"
+        android:layout_weight="1"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
+        android:ellipsize="end"
+        android:maxLines="2"
+        android:textAppearance="?attr/textAppearanceMedium"/>
+  </LinearLayout>
+</LinearLayout>
+
diff --git a/core/res/res/layout/chooser_row_direct_share.xml b/core/res/res/layout/chooser_row_direct_share.xml
new file mode 100644
index 0000000..d7e36ee
--- /dev/null
+++ b/core/res/res/layout/chooser_row_direct_share.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2019, 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.
+*/
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:orientation="vertical"
+                android:layout_width="match_parent"
+                android:layout_height="200dp">
+
+</LinearLayout>
+
+
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index 8f2d6c3..f058985 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -175,13 +175,7 @@
     </array>
 
     <!-- Used in ResolverTargetActionsDialogFragment -->
-    <string-array name="resolver_target_actions_pin">
-        <item>@string/pin_target</item>
-        <item>@string/app_info</item>
-    </string-array>
-
-    <string-array name="resolver_target_actions_unpin">
-        <item>@string/unpin_target</item>
+    <string-array name="resolver_target_actions">
         <item>@string/app_info</item>
     </string-array>
 
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index bfb6d24..dce144a 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3513,6 +3513,12 @@
     -->
     <string name="config_defaultAttentionService" translatable="false"></string>
 
+    <!-- The component name for the system-wide captions service.
+         This service must be trusted, as it controls part of the UI of the volume bar.
+         Example: "com.android.captions/.SystemCaptionsService"
+    -->
+    <string name="config_defaultSystemCaptionsService" translatable="false"></string>
+
     <!-- The package name for the incident report approver app.
         This app is usually PermissionController or an app that replaces it.  When
         a bugreport or incident report with EXPLICT-level sharing flags is going to be
diff --git a/core/res/res/values/dimens_car.xml b/core/res/res/values/dimens_car.xml
index 5014a29..d2cf40a 100644
--- a/core/res/res/values/dimens_car.xml
+++ b/core/res/res/values/dimens_car.xml
@@ -102,4 +102,7 @@
     <!-- Progress Bar -->
     <dimen name="car_progress_bar_height">@dimen/car_seekbar_height</dimen>
 
+    <!-- TextView -->
+    <dimen name="car_textview_fading_edge_length">40dp</dimen>
+
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index a69655a..30a11b1 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -525,8 +525,8 @@
     <!-- label for screenshot item in power menu -->
     <string name="global_action_screenshot">Screenshot</string>
 
-    <!-- Take bug report menu title [CHAR LIMIT=NONE] -->
-    <string name="bugreport_title">Take bug report</string>
+    <!-- Take bug report menu title [CHAR LIMIT=20] -->
+    <string name="bugreport_title">Bug report</string>
     <!-- Message in bugreport dialog describing what it does [CHAR LIMIT=NONE] -->
     <!-- TODO: remove if not used anymore -->
     <string name="bugreport_message">This will collect information about your
@@ -800,7 +800,9 @@
     <string name="permgroupdesc_visual">access your photos &amp; videos</string>
     <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] -->
     <string name="permgrouprequest_visual">Allow
-        &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to access your photos and videos, including tagged locations?</string>
+        &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to access your photos and videos?</string>
+    <!-- Subtitle of the message shown to the user when the apps requests permission to access photos and videos [CHAR LIMIT=150]-->
+    <string name="permgrouprequestdetail_visual">Locations and other people in your photos and videos can be identified by the app</string>
 
     <!-- Title for the capability of an accessibility service to retrieve window content. -->
     <string name="capability_title_canRetrieveWindowContent">Retrieve window content</string>
@@ -5046,12 +5048,6 @@
     <string name="usb_mtp_launch_notification_description">Tap to view files</string>
 
     <!-- Resolver target actions strings -->
-
-    <!-- Pin (as in to a bulletin board with a pushpin) a resolver
-         target to the front of the list. -->
-    <string name="pin_target">Pin</string>
-    <!-- Unpin a resolver target such that it sorts normally. -->
-    <string name="unpin_target">Unpin</string>
     <!-- View application info for a target. -->
     <string name="app_info">App info</string>
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 69def5b..76d41a0 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2762,6 +2762,9 @@
   <java-symbol type="dimen" name="chooser_preview_image_font_size"/>
   <java-symbol type="dimen" name="chooser_preview_width" />
   <java-symbol type="layout" name="chooser_grid" />
+  <java-symbol type="layout" name="chooser_grid_preview_text" />
+  <java-symbol type="layout" name="chooser_grid_preview_image" />
+  <java-symbol type="layout" name="chooser_grid_preview_file" />
   <java-symbol type="id" name="chooser_row_text_option" />
   <java-symbol type="dimen" name="chooser_row_text_option_translate" />
   <java-symbol type="layout" name="resolve_grid_item" />
@@ -2770,6 +2773,7 @@
   <java-symbol type="drawable" name="scroll_indicator_material" />
 
   <java-symbol type="layout" name="chooser_row" />
+  <java-symbol type="layout" name="chooser_row_direct_share" />
   <java-symbol type="id" name="target_badge" />
   <java-symbol type="bool" name="config_supportDoubleTapWake" />
   <java-symbol type="drawable" name="ic_perm_device_info" />
@@ -2989,8 +2993,7 @@
   <java-symbol type="color" name="notification_material_background_color" />
 
   <!-- Resolver target actions -->
-  <java-symbol type="array" name="resolver_target_actions_pin" />
-  <java-symbol type="array" name="resolver_target_actions_unpin" />
+  <java-symbol type="array" name="resolver_target_actions" />
 
   <java-symbol type="array" name="non_removable_euicc_slots" />
 
@@ -3382,6 +3385,7 @@
   <java-symbol type="string" name="config_defaultAppPredictionService" />
   <java-symbol type="string" name="config_defaultContentSuggestionsService" />
   <java-symbol type="string" name="config_defaultAttentionService" />
+  <java-symbol type="string" name="config_defaultSystemCaptionsService" />
 
   <java-symbol type="string" name="notification_channel_foreground_service" />
   <java-symbol type="string" name="foreground_service_app_in_background" />
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index 3791305..9955c51 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -55,6 +55,7 @@
     <uses-permission android:name="android.permission.GET_PACKAGE_SIZE" />
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.INJECT_EVENTS" />
+    <uses-permission android:name="android.permission.MANAGE_APP_PREDICTIONS"/>
     <uses-permission android:name="android.permission.READ_CONTACTS" />
     <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
     <uses-permission android:name="android.permission.READ_DREAM_STATE" />
diff --git a/core/tests/coretests/src/android/content/pm/AndroidHidlUpdaterTest.java b/core/tests/coretests/src/android/content/pm/AndroidHidlUpdaterTest.java
index 9b360db..cc48239 100644
--- a/core/tests/coretests/src/android/content/pm/AndroidHidlUpdaterTest.java
+++ b/core/tests/coretests/src/android/content/pm/AndroidHidlUpdaterTest.java
@@ -42,8 +42,17 @@
         PackageBuilder before = builder()
                 .targetSdkVersion(Build.VERSION_CODES.P);
 
+        // no change, not system
+        checkBackwardsCompatibility(before, before);
+    }
+
+    @Test
+    public void targeted_at_P_system() {
+        PackageBuilder before = builder().asSystemApp()
+                .targetSdkVersion(Build.VERSION_CODES.P);
+
         // Should add both HIDL libraries
-        PackageBuilder after = builder()
+        PackageBuilder after = builder().asSystemApp()
                 .targetSdkVersion(Build.VERSION_CODES.P)
                 .requiredLibraries(ANDROID_HIDL_MANAGER, ANDROID_HIDL_BASE);
 
@@ -56,9 +65,19 @@
                 .targetSdkVersion(Build.VERSION_CODES.P)
                 .requiredLibraries(OTHER_LIBRARY);
 
+        // no change, not system
+        checkBackwardsCompatibility(before, before);
+    }
+
+    @Test
+    public void targeted_at_P_not_empty_usesLibraries_system() {
+        PackageBuilder before = builder().asSystemApp()
+                .targetSdkVersion(Build.VERSION_CODES.P)
+                .requiredLibraries(OTHER_LIBRARY);
+
         // The hidl jars should be added at the start of the list because it
         // is not on the bootclasspath and the package targets pre-P.
-        PackageBuilder after = builder()
+        PackageBuilder after = builder().asSystemApp()
                 .targetSdkVersion(Build.VERSION_CODES.P)
                 .requiredLibraries(ANDROID_HIDL_MANAGER, ANDROID_HIDL_BASE, OTHER_LIBRARY);
 
@@ -71,8 +90,21 @@
                 .targetSdkVersion(Build.VERSION_CODES.P)
                 .requiredLibraries(ANDROID_HIDL_MANAGER, ANDROID_HIDL_BASE);
 
-        // No change is required because although the HIDL libraries has been removed from
-        // the bootclasspath the package explicitly requests it.
+        PackageBuilder after = builder()
+                .targetSdkVersion(Build.VERSION_CODES.P);
+
+        // Libraries are removed because they are not available for non-system apps
+        checkBackwardsCompatibility(before, after);
+    }
+
+    @Test
+    public void targeted_at_P_in_usesLibraries_system() {
+        PackageBuilder before = builder().asSystemApp()
+                .targetSdkVersion(Build.VERSION_CODES.P)
+                .requiredLibraries(ANDROID_HIDL_MANAGER, ANDROID_HIDL_BASE);
+
+        // No change is required because the package explicitly requests the HIDL libraries
+        // and is targeted at the current version so does not need backwards compatibility.
         checkBackwardsCompatibility(before, before);
     }
 
@@ -83,8 +115,7 @@
         // Dependency is removed, it is not available.
         PackageBuilder after = builder();
 
-        // No change is required because the package explicitly requests the HIDL libraries
-        // and is targeted at the current version so does not need backwards compatibility.
+        // Libraries are removed because they are not available for apps targetting Q+
         checkBackwardsCompatibility(before, after);
     }
 
@@ -95,8 +126,7 @@
         // Dependency is removed, it is not available.
         PackageBuilder after = builder();
 
-        // No change is required because the package explicitly requests the HIDL libraries
-        // and is targeted at the current version so does not need backwards compatibility.
+        // Libraries are removed because they are not available for apps targetting Q+
         checkBackwardsCompatibility(before, after);
     }
 
diff --git a/core/tests/coretests/src/android/content/pm/PackageBuilder.java b/core/tests/coretests/src/android/content/pm/PackageBuilder.java
index c5db962..f7544af 100644
--- a/core/tests/coretests/src/android/content/pm/PackageBuilder.java
+++ b/core/tests/coretests/src/android/content/pm/PackageBuilder.java
@@ -31,6 +31,8 @@
 
     private int mTargetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
 
+    private int mFlags = 0;
+
     private ArrayList<String> mRequiredLibraries;
 
     private ArrayList<String> mOptionalLibraries;
@@ -42,6 +44,7 @@
     public PackageParser.Package build() {
         PackageParser.Package pkg = new PackageParser.Package("org.package.name");
         pkg.applicationInfo.targetSdkVersion = mTargetSdkVersion;
+        pkg.applicationInfo.flags = mFlags;
         pkg.usesLibraries = mRequiredLibraries;
         pkg.usesOptionalLibraries = mOptionalLibraries;
         return pkg;
@@ -52,6 +55,11 @@
         return this;
     }
 
+    PackageBuilder asSystemApp() {
+        this.mFlags |= ApplicationInfo.FLAG_SYSTEM;
+        return this;
+    }
+
     PackageBuilder requiredLibraries(String... names) {
         this.mRequiredLibraries = arrayListOrNull(names);
         return this;
diff --git a/core/tests/coretests/src/android/provider/DeviceConfigTest.java b/core/tests/coretests/src/android/provider/DeviceConfigTest.java
index 04fa524..7a4fa3a 100644
--- a/core/tests/coretests/src/android/provider/DeviceConfigTest.java
+++ b/core/tests/coretests/src/android/provider/DeviceConfigTest.java
@@ -61,6 +61,26 @@
     }
 
     @Test
+    public void getProperty_nullNamespace() {
+        try {
+            DeviceConfig.getProperty(null, sKey);
+            Assert.fail("Null namespace should have resulted in an NPE.");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void getProperty_nullName() {
+        try {
+            DeviceConfig.getProperty(sNamespace, null);
+            Assert.fail("Null name should have resulted in an NPE.");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    @Test
     public void getString_empty() {
         final String default_value = "default_value";
         final String result = DeviceConfig.getString(sNamespace, sKey, default_value);
@@ -68,6 +88,12 @@
     }
 
     @Test
+    public void getString_nullDefault() {
+        final String result = DeviceConfig.getString(sNamespace, sKey, null);
+        assertThat(result).isNull();
+    }
+
+    @Test
     public void getString_nonEmpty() {
         final String value = "new_value";
         final String default_value = "default";
@@ -78,6 +104,26 @@
     }
 
     @Test
+    public void getString_nullNamespace() {
+        try {
+            DeviceConfig.getString(null, sKey, "default_value");
+            Assert.fail("Null namespace should have resulted in an NPE.");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void getString_nullName() {
+        try {
+            DeviceConfig.getString(sNamespace, null, "default_value");
+            Assert.fail("Null name should have resulted in an NPE.");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    @Test
     public void getBoolean_empty() {
         final boolean default_value = true;
         final boolean result = DeviceConfig.getBoolean(sNamespace, sKey, default_value);
@@ -105,6 +151,26 @@
     }
 
     @Test
+    public void getBoolean_nullNamespace() {
+        try {
+            DeviceConfig.getBoolean(null, sKey, false);
+            Assert.fail("Null namespace should have resulted in an NPE.");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void getBoolean_nullName() {
+        try {
+            DeviceConfig.getBoolean(sNamespace, null, false);
+            Assert.fail("Null name should have resulted in an NPE.");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    @Test
     public void getInt_empty() {
         final int default_value = 999;
         final int result = DeviceConfig.getInt(sNamespace, sKey, default_value);
@@ -132,6 +198,26 @@
     }
 
     @Test
+    public void getInt_nullNamespace() {
+        try {
+            DeviceConfig.getInt(null, sKey, 0);
+            Assert.fail("Null namespace should have resulted in an NPE.");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void getInt_nullName() {
+        try {
+            DeviceConfig.getInt(sNamespace, null, 0);
+            Assert.fail("Null name should have resulted in an NPE.");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    @Test
     public void getLong_empty() {
         final long default_value = 123456;
         final long result = DeviceConfig.getLong(sNamespace, sKey, default_value);
@@ -159,6 +245,26 @@
     }
 
     @Test
+    public void getLong_nullNamespace() {
+        try {
+            DeviceConfig.getLong(null, sKey, 0);
+            Assert.fail("Null namespace should have resulted in an NPE.");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void getLong_nullName() {
+        try {
+            DeviceConfig.getLong(sNamespace, null, 0);
+            Assert.fail("Null name should have resulted in an NPE.");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    @Test
     public void getFloat_empty() {
         final float default_value = 123.456f;
         final float result = DeviceConfig.getFloat(sNamespace, sKey, default_value);
@@ -186,6 +292,46 @@
     }
 
     @Test
+    public void getFloat_nullNamespace() {
+        try {
+            DeviceConfig.getFloat(null, sKey, 0);
+            Assert.fail("Null namespace should have resulted in an NPE.");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void getFloat_nullName() {
+        try {
+            DeviceConfig.getFloat(sNamespace, null, 0);
+            Assert.fail("Null name should have resulted in an NPE.");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void setProperty_nullNamespace() {
+        try {
+            DeviceConfig.setProperty(null, sKey, sValue, false);
+            Assert.fail("Null namespace should have resulted in an NPE.");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void setProperty_nullName() {
+        try {
+            DeviceConfig.setProperty(sNamespace, null, sValue, false);
+            Assert.fail("Null name should have resulted in an NPE.");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    @Test
     public void setAndGetProperty_sameNamespace() {
         DeviceConfig.setProperty(sNamespace, sKey, sValue, false);
         String result = DeviceConfig.getProperty(sNamespace, sKey);
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 43f8db1..7322a54 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -655,6 +655,7 @@
                  Settings.Secure.NIGHT_DISPLAY_ACTIVATED,
                  Settings.Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME,
                  Settings.Secure.NUM_ROTATION_SUGGESTIONS_ACCEPTED,
+                 Settings.Secure.ODI_CAPTIONS_ENABLED,
                  Settings.Secure.PACKAGE_VERIFIER_STATE,
                  Settings.Secure.PACKAGE_VERIFIER_USER_CONSENT,
                  Settings.Secure.PARENTAL_CONTROL_LAST_UPDATE,
diff --git a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureContextTest.java b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureContextTest.java
new file mode 100644
index 0000000..4680a64
--- /dev/null
+++ b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureContextTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2019 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.view.contentcapture;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.ComponentName;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Unit test for {@link ContentCaptureEvent}.
+ *
+ * <p>To run it:
+ * {@code atest FrameworksCoreTests:android.view.contentcapture.ContentCaptureContextTest}
+ */
+@RunWith(JUnit4.class)
+public class ContentCaptureContextTest {
+
+    @Test
+    public void testConstructorAdditionalFlags() {
+        final ComponentName componentName = new ComponentName("component", "name");
+        final ContentCaptureContext ctx = new ContentCaptureContext(/* clientContext= */ null,
+                componentName, /* taskId= */ 666, /* displayId= */ 42, /* flags= */ 1);
+        final ContentCaptureContext newCtx = new ContentCaptureContext(ctx, /* extraFlags= */ 2);
+        assertThat(newCtx.getFlags()).isEqualTo(3);
+
+        assertThat(newCtx.getActivityComponent()).isEqualTo(componentName);
+        assertThat(newCtx.getTaskId()).isEqualTo(666);
+        assertThat(newCtx.getDisplayId()).isEqualTo(42);
+        assertThat(newCtx.getExtras()).isNull();
+        assertThat(newCtx.getLocusId()).isNull();
+        assertThat(newCtx.getParentSessionId()).isNull();
+    }
+}
diff --git a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java
index de2edc3..2416de1 100644
--- a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java
+++ b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java
@@ -19,6 +19,7 @@
 import static android.view.contentcapture.ContentCaptureEvent.TYPE_SESSION_FINISHED;
 import static android.view.contentcapture.ContentCaptureEvent.TYPE_SESSION_STARTED;
 import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_DISAPPEARED;
+import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_TEXT_CHANGED;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -230,6 +231,68 @@
         assertContextUpdatedEvent(clone);
     }
 
+    @Test
+    public void testMergeEvent_typeViewTextChanged() {
+        final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_TEXT_CHANGED)
+                .setText("test");
+        final ContentCaptureEvent event2 = new ContentCaptureEvent("43", TYPE_VIEW_TEXT_CHANGED)
+                .setText("empty");
+
+        event.mergeEvent(event2);
+        assertThat(event.getText()).isEqualTo(event2.getText());
+    }
+
+    @Test
+    public void testMergeEvent_typeViewDisappeared() {
+        final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED)
+                .setAutofillId(new AutofillId(1));
+        final ContentCaptureEvent event2 = new ContentCaptureEvent("43", TYPE_VIEW_DISAPPEARED)
+                .setAutofillId(new AutofillId(2));
+        final ArrayList<AutofillId> autofillIds = new ArrayList<>();
+        autofillIds.add(new AutofillId(3));
+        autofillIds.add(new AutofillId(4));
+        final ContentCaptureEvent event3 = new ContentCaptureEvent("17", TYPE_VIEW_DISAPPEARED)
+                .setAutofillIds(autofillIds);
+
+        event.mergeEvent(event2);
+        assertThat(event.getIds()).containsExactly(new AutofillId(1), new AutofillId(2));
+
+        event2.mergeEvent(event3);
+        assertThat(event2.getIds()).containsExactly(new AutofillId(2), new AutofillId(3),
+                new AutofillId(4));
+    }
+
+    @Test
+    public void testMergeEvent_typeViewDisappeared_noIds() {
+        final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED)
+                .setAutofillId(new AutofillId(1));
+        final ContentCaptureEvent event2 = new ContentCaptureEvent("43", TYPE_VIEW_DISAPPEARED);
+
+        assertThrows(IllegalArgumentException.class, () -> event.mergeEvent(event2));
+    }
+
+    @Test
+    public void testMergeEvent_nullArgument() {
+        final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED);
+        assertThrows(NullPointerException.class, () -> event.mergeEvent(null));
+    }
+
+    @Test
+    public void testMergeEvent_differentEventTypes() {
+        final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED)
+                .setText("test").setAutofillId(new AutofillId(1));
+        final ContentCaptureEvent event2 = new ContentCaptureEvent("17", TYPE_VIEW_TEXT_CHANGED)
+                .setText("empty").setAutofillId(new AutofillId(2));
+
+        event.mergeEvent(event2);
+        assertThat(event.getText()).isEqualTo("test");
+        assertThat(event.getId()).isEqualTo(new AutofillId(1));
+
+        event2.mergeEvent(event);
+        assertThat(event2.getText()).isEqualTo("empty");
+        assertThat(event2.getId()).isEqualTo(new AutofillId(2));
+    }
+
     private void assertContextUpdatedEvent(ContentCaptureEvent event) {
         assertThat(event.getType()).isEqualTo(TYPE_CONTEXT_UPDATED);
         assertThat(event.getEventTime()).isAtLeast(MY_EPOCH);
diff --git a/core/tests/coretests/src/android/view/textclassifier/ActionsSuggestionsHelperTest.java b/core/tests/coretests/src/android/view/textclassifier/ActionsSuggestionsHelperTest.java
index f440953..7150d81 100644
--- a/core/tests/coretests/src/android/view/textclassifier/ActionsSuggestionsHelperTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/ActionsSuggestionsHelperTest.java
@@ -215,7 +215,7 @@
             long referenceTimeInMsUtc) {
         assertThat(nativeMessage.getText()).isEqualTo(text.toString());
         assertThat(nativeMessage.getUserId()).isEqualTo(userId);
-        assertThat(nativeMessage.getLocales()).isEqualTo(LOCALE_TAG);
+        assertThat(nativeMessage.getDetectedTextLanguageTags()).isEqualTo(LOCALE_TAG);
         assertThat(nativeMessage.getReferenceTimeMsUtc()).isEqualTo(referenceTimeInMsUtc);
     }
 }
diff --git a/core/tests/coretests/src/android/view/textclassifier/LegacyIntentFactoryTest.java b/core/tests/coretests/src/android/view/textclassifier/LegacyIntentFactoryTest.java
index 743818c..2a79c1c 100644
--- a/core/tests/coretests/src/android/view/textclassifier/LegacyIntentFactoryTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/LegacyIntentFactoryTest.java
@@ -61,6 +61,7 @@
                         null,
                         null,
                         null,
+                        null,
                         null);
 
         List<LabeledIntent> intents = mLegacyIntentFactory.create(
@@ -95,6 +96,7 @@
                         null,
                         null,
                         null,
+                        null,
                         null);
 
         List<LabeledIntent> intents = mLegacyIntentFactory.create(
diff --git a/core/tests/coretests/src/android/view/textclassifier/TemplateClassificationIntentFactoryTest.java b/core/tests/coretests/src/android/view/textclassifier/TemplateClassificationIntentFactoryTest.java
index 9fd9e8e..fac58f8 100644
--- a/core/tests/coretests/src/android/view/textclassifier/TemplateClassificationIntentFactoryTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/TemplateClassificationIntentFactoryTest.java
@@ -72,6 +72,7 @@
                         null,
                         null,
                         null,
+                        null,
                         createRemoteActionTemplates());
 
         List<LabeledIntent> intents =
@@ -111,6 +112,7 @@
                         null,
                         null,
                         null,
+                        null,
                         createRemoteActionTemplates());
 
         List<LabeledIntent> intents =
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
index 3578bc0..185fa07 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -97,9 +97,12 @@
         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
                 Mockito.anyBoolean(),
                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
-        mActivityRule.launchActivity(Intent.createChooser(viewIntent, "chooser test"));
+        final ChooserWrapperActivity activity = mActivityRule.launchActivity(
+                Intent.createChooser(viewIntent, "chooser test"));
 
         waitForIdle();
+        assertThat(activity.getAdapter().getCount(), is(2));
+        assertThat(activity.getAdapter().getServiceTargetCount(), is(0));
         onView(withId(R.id.title)).check(matches(withText("chooser test")));
     }
 
@@ -596,7 +599,7 @@
 
         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
         waitForIdle();
-        verify(mockLogger, Mockito.times(3)).write(logMakerCaptor.capture());
+        verify(mockLogger, Mockito.times(2)).write(logMakerCaptor.capture());
         // First invocation is from onCreate
         assertThat(logMakerCaptor.getAllValues().get(1).getCategory(),
                 is(MetricsEvent.ACTION_SHARE_WITH_PREVIEW));
@@ -626,16 +629,12 @@
         ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
         waitForIdle();
-        verify(mockLogger, Mockito.times(3)).write(logMakerCaptor.capture());
+        verify(mockLogger, Mockito.times(2)).write(logMakerCaptor.capture());
         // First invocation is from onCreate
         assertThat(logMakerCaptor.getAllValues().get(1).getCategory(),
                 is(MetricsEvent.ACTION_SHARE_WITH_PREVIEW));
         assertThat(logMakerCaptor.getAllValues().get(1).getSubtype(),
                 is(CONTENT_PREVIEW_IMAGE));
-        assertThat(logMakerCaptor.getAllValues().get(2).getCategory(),
-                is(MetricsEvent.ACTION_SHARE_WITH_PREVIEW));
-        assertThat(logMakerCaptor.getAllValues().get(2).getSubtype(),
-                is(CONTENT_PREVIEW_IMAGE));
     }
 
     @Test
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
index a8dd69a..5e71129 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
@@ -39,8 +39,8 @@
     static final OverrideData sOverrides = new OverrideData();
     private UsageStatsManager mUsm;
 
-    ResolveListAdapter getAdapter() {
-        return mAdapter;
+    ChooserListAdapter getAdapter() {
+        return (ChooserListAdapter) mAdapter;
     }
 
     boolean getIsSelected() { return mIsSuccessfullySelected; }
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 2e56e09..4bd344f 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -122,13 +122,22 @@
     }
 
     /**
-     * Private constructor that must received an already allocated native bitmap
+     * Private constructor that must receive an already allocated native bitmap
      * int (pointer).
      */
-    // called from JNI
-    @UnsupportedAppUsage
-    Bitmap(long nativeBitmap, int width, int height, int density, boolean requestPremultiplied,
-            byte[] ninePatchChunk, NinePatch.InsetStruct ninePatchInsets) {
+    // JNI now calls the version below this one. This is preserved due to UnsupportedAppUsage.
+    @UnsupportedAppUsage(maxTargetSdk = 28)
+    Bitmap(long nativeBitmap, int width, int height, int density,
+            boolean requestPremultiplied, byte[] ninePatchChunk,
+            NinePatch.InsetStruct ninePatchInsets) {
+        this(nativeBitmap, width, height, density, requestPremultiplied, ninePatchChunk,
+                ninePatchInsets, true);
+    }
+
+    // called from JNI and Bitmap_Delegate.
+    Bitmap(long nativeBitmap, int width, int height, int density,
+            boolean requestPremultiplied, byte[] ninePatchChunk,
+            NinePatch.InsetStruct ninePatchInsets, boolean fromMalloc) {
         if (nativeBitmap == 0) {
             throw new RuntimeException("internal error: native bitmap is 0");
         }
@@ -144,13 +153,21 @@
         }
 
         mNativePtr = nativeBitmap;
-        long nativeSize = NATIVE_ALLOCATION_SIZE + getAllocationByteCount();
-        NativeAllocationRegistry registry = new NativeAllocationRegistry(
-            Bitmap.class.getClassLoader(), nativeGetNativeFinalizer(), nativeSize);
+
+        final int allocationByteCount = getAllocationByteCount();
+        NativeAllocationRegistry registry;
+        if (fromMalloc) {
+            registry = NativeAllocationRegistry.createMalloced(
+                    Bitmap.class.getClassLoader(), nativeGetNativeFinalizer(), allocationByteCount);
+        } else {
+            registry = NativeAllocationRegistry.createNonmalloced(
+                    Bitmap.class.getClassLoader(), nativeGetNativeFinalizer(), allocationByteCount);
+        }
         registry.registerNativeAllocation(this, nativeBitmap);
 
         if (ResourcesImpl.TRACE_FOR_DETAILED_PRELOAD) {
             sPreloadTracingNumInstantiatedBitmaps++;
+            long nativeSize = NATIVE_ALLOCATION_SIZE + allocationByteCount;
             sPreloadTracingTotalBitmapsSize += nativeSize;
         }
     }
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 8f46e1a..7b3f3da 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -76,14 +76,11 @@
     // (see SkCanvas.cpp, SkDraw.cpp)
     private static final int MAXMIMUM_BITMAP_SIZE = 32766;
 
-    // The approximate size of the native allocation associated with
-    // a Canvas object.
-    private static final long NATIVE_ALLOCATION_SIZE = 525;
-
     // Use a Holder to allow static initialization of Canvas in the boot image.
     private static class NoImagePreloadHolder {
-        public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
-                Canvas.class.getClassLoader(), nGetNativeFinalizer(), NATIVE_ALLOCATION_SIZE);
+        public static final NativeAllocationRegistry sRegistry =
+                NativeAllocationRegistry.createMalloced(
+                Canvas.class.getClassLoader(), nGetNativeFinalizer());
     }
 
     // This field is used to finalize the native Canvas properly
diff --git a/graphics/java/android/graphics/ColorFilter.java b/graphics/java/android/graphics/ColorFilter.java
index b24b988..4c2ef84 100644
--- a/graphics/java/android/graphics/ColorFilter.java
+++ b/graphics/java/android/graphics/ColorFilter.java
@@ -26,8 +26,9 @@
 public class ColorFilter {
 
     private static class NoImagePreloadHolder {
-        public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
-                ColorFilter.class.getClassLoader(), nativeGetFinalizer(), 50);
+        public static final NativeAllocationRegistry sRegistry =
+                NativeAllocationRegistry.createMalloced(
+                ColorFilter.class.getClassLoader(), nativeGetFinalizer());
     }
 
     /**
diff --git a/graphics/java/android/graphics/FontFamily.java b/graphics/java/android/graphics/FontFamily.java
index 5d8ba93..5af0da8 100644
--- a/graphics/java/android/graphics/FontFamily.java
+++ b/graphics/java/android/graphics/FontFamily.java
@@ -44,13 +44,15 @@
 
     private static String TAG = "FontFamily";
 
-    private static final NativeAllocationRegistry sBuilderRegistry = new NativeAllocationRegistry(
-            FontFamily.class.getClassLoader(), nGetBuilderReleaseFunc(), 64);
+    private static final NativeAllocationRegistry sBuilderRegistry =
+            NativeAllocationRegistry.createMalloced(
+            FontFamily.class.getClassLoader(), nGetBuilderReleaseFunc());
 
     private @Nullable Runnable mNativeBuilderCleaner;
 
-    private static final NativeAllocationRegistry sFamilyRegistry = new NativeAllocationRegistry(
-            FontFamily.class.getClassLoader(), nGetFamilyReleaseFunc(), 64);
+    private static final NativeAllocationRegistry sFamilyRegistry =
+            NativeAllocationRegistry.createMalloced(
+            FontFamily.class.getClassLoader(), nGetFamilyReleaseFunc());
 
     /**
      * @hide
diff --git a/graphics/java/android/graphics/Matrix.java b/graphics/java/android/graphics/Matrix.java
index f8cb366..22b6401 100644
--- a/graphics/java/android/graphics/Matrix.java
+++ b/graphics/java/android/graphics/Matrix.java
@@ -16,12 +16,13 @@
 
 package android.graphics;
 
+import android.annotation.UnsupportedAppUsage;
+
 import dalvik.annotation.optimization.CriticalNative;
 import dalvik.annotation.optimization.FastNative;
 
 import libcore.util.NativeAllocationRegistry;
 
-import android.annotation.UnsupportedAppUsage;
 import java.io.PrintWriter;
 
 /**
@@ -222,12 +223,10 @@
         }
     };
 
-    // sizeof(SkMatrix) is 9 * sizeof(float) + uint32_t
-    private static final long NATIVE_ALLOCATION_SIZE = 40;
-
     private static class NoImagePreloadHolder {
-        public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
-                Matrix.class.getClassLoader(), nGetNativeFinalizer(), NATIVE_ALLOCATION_SIZE);
+        public static final NativeAllocationRegistry sRegistry =
+                NativeAllocationRegistry.createMalloced(
+                Matrix.class.getClassLoader(), nGetNativeFinalizer());
     }
 
     /**
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 452f7c9..79ee4a9 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -58,13 +58,11 @@
     private long mNativeShader;
     private long mNativeColorFilter;
 
-    // The approximate size of a native paint object.
-    private static final long NATIVE_PAINT_SIZE = 98;
-
     // Use a Holder to allow static initialization of Paint in the boot image.
     private static class NoImagePreloadHolder {
-        public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
-                Paint.class.getClassLoader(), nGetNativeFinalizer(), NATIVE_PAINT_SIZE);
+        public static final NativeAllocationRegistry sRegistry =
+                NativeAllocationRegistry.createMalloced(
+                Paint.class.getClassLoader(), nGetNativeFinalizer());
     }
 
     @ColorLong private long mColor;
diff --git a/graphics/java/android/graphics/Path.java b/graphics/java/android/graphics/Path.java
index 405ab0b..7282d52 100644
--- a/graphics/java/android/graphics/Path.java
+++ b/graphics/java/android/graphics/Path.java
@@ -36,8 +36,9 @@
  */
 public class Path {
 
-    private static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
-                Path.class.getClassLoader(), nGetFinalizer(), 48 /* dummy size */);
+    private static final NativeAllocationRegistry sRegistry =
+            NativeAllocationRegistry.createMalloced(
+                Path.class.getClassLoader(), nGetFinalizer());
 
     /**
      * @hide
diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java
index 5e48ea1..9b4f2c1 100644
--- a/graphics/java/android/graphics/RenderNode.java
+++ b/graphics/java/android/graphics/RenderNode.java
@@ -70,8 +70,7 @@
  *         canvas.drawRect(...);
  *     } finally {
  *         renderNode.endRecording();
- *     }
- * </pre>
+ *     }</pre>
  *
  * <h3>Drawing a RenderNode in a View</h3>
  * <pre class="prettyprint">
@@ -84,8 +83,7 @@
  *             // Draw the RenderNode into this canvas.
  *             canvas.drawRenderNode(myRenderNode);
  *         }
- *     }
- * </pre>
+ *     }</pre>
  *
  * <h3>Releasing resources</h3>
  * <p>This step is not mandatory but recommended if you want to release resources
@@ -93,8 +91,7 @@
  * <pre class="prettyprint">
  *     // Discards the display list content allowing for any held resources to be released.
  *     // After calling this
- *     renderNode.discardDisplayList();
- * </pre>
+ *     renderNode.discardDisplayList();</pre>
  *
  *
  * <h3>Properties</h3>
@@ -132,8 +129,7 @@
  *          // will be invoked and will execute very quickly
  *          mRenderNode.offsetLeftAndRight(x);
  *          invalidate();
- *     }
- * </pre>
+ *     }</pre>
  *
  * <p>A few of the properties may at first appear redundant, such as {@link #setElevation(float)}
  * and {@link #setTranslationZ(float)}. The reason for these duplicates are to allow for a
@@ -146,24 +142,26 @@
  * overlap with {@link #setPosition(Rect)}.
  *
  * <p>The RenderNode's transform matrix is computed at render time as follows:
- * First a setTranslate(getTranslationX(), getTranslationY()) is applied to a {@link Matrix}.
- * Second a preRotate(getRotationZ(), getPivotX(), getPivotY()) is applied to the matrix. And
- * finally a preScale(getScaleX(), getScaleY(), getPivotX(), getPivotY()) is applied. The current
- * canvas transform matrix, which is translated to the RenderNode's position,
- * is then multiplied by the RenderNode's transform matrix. Therefore there is no implicit
- * ordering in setting various RenderNode properties. That is to say that:
+ * <pre class="prettyprint">
+ *     Matrix transform = new Matrix();
+ *     transform.setTranslate(renderNode.getTranslationX(), renderNode.getTranslationY());
+ *     transform.preRotate(renderNode.getRotationZ(),
+ *             renderNode.getPivotX(), renderNode.getPivotY());
+ *     transform.preScale(renderNode.getScaleX(), renderNode.getScaleY(),
+ *             renderNode.getPivotX(), renderNode.getPivotY());</pre>
+ * The current canvas transform matrix, which is translated to the RenderNode's position,
+ * is then multiplied by the RenderNode's transform matrix. Therefore the ordering of calling
+ * property setters does not affect the result. That is to say that:
  *
  * <pre class="prettyprint">
  *     renderNode.setTranslationX(100);
- *     renderNode.setScaleX(100);
- * </pre>
+ *     renderNode.setScaleX(100);</pre>
  *
- * is equivalent to
+ * is equivalent to:
  *
  * <pre class="prettyprint">
  *     renderNode.setScaleX(100);
- *     renderNode.setTranslationX(100);
- * </pre>
+ *     renderNode.setTranslationX(100);</pre>
  *
  * <h3>Threading</h3>
  * <p>RenderNode may be created and used on any thread but they are not thread-safe. Only
@@ -182,8 +180,7 @@
  *         if (needsUpdate) {
  *             myOwningView.invalidate();
  *         }
- *     }
- * </pre>
+ *     }</pre>
  * This is marginally faster than doing a more explicit up-front check if the value changed by
  * comparing the desired value against {@link #getTranslationX()} as it minimizes JNI transitions.
  * The actual mechanism of requesting a new frame to be rendered will depend on how this
@@ -198,8 +195,9 @@
 
     // Use a Holder to allow static initialization in the boot image.
     private static class NoImagePreloadHolder {
-        public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
-                RenderNode.class.getClassLoader(), nGetNativeFinalizer(), 1024);
+        public static final NativeAllocationRegistry sRegistry =
+                NativeAllocationRegistry.createMalloced(
+                RenderNode.class.getClassLoader(), nGetNativeFinalizer());
     }
 
     /**
@@ -808,14 +806,37 @@
      * for the matrix parameter.
      *
      * @param matrix The matrix, null indicates that the matrix should be cleared.
+     * @see #getAnimationMatrix()
+     *
      * @hide TODO Do we want this?
      */
-    public boolean setAnimationMatrix(Matrix matrix) {
+    public boolean setAnimationMatrix(@Nullable Matrix matrix) {
         return nSetAnimationMatrix(mNativeRenderNode,
                 (matrix != null) ? matrix.native_instance : 0);
     }
 
     /**
+     * Returns the previously set Animation matrix. This matrix exists if an Animation is
+     * currently playing on a View, and is set on the display list during at draw() time.
+     * Returns <code>null</code> when there is no transformation provided by
+     * {@link #setAnimationMatrix(Matrix)}.
+     *
+     * @return the current Animation matrix.
+     * @see #setAnimationMatrix(Matrix)
+     *
+     * @hide
+     */
+    @Nullable
+    public Matrix getAnimationMatrix() {
+        Matrix output = new Matrix();
+        if (nGetAnimationMatrix(mNativeRenderNode, output.native_instance)) {
+            return output;
+        } else {
+            return null;
+        }
+    }
+
+    /**
      * Sets the translucency level for the display list.
      *
      * @param alpha The translucency of the display list, must be a value between 0.0f and 1.0f
@@ -1660,6 +1681,9 @@
     private static native boolean nHasOverlappingRendering(long renderNode);
 
     @CriticalNative
+    private static native boolean nGetAnimationMatrix(long renderNode, long animationMatrix);
+
+    @CriticalNative
     private static native boolean nGetClipToOutline(long renderNode);
 
     @CriticalNative
diff --git a/graphics/java/android/graphics/Shader.java b/graphics/java/android/graphics/Shader.java
index d555128..3050d1d 100644
--- a/graphics/java/android/graphics/Shader.java
+++ b/graphics/java/android/graphics/Shader.java
@@ -33,8 +33,9 @@
 public class Shader {
 
     private static class NoImagePreloadHolder {
-        public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
-                Shader.class.getClassLoader(), nativeGetFinalizer(), 50);
+        public static final NativeAllocationRegistry sRegistry =
+                NativeAllocationRegistry.createMalloced(
+                Shader.class.getClassLoader(), nativeGetFinalizer());
     }
 
     /**
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 9518714..64f7591 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -33,12 +33,12 @@
 import android.graphics.fonts.FontVariationAxis;
 import android.graphics.fonts.SystemFonts;
 import android.os.Build;
-import android.os.Build.VERSION_CODES;
 import android.os.ParcelFileDescriptor;
 import android.provider.FontRequest;
 import android.provider.FontsContract;
 import android.text.FontConfig;
 import android.util.Base64;
+import android.util.Log;
 import android.util.LongSparseArray;
 import android.util.LruCache;
 import android.util.SparseArray;
@@ -48,7 +48,6 @@
 import com.android.internal.util.Preconditions;
 
 import dalvik.annotation.optimization.CriticalNative;
-import dalvik.system.VMRuntime;
 
 import libcore.util.NativeAllocationRegistry;
 
@@ -75,8 +74,9 @@
 
     private static String TAG = "Typeface";
 
-    private static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
-            Typeface.class.getClassLoader(), nativeGetReleaseFunc(), 64);
+    private static final NativeAllocationRegistry sRegistry =
+            NativeAllocationRegistry.createMalloced(
+            Typeface.class.getClassLoader(), nativeGetReleaseFunc());
 
     /** The default NORMAL typeface object */
     public static final Typeface DEFAULT;
@@ -262,18 +262,29 @@
                             ?  FontStyle.FONT_SLANT_ITALIC : FontStyle.FONT_SLANT_UPRIGHT);
                 }
 
+                Font font = null;
+                try {
+                    font = fontBuilder.build();
+                } catch (IllegalArgumentException e) {
+                    // The exception happens if the unsupported font is passed. We suppress this
+                    // exception and just ignore this font here since there is no way of
+                    // resolving this issue by users during inflating layout.
+                    Log.w(TAG, "Ignoring font file since failed to create font object."
+                            + " The font file is not supported on this platform.");
+                    continue;
+                }
                 if (familyBuilder == null) {
-                    familyBuilder = new FontFamily.Builder(fontBuilder.build());
+                    familyBuilder = new FontFamily.Builder(font);
                 } else {
                     try {
-                        familyBuilder.addFont(fontBuilder.build());
+                        familyBuilder.addFont(font);
                     } catch (IllegalArgumentException e) {
-                        if (VMRuntime.getRuntime().getTargetSdkVersion() <= VERSION_CODES.P) {
-                            // Surpress the IllegalArgumentException for keeping the backward
-                            // compatibility.
-                            continue;
-                        }
-                        throw e;
+                        // The exception happens if the same style is added to the family.
+                        // We suppress this exception and just ignore this font here since there is
+                        // no way of resolving this issue by users during inflating layout.
+                        Log.w(TAG,
+                                "Ignoring font file since the same style font is already added.");
+                        continue;
                     }
                 }
             }
diff --git a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
index bb6bf24..82f5870 100644
--- a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
@@ -313,7 +313,7 @@
                     extended, cropRect), inputStream, afd);
 
         final long nativeSize = nNativeByteSize(mState.mNativePtr);
-        NativeAllocationRegistry registry = new NativeAllocationRegistry(
+        NativeAllocationRegistry registry = NativeAllocationRegistry.createMalloced(
                 AnimatedImageDrawable.class.getClassLoader(), nGetNativeFinalizer(), nativeSize);
         registry.registerNativeAllocation(mState, mState.mNativePtr);
     }
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index d7aee77..d9dab98 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -1253,7 +1253,6 @@
         private boolean mInitialized = false;
         private boolean mIsReversible = false;
         private boolean mIsInfinite = false;
-        // TODO: Consider using NativeAllocationRegistery to track native allocation
         private final VirtualRefBasePtr mSetRefBasePtr;
         private WeakReference<RenderNode> mLastSeenTarget = null;
         private int mLastListenerId = 0;
diff --git a/graphics/java/android/graphics/fonts/Font.java b/graphics/java/android/graphics/fonts/Font.java
index f715f43..b857465 100644
--- a/graphics/java/android/graphics/fonts/Font.java
+++ b/graphics/java/android/graphics/fonts/Font.java
@@ -54,13 +54,13 @@
      * A builder class for creating new Font.
      */
     public static final class Builder {
-        private static final NativeAllocationRegistry sAssetByteBufferRegistroy =
-                new NativeAllocationRegistry(ByteBuffer.class.getClassLoader(),
-                    nGetReleaseNativeAssetFunc(), 64);
+        private static final NativeAllocationRegistry sAssetByteBufferRegistry =
+                NativeAllocationRegistry.createMalloced(ByteBuffer.class.getClassLoader(),
+                    nGetReleaseNativeAssetFunc());
 
-        private static final NativeAllocationRegistry sFontRegistory =
-                new NativeAllocationRegistry(Font.class.getClassLoader(),
-                    nGetReleaseNativeFont(), 64);
+        private static final NativeAllocationRegistry sFontRegistry =
+                NativeAllocationRegistry.createMalloced(Font.class.getClassLoader(),
+                    nGetReleaseNativeFont());
 
         private @Nullable ByteBuffer mBuffer;
         private @Nullable File mFile;
@@ -171,7 +171,7 @@
                 return;
             }
             final ByteBuffer b = nGetAssetBuffer(nativeAsset);
-            sAssetByteBufferRegistroy.registerNativeAllocation(b, nativeAsset);
+            sAssetByteBufferRegistry.registerNativeAllocation(b, nativeAsset);
             if (b == null) {
                 mException = new FileNotFoundException(path + " not found");
                 return;
@@ -206,7 +206,7 @@
                 return;
             }
             final ByteBuffer b = nGetAssetBuffer(nativeAsset);
-            sAssetByteBufferRegistroy.registerNativeAllocation(b, nativeAsset);
+            sAssetByteBufferRegistry.registerNativeAllocation(b, nativeAsset);
             if (b == null) {
                 mException = new FileNotFoundException(str + " not found");
                 return;
@@ -354,9 +354,13 @@
 
         /**
          * Creates the font based on the configured values.
+         *
+         * If the font is not supported by the platform, this function will fail with
+         * {@link IllegalArgumentException}.
+         *
          * @return the Font object
          */
-        public @Nullable Font build() throws IOException {
+        public @NonNull Font build() throws IOException {
             if (mException != null) {
                 throw new IOException("Failed to read font contents", mException);
             }
@@ -391,7 +395,7 @@
                     mTtcIndex);
             final Font font = new Font(ptr, readonlyBuffer, mFile,
                     new FontStyle(mWeight, slant), mTtcIndex, mAxes, mLocaleList);
-            sFontRegistory.registerNativeAllocation(font, ptr);
+            sFontRegistry.registerNativeAllocation(font, ptr);
             return font;
         }
 
diff --git a/graphics/java/android/graphics/fonts/FontFamily.java b/graphics/java/android/graphics/fonts/FontFamily.java
index 4772c1c..75ea120 100644
--- a/graphics/java/android/graphics/fonts/FontFamily.java
+++ b/graphics/java/android/graphics/fonts/FontFamily.java
@@ -63,8 +63,8 @@
      */
     public static final class Builder {
         private static final NativeAllocationRegistry sFamilyRegistory =
-                new NativeAllocationRegistry(FontFamily.class.getClassLoader(),
-                    nGetReleaseNativeFamily(), 64);
+                NativeAllocationRegistry.createMalloced(FontFamily.class.getClassLoader(),
+                    nGetReleaseNativeFamily());
 
         private final ArrayList<Font> mFonts = new ArrayList<>();
         private final HashSet<Integer> mStyleHashSet = new HashSet<>();
diff --git a/graphics/java/android/graphics/text/LineBreaker.java b/graphics/java/android/graphics/text/LineBreaker.java
index 9cabf1c..54622c5 100644
--- a/graphics/java/android/graphics/text/LineBreaker.java
+++ b/graphics/java/android/graphics/text/LineBreaker.java
@@ -69,7 +69,7 @@
  * }
  *
  * // Draw text to the canvas
- * Bitmap bmp = new Bitmap.createBitmap(240, totalHeight, Bitmap.Config.ARGB_8888);
+ * Bitmap bmp = Bitmap.createBitmap(240, totalHeight, Bitmap.Config.ARGB_8888);
  * Canvas c = new Canvas(bmp);
  * float yOffset = 0f;
  * int prevOffset = 0;
@@ -248,8 +248,8 @@
         private @FloatRange(from = 0.0f) float mWidth = 0;
         private @FloatRange(from = 0.0f) float mFirstWidth = 0;
         private @IntRange(from = 0) int mFirstWidthLineCount = 0;
-        private @Nullable int[] mVariableTabStops = null;
-        private @IntRange(from = 0) int mDefaultTabStop = 0;
+        private @Nullable float[] mVariableTabStops = null;
+        private @FloatRange(from = 0) float mDefaultTabStop = 0;
 
         public ParagraphConstraints() {}
 
@@ -284,8 +284,8 @@
          * @see #getTabStops()
          * @see #getDefaultTabStop()
          */
-        public void setTabStops(@Nullable int[] tabStops,
-                @Px @IntRange(from = 0) int defaultTabStop) {
+        public void setTabStops(@Nullable float[] tabStops,
+                @Px @FloatRange(from = 0) float defaultTabStop) {
             mVariableTabStops = tabStops;
             mDefaultTabStop = defaultTabStop;
         }
@@ -320,18 +320,18 @@
         /**
          * Returns the array of tab stops in pixels.
          *
-         * @see #setTabStops(int[], int)
+         * @see #setTabStops(float[], int)
          */
-        public @Nullable int[] getTabStops() {
+        public @Nullable float[] getTabStops() {
             return mVariableTabStops;
         }
 
         /**
          * Returns the default tab stops in pixels.
          *
-         * @see #setTabStop(int[], int)
+         * @see #setTabStop(float[], int)
          */
-        public @Px @IntRange(from = 0) int getDefaultTabStop() {
+        public @Px @FloatRange(from = 0) float getDefaultTabStop() {
             return mDefaultTabStop;
         }
     }
@@ -349,8 +349,9 @@
         private static final int END_HYPHEN_MASK = 0x7;  // 0b00111
         private static final int START_HYPHEN_BITS_SHIFT = 3;
 
-        private static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
-                Result.class.getClassLoader(), nGetReleaseResultFunc(), 32);
+        private static final NativeAllocationRegistry sRegistry =
+                NativeAllocationRegistry.createMalloced(
+                Result.class.getClassLoader(), nGetReleaseResultFunc());
         private final long mPtr;
 
         private Result(long ptr) {
@@ -444,8 +445,9 @@
         }
     }
 
-    private static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
-            LineBreaker.class.getClassLoader(), nGetReleaseFunc(), 64);
+    private static final NativeAllocationRegistry sRegistry =
+            NativeAllocationRegistry.createMalloced(
+            LineBreaker.class.getClassLoader(), nGetReleaseFunc());
 
     private final long mNativePtr;
 
@@ -513,8 +515,8 @@
             @FloatRange(from = 0.0f) float firstWidth,
             @IntRange(from = 0) int firstWidthLineCount,
             @FloatRange(from = 0.0f) float restWidth,
-            @Nullable int[] variableTabStops,
-            int defaultTabStop,
+            @Nullable float[] variableTabStops,
+            float defaultTabStop,
             @IntRange(from = 0) int indentsOffset);
 
     // Result accessors
diff --git a/graphics/java/android/graphics/text/MeasuredText.java b/graphics/java/android/graphics/text/MeasuredText.java
index 480aff2..66bcd865 100644
--- a/graphics/java/android/graphics/text/MeasuredText.java
+++ b/graphics/java/android/graphics/text/MeasuredText.java
@@ -169,8 +169,9 @@
      * Note: The appendStyle and appendReplacementRun should be called to cover the text length.
      */
     public static final class Builder {
-        private static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
-                MeasuredText.class.getClassLoader(), nGetReleaseFunc(), 1024);
+        private static final NativeAllocationRegistry sRegistry =
+                NativeAllocationRegistry.createMalloced(
+                MeasuredText.class.getClassLoader(), nGetReleaseFunc());
 
         private long mNativePtr;
 
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index 3bbee18..219d040 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -287,6 +287,8 @@
     switch (mPixelStorageType) {
         case PixelStorageType::Heap:
             return mPixelStorage.heap.size;
+        case PixelStorageType::Ashmem:
+            return mPixelStorage.ashmem.size;
         default:
             return rowBytes() * height();
     }
diff --git a/libs/hwui/hwui/Bitmap.h b/libs/hwui/hwui/Bitmap.h
index 01e4516..dd98b25 100644
--- a/libs/hwui/hwui/Bitmap.h
+++ b/libs/hwui/hwui/Bitmap.h
@@ -103,6 +103,8 @@
 
     bool isHardware() const { return mPixelStorageType == PixelStorageType::Hardware; }
 
+    PixelStorageType pixelStorageType() const { return mPixelStorageType; }
+
     GraphicBuffer* graphicBuffer();
 
     /**
diff --git a/libs/hwui/tests/scripts/prep_generic.sh b/libs/hwui/tests/scripts/prep_generic.sh
new file mode 100755
index 0000000..223bf37
--- /dev/null
+++ b/libs/hwui/tests/scripts/prep_generic.sh
@@ -0,0 +1,249 @@
+#
+# 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.
+#
+
+#################################################################
+###
+###  DO NOT MODIFY THIS FILE
+###  This is a copy of androidx's benchmark/lockClocks.sh
+###  Make changes there instead then copy here!
+###
+#################################################################
+
+# This script can be used to lock device clocks to stable levels for comparing
+# different versions of software.  Since the clock levels are not necessarily
+# indicative of real world behavior, this should **never** be used to compare
+# performance between different device models.
+
+# Fun notes for maintaining this file:
+#      `expr` can deal with ints > INT32_MAX, but if compares cannot. This is why we use MHz.
+#      `expr` can sometimes evaluate right-to-left. This is why we use parens.
+#      Everything below the initial host-check isn't bash - Android uses mksh
+#      mksh allows `\n` in an echo, bash doesn't
+#      can't use `awk`
+
+CPU_TARGET_FREQ_PERCENT=50
+GPU_TARGET_FREQ_PERCENT=50
+
+if [ "`command -v getprop`" == "" ]; then
+    if [ -n "`command -v adb`" ]; then
+        echo ""
+        echo "Pushing $0 and running it on device..."
+        dest=/data/local/tmp/`basename $0`
+        adb push $0 ${dest}
+        adb shell ${dest}
+        adb shell rm ${dest}
+        exit
+    else
+        echo "Could not find adb. Options are:"
+        echo "  1. Ensure adb is on your \$PATH"
+        echo "  2. Use './gradlew lockClocks'"
+        echo "  3. Manually adb push this script to your device, and run it there"
+        exit -1
+    fi
+fi
+
+# require root
+if [ "`id -u`" -ne "0" ]; then
+    echo "Not running as root, cannot lock clocks, aborting"
+    exit -1
+fi
+
+DEVICE=`getprop ro.product.device`
+MODEL=`getprop ro.product.model`
+
+# Find CPU max frequency, and lock big cores to an available frequency
+# that's >= $CPU_TARGET_FREQ_PERCENT% of max. Disable other cores.
+function_lock_cpu() {
+    CPU_BASE=/sys/devices/system/cpu
+    GOV=cpufreq/scaling_governor
+
+    # Find max CPU freq, and associated list of available freqs
+    cpuMaxFreq=0
+    cpuAvailFreqCmpr=0
+    cpuAvailFreq=0
+    enableIndices=''
+    disableIndices=''
+    cpu=0
+    while [ -f ${CPU_BASE}/cpu${cpu}/online ]; do
+        # enable core, so we can find its frequencies
+        echo 1 > ${CPU_BASE}/cpu${cpu}/online
+
+        maxFreq=`cat ${CPU_BASE}/cpu$cpu/cpufreq/cpuinfo_max_freq`
+        availFreq=`cat ${CPU_BASE}/cpu$cpu/cpufreq/scaling_available_frequencies`
+        availFreqCmpr=${availFreq// /-}
+
+        if [ ${maxFreq} -gt ${cpuMaxFreq} ]; then
+            # new highest max freq, look for cpus with same max freq and same avail freq list
+            cpuMaxFreq=${maxFreq}
+            cpuAvailFreq=${availFreq}
+            cpuAvailFreqCmpr=${availFreqCmpr}
+
+            if [ -z ${disableIndices} ]; then
+                disableIndices="$enableIndices"
+            else
+                disableIndices="$disableIndices $enableIndices"
+            fi
+            enableIndices=${cpu}
+        elif [ ${maxFreq} == ${cpuMaxFreq} ] && [ ${availFreqCmpr} == ${cpuAvailFreqCmpr} ]; then
+            enableIndices="$enableIndices $cpu"
+        else
+            disableIndices="$disableIndices $cpu"
+        fi
+        cpu=$(($cpu + 1))
+    done
+
+    # Chose a frequency to lock to that's >= $CPU_TARGET_FREQ_PERCENT% of max
+    # (below, 100M = 1K for KHz->MHz * 100 for %)
+    TARGET_FREQ_MHZ=`expr \( ${cpuMaxFreq} \* ${CPU_TARGET_FREQ_PERCENT} \) \/ 100000`
+    chosenFreq=0
+    for freq in ${cpuAvailFreq}; do
+        freqMhz=`expr ${freq} \/ 1000`
+        if [ ${freqMhz} -ge ${TARGET_FREQ_MHZ} ]; then
+            chosenFreq=${freq}
+            break
+        fi
+    done
+
+    # enable 'big' CPUs
+    for cpu in ${enableIndices}; do
+        freq=${CPU_BASE}/cpu$cpu/cpufreq
+
+        echo 1 > ${CPU_BASE}/cpu${cpu}/online
+        echo userspace > ${CPU_BASE}/cpu${cpu}/${GOV}
+        echo ${chosenFreq} > ${freq}/scaling_max_freq
+        echo ${chosenFreq} > ${freq}/scaling_min_freq
+        echo ${chosenFreq} > ${freq}/scaling_setspeed
+
+        # validate setting the freq worked
+        obsCur=`cat ${freq}/scaling_cur_freq`
+        obsMin=`cat ${freq}/scaling_min_freq`
+        obsMax=`cat ${freq}/scaling_max_freq`
+        if [ obsCur -ne ${chosenFreq} ] || [ obsMin -ne ${chosenFreq} ] || [ obsMax -ne ${chosenFreq} ]; then
+            echo "Failed to set CPU$cpu to $chosenFreq Hz! Aborting..."
+            echo "scaling_cur_freq = $obsCur"
+            echo "scaling_min_freq = $obsMin"
+            echo "scaling_max_freq = $obsMax"
+            exit -1
+        fi
+    done
+
+    # disable other CPUs (Note: important to enable big cores first!)
+    for cpu in ${disableIndices}; do
+      echo 0 > ${CPU_BASE}/cpu${cpu}/online
+    done
+
+    echo "\nLocked CPUs ${enableIndices// /,} to $chosenFreq / $maxFreq KHz"
+    echo "Disabled CPUs ${disableIndices// /,}"
+}
+
+# If we have a Qualcomm GPU, find its max frequency, and lock to
+# an available frequency that's >= GPU_TARGET_FREQ_PERCENT% of max.
+function_lock_gpu_kgsl() {
+    if [ ! -d /sys/class/kgsl/kgsl-3d0/ ]; then
+        # not kgsl, abort
+        echo "\nCurrently don't support locking GPU clocks of $MODEL ($DEVICE)"
+        return -1
+    fi
+    if [ ${DEVICE} == "walleye" ] || [ ${DEVICE} == "taimen" ]; then
+        # Workaround crash
+        echo "\nUnable to lock GPU clocks of $MODEL ($DEVICE)"
+        return -1
+    fi
+
+    GPU_BASE=/sys/class/kgsl/kgsl-3d0
+
+    gpuMaxFreq=0
+    gpuAvailFreq=`cat $GPU_BASE/devfreq/available_frequencies`
+    for freq in ${gpuAvailFreq}; do
+        if [ ${freq} -gt ${gpuMaxFreq} ]; then
+            gpuMaxFreq=${freq}
+        fi
+    done
+
+    # (below, 100M = 1M for MHz * 100 for %)
+    TARGET_FREQ_MHZ=`expr \( ${gpuMaxFreq} \* ${GPU_TARGET_FREQ_PERCENT} \) \/ 100000000`
+
+    chosenFreq=${gpuMaxFreq}
+    index=0
+    chosenIndex=0
+    for freq in ${gpuAvailFreq}; do
+        freqMhz=`expr ${freq} \/ 1000000`
+        if [ ${freqMhz} -ge ${TARGET_FREQ_MHZ} ] && [ ${chosenFreq} -ge ${freq} ]; then
+            # note avail freq are generally in reverse order, so we don't break out of this loop
+            chosenFreq=${freq}
+            chosenIndex=${index}
+        fi
+        index=$(($index + 1))
+    done
+    lastIndex=$(($index - 1))
+
+    firstFreq=`echo $gpuAvailFreq | cut -d" " -f1`
+
+    if [ ${gpuMaxFreq} != ${firstFreq} ]; then
+        # pwrlevel is index of desired freq among available frequencies, from highest to lowest.
+        # If gpuAvailFreq appears to be in-order, reverse the index
+        chosenIndex=$(($lastIndex - $chosenIndex))
+    fi
+
+    echo 0 > ${GPU_BASE}/bus_split
+    echo 1 > ${GPU_BASE}/force_clk_on
+    echo 10000 > ${GPU_BASE}/idle_timer
+
+    echo performance > ${GPU_BASE}/devfreq/governor
+
+    # NOTE: we store in min/max twice, because we don't know if we're increasing
+    # or decreasing, and it's invalid to try and set min > max, or max < min
+    echo ${chosenFreq} > ${GPU_BASE}/devfreq/min_freq
+    echo ${chosenFreq} > ${GPU_BASE}/devfreq/max_freq
+    echo ${chosenFreq} > ${GPU_BASE}/devfreq/min_freq
+    echo ${chosenFreq} > ${GPU_BASE}/devfreq/max_freq
+    echo ${chosenIndex} > ${GPU_BASE}/min_pwrlevel
+    echo ${chosenIndex} > ${GPU_BASE}/max_pwrlevel
+    echo ${chosenIndex} > ${GPU_BASE}/min_pwrlevel
+    echo ${chosenIndex} > ${GPU_BASE}/max_pwrlevel
+
+    obsCur=`cat ${GPU_BASE}/devfreq/cur_freq`
+    obsMin=`cat ${GPU_BASE}/devfreq/min_freq`
+    obsMax=`cat ${GPU_BASE}/devfreq/max_freq`
+    if [ obsCur -ne ${chosenFreq} ] || [ obsMin -ne ${chosenFreq} ] || [ obsMax -ne ${chosenFreq} ]; then
+        echo "Failed to set GPU to $chosenFreq Hz! Aborting..."
+        echo "cur_freq = $obsCur"
+        echo "min_freq = $obsMin"
+        echo "max_freq = $obsMax"
+        echo "index = $chosenIndex"
+        exit -1
+    fi
+    echo "\nLocked GPU to $chosenFreq / $gpuMaxFreq Hz"
+}
+
+# kill processes that manage thermals / scaling
+stop thermal-engine
+stop perfd
+stop vendor.thermal-engine
+stop vendor.perfd
+
+function_lock_cpu
+
+function_lock_gpu_kgsl
+
+# Memory bus - hardcoded per-device for now
+if [ ${DEVICE} == "marlin" ] || [ ${DEVICE} == "sailfish" ]; then
+    echo 13763 > /sys/class/devfreq/soc:qcom,gpubw/max_freq
+else
+    echo "\nUnable to lock memory bus of $MODEL ($DEVICE)."
+fi
+
+echo "\n$DEVICE clocks have been locked - to reset, reboot the device\n"
\ No newline at end of file
diff --git a/libs/hwui/tests/scripts/prep_ryu.sh b/libs/hwui/tests/scripts/prep_ryu.sh
old mode 100644
new mode 100755
diff --git a/location/java/android/location/GpsStatus.java b/location/java/android/location/GpsStatus.java
index 4e37654..609a15e 100644
--- a/location/java/android/location/GpsStatus.java
+++ b/location/java/android/location/GpsStatus.java
@@ -30,7 +30,6 @@
  * <p>This class is used in conjunction with the {@link Listener} interface.
  *
  * @deprecated use {@link GnssStatus} and {@link GnssStatus.Callback}.
- * @removed
  */
 @Deprecated
 public final class GpsStatus {
@@ -113,7 +112,6 @@
     /**
      * Used for receiving notifications when GPS status has changed.
      * @deprecated use {@link GnssStatus.Callback} instead.
-     * @removed
      */
     @Deprecated
     public interface Listener {
@@ -144,7 +142,6 @@
      * You can implement this interface and call {@link LocationManager#addNmeaListener}
      * to receive NMEA data from the GPS engine.
      * @deprecated use {@link OnNmeaMessageListener} instead.
-     * @removed
      */
     @Deprecated
     public interface NmeaListener {
diff --git a/location/java/android/location/Location.java b/location/java/android/location/Location.java
index ed74333..673b411 100644
--- a/location/java/android/location/Location.java
+++ b/location/java/android/location/Location.java
@@ -150,7 +150,7 @@
     private Bundle mExtras = null;
 
     // A bitmask of fields present in this object (see HAS_* constants defined above).
-    private byte mFieldsMask = 0;
+    private int mFieldsMask = 0;
 
     /**
      * Construct a new Location with a named provider.
@@ -1137,7 +1137,7 @@
             l.mTime = in.readLong();
             l.mElapsedRealtimeNanos = in.readLong();
             l.mElapsedRealtimeUncertaintyNanos = in.readLong();
-            l.mFieldsMask = in.readByte();
+            l.mFieldsMask = in.readInt();
             l.mLatitude = in.readDouble();
             l.mLongitude = in.readDouble();
             l.mAltitude = in.readDouble();
@@ -1168,7 +1168,7 @@
         parcel.writeLong(mTime);
         parcel.writeLong(mElapsedRealtimeNanos);
         parcel.writeLong(mElapsedRealtimeUncertaintyNanos);
-        parcel.writeByte(mFieldsMask);
+        parcel.writeInt(mFieldsMask);
         parcel.writeDouble(mLatitude);
         parcel.writeDouble(mLongitude);
         parcel.writeDouble(mAltitude);
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index db6a4d0..dd179f3 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -1360,10 +1360,10 @@
             @NonNull String provider, boolean enabled, @NonNull UserHandle userHandle) {
         checkProvider(provider);
 
-        return Settings.Secure.setLocationProviderEnabledForUser(
+        return Settings.Secure.putStringForUser(
                 mContext.getContentResolver(),
-                provider,
-                enabled,
+                Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
+                (enabled ? "+" : "-") + provider,
                 userHandle.getIdentifier());
     }
 
@@ -1749,7 +1749,6 @@
      *
      * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
      * @deprecated use {@link #registerGnssStatusCallback(GnssStatus.Callback)} instead.
-     * @removed
      */
     @Deprecated
     @RequiresPermission(ACCESS_FINE_LOCATION)
@@ -1762,7 +1761,6 @@
      *
      * @param listener GPS status listener object to remove
      * @deprecated use {@link #unregisterGnssStatusCallback(GnssStatus.Callback)} instead.
-     * @removed
      */
     @Deprecated
     public void removeGpsStatusListener(GpsStatus.Listener listener) {}
@@ -2088,7 +2086,6 @@
      *
      * @param status object containing GPS status details, or null.
      * @return status object containing updated GPS status.
-     * @removed
      */
     @Deprecated
     @RequiresPermission(ACCESS_FINE_LOCATION)
diff --git a/media/apex/java/android/media/MediaSession2.java b/media/apex/java/android/media/MediaSession2.java
index 09ac9ca..d63de09 100644
--- a/media/apex/java/android/media/MediaSession2.java
+++ b/media/apex/java/android/media/MediaSession2.java
@@ -511,7 +511,8 @@
         }
 
         /**
-         * Set extras for the session token.
+         * Set extras for the session token. If null or not set, {@link Session2Token#getExtras()}
+         * will return {@link Bundle#EMPTY}.
          *
          * @return The Builder to allow chaining
          * @see Session2Token#getExtras()
diff --git a/media/apex/java/android/media/Session2Token.java b/media/apex/java/android/media/Session2Token.java
index dc970ae..d7cb978 100644
--- a/media/apex/java/android/media/Session2Token.java
+++ b/media/apex/java/android/media/Session2Token.java
@@ -216,10 +216,11 @@
 
     /**
      * @return extras of the token
+     * @see MediaSession2.Builder#setExtras(Bundle)
      */
-    @Nullable
+    @NonNull
     public Bundle getExtras() {
-        return mExtras;
+        return mExtras == null ? Bundle.EMPTY : mExtras;
     }
 
     Session2Link getSessionLink() {
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index 9258b85..f5abb24 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -16,6 +16,7 @@
 
 package android.media;
 
+import android.annotation.CallbackExecutor;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -24,6 +25,7 @@
 import android.annotation.UnsupportedAppUsage;
 import android.app.ActivityThread;
 import android.os.Handler;
+import android.os.HandlerExecutor;
 import android.os.Looper;
 import android.os.Message;
 import android.os.Parcel;
@@ -36,8 +38,13 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executor;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
+import java.util.function.Function;
 
 
 /**
@@ -131,21 +138,6 @@
 
     private static final String PERMISSION = android.Manifest.permission.ACCESS_DRM_CERTIFICATES;
 
-    private EventHandler mEventHandler;
-    private EventHandler mKeyStatusChangeHandler;
-    private EventHandler mExpirationUpdateHandler;
-    private EventHandler mSessionLostStateHandler;
-
-    private OnEventListener mOnEventListener;
-    private OnKeyStatusChangeListener mOnKeyStatusChangeListener;
-    private OnExpirationUpdateListener mOnExpirationUpdateListener;
-    private OnSessionLostStateListener mOnSessionLostStateListener;
-
-    private final Object mEventLock = new Object();
-    private final Object mKeyStatusChangeLock = new Object();
-    private final Object mExpirationUpdateLock = new Object();
-    private final Object mSessionLostStateLock = new Object();
-
     private long mNativeContext;
 
     /**
@@ -227,35 +219,19 @@
     private static final native boolean isCryptoSchemeSupportedNative(
             @NonNull byte[] uuid, @Nullable String mimeType, @SecurityLevel int securityLevel);
 
-    private EventHandler createHandler() {
+    private Handler createHandler() {
         Looper looper;
-        EventHandler handler;
+        Handler handler;
         if ((looper = Looper.myLooper()) != null) {
-            handler = new EventHandler(this, looper);
+            handler = new Handler(looper);
         } else if ((looper = Looper.getMainLooper()) != null) {
-            handler = new EventHandler(this, looper);
+            handler = new Handler(looper);
         } else {
             handler = null;
         }
         return handler;
     }
 
-    private EventHandler updateHandler(Handler handler) {
-        Looper looper;
-        EventHandler newHandler = null;
-        if (handler != null) {
-            looper = handler.getLooper();
-        } else {
-            looper = Looper.myLooper();
-        }
-        if (looper != null) {
-            if (handler == null || handler.getLooper() != looper) {
-                newHandler = new EventHandler(this, looper);
-            }
-        }
-        return newHandler;
-    }
-
     /**
      * Instantiate a MediaDrm object
      *
@@ -265,11 +241,6 @@
      * specified scheme UUID
      */
     public MediaDrm(@NonNull UUID uuid) throws UnsupportedSchemeException {
-        mEventHandler = createHandler();
-        mKeyStatusChangeHandler = createHandler();
-        mExpirationUpdateHandler = createHandler();
-        mSessionLostStateHandler = createHandler();
-
         /* Native setup requires a weak reference to our object.
          * It's easier to create it here than in C++.
          */
@@ -368,12 +339,30 @@
      */
     public void setOnExpirationUpdateListener(
             @Nullable OnExpirationUpdateListener listener, @Nullable Handler handler) {
-        synchronized(mExpirationUpdateLock) {
-            if (listener != null) {
-                mExpirationUpdateHandler = updateHandler(handler);
-            }
-            mOnExpirationUpdateListener = listener;
-        }
+        setListenerWithHandler(EXPIRATION_UPDATE, handler, listener,
+                this::createOnExpirationUpdateListener);
+    }
+    /**
+     * Register a callback to be invoked when a session expiration update
+     * occurs.
+     *
+     * @see #setOnExpirationUpdateListener(OnExpirationUpdateListener, Handler)
+     *
+     * @param executor the executor through which the listener should be invoked
+     * @param listener the callback that will be run.
+     */
+    public void setOnExpirationUpdateListener(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull OnExpirationUpdateListener listener) {
+        setListenerWithExecutor(EXPIRATION_UPDATE, executor, listener,
+                this::createOnExpirationUpdateListener);
+    }
+
+    /**
+     * Clear the {@link OnExpirationUpdateListener}.
+     */
+    public void clearOnExpirationUpdateListener() {
+        clearGenericListener(EXPIRATION_UPDATE);
     }
 
     /**
@@ -407,12 +396,31 @@
      */
     public void setOnKeyStatusChangeListener(
             @Nullable OnKeyStatusChangeListener listener, @Nullable Handler handler) {
-        synchronized(mKeyStatusChangeLock) {
-            if (listener != null) {
-                mKeyStatusChangeHandler = updateHandler(handler);
-            }
-            mOnKeyStatusChangeListener = listener;
-        }
+        setListenerWithHandler(KEY_STATUS_CHANGE, handler, listener,
+                this::createOnKeyStatusChangeListener);
+    }
+
+    /**
+     * Register a callback to be invoked when the state of keys in a session
+     * change.
+     *
+     * @see #setOnKeyStatusChangeListener(OnKeyStatusChangeListener, Handler)
+     *
+     * @param listener the callback that will be run when key status changes.
+     * @param executor the executor on which the listener should be invoked.
+     */
+    public void setOnKeyStatusChangeListener(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull OnKeyStatusChangeListener listener) {
+        setListenerWithExecutor(KEY_STATUS_CHANGE, executor, listener,
+                this::createOnKeyStatusChangeListener);
+    }
+
+    /**
+     * Clear the {@link OnKeyStatusChangeListener}.
+     */
+    public void clearOnKeyStatusChangeListener() {
+        clearGenericListener(KEY_STATUS_CHANGE);
     }
 
     /**
@@ -453,12 +461,31 @@
      */
     public void setOnSessionLostStateListener(
             @Nullable OnSessionLostStateListener listener, @Nullable Handler handler) {
-        synchronized(mSessionLostStateLock) {
-            if (listener != null) {
-                mSessionLostStateHandler = updateHandler(handler);
-            }
-            mOnSessionLostStateListener = listener;
-        }
+        setListenerWithHandler(SESSION_LOST_STATE, handler, listener,
+                this::createOnSessionLostStateListener);
+    }
+
+    /**
+     * Register a callback to be invoked when session state has been
+     * lost.
+     *
+     * @see #setOnSessionLostStateListener(OnSessionLostStateListener, Handler)
+     *
+     * @param listener the callback that will be run.
+     * @param executor the executor on which the listener should be invoked.
+     */
+    public void setOnSessionLostStateListener(
+            @NonNull @CallbackExecutor Executor executor,
+            @Nullable OnSessionLostStateListener listener) {
+        setListenerWithExecutor(SESSION_LOST_STATE, executor, listener,
+                this::createOnSessionLostStateListener);
+    }
+
+    /**
+     * Clear the {@link OnSessionLostStateListener}.
+     */
+    public void clearOnSessionLostStateListener() {
+        clearGenericListener(SESSION_LOST_STATE);
     }
 
     /**
@@ -552,14 +579,48 @@
     /**
      * Register a callback to be invoked when an event occurs
      *
+     * @see #setOnEventListener(OnEventListener, Handler)
+     *
      * @param listener the callback that will be run.  Use {@code null} to
      *        stop receiving event callbacks.
      */
     public void setOnEventListener(@Nullable OnEventListener listener)
     {
-        synchronized(mEventLock) {
-            mOnEventListener = listener;
-        }
+        setOnEventListener(listener, null);
+    }
+
+    /**
+     * Register a callback to be invoked when an event occurs
+     *
+     * @param listener the callback that will be run.  Use {@code null} to
+     *        stop receiving event callbacks.
+     * @param handler the handler on which the listener should be invoked, or
+     *        null if the listener should be invoked on the calling thread's looper.
+     */
+
+    public void setOnEventListener(@Nullable OnEventListener listener, @Nullable Handler handler)
+    {
+        setListenerWithHandler(DRM_EVENT, handler, listener, this::createOnEventListener);
+    }
+
+    /**
+     * Register a callback to be invoked when an event occurs
+     *
+     * @see #setOnEventListener(OnEventListener)
+     *
+     * @param executor the executor through which the listener should be invoked
+     * @param listener the callback that will be run.
+     */
+    public void setOnEventListener(@NonNull @CallbackExecutor Executor executor,
+            @NonNull OnEventListener listener) {
+        setListenerWithExecutor(DRM_EVENT, executor, listener, this::createOnEventListener);
+    }
+
+    /**
+     * Clear the {@link OnEventListener}.
+     */
+    public void clearOnEventListener() {
+        clearGenericListener(DRM_EVENT);
     }
 
     /**
@@ -637,99 +698,112 @@
     private static final int KEY_STATUS_CHANGE = 202;
     private static final int SESSION_LOST_STATE = 203;
 
-    private class EventHandler extends Handler
-    {
-        private MediaDrm mMediaDrm;
+    // Use ConcurrentMap to support concurrent read/write to listener settings.
+    // ListenerWithExecutor is immutable so we shouldn't need further locks.
+    private final Map<Integer, ListenerWithExecutor> mListenerMap = new ConcurrentHashMap<>();
 
-        public EventHandler(@NonNull MediaDrm md, @NonNull Looper looper) {
-            super(looper);
-            mMediaDrm = md;
+    // called by old-style set*Listener APIs using Handlers; listener & handler are Nullable
+    private <T> void setListenerWithHandler(int what, Handler handler, T listener,
+            Function<T, Consumer<ListenerArgs>> converter) {
+        if (listener == null) {
+            clearGenericListener(what);
+        } else {
+            handler = handler == null ? createHandler() : handler;
+            final HandlerExecutor executor = new HandlerExecutor(handler);
+            setGenericListener(what, executor, listener, converter);
         }
+    }
 
-        @Override
-        public void handleMessage(@NonNull Message msg) {
-            if (mMediaDrm.mNativeContext == 0) {
-                Log.w(TAG, "MediaDrm went away with unhandled events");
-                return;
+    // called by new-style set*Listener APIs using Executors; listener & executor must be NonNull
+    private <T> void setListenerWithExecutor(int what, Executor executor, T listener,
+            Function<T, Consumer<ListenerArgs>> converter) {
+        if (executor == null || listener == null) {
+            final String errMsg = String.format("executor %s listener %s", executor, listener);
+            throw new IllegalArgumentException(errMsg);
+        }
+        setGenericListener(what, executor, listener, converter);
+    }
+
+    private <T> void setGenericListener(int what, Executor executor, T listener,
+            Function<T, Consumer<ListenerArgs>> converter) {
+        mListenerMap.put(what, new ListenerWithExecutor(executor, converter.apply(listener)));
+    }
+
+    private void clearGenericListener(int what) {
+        mListenerMap.remove(what);
+    }
+
+    private Consumer<ListenerArgs> createOnEventListener(OnEventListener listener) {
+        return args -> {
+            byte[] sessionId = args.parcel.createByteArray();
+            if (sessionId.length == 0) {
+                sessionId = null;
             }
-            switch(msg.what) {
-
-            case DRM_EVENT:
-                synchronized(mEventLock) {
-                    if (mOnEventListener != null) {
-                        if (msg.obj != null && msg.obj instanceof Parcel) {
-                            Parcel parcel = (Parcel)msg.obj;
-                            byte[] sessionId = parcel.createByteArray();
-                            if (sessionId.length == 0) {
-                                sessionId = null;
-                            }
-                            byte[] data = parcel.createByteArray();
-                            if (data.length == 0) {
-                                data = null;
-                            }
-
-                            Log.i(TAG, "Drm event (" + msg.arg1 + "," + msg.arg2 + ")");
-                            mOnEventListener.onEvent(mMediaDrm, sessionId, msg.arg1, msg.arg2, data);
-                        }
-                    }
-                }
-                return;
-
-            case KEY_STATUS_CHANGE:
-                synchronized(mKeyStatusChangeLock) {
-                    if (mOnKeyStatusChangeListener != null) {
-                        if (msg.obj != null && msg.obj instanceof Parcel) {
-                            Parcel parcel = (Parcel)msg.obj;
-                            byte[] sessionId = parcel.createByteArray();
-                            if (sessionId.length > 0) {
-                                List<KeyStatus> keyStatusList = keyStatusListFromParcel(parcel);
-                                boolean hasNewUsableKey = (parcel.readInt() != 0);
-
-                                Log.i(TAG, "Drm key status changed");
-                                mOnKeyStatusChangeListener.onKeyStatusChange(mMediaDrm, sessionId,
-                                        keyStatusList, hasNewUsableKey);
-                            }
-                        }
-                    }
-                }
-                return;
-
-            case EXPIRATION_UPDATE:
-                synchronized(mExpirationUpdateLock) {
-                    if (mOnExpirationUpdateListener != null) {
-                        if (msg.obj != null && msg.obj instanceof Parcel) {
-                            Parcel parcel = (Parcel)msg.obj;
-                            byte[] sessionId = parcel.createByteArray();
-                            if (sessionId.length > 0) {
-                                long expirationTime = parcel.readLong();
-
-                                Log.i(TAG, "Drm key expiration update: " + expirationTime);
-                                mOnExpirationUpdateListener.onExpirationUpdate(mMediaDrm, sessionId,
-                                        expirationTime);
-                            }
-                        }
-                    }
-                }
-                return;
-
-            case SESSION_LOST_STATE:
-                synchronized(mSessionLostStateLock) {
-                    if (mOnSessionLostStateListener != null) {
-                        if (msg.obj != null && msg.obj instanceof Parcel) {
-                            Parcel parcel = (Parcel)msg.obj;
-                            byte[] sessionId = parcel.createByteArray();
-                            Log.i(TAG, "Drm session lost state event: ");
-                            mOnSessionLostStateListener.onSessionLostState(mMediaDrm,
-                                    sessionId);
-                        }
-                    }
-                }
-                return;
-
-            default:
-                Log.e(TAG, "Unknown message type " + msg.what);
-                return;
+            byte[] data = args.parcel.createByteArray();
+            if (data.length == 0) {
+                data = null;
             }
+
+            Log.i(TAG, "Drm event (" + args.arg1 + "," + args.arg2 + ")");
+            listener.onEvent(this, sessionId, args.arg1, args.arg2, data);
+        };
+    }
+
+    private Consumer<ListenerArgs> createOnKeyStatusChangeListener(
+            OnKeyStatusChangeListener listener) {
+        return args -> {
+            byte[] sessionId = args.parcel.createByteArray();
+            if (sessionId.length > 0) {
+                List<KeyStatus> keyStatusList = keyStatusListFromParcel(args.parcel);
+                boolean hasNewUsableKey = (args.parcel.readInt() != 0);
+
+                Log.i(TAG, "Drm key status changed");
+                listener.onKeyStatusChange(this, sessionId, keyStatusList, hasNewUsableKey);
+            }
+        };
+    }
+
+    private Consumer<ListenerArgs> createOnExpirationUpdateListener(
+            OnExpirationUpdateListener listener) {
+        return args -> {
+            byte[] sessionId = args.parcel.createByteArray();
+            if (sessionId.length > 0) {
+                long expirationTime = args.parcel.readLong();
+
+                Log.i(TAG, "Drm key expiration update: " + expirationTime);
+                listener.onExpirationUpdate(this, sessionId, expirationTime);
+            }
+        };
+    }
+
+    private Consumer<ListenerArgs> createOnSessionLostStateListener(
+            OnSessionLostStateListener listener) {
+        return args -> {
+            byte[] sessionId = args.parcel.createByteArray();
+            Log.i(TAG, "Drm session lost state event: ");
+            listener.onSessionLostState(this, sessionId);
+        };
+    }
+
+    private static class ListenerArgs {
+        private final Parcel parcel;
+        private final int arg1;
+        private final int arg2;
+
+        public ListenerArgs(Parcel parcel, int arg1, int arg2) {
+            this.parcel = parcel;
+            this.arg1 = arg1;
+            this.arg2 = arg2;
+        }
+    }
+
+    private static class ListenerWithExecutor {
+        private final Consumer<ListenerArgs> mConsumer;
+        private final Executor mExecutor;
+
+        public ListenerWithExecutor(Executor executor, Consumer<ListenerArgs> consumer) {
+            this.mExecutor = executor;
+            this.mConsumer = consumer;
         }
     }
 
@@ -764,35 +838,22 @@
         }
         switch (what) {
             case DRM_EVENT:
-                synchronized(md.mEventLock) {
-                    if (md.mEventHandler != null) {
-                        Message m = md.mEventHandler.obtainMessage(what, eventType, extra, obj);
-                        md.mEventHandler.sendMessage(m);
-                    }
-                }
-                break;
             case EXPIRATION_UPDATE:
-                synchronized(md.mExpirationUpdateLock) {
-                    if (md.mExpirationUpdateHandler != null) {
-                        Message m = md.mExpirationUpdateHandler.obtainMessage(what, obj);
-                        md.mExpirationUpdateHandler.sendMessage(m);
-                    }
-                }
-                break;
             case KEY_STATUS_CHANGE:
-                synchronized(md.mKeyStatusChangeLock) {
-                    if (md.mKeyStatusChangeHandler != null) {
-                        Message m = md.mKeyStatusChangeHandler.obtainMessage(what, obj);
-                        md.mKeyStatusChangeHandler.sendMessage(m);
-                    }
-                }
-                break;
             case SESSION_LOST_STATE:
-                synchronized(md.mSessionLostStateLock) {
-                    if (md.mSessionLostStateHandler != null) {
-                        Message m = md.mSessionLostStateHandler.obtainMessage(what, obj);
-                        md.mSessionLostStateHandler.sendMessage(m);
-                    }
+                ListenerWithExecutor listener  = md.mListenerMap.get(what);
+                if (listener != null) {
+                    final Runnable command = () -> {
+                        if (md.mNativeContext == 0) {
+                            Log.w(TAG, "MediaDrm went away with unhandled events");
+                            return;
+                        }
+                        if (obj != null && obj instanceof Parcel) {
+                            Parcel p = (Parcel)obj;
+                            listener.mConsumer.accept(new ListenerArgs(p, eventType, extra));
+                        }
+                    };
+                    listener.mExecutor.execute(command);
                 }
                 break;
             default:
diff --git a/media/java/android/media/session/ISessionManager.aidl b/media/java/android/media/session/ISessionManager.aidl
index e85461f..cfcc294 100644
--- a/media/java/android/media/session/ISessionManager.aidl
+++ b/media/java/android/media/session/ISessionManager.aidl
@@ -55,8 +55,8 @@
     void addSession2TokensListener(in ISession2TokensListener listener, int userId);
     void removeSession2TokensListener(in ISession2TokensListener listener);
 
-    // This is for the system volume UI only
-    void setRemoteVolumeController(in IRemoteVolumeController rvc);
+    void registerRemoteVolumeController(in IRemoteVolumeController rvc);
+    void unregisterRemoteVolumeController(in IRemoteVolumeController rvc);
 
     // For PhoneWindowManager to precheck media keys
     boolean isGlobalPriorityActive();
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index 5ee52ce..7334044 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -18,7 +18,6 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.SystemApi;
 import android.annotation.UnsupportedAppUsage;
 import android.app.PendingIntent;
 import android.content.Context;
@@ -954,7 +953,6 @@
         /**
          * @hide
          */
-        @SystemApi
         public PlaybackInfo(int type, int control, int max, int current, AudioAttributes attrs) {
             mVolumeType = type;
             mVolumeControl = control;
diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java
index fde4f88..f530442 100644
--- a/media/java/android/media/session/MediaSessionManager.java
+++ b/media/java/android/media/session/MediaSessionManager.java
@@ -424,17 +424,33 @@
     }
 
     /**
-     * Set the remote volume controller to receive volume updates on. Only for
-     * use by system UI.
+     * Set the remote volume controller to receive volume updates on.
+     * Only for use by System UI and Settings application.
      *
      * @param rvc The volume controller to receive updates on.
      * @hide
      */
-    public void setRemoteVolumeController(IRemoteVolumeController rvc) {
+    public void registerRemoteVolumeController(IRemoteVolumeController rvc) {
         try {
-            mService.setRemoteVolumeController(rvc);
+            mService.registerRemoteVolumeController(rvc);
         } catch (RemoteException e) {
-            Log.e(TAG, "Error in setRemoteVolumeController.", e);
+            Log.e(TAG, "Error in registerRemoteVolumeController.", e);
+        }
+    }
+
+    /**
+     * Unregisters the remote volume controller which was previously registered with
+     * {@link #registerRemoteVolumeController(IRemoteVolumeController)}.
+     * Only for use by System UI and Settings application.
+     *
+     * @param rvc The volume controller which was registered.
+     * @hide
+     */
+    public void unregisterRemoteVolumeController(IRemoteVolumeController rvc) {
+        try {
+            mService.unregisterRemoteVolumeController(rvc);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error in unregisterRemoteVolumeController.", e);
         }
     }
 
diff --git a/media/native/midi/include/Doxyfile b/media/native/midi/include/Doxyfile
index 2828f48..e40bbdc 100644
--- a/media/native/midi/include/Doxyfile
+++ b/media/native/midi/include/Doxyfile
@@ -790,7 +790,7 @@
 # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
 # Note: If this tag is empty the current directory is searched.
 
-INPUT                  = "midi.h"
+INPUT                  = "amidi/AMidi.h"
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/media/native/midi/include/amidi/AMidi.h b/media/native/midi/include/amidi/AMidi.h
index 0d60b0d..cbe410f 100644
--- a/media/native/midi/include/amidi/AMidi.h
+++ b/media/native/midi/include/amidi/AMidi.h
@@ -13,6 +13,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+/**
+ * @addtogroup Midi
+ * @{
+ */
+
+/**
+ * @file AMidi.h
+ */
 
 #ifndef ANDROID_MEDIA_AMIDI_H_
 #define ANDROID_MEDIA_AMIDI_H_
@@ -244,3 +252,6 @@
 #endif
 
 #endif /* ANDROID_MEDIA_AMIDI_H_ */
+/**
+@}
+*/
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
index 0c35204..3b278b4 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
@@ -20,9 +20,11 @@
 
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.ViewMediatorCallback;
+import com.android.systemui.car.CarNotificationEntryManager;
 import com.android.systemui.car.CarNotificationInterruptionStateProvider;
 import com.android.systemui.statusbar.car.CarFacetButtonController;
 import com.android.systemui.statusbar.car.CarStatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.volume.CarVolumeDialogComponent;
@@ -54,7 +56,7 @@
     }
 
     public StatusBarKeyguardViewManager createStatusBarKeyguardViewManager(Context context,
-        ViewMediatorCallback viewMediatorCallback, LockPatternUtils lockPatternUtils) {
+            ViewMediatorCallback viewMediatorCallback, LockPatternUtils lockPatternUtils) {
         return new CarStatusBarKeyguardViewManager(context, viewMediatorCallback, lockPatternUtils);
     }
 
@@ -92,4 +94,12 @@
     public interface CarDependencyComponent {
         CarFacetButtonController getCarFacetButtonController();
     }
+
+    /**
+     * Use {@link CarNotificationEntryManager}, which does nothing when adding a notification.
+     */
+    @Singleton
+    public NotificationEntryManager provideNotificationEntryManager(Context context) {
+        return new CarNotificationEntryManager(context);
+    }
 }
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java b/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
new file mode 100644
index 0000000..6d9c7ba
--- /dev/null
+++ b/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 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.systemui.car;
+
+import android.content.Context;
+import android.service.notification.NotificationListenerService;
+import android.service.notification.StatusBarNotification;
+
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+
+/**
+ * Car specific notification entry manager that does nothing when adding a notification.
+ *
+ * <p> This is because system UI notifications are disabled and we have a different implementation.
+ * Please see {@link com.android.car.notification}.
+ */
+public class CarNotificationEntryManager extends NotificationEntryManager {
+    public CarNotificationEntryManager(Context context) {
+        super(context);
+    }
+
+    @Override
+    public void addNotification(
+            StatusBarNotification notification, NotificationListenerService.RankingMap ranking) {
+    }
+}
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index bd0e0b8..45459fc 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -161,6 +161,11 @@
         }
 
         buildNavBarContent();
+        // If the UI was rebuilt (day/night change) while the keyguard was up we need to
+        // correctly respect that state.
+        if (mIsKeyguard) {
+            updateNavBarForKeyguardContent();
+        }
     }
 
     private void addTemperatureViewToController(View v) {
@@ -211,6 +216,13 @@
     @Override
     public void showKeyguard() {
         super.showKeyguard();
+        updateNavBarForKeyguardContent();
+    }
+
+    /**
+     * Switch to the keyguard applicable content contained in the nav bars
+     */
+    private void updateNavBarForKeyguardContent() {
         getComponent(NotificationsUI.class).closeCarNotifications(0);
         if (mNavigationBarView != null) {
             mNavigationBarView.showKeyguardButtons();
@@ -606,4 +618,8 @@
         getComponent(NotificationsUI.class).toggleShowingCarNotifications();
     }
 
+    @Override
+    public void maybeEscalateHeadsUp() {
+        // Never send full screen intent in car.
+    }
 }
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
index 8c6b9b0..5921868 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
@@ -64,4 +64,12 @@
         CarStatusBar statusBar = (CarStatusBar) mStatusBar;
         statusBar.showUserSwitcher();
     }
+
+    /**
+     * Do nothing on this change.
+     * The base class hides the keyguard which for automotive we want to avoid b/c this would happen
+     * on a configuration change due to day/night (headlight state).
+     */
+    @Override
+    public void onDensityOrFontScaleChanged() {  }
 }
diff --git a/packages/CtsShim/build/shim/AndroidManifest.xml b/packages/CtsShim/build/shim/AndroidManifest.xml
index 9b813ac..3e546f1e 100644
--- a/packages/CtsShim/build/shim/AndroidManifest.xml
+++ b/packages/CtsShim/build/shim/AndroidManifest.xml
@@ -20,7 +20,7 @@
     package="com.android.cts.ctsshim" >
 
     <uses-sdk android:minSdkVersion="24"
-        android:targetSdkVersion="24" />
+        android:targetSdkVersion="28" />
 
     <restrict-update
         android:hash="__CAN_NOT_BE_UPDATED__" />
diff --git a/packages/CtsShim/build/shim_priv/AndroidManifest.xml b/packages/CtsShim/build/shim_priv/AndroidManifest.xml
index 9bf454c..9ab12c9 100644
--- a/packages/CtsShim/build/shim_priv/AndroidManifest.xml
+++ b/packages/CtsShim/build/shim_priv/AndroidManifest.xml
@@ -20,7 +20,7 @@
     package="com.android.cts.priv.ctsshim" >
 
     <uses-sdk android:minSdkVersion="24"
-        android:targetSdkVersion="24" />
+        android:targetSdkVersion="28" />
 
     <restrict-update
         android:hash="__HASH__" />
diff --git a/packages/CtsShim/build/shim_priv_upgrade/AndroidManifest.xml b/packages/CtsShim/build/shim_priv_upgrade/AndroidManifest.xml
index 023e93e..2354061 100644
--- a/packages/CtsShim/build/shim_priv_upgrade/AndroidManifest.xml
+++ b/packages/CtsShim/build/shim_priv_upgrade/AndroidManifest.xml
@@ -20,7 +20,7 @@
     package="com.android.cts.priv.ctsshim" >
 
     <uses-sdk android:minSdkVersion="24"
-        android:targetSdkVersion="24" />
+        android:targetSdkVersion="28" />
 
     <application
         android:hasCode="false"
diff --git a/packages/DynamicAndroidInstallationService/res/values/strings.xml b/packages/DynamicAndroidInstallationService/res/values/strings.xml
index 221e1d7..03c7c28 100644
--- a/packages/DynamicAndroidInstallationService/res/values/strings.xml
+++ b/packages/DynamicAndroidInstallationService/res/values/strings.xml
@@ -13,7 +13,7 @@
     <string name="keyguard_description">Please enter your password and continue to AndroidOnTap installation</string>
 
     <!-- Displayed on notification: DynAndroid installation is completed [CHAR LIMIT=128] -->
-    <string name="notification_install_completed">Installation is completed, you can reboot into the new installed system now.</string>
+    <string name="notification_install_completed">New system is ready, you can reboot into it or discard it.</string>
     <!-- Displayed on notification: DynAndroid installation is in progress [CHAR LIMIT=128] -->
     <string name="notification_install_inprogress">Installation is in progress.</string>
     <!-- Displayed on notification: DynAndroid installation is in progress [CHAR LIMIT=128] -->
@@ -30,4 +30,9 @@
     <!-- Action on notification: Reboot to AndroidOnTap [CHAR LIMIT=16] -->
     <string name="notification_action_reboot_to_dynandroid">Reboot</string>
 
+    <!-- Toast when installed DynamicAndroid is discarded [CHAR LIMIT=64] -->
+    <string name="toast_dynandroid_discarded">Installed AndroidOnTap is discarded.</string>
+    <!-- Toast when we fail to launch into DynamicAndroid [CHAR LIMIT=64] -->
+    <string name="toast_failed_to_reboot_to_dynandroid">Failed to reboot into AndroidOnTap.</string>
+
 </resources>
diff --git a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/DynamicAndroidInstallationService.java b/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/DynamicAndroidInstallationService.java
index 719417e..d942bab 100644
--- a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/DynamicAndroidInstallationService.java
+++ b/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/DynamicAndroidInstallationService.java
@@ -54,6 +54,7 @@
 import android.os.PowerManager;
 import android.os.RemoteException;
 import android.util.Log;
+import android.widget.Toast;
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
@@ -73,6 +74,8 @@
      */
     private static final String ACTION_CANCEL_INSTALL =
             "com.android.dynandroid.ACTION_CANCEL_INSTALL";
+    private static final String ACTION_DISCARD_INSTALL =
+            "com.android.dynandroid.ACTION_DISCARD_INSTALL";
     private static final String ACTION_REBOOT_TO_DYN_ANDROID =
             "com.android.dynandroid.ACTION_REBOOT_TO_DYN_ANDROID";
     private static final String ACTION_REBOOT_TO_NORMAL =
@@ -118,10 +121,6 @@
     private long mInstalledSize;
     private boolean mJustCancelledByUser;
 
-    private PendingIntent mPiCancel;
-    private PendingIntent mPiRebootToDynamicAndroid;
-    private PendingIntent mPiUninstallAndReboot;
-
     private InstallationAsyncTask mInstallTask;
 
 
@@ -155,6 +154,8 @@
             executeInstallCommand(intent);
         } else if (ACTION_CANCEL_INSTALL.equals(action)) {
             executeCancelCommand();
+        } else if (ACTION_DISCARD_INSTALL.equals(action)) {
+            executeDiscardCommand();
         } else if (ACTION_REBOOT_TO_DYN_ANDROID.equals(action)) {
             executeRebootToDynAndroidCommand();
         } else if (ACTION_REBOOT_TO_NORMAL.equals(action)) {
@@ -210,7 +211,7 @@
         }
 
         if (mInstallTask != null) {
-            Log.e(TAG, "There is already an install task running");
+            Log.e(TAG, "There is already an installation task running");
             return;
         }
 
@@ -234,10 +235,8 @@
     }
 
     private void executeCancelCommand() {
-        if (mInstallTask == null || mInstallTask.getStatus() == PENDING) {
+        if (mInstallTask == null || mInstallTask.getStatus() != RUNNING) {
             Log.e(TAG, "Cancel command triggered, but there is no task running");
-            mNM.cancel(NOTIFICATION_ID);
-
             return;
         }
 
@@ -247,25 +246,47 @@
             // Will cleanup and post status in onCancelled()
             Log.d(TAG, "Cancel request filed successfully");
         } else {
-            Log.d(TAG, "Requested cancel, completed task will be discarded");
+            Log.e(TAG, "Trying to cancel installation while it's already completed.");
+        }
+    }
 
-            resetTaskAndStop();
-            postStatus(STATUS_NOT_STARTED, CAUSE_INSTALL_CANCELLED);
+    private void executeDiscardCommand() {
+        if (isInDynamicAndroid()) {
+            Log.e(TAG, "We are now running in AOT, please reboot to normal system first");
+            return;
         }
 
+        if (getStatus() != STATUS_READY) {
+            Log.e(TAG, "Trying to discard AOT while there is no complete installation");
+            return;
+        }
+
+        Toast.makeText(this,
+                getString(R.string.toast_dynandroid_discarded),
+                Toast.LENGTH_LONG).show();
+
+        resetTaskAndStop();
+        postStatus(STATUS_NOT_STARTED, CAUSE_INSTALL_CANCELLED);
+
+        mDynAndroid.remove();
     }
 
     private void executeRebootToDynAndroidCommand() {
         if (mInstallTask == null || mInstallTask.getStatus() != FINISHED) {
-            Log.e(TAG, "Trying to reboot to DynamicAndroid, but there is no complete installation");
+            Log.e(TAG, "Trying to reboot to AOT while there is no complete installation");
             return;
         }
 
         if (!mInstallTask.commit()) {
-            // TODO: b/123673280 better UI response
             Log.e(TAG, "Failed to commit installation because of native runtime error.");
             mNM.cancel(NOTIFICATION_ID);
 
+            Toast.makeText(this,
+                    getString(R.string.toast_failed_to_reboot_to_dynandroid),
+                    Toast.LENGTH_LONG).show();
+
+            mDynAndroid.remove();
+
             return;
         }
 
@@ -277,8 +298,13 @@
     }
 
     private void executeRebootToNormalCommand() {
-        mDynAndroid.remove();
+        if (!isInDynamicAndroid()) {
+            Log.e(TAG, "It's already running in normal system.");
+            return;
+        }
 
+        // Per current design, we don't have disable() API. AOT is disabled on next reboot.
+        // TODO: Use better status query when b/125079548 is done.
         PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
 
         if (powerManager != null) {
@@ -287,9 +313,14 @@
     }
 
     private void executeNotifyIfInUseCommand() {
-        if (isInDynamicAndroid()) {
+        int status = getStatus();
+
+        if (status == STATUS_IN_USE) {
             startForeground(NOTIFICATION_ID,
                     buildNotification(STATUS_IN_USE, CAUSE_NOT_SPECIFIED));
+        } else if (status == STATUS_READY) {
+            startForeground(NOTIFICATION_ID,
+                    buildNotification(STATUS_READY, CAUSE_NOT_SPECIFIED));
         }
     }
 
@@ -312,18 +343,12 @@
         if (mNM != null) {
             mNM.createNotificationChannel(chan);
         }
+    }
 
-        Intent intentCancel = new Intent(this, DynamicAndroidInstallationService.class);
-        intentCancel.setAction(ACTION_CANCEL_INSTALL);
-        mPiCancel = PendingIntent.getService(this, 0, intentCancel, 0);
-
-        Intent intentRebootToDyn = new Intent(this, DynamicAndroidInstallationService.class);
-        intentRebootToDyn.setAction(ACTION_REBOOT_TO_DYN_ANDROID);
-        mPiRebootToDynamicAndroid = PendingIntent.getService(this, 0, intentRebootToDyn, 0);
-
-        Intent intentUninstallAndReboot = new Intent(this, DynamicAndroidInstallationService.class);
-        intentUninstallAndReboot.setAction(ACTION_REBOOT_TO_NORMAL);
-        mPiUninstallAndReboot = PendingIntent.getService(this, 0, intentUninstallAndReboot, 0);
+    private PendingIntent createPendingIntent(String action) {
+        Intent intent = new Intent(this, DynamicAndroidInstallationService.class);
+        intent.setAction(action);
+        return PendingIntent.getService(this, 0, intent, 0);
     }
 
     private Notification buildNotification(int status, int cause) {
@@ -342,7 +367,7 @@
 
                 builder.addAction(new Notification.Action.Builder(
                         null, getString(R.string.notification_action_cancel),
-                        mPiCancel).build());
+                        createPendingIntent(ACTION_CANCEL_INSTALL)).build());
 
                 break;
 
@@ -351,11 +376,11 @@
 
                 builder.addAction(new Notification.Action.Builder(
                         null, getString(R.string.notification_action_reboot_to_dynandroid),
-                        mPiRebootToDynamicAndroid).build());
+                        createPendingIntent(ACTION_REBOOT_TO_DYN_ANDROID)).build());
 
                 builder.addAction(new Notification.Action.Builder(
-                        null, getString(R.string.notification_action_cancel),
-                        mPiCancel).build());
+                        null, getString(R.string.notification_action_discard),
+                        createPendingIntent(ACTION_DISCARD_INSTALL)).build());
 
                 break;
 
@@ -364,7 +389,7 @@
 
                 builder.addAction(new Notification.Action.Builder(
                         null, getString(R.string.notification_action_uninstall),
-                        mPiUninstallAndReboot).build());
+                        createPendingIntent(ACTION_REBOOT_TO_NORMAL)).build());
 
                 break;
 
@@ -427,10 +452,10 @@
     private int getStatus() {
         if (isInDynamicAndroid()) {
             return STATUS_IN_USE;
-
+        } else if (isDynamicAndroidInstalled()) {
+            return STATUS_READY;
         } else if (mInstallTask == null) {
             return STATUS_NOT_STARTED;
-
         }
 
         switch (mInstallTask.getStatus()) {
@@ -458,6 +483,10 @@
         return mDynAndroid.isInUse();
     }
 
+    private boolean isDynamicAndroidInstalled() {
+        return mDynAndroid.isInstalled();
+    }
+
     void handleMessage(Message msg) {
         switch (msg.what) {
             case DynamicAndroidClient.MSG_REGISTER_LISTENER:
diff --git a/packages/NetworkStack/src/android/net/metrics/DataStallStatsUtils.java b/packages/NetworkStack/src/android/net/metrics/DataStallStatsUtils.java
index d1ca109..e23f10f 100644
--- a/packages/NetworkStack/src/android/net/metrics/DataStallStatsUtils.java
+++ b/packages/NetworkStack/src/android/net/metrics/DataStallStatsUtils.java
@@ -48,6 +48,8 @@
             return DataStallEventProto.VALID;
         } else if (result.isPortal()) {
             return DataStallEventProto.PORTAL;
+        } else if (result.isPartialConnectivity()) {
+            return DataStallEventProto.PARTIAL;
         } else {
             return DataStallEventProto.INVALID;
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/volume/MediaSessions.java b/packages/SettingsLib/src/com/android/settingslib/volume/MediaSessions.java
index 4ed1154..f6cd971 100644
--- a/packages/SettingsLib/src/com/android/settingslib/volume/MediaSessions.java
+++ b/packages/SettingsLib/src/com/android/settingslib/volume/MediaSessions.java
@@ -95,7 +95,7 @@
         mMgr.addOnActiveSessionsChangedListener(mSessionsListener, null, mHandler);
         mInit = true;
         postUpdateSessions();
-        mMgr.setRemoteVolumeController(mRvc);
+        mMgr.registerRemoteVolumeController(mRvc);
     }
 
     protected void postUpdateSessions() {
@@ -110,6 +110,7 @@
         if (D.BUG) Log.d(TAG, "destroy");
         mInit = false;
         mMgr.removeOnActiveSessionsChangedListener(mSessionsListener);
+        mMgr.unregisterRemoteVolumeController(mRvc);
     }
 
     /**
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index 59fbb72..800c401 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -307,6 +307,7 @@
     public AccessPoint(Context context, WifiConfiguration config) {
         mContext = context;
         loadConfig(config);
+        updateKey();
     }
 
     /**
@@ -317,6 +318,7 @@
         mContext = context;
         mFqdn = config.getHomeSp().getFqdn();
         mProviderFriendlyName = config.getHomeSp().getFriendlyName();
+        updateKey();
     }
 
     /**
@@ -355,7 +357,6 @@
         security = getSecurity(config);
         networkId = config.networkId;
         mConfig = config;
-        updateKey();
     }
 
     /** Updates {@link #mKey} and should only called upon object creation/initialization. */
@@ -363,6 +364,8 @@
         // TODO(sghuman): Consolidate Key logic on ScanResultMatchInfo
         if (isPasspoint()) {
             mKey = getKey(mConfig);
+        } else if (isPasspointConfig()) {
+            mKey = getKey(mFqdn);
         } else if (isOsuProvider()) {
             mKey = getKey(mOsuProvider);
         } else { // Non-Passpoint AP
@@ -618,15 +621,22 @@
      */
     public static String getKey(WifiConfiguration config) {
         if (config.isPasspoint()) {
-            return new StringBuilder()
-                    .append(KEY_PREFIX_FQDN)
-                    .append(config.FQDN).toString();
+            return getKey(config.FQDN);
         } else {
             return getKey(removeDoubleQuotes(config.SSID), config.BSSID, getSecurity(config));
         }
     }
 
     /**
+     * Returns the AccessPoint key corresponding to a Passpoint network by its FQDN.
+     */
+    public static String getKey(String fqdn) {
+        return new StringBuilder()
+                .append(KEY_PREFIX_FQDN)
+                .append(fqdn).toString();
+    }
+
+    /**
      * Returns the AccessPoint key corresponding to the OsuProvider.
      */
     public static String getKey(OsuProvider provider) {
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
index 7c367c7..9c8e3f4 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
@@ -1250,6 +1250,14 @@
         AccessPoint passpointAp = new AccessPoint(mContext, spyConfig, mScanResults, null);
         assertThat(passpointAp.getKey()).isEqualTo(AccessPoint.getKey(spyConfig));
 
+        PasspointConfiguration passpointConfig = new PasspointConfiguration();
+        HomeSp homeSp = new HomeSp();
+        homeSp.setFqdn("fqdn");
+        homeSp.setFriendlyName("Test Provider");
+        passpointConfig.setHomeSp(homeSp);
+        AccessPoint passpointConfigAp = new AccessPoint(mContext, passpointConfig);
+        assertThat(passpointConfigAp.getKey()).isEqualTo(AccessPoint.getKey("fqdn"));
+
         OsuProvider provider = createOsuProvider();
         AccessPoint osuAp = new AccessPoint(mContext, provider, mScanResults);
         assertThat(osuAp.getKey()).isEqualTo(AccessPoint.getKey(provider));
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index 274acad..36bb8ef 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -16,10 +16,6 @@
 
 package com.android.providers.settings;
 
-import android.os.Process;
-import com.android.internal.app.LocalePicker;
-import com.android.internal.annotations.VisibleForTesting;
-
 import android.annotation.NonNull;
 import android.app.ActivityManager;
 import android.app.IActivityManager;
@@ -30,7 +26,6 @@
 import android.content.Intent;
 import android.content.res.Configuration;
 import android.icu.util.ULocale;
-import android.location.LocationManager;
 import android.media.AudioManager;
 import android.media.RingtoneManager;
 import android.net.Uri;
@@ -38,13 +33,14 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
-import android.os.UserManager;
 import android.provider.Settings;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.ArraySet;
 
-import java.lang.IllegalArgumentException;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.app.LocalePicker;
+
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Locale;
@@ -145,9 +141,6 @@
             if (Settings.System.SOUND_EFFECTS_ENABLED.equals(name)) {
                 setSoundEffects(Integer.parseInt(value) == 1);
                 // fall through to the ordinary write to settings
-            } else if (Settings.Secure.LOCATION_PROVIDERS_ALLOWED.equals(name)) {
-                setGpsLocation(value);
-                return;
             } else if (Settings.Secure.BACKUP_AUTO_RESTORE.equals(name)) {
                 setAutoRestore(Integer.parseInt(value) == 1);
             } else if (isAlreadyConfiguredCriticalAccessibilitySetting(name)) {
@@ -297,21 +290,6 @@
         } catch (RemoteException e) {}
     }
 
-    private void setGpsLocation(String value) {
-        UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-        if (um.hasUserRestriction(UserManager.DISALLOW_SHARE_LOCATION)) {
-            return;
-        }
-        final String GPS = LocationManager.GPS_PROVIDER;
-        boolean enabled =
-            GPS.equals(value) ||
-                value.startsWith(GPS + ",") ||
-                value.endsWith("," + GPS) ||
-                value.contains("," + GPS + ",");
-        LocationManager lm = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
-        lm.setProviderEnabledForUser(GPS, enabled, Process.myUserHandle());
-    }
-
     private void setSoundEffects(boolean enable) {
         if (enable) {
             mAudioManager.loadSoundEffects();
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index fc6ef2b..d639e5e 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -175,6 +175,9 @@
 
     <uses-permission android:name="android.permission.MANAGE_APPOPS" />
 
+    <!-- Permission needed to run network tests in CTS -->
+    <uses-permission android:name="android.permission.MANAGE_TEST_NETWORKS" />
+
     <application android:label="@string/app_label"
                  android:defaultToDeviceProtectedStorage="true"
                  android:directBootAware="true">
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 9425941..c2495b5 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -58,7 +58,6 @@
         "androidx.arch.core_core-runtime",
         "androidx.lifecycle_lifecycle-extensions",
         "androidx.dynamicanimation_dynamicanimation",
-        "iconloader_base",
         "SystemUI-tags",
         "SystemUI-proto",
         "dagger2-2.19",
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java
index 5f4cf03..2b10ccb 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java
@@ -58,6 +58,10 @@
     void userActivity();
     void getState();
 
+    boolean areCaptionsEnabled();
+    void setCaptionsEnabled(boolean isEnabled);
+    void getCaptionsComponentState();
+
     @ProvidesInterface(version = StreamState.VERSION)
     public static final class StreamState {
         public static final int VERSION = 1;
@@ -186,5 +190,6 @@
         void onScreenOff();
         void onShowSafetyWarning(int flags);
         void onAccessibilityModeChanged(Boolean showA11yStream);
+        void onCaptionComponentStateChanged(Boolean isComponentEnabled);
     }
 }
diff --git a/packages/SystemUI/res/drawable/ic_volume_odi_captions.xml b/packages/SystemUI/res/drawable/ic_volume_odi_captions.xml
new file mode 100644
index 0000000..9b90729
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_volume_odi_captions.xml
@@ -0,0 +1,24 @@
+<!--
+     Copyright (C) 2019 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+  <path
+      android:fillColor="#FF000000"
+      android:pathData="M20,4C21.1,4 22,4.9 22,6L22,18C22,19.1 21.1,20 20,20L4,20C2.9,20 2,19.1 2,18L2,6C2,4.9 2.9,4 4,4L20,4ZM20,18L20,6L4,6L4,18L20,18ZM6,10L8,10L8,12L6,12L6,10ZM6,14L14,14L14,16L6,16L6,14ZM16,14L18,14L18,16L16,16L16,14ZM10,10L18,10L18,12L10,12L10,10Z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_odi_captions_disabled.xml b/packages/SystemUI/res/drawable/ic_volume_odi_captions_disabled.xml
new file mode 100644
index 0000000..f3d8d3b9
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_volume_odi_captions_disabled.xml
@@ -0,0 +1,24 @@
+<!--
+     Copyright (C) 2019 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+  <path
+      android:fillColor="#FF000000"
+      android:pathData="M16.9675,14L18,14L18,15.0275L16.9675,14ZM20,17.0176L20,6L8.9281,6L6.9182,4L20,4C21.1,4 22,4.9 22,6L22,18C22,18.2949 21.9353,18.5755 21.8194,18.8281L20,17.0176ZM12.9478,10L18,10L18,12L14.9576,12L12.9478,10ZM1.2823,0.8824L22.8489,22.4489L21.6337,23.6641L17.9696,20L4,20C2.9,20 2,19.1 2,18L2,6C2,5.4577 2.2188,4.964 2.5724,4.6028L0.0672,2.0975L1.2823,0.8824ZM13.9696,16L6,16L6,14L11.9696,14L8,10.0304L8,12L6,12L6,10L7.9696,10L4,6.0304L4,18L15.9696,18L13.9696,16Z"/>
+</vector>
diff --git a/packages/SystemUI/res/layout-land/global_actions_grid.xml b/packages/SystemUI/res/layout-land/global_actions_grid.xml
index 235d0fc..c51e71b 100644
--- a/packages/SystemUI/res/layout-land/global_actions_grid.xml
+++ b/packages/SystemUI/res/layout-land/global_actions_grid.xml
@@ -7,7 +7,8 @@
     android:orientation="horizontal"
     android:clipToPadding="false"
     android:theme="@style/qs_theme"
-    android:gravity="top|right"
+    android:paddingLeft="@dimen/global_actions_top_padding"
+    android:gravity="top|left"
     android:clipChildren="false"
 >
     <LinearLayout
diff --git a/packages/SystemUI/res/layout-land/global_actions_grid_seascape.xml b/packages/SystemUI/res/layout-land/global_actions_grid_seascape.xml
index e028214..de853c7 100644
--- a/packages/SystemUI/res/layout-land/global_actions_grid_seascape.xml
+++ b/packages/SystemUI/res/layout-land/global_actions_grid_seascape.xml
@@ -7,7 +7,8 @@
     android:orientation="horizontal"
     android:clipToPadding="false"
     android:theme="@style/qs_theme"
-    android:gravity="top|left"
+    android:gravity="top|right"
+    android:paddingRight="@dimen/global_actions_top_padding"
     android:clipChildren="false"
 >
     <LinearLayout
diff --git a/packages/SystemUI/res/layout/assistant_handle.xml b/packages/SystemUI/res/layout/assistant_handle.xml
deleted file mode 100644
index a952ca5..0000000
--- a/packages/SystemUI/res/layout/assistant_handle.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2019 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
-  -->
-
-<com.android.systemui.statusbar.phone.NavigationHandle
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/assistant_handle"
-    android:layout_width="@dimen/navigation_assistant_handle_width"
-    android:layout_height="match_parent"
-    android:layout_weight="0"
-/>
-
diff --git a/packages/SystemUI/res/layout/global_actions_grid.xml b/packages/SystemUI/res/layout/global_actions_grid.xml
index a620a8e..d90d5e9 100644
--- a/packages/SystemUI/res/layout/global_actions_grid.xml
+++ b/packages/SystemUI/res/layout/global_actions_grid.xml
@@ -6,8 +6,9 @@
     android:layout_height="match_parent"
     android:orientation="horizontal"
     android:clipToPadding="false"
+    android:paddingTop="@dimen/global_actions_top_padding"
     android:theme="@style/qs_theme"
-    android:gravity="bottom|center"
+    android:gravity="top|center"
     android:clipChildren="false"
 >
     <LinearLayout
diff --git a/packages/SystemUI/res/layout/notification_info.xml b/packages/SystemUI/res/layout/notification_info.xml
index 725ace4..0d44931 100644
--- a/packages/SystemUI/res/layout/notification_info.xml
+++ b/packages/SystemUI/res/layout/notification_info.xml
@@ -255,6 +255,7 @@
                             android:layout_width="40dp"
                             android:layout_height="40dp"
                             android:clickable="false"
+                            android:contentDescription="@string/inline_block_button"
                             android:tint="@color/GM2_grey_400"
                             style="@style/TextAppearance.NotificationInfo.Button"/>
                     </FrameLayout>
@@ -289,6 +290,7 @@
                             android:layout_width="40dp"
                             android:layout_height="40dp"
                             android:clickable="false"
+                            android:contentDescription="@string/inline_silent_button_silent"
                             android:tint="@color/GM2_grey_400"
                             style="@style/TextAppearance.NotificationInfo.Button"/>
                     </FrameLayout>
@@ -322,6 +324,7 @@
                             android:layout_gravity="center"
                             android:layout_width="40dp"
                             android:layout_height="40dp"
+                            android:contentDescription="@string/inline_silent_button_alert"
                             android:clickable="false"
                             android:tint="@color/GM2_grey_400"
                             style="@style/TextAppearance.NotificationInfo.Button"/>
diff --git a/packages/SystemUI/res/layout/ongoing_privacy_chip.xml b/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
index f64a64e6..b16e062 100644
--- a/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
+++ b/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
@@ -28,7 +28,7 @@
     android:orientation="horizontal"
     android:focusable="true">
 
-        <LinearLayout
+        <FrameLayout
             android:id="@+id/background"
             android:layout_height="@dimen/ongoing_appops_chip_height"
             android:layout_width="wrap_content"
@@ -37,25 +37,8 @@
                     android:id="@+id/icons_container"
                     android:layout_height="match_parent"
                     android:layout_width="wrap_content"
-                    android:layout_marginStart="@dimen/ongoing_appops_chip_items_margin"
-                    android:layout_gravity="center_vertical"
+                    android:layout_gravity="center"
                     android:gravity="center_vertical"
                     />
-
-                <TextView
-                    android:id="@+id/text_container"
-                    android:layout_height="match_parent"
-                    android:layout_width="wrap_content"
-                    android:layout_gravity="center_vertical|end"
-                    android:paddingStart="@dimen/ongoing_appops_chip_text_padding"
-                    android:paddingEnd="@dimen/ongoing_appops_chip_text_padding"
-                    android:gravity="center_vertical"
-                    android:singleLine="true"
-                    android:ellipsize="end"
-                    android:lines="1"
-                    android:textAppearance="@style/TextAppearance.StatusBar.Clock"
-                    android:textSize="@dimen/ongoing_appops_chip_text_size"
-                    android:textColor="@color/status_bar_clock_color"
-                />
-          </LinearLayout>
+          </FrameLayout>
 </com.android.systemui.privacy.OngoingPrivacyChip>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/status_bar_notification_footer.xml b/packages/SystemUI/res/layout/status_bar_notification_footer.xml
index 056f16a..174a3b8 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_footer.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_footer.xml
@@ -33,6 +33,7 @@
             android:layout_height="wrap_content"
             android:layout_gravity="start"
             android:focusable="true"
+            android:contentDescription="@string/accessibility_manage_notification"
             android:text="@string/manage_notifications_text"
             android:textColor="?attr/wallpaperTextColor"
             android:textAllCaps="false"/>
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index ca34c23..130be89 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -98,5 +98,27 @@
             </FrameLayout>
         </LinearLayout>
 
+        <FrameLayout
+            android:id="@+id/odi_captions"
+            android:layout_width="@dimen/volume_dialog_caption_size"
+            android:layout_height="@dimen/volume_dialog_caption_size"
+            android:layout_marginTop="@dimen/volume_dialog_spacer"
+            android:translationZ="@dimen/volume_dialog_elevation"
+            android:layout_gravity="right"
+            android:clipToPadding="false"
+            android:visibility="gone"
+            android:background="@drawable/rounded_bg_full">
+            <com.android.keyguard.AlphaOptimizedImageButton
+                android:id="@+id/odi_captions_icon"
+                android:src="@drawable/ic_volume_odi_captions_disabled"
+                style="@style/VolumeButtons"
+                android:background="@drawable/rounded_ripple"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:tint="@color/accent_tint_color_selector"
+                android:layout_gravity="center"
+                android:soundEffectsEnabled="false" />
+        </FrameLayout>
+
     </LinearLayout>
 </FrameLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 8b4f66d..f8295eb 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -330,7 +330,7 @@
     <!-- Nav bar button default ordering/layout -->
     <string name="config_navBarLayout" translatable="false">left[.5W],back[1WC];home;recent[1WC],right[.5W]</string>
     <string name="config_navBarLayoutQuickstep" translatable="false">back[1.7WC];home;contextual[1.7WC]</string>
-    <string name="config_navBarLayoutHandle" translatable="false">";home_handle;assistant_handle[.18WC]"</string>
+    <string name="config_navBarLayoutHandle" translatable="false">";home_handle;"</string>
 
     <bool name="quick_settings_show_full_alarm">false</bool>
 
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index c83cb59..30cbaaa 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -34,11 +34,10 @@
     <dimen name="navigation_bar_deadzone_size_max">32dp</dimen>
 
     <!-- dimensions for the navigation bar handle -->
-    <dimen name="navigation_handle_radius">2dp</dimen>
-    <dimen name="navigation_handle_bottom">8dp</dimen>
+    <dimen name="navigation_handle_radius">1dp</dimen>
+    <dimen name="navigation_handle_bottom">6dp</dimen>
     <dimen name="navigation_handle_horizontal_margin">30dp</dimen>
-    <dimen name="navigation_home_handle_width">180dp</dimen>
-    <dimen name="navigation_assistant_handle_width">36dp</dimen>
+    <dimen name="navigation_home_handle_width">280dp</dimen>
 
     <!-- Height of notification icons in the status bar -->
     <dimen name="status_bar_icon_size">@*android:dimen/status_bar_icon_size</dimen>
@@ -336,6 +335,8 @@
 
     <dimen name="volume_dialog_ringer_size">64dp</dimen>
 
+    <dimen name="volume_dialog_caption_size">64dp</dimen>
+
     <dimen name="volume_dialog_tap_target_size">48dp</dimen>
 
     <dimen name="volume_dialog_spacer">4dp</dimen>
@@ -865,10 +866,12 @@
 
     <!-- Global actions power menu -->
     <dimen name="global_actions_panel_width">120dp</dimen>
-    <dimen name="global_actions_top_padding">120dp</dimen>
     <dimen name="global_actions_padding">12dp</dimen>
     <dimen name="global_actions_translate">9dp</dimen>
 
+    <!-- Distance from the top of screen in pixels, to position the power menu near the button. -->
+    <dimen name="global_actions_top_padding">330px</dimen>
+
     <!-- Global actions grid layout -->
     <dimen name="global_actions_grid_side_margin">4dp</dimen>
 
@@ -999,10 +1002,8 @@
     <dimen name="ongoing_appops_chip_margin">0dp</dimen>
     <!-- Height of the Ongoing App Ops chip -->
     <dimen name="ongoing_appops_chip_height">32dp</dimen>
-    <!-- Start and End padding for Ongoing App Ops chip -->
-    <dimen name="ongoing_appops_chip_text_padding">8dp</dimen>
     <!-- Padding between background of Ongoing App Ops chip and content -->
-    <dimen name="ongoing_appops_chip_bg_padding">0dp</dimen>
+    <dimen name="ongoing_appops_chip_bg_padding">8dp</dimen>
     <!-- Side padding between background of Ongoing App Ops chip and content -->
     <dimen name="ongoing_appops_chip_side_padding">8dp</dimen>
     <!-- Margin between icons of Ongoing App Ops chip when QQS-->
@@ -1013,10 +1014,7 @@
     <dimen name="ongoing_appops_chip_icon_size">@*android:dimen/status_bar_icon_size</dimen>
     <!-- Radius of Ongoing App Ops chip corners -->
     <dimen name="ongoing_appops_chip_bg_corner_radius">16dp</dimen>
-    <!-- Size of text of Ongoing App Ops chip -->
-    <dimen name="ongoing_appops_chip_text_size">12sp</dimen>
-    <!-- Margin between items in Ongoing App Ops chip -->
-    <dimen name="ongoing_appops_chip_items_margin">8dp</dimen>
+
 
     <!-- How much a bubble is elevated -->
     <dimen name="bubble_elevation">8dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 16222f7..da43391 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -266,6 +266,8 @@
     <string name="accessibility_scanning_face">Scanning face</string>
     <!-- Click action label for accessibility for the smart reply buttons (not shown on-screen).". [CHAR LIMIT=NONE] -->
     <string name="accessibility_send_smart_reply">Send</string>
+    <!-- Content description of the manage notification button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+    <string name="accessibility_manage_notification">Manage notifications</string>
     <!-- Click action label for accessibility for the unlock button. [CHAR LIMIT=NONE] -->
     <string name="unlock_label">unlock</string>
     <!-- Click action label for accessibility for the phone button. [CHAR LIMIT=NONE] -->
@@ -2318,26 +2320,12 @@
          app for debugging. Will not be seen by users. [CHAR LIMIT=20] -->
     <string name="heap_dump_tile_name">Dump SysUI Heap</string>
 
-    <!-- Text on chip for multiple apps using a single app op [CHAR LIMIT=12] -->
-    <plurals name="ongoing_privacy_chip_multiple_apps">
-        <item quantity="one"><xliff:g id="num_apps" example="1">%d</xliff:g> app</item>
-        <item quantity="few"><xliff:g id="num_apps" example="3">%d</xliff:g> apps</item>
-        <item quantity="other"><xliff:g id="num_apps" example="3">%d</xliff:g> apps</item>
-    </plurals>
-
     <!-- Content description for ongoing privacy chip. Use with a single app [CHAR LIMIT=NONE]-->
     <string name="ongoing_privacy_chip_content_single_app"><xliff:g id="app" example="Example App">%1$s</xliff:g> is using your <xliff:g id="types_list" example="camera, location">%2$s</xliff:g>.</string>
 
     <!-- Content description for ongoing privacy chip. Use with multiple apps [CHAR LIMIT=NONE]-->
     <string name="ongoing_privacy_chip_content_multiple_apps">Applications are using your <xliff:g id="types_list" example="camera, location">%s</xliff:g>.</string>
 
-    <!-- Content description for ongoing privacy chip. Use with multiple apps using same app op[CHAR LIMIT=NONE]-->
-    <plurals name="ongoing_privacy_chip_content_multiple_apps_single_op">
-        <item quantity="one"><xliff:g id="num_apps" example="1">%1$d</xliff:g> application is using your <xliff:g id="type" example="camera">%2$s</xliff:g>.</item>
-        <item quantity="few"><xliff:g id="num_apps" example="3">%1$d</xliff:g> applications are using your <xliff:g id="type" example="camera">%2$s</xliff:g>.</item>
-        <item quantity="other"><xliff:g id="num_apps" example="3">%1$d</xliff:g> applications are using your <xliff:g id="type" example="camera">%2$s</xliff:g>.</item>
-    </plurals>
-
     <!-- Action for accepting the Ongoing privacy dialog [CHAR LIMIT=10]-->
     <string name="ongoing_privacy_dialog_ok">Got it</string>
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 97160b6..63f8cd6 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -105,11 +105,6 @@
  * Watches for updates that may be interesting to the keyguard, and provides
  * the up to date information as well as a registration for callbacks that care
  * to be updated.
- *
- * Note: under time crunch, this has been extended to include some stuff that
- * doesn't really belong here.  see {@link #handleBatteryUpdate} where it shutdowns
- * the device, and {@link #getFailedUnlockAttempts()}, {@link #reportFailedAttempt()}
- * and {@link #clearFailedUnlockAttempts()}.  Maybe we should rename this 'KeyguardContext'...
  */
 public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
 
@@ -1568,6 +1563,15 @@
         updateFaceListeningState();
     }
 
+    /**
+     * Requests face authentication if we're on a state where it's allowed.
+     * This will re-trigger auth in case it fails.
+     */
+    public void requestFaceAuth() {
+        if (DEBUG) Log.d(TAG, "requestFaceAuth()");
+        updateFaceListeningState();
+    }
+
     private void updateFaceListeningState() {
         // If this message exists, we should not authenticate again until this message is
         // consumed by the handler
@@ -1629,7 +1633,7 @@
             return;
         }
         if (DEBUG) Log.v(TAG, "startListeningForFingerprint()");
-        int userId = ActivityManager.getCurrentUser();
+        int userId = getCurrentUser();
         if (isUnlockWithFingerprintPossible(userId)) {
             if (mFingerprintCancelSignal != null) {
                 mFingerprintCancelSignal.cancel();
@@ -1647,7 +1651,7 @@
             return;
         }
         if (DEBUG) Log.v(TAG, "startListeningForFace()");
-        int userId = ActivityManager.getCurrentUser();
+        int userId = getCurrentUser();
         if (isUnlockWithFacePossible(userId)) {
             if (mFaceCancelSignal != null) {
                 mFaceCancelSignal.cancel();
diff --git a/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java b/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java
index 5086c99..72ab02c 100644
--- a/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java
@@ -215,7 +215,7 @@
         } else {
             rotateLeft();
         }
-        if (mSeparated) {
+        if (mAdapter.hasSeparatedItems()) {
             if (from == ROTATION_SEASCAPE || to == ROTATION_SEASCAPE) {
                 // Separated view has top margin, so seascape separated view need special rotation,
                 // not a full left or right rotation.
@@ -257,10 +257,10 @@
 
     @Override
     public void onUpdateList() {
-        removeAllItems();
+        super.onUpdateList();
         ArrayList<GlobalActionsDialog.Action> separatedActions =
-                mAdapter.getSeparatedItems(mSeparated);
-        ArrayList<GlobalActionsDialog.Action> listActions = mAdapter.getListItems(mSeparated);
+                mAdapter.getSeparatedItems();
+        ArrayList<GlobalActionsDialog.Action> listActions = mAdapter.getListItems();
 
         for (int i = 0; i < mAdapter.getCount(); i++) {
             Object action = mAdapter.getItem(i);
@@ -461,8 +461,9 @@
         if (mList == null) return;
         // If got separated button, setRotatedBackground to false,
         // all items won't get white background.
-        mListBackground.setRotatedBackground(mSeparated);
-        mSeparatedViewBackground.setRotatedBackground(mSeparated);
+        boolean separated = mAdapter.hasSeparatedItems();
+        mListBackground.setRotatedBackground(separated);
+        mSeparatedViewBackground.setRotatedBackground(separated);
         if (mDivision != null && mDivision.getVisibility() == VISIBLE) {
             int index = mRotatedBackground ? 0 : 1;
             mDivision.getLocationOnScreen(mTmp2);
@@ -508,26 +509,27 @@
         int screenHeight;
         int totalHeight;
         int targetGravity;
+        boolean separated = mAdapter.hasSeparatedItems();
         MarginLayoutParams params = (MarginLayoutParams) mSeparatedView.getLayoutParams();
         switch (RotationUtils.getRotation(getContext())) {
             case RotationUtils.ROTATION_LANDSCAPE:
                 defaultTopPadding = getPaddingLeft();
                 viewsTotalHeight = mList.getMeasuredWidth() + mSeparatedView.getMeasuredWidth();
-                separatedViewTopMargin = mSeparated ? params.leftMargin : 0;
+                separatedViewTopMargin = separated ? params.leftMargin : 0;
                 screenHeight = getMeasuredWidth();
                 targetGravity = Gravity.CENTER_HORIZONTAL|Gravity.TOP;
                 break;
             case RotationUtils.ROTATION_SEASCAPE:
                 defaultTopPadding = getPaddingRight();
                 viewsTotalHeight = mList.getMeasuredWidth() + mSeparatedView.getMeasuredWidth();
-                separatedViewTopMargin = mSeparated ? params.leftMargin : 0;
+                separatedViewTopMargin = separated ? params.leftMargin : 0;
                 screenHeight = getMeasuredWidth();
                 targetGravity = Gravity.CENTER_HORIZONTAL|Gravity.BOTTOM;
                 break;
             default: // Portrait
                 defaultTopPadding = getPaddingTop();
                 viewsTotalHeight = mList.getMeasuredHeight() + mSeparatedView.getMeasuredHeight();
-                separatedViewTopMargin = mSeparated ? params.topMargin : 0;
+                separatedViewTopMargin = separated ? params.topMargin : 0;
                 screenHeight = getMeasuredHeight();
                 targetGravity = Gravity.CENTER_VERTICAL|Gravity.RIGHT;
                 break;
diff --git a/packages/SystemUI/src/com/android/systemui/MultiListLayout.java b/packages/SystemUI/src/com/android/systemui/MultiListLayout.java
index 2bc4720..d063a0f 100644
--- a/packages/SystemUI/src/com/android/systemui/MultiListLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/MultiListLayout.java
@@ -33,8 +33,8 @@
  */
 public abstract class MultiListLayout extends LinearLayout {
     protected boolean mHasOutsideTouch;
-    protected boolean mSeparated;
     protected MultiListAdapter mAdapter;
+    protected boolean mSnapToEdge;
 
     protected int mRotation;
     protected RotationListener mRotationListener;
@@ -70,12 +70,10 @@
     }
 
     /**
-     * Sets whether the separated view should be shown, and handles updating visibility on
-     * that view.
+     * Sets whether the GlobalActions view should snap to the edge of the screen.
      */
-    public void setSeparated(boolean separated) {
-        mSeparated = separated;
-        setSeparatedViewVisibility(separated);
+    public void setSnapToEdge(boolean snap) {
+        mSnapToEdge = snap;
     }
 
     /**
@@ -123,7 +121,9 @@
         onUpdateList();
     }
 
-    protected abstract void onUpdateList();
+    protected void onUpdateList() {
+        setSeparatedViewVisibility(mAdapter.hasSeparatedItems());
+    }
 
     public void setRotationListener(RotationListener listener) {
         mRotationListener = listener;
@@ -156,13 +156,13 @@
          * Creates an ArrayList of items which should be rendered in the separated view.
          * @param useSeparatedView is true if the separated view will be used, false otherwise.
          */
-        public abstract ArrayList getSeparatedItems(boolean useSeparatedView);
+        public abstract ArrayList getSeparatedItems();
 
         /**
          * Creates an ArrayList of items which should be rendered in the list view.
          * @param useSeparatedView True if the separated view will be used, false otherwise.
          */
-        public abstract ArrayList getListItems(boolean useSeparatedView);
+        public abstract ArrayList getListItems();
 
         /**
          * Callback to run when an individual item is clicked or pressed.
@@ -176,5 +176,13 @@
          * @return True if the long-click was handled, false otherwise.
          */
         public abstract boolean onLongClickItem(int position);
+
+        /**
+         * Determines whether the mAdapter contains any separated items, used to determine whether
+         * or not to hide the separated list from view.
+         */
+        public boolean hasSeparatedItems() {
+            return getSeparatedItems().size() > 0;
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index 888e3fe..f3a701e 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -426,7 +426,9 @@
 
         if (reason == BubbleController.DISMISS_USER_GESTURE) {
             Notification.BubbleMetadata bubbleMetadata = bubble.entry.getBubbleMetadata();
-            PendingIntent deleteIntent = bubbleMetadata.getDeleteIntent();
+            PendingIntent deleteIntent = bubbleMetadata != null
+                    ? bubbleMetadata.getDeleteIntent()
+                    : null;
             if (deleteIntent != null) {
                 try {
                     deleteIntent.send();
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java b/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java
index 06dbdbf..a4592d5 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java
@@ -121,11 +121,17 @@
                     if (dozeState == State.DOZE
                             && mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT)) {
                         mMachine.requestState(State.DOZE_AOD);
-                        break;
                     }
-                    // continue below
+                    else {
+                        requestPulseOutNow(dozeState);
+                    }
+                    break;
                 case DockManager.STATE_DOCKED_HIDE:
-                    requestPulseOutNow(dozeState);
+                    if (dozeState == State.DOZE_AOD) {
+                        mMachine.requestState(State.DOZE);
+                    } else {
+                        requestPulseOutNow(dozeState);
+                    }
                     break;
                 default:
                     // no-op
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index b2f707f..bc3f48d 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -28,6 +28,7 @@
 import android.hardware.SensorEventListener;
 import android.hardware.SensorManager;
 import android.hardware.display.AmbientDisplayConfiguration;
+import android.metrics.LogMaker;
 import android.os.Handler;
 import android.os.SystemClock;
 import android.os.UserHandle;
@@ -35,7 +36,10 @@
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.util.Preconditions;
+import com.android.systemui.Dependency;
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.util.Assert;
@@ -79,6 +83,7 @@
     private long mNotificationPulseTime;
     private boolean mPulsePending;
 
+    private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
 
     public DozeTriggers(Context context, DozeMachine machine, DozeHost dozeHost,
             AlarmManager alarmManager, AmbientDisplayConfiguration config,
@@ -159,8 +164,15 @@
                     if (screenX != -1 && screenY != -1) {
                         mDozeHost.onSlpiTap(screenX, screenY);
                     }
+                    // Logs screen wake up reason of either single or double tap.
+                    mMetricsLogger.write(new LogMaker(MetricsEvent.DOZING)
+                            .setType(MetricsEvent.TYPE_UPDATE).setSubtype(pulseReason));
                     mMachine.wakeUp();
                 } else if (isPickup) {
+                    // Logs screen wake up reason of lift.
+                    mMetricsLogger.write(new LogMaker(MetricsEvent.DOZING)
+                            .setType(MetricsEvent.TYPE_UPDATE)
+                            .setSubtype(DozeLog.REASON_SENSOR_PICKUP));
                     mMachine.wakeUp();
                 } else {
                     mDozeHost.extendPulse();
@@ -298,6 +310,10 @@
                 continuePulseRequest(reason);
             }
         }, !mDozeParameters.getProxCheckBeforePulse() || performedProxCheck, reason);
+
+        // Logs request pulse reason on AOD screen.
+        mMetricsLogger.write(new LogMaker(MetricsEvent.DOZING)
+                .setType(MetricsEvent.TYPE_UPDATE).setSubtype(reason));
     }
 
     private boolean canPulse() {
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index b07f909..ce58895 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -38,7 +38,6 @@
 import android.graphics.drawable.Drawable;
 import android.media.AudioManager;
 import android.net.ConnectivityManager;
-import android.os.Build;
 import android.os.Handler;
 import android.os.Message;
 import android.os.RemoteException;
@@ -156,7 +155,6 @@
     private boolean mHasVibrator;
     private boolean mHasLogoutButton;
     private boolean mHasLockdownButton;
-    private boolean mUseSeparatedList;
     private final boolean mShowSilentToggle;
     private final EmergencyAffordanceManager mEmergencyAffordanceManager;
     private final ScreenshotHelper mScreenshotHelper;
@@ -334,7 +332,6 @@
         ArraySet<String> addedKeys = new ArraySet<String>();
         mHasLogoutButton = false;
         mHasLockdownButton = false;
-        mUseSeparatedList = true;
         for (int i = 0; i < defaultActions.length; i++) {
             String actionKey = defaultActions[i];
             if (addedKeys.contains(actionKey)) {
@@ -382,7 +379,7 @@
                     mHasLogoutButton = true;
                 }
             } else if (GLOBAL_ACTION_KEY_EMERGENCY.equals(actionKey)) {
-                if (mUseSeparatedList
+                if (shouldUseSeparatedView()
                         && !mEmergencyAffordanceManager.needsEmergencyAffordance()) {
                     mItems.add(new EmergencyDialerAction());
                 }
@@ -407,8 +404,7 @@
                             }
                         })
                         : null;
-        ActionsDialog dialog = new ActionsDialog(mContext, mAdapter, mUseSeparatedList,
-                panelViewController);
+        ActionsDialog dialog = new ActionsDialog(mContext, mAdapter, panelViewController);
         dialog.setCanceledOnTouchOutside(false); // Handled by the custom class.
         dialog.setKeyguardShowing(mKeyguardShowing);
 
@@ -636,14 +632,6 @@
         public boolean showBeforeProvisioning() {
             return false;
         }
-
-        @Override
-        public String getStatus() {
-            return mContext.getString(
-                    R.string.bugreport_status,
-                    Build.VERSION.RELEASE,
-                    Build.ID);
-        }
     }
 
     private final class LogoutAction extends SinglePressAction {
@@ -702,7 +690,7 @@
 
     private Action getEmergencyAction() {
         Drawable emergencyIcon = mContext.getDrawable(R.drawable.emergency_icon);
-        if (!mUseSeparatedList) {
+        if (!shouldUseSeparatedView()) {
             // use un-colored legacy treatment
             emergencyIcon.setTintList(null);
         }
@@ -931,9 +919,9 @@
         }
 
         @Override
-        public ArrayList<Action> getSeparatedItems(boolean shouldUseSeparatedView) {
+        public ArrayList<Action> getSeparatedItems() {
             ArrayList<Action> separatedActions = new ArrayList<Action>();
-            if (!shouldUseSeparatedView) {
+            if (!shouldUseSeparatedView()) {
                 return separatedActions;
             }
             for (int i = 0; i < mItems.size(); i++) {
@@ -946,8 +934,8 @@
         }
 
         @Override
-        public ArrayList<Action> getListItems(boolean shouldUseSeparatedView) {
-            if (!shouldUseSeparatedView) {
+        public ArrayList<Action> getListItems() {
+            if (!shouldUseSeparatedView()) {
                 return new ArrayList<Action>(mItems);
             }
             ArrayList<Action> listActions = new ArrayList<Action>();
@@ -1495,17 +1483,15 @@
         private final ColorExtractor mColorExtractor;
         private final GlobalActionsPanelPlugin.PanelViewController mPanelController;
         private boolean mKeyguardShowing;
-        private boolean mUseSeparatedList;
         private boolean mShowing;
         private final float mScrimAlpha;
 
-        ActionsDialog(Context context, MyAdapter adapter, boolean separated,
+        ActionsDialog(Context context, MyAdapter adapter,
                 GlobalActionsPanelPlugin.PanelViewController plugin) {
             super(context, com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActions);
             mContext = context;
             mAdapter = adapter;
             mColorExtractor = Dependency.get(SysuiColorExtractor.class);
-            mUseSeparatedList = separated;
 
             // Window initialization
             Window window = getWindow();
@@ -1569,7 +1555,6 @@
             mGlobalActionsLayout = (MultiListLayout)
                     findViewById(com.android.systemui.R.id.global_actions_view);
             mGlobalActionsLayout.setOutsideTouchListener(view -> dismiss());
-            mGlobalActionsLayout.setSeparated(mUseSeparatedList);
             mGlobalActionsLayout.setListViewAccessibilityDelegate(new View.AccessibilityDelegate() {
                 @Override
                 public boolean dispatchPopulateAccessibilityEvent(
@@ -1581,11 +1566,8 @@
             });
             mGlobalActionsLayout.setRotationListener(this::onRotate);
             mGlobalActionsLayout.setAdapter(mAdapter);
-        }
-
-        private boolean isPanelEnabled(Context context) {
-            return FeatureFlagUtils.isEnabled(
-                    context, FeatureFlagUtils.GLOBAL_ACTIONS_PANEL_ENABLED);
+            mGlobalActionsLayout.setSnapToEdge(isPanelEnabled(mContext)
+                    && mPanelController != null);
         }
 
         private int getGlobalActionsLayoutId(Context context) {
@@ -1726,9 +1708,24 @@
     }
 
     /**
-     * Determines whether or not the Global Actions Dialog should use the newer grid-style layout.
+     * Determines whether or not the Global Actions menu should use the newer grid-style layout.
      */
-    public static boolean isGridEnabled(Context context) {
+    private static boolean isGridEnabled(Context context) {
         return FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.GLOBAL_ACTIONS_GRID_ENABLED);
     }
+
+    /**
+     * Determines whether or not the Global Actions Panel should appear when the power button
+     * is held.
+     */
+    private static boolean isPanelEnabled(Context context) {
+        return FeatureFlagUtils.isEnabled(
+                context, FeatureFlagUtils.GLOBAL_ACTIONS_PANEL_ENABLED);    }
+
+    /**
+     * Determines whether the Global Actions menu should use a separated view for emergency actions.
+     */
+    private static boolean shouldUseSeparatedView() {
+        return true;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java
index cda7669..058ea60 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.text.TextUtils;
 import android.util.AttributeSet;
+import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
 
@@ -71,10 +72,10 @@
 
     @Override
     public void onUpdateList() {
-        removeAllItems();
+        super.onUpdateList();
         ArrayList<GlobalActionsDialog.Action> separatedActions =
-                mAdapter.getSeparatedItems(mSeparated);
-        ArrayList<GlobalActionsDialog.Action> listActions = mAdapter.getListItems(mSeparated);
+                mAdapter.getSeparatedItems();
+        ArrayList<GlobalActionsDialog.Action> listActions = mAdapter.getListItems();
         setExpectedListItemCount(listActions.size());
         int rotation = RotationUtils.getRotation(mContext);
 
@@ -108,6 +109,7 @@
                 parent.addView(v);
             }
         }
+        updateSnapPosition();
     }
 
     @Override
@@ -115,6 +117,19 @@
         return findViewById(com.android.systemui.R.id.separated_button);
     }
 
+    private void updateSnapPosition() {
+        if (mSnapToEdge) {
+            setPadding(0, 0, 0, 0);
+            if (mRotation == RotationUtils.ROTATION_LANDSCAPE) {
+                setGravity(Gravity.RIGHT);
+            } else if (mRotation == RotationUtils.ROTATION_SEASCAPE) {
+                setGravity(Gravity.LEFT);
+            } else {
+                setGravity(Gravity.BOTTOM);
+            }
+        }
+    }
+
     @Override
     protected ListGridLayout getListView() {
         return findViewById(android.R.id.list);
@@ -148,7 +163,7 @@
     }
 
     /**
-     * Not used in this implementation of the Global Actions Menu, but necessary for some others.
+     * Not ued in this implementation of the Global Actions Menu, but necessary for some others.
      */
     @Override
     public void setDivisionView(View v) {
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/ListGridLayout.java b/packages/SystemUI/src/com/android/systemui/globalactions/ListGridLayout.java
index 6c106df..048f801 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/ListGridLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/ListGridLayout.java
@@ -114,7 +114,7 @@
         if (mExpectedCount == 3) {
             return 1;
         }
-        return (int) Math.ceil(Math.sqrt(mExpectedCount));
+        return (int) Math.round(Math.sqrt(mExpectedCount));
     }
 
     private int getColumnCount() {
@@ -122,6 +122,6 @@
         if (mExpectedCount == 3) {
             return 3;
         }
-        return (int) Math.round(Math.sqrt(mExpectedCount));
+        return (int) Math.ceil(Math.sqrt(mExpectedCount));
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
index 15dc43f..23742c0 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
@@ -17,9 +17,9 @@
 import android.content.Context
 import android.util.AttributeSet
 import android.view.ViewGroup
+import android.widget.FrameLayout
 import android.widget.ImageView
 import android.widget.LinearLayout
-import android.widget.TextView
 import com.android.systemui.Dependency
 import com.android.systemui.R
 import com.android.systemui.statusbar.policy.KeyguardMonitor
@@ -42,9 +42,8 @@
     private val sidePadding =
             context.resources.getDimensionPixelSize(R.dimen.ongoing_appops_chip_side_padding)
     private val backgroundDrawable = context.getDrawable(R.drawable.privacy_chip_bg)
-    private lateinit var text: TextView
     private lateinit var iconsContainer: LinearLayout
-    private lateinit var back: LinearLayout
+    private lateinit var back: FrameLayout
     var expanded = false
         set(value) {
             if (value != field) {
@@ -66,14 +65,14 @@
         super.onFinishInflate()
 
         back = findViewById(R.id.background)
-        text = findViewById(R.id.text_container)
         iconsContainer = findViewById(R.id.icons_container)
     }
 
     // Should only be called if the builder icons or app changed
     private fun updateView() {
         back.background = if (expanded) backgroundDrawable else null
-        back.setPaddingRelative(0, 0, if (expanded) sidePadding else 0, 0)
+        val padding = if (expanded) sidePadding else 0
+        back.setPaddingRelative(padding, 0, padding, 0)
         fun setIcons(dialogBuilder: PrivacyDialogBuilder, iconsContainer: ViewGroup) {
             iconsContainer.removeAllViews()
             dialogBuilder.generateIcons().forEachIndexed { i, it ->
@@ -95,44 +94,17 @@
         if (!privacyList.isEmpty()) {
             generateContentDescription()
             setIcons(builder, iconsContainer)
-            setApplicationText()
         } else {
-            text.visibility = GONE
             iconsContainer.removeAllViews()
         }
         requestLayout()
     }
 
-    private fun setApplicationText() {
-        text.visibility = if (builder.types.size == 1 && expanded) VISIBLE else GONE
-        if (builder.types.size == 1 && expanded) {
-            if (builder.app != null && !amISecure()) {
-                text.setText(builder.app?.applicationName)
-            } else {
-                text.text = context.resources.getQuantityString(
-                        R.plurals.ongoing_privacy_chip_multiple_apps,
-                        builder.appsAndTypes.size, builder.appsAndTypes.size)
-            }
-        }
-    }
-
     private fun amISecure() = keyguardMonitor.isShowing && keyguardMonitor.isSecure
 
     private fun generateContentDescription() {
         val typesText = builder.joinTypes()
-        if (builder.types.size > 1) {
-            contentDescription = context.getString(
-                    R.string.ongoing_privacy_chip_content_multiple_apps, typesText)
-        } else {
-            if (builder.app != null && !amISecure()) {
-                contentDescription =
-                        context.getString(R.string.ongoing_privacy_chip_content_single_app,
-                                builder.app?.applicationName, typesText)
-            } else {
-                contentDescription = context.resources.getQuantityString(
-                        R.plurals.ongoing_privacy_chip_content_multiple_apps_single_op,
-                        builder.appsAndTypes.size, builder.appsAndTypes.size, typesText)
-            }
-        }
+        contentDescription = context.getString(
+                R.string.ongoing_privacy_chip_content_multiple_apps, typesText)
     }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt
index bbea6b2..59b3c34 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt
@@ -22,7 +22,6 @@
 
     val appsAndTypes: List<Pair<PrivacyApplication, List<PrivacyType>>>
     val types: List<PrivacyType>
-    val app: PrivacyApplication?
     private val separator = context.getString(R.string.ongoing_privacy_dialog_separator)
     private val lastSeparator = context.getString(R.string.ongoing_privacy_dialog_last_separator)
 
@@ -32,8 +31,6 @@
                 .sortedWith(compareBy({ -it.second.size }, // Sort by number of AppOps
                         { it.second.min() })) // Sort by "smallest" AppOpp (Location is largest)
         types = itemsList.map { it.privacyType }.distinct().sorted()
-        val singleApp = appsAndTypes.size == 1
-        app = if (singleApp) appsAndTypes[0].first else null
     }
 
     fun generateIconsForApp(types: List<PrivacyType>): List<Drawable> {
@@ -58,11 +55,7 @@
     }
 
     fun getDialogTitle(): String {
-        if (app != null) {
-            return context.getString(R.string.ongoing_privacy_dialog_single_app_title, joinTypes())
-        } else {
-            return context.getString(R.string.ongoing_privacy_dialog_multiple_apps_title,
+        return context.getString(R.string.ongoing_privacy_dialog_multiple_apps_title,
                     joinTypes())
-        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
index 305fbf2..b135f7b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
@@ -159,8 +159,8 @@
             mBindTryCount++;
             try {
                 mIsBound = mContext.bindServiceAsUser(mIntent, this,
-                        Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE,
-                        mUser);
+                        Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE
+                        | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS, mUser);
             } catch (SecurityException e) {
                 Log.e(TAG, "Failed to bind to service", e);
                 mIsBound = false;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 4da8ca2..9219594 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -107,6 +107,7 @@
     private IOverviewProxy mOverviewProxy;
     private int mConnectionBackoffAttempts;
     private @InteractionType int mInteractionFlags;
+    private boolean mBound;
     private boolean mIsEnabled;
     private int mCurrentBoundedUserId = -1;
     private float mBackButtonAlpha;
@@ -510,16 +511,15 @@
         mHandler.removeCallbacks(mConnectionRunnable);
         Intent launcherServiceIntent = new Intent(ACTION_QUICKSTEP)
                 .setPackage(mRecentsComponentName.getPackageName());
-        boolean bound = false;
         try {
-            bound = mContext.bindServiceAsUser(launcherServiceIntent,
+            mBound = mContext.bindServiceAsUser(launcherServiceIntent,
                     mOverviewServiceConnection,
                     Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE,
                     UserHandle.of(mDeviceProvisionedController.getCurrentUser()));
         } catch (SecurityException e) {
             Log.e(TAG_OPS, "Unable to bind because of security error", e);
         }
-        if (bound) {
+        if (mBound) {
             // Ensure that connection has been established even if it thinks it is bound
             mHandler.postDelayed(mDeferredConnectionCallback, DEFERRED_CALLBACK_MILLIS);
         } else {
@@ -573,9 +573,14 @@
     }
 
     private void disconnectFromLauncherService() {
+        if (mBound) {
+            // Always unbind the service (ie. if called through onNullBinding or onBindingDied)
+            mContext.unbindService(mOverviewServiceConnection);
+            mBound = false;
+        }
+
         if (mOverviewProxy != null) {
             mOverviewProxy.asBinder().unlinkToDeath(mOverviewServiceDeathRcpt, 0);
-            mContext.unbindService(mOverviewServiceConnection);
             mOverviewProxy = null;
             notifyBackButtonAlphaChanged(1f, false /* animate */);
             notifyConnectionChanged();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index dfbb32e..8faeb15 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -664,6 +664,9 @@
         public void onBiometricRunningStateChanged(boolean running,
                 BiometricSourceType biometricSourceType) {
             if (running) {
+                // Let's hide any previous messages when authentication starts, otherwise
+                // multiple auth attempts would overlap.
+                hideTransientIndication();
                 mMessageToShowOnScreenOn = null;
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
index 311bf7a..c2da517 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
@@ -79,6 +79,8 @@
         mDismissButton.setContentDescription(
                 mContext.getString(R.string.accessibility_clear_all));
         mManageButton.setText(R.string.manage_notifications_text);
+        mManageButton.setContentDescription(
+                mContext.getString(R.string.accessibility_manage_notification));
     }
 
     public boolean isButtonVisible() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index fea01ef..54bdaa2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -122,11 +122,22 @@
     }
 
     /**
-     * Sends an intent to open the app settings for a particular package and optional
+     * Sends an intent to open the notification settings for a particular package and optional
      * channel.
      */
     private void startAppNotificationSettingsActivity(String packageName, final int appUid,
             final NotificationChannel channel, ExpandableNotificationRow row) {
+        final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
+        intent.putExtra(Settings.EXTRA_APP_PACKAGE, packageName);
+        intent.putExtra(Settings.EXTRA_APP_UID, appUid);
+        if (channel != null) {
+            intent.putExtra(EXTRA_FRAGMENT_ARG_KEY, channel.getId());
+        }
+        mNotificationActivityStarter.startNotificationGutsIntent(intent, appUid, row);
+    }
+
+    private void startAppDetailsSettingsActivity(String packageName, final int appUid,
+            final NotificationChannel channel, ExpandableNotificationRow row) {
         final Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
         intent.setData(Uri.fromParts("package", packageName, null));
         intent.putExtra(Settings.EXTRA_APP_PACKAGE, packageName);
@@ -141,7 +152,7 @@
             ExpandableNotificationRow row) {
         if (ops.contains(OP_SYSTEM_ALERT_WINDOW)) {
             if (ops.contains(OP_CAMERA) || ops.contains(OP_RECORD_AUDIO)) {
-                startAppNotificationSettingsActivity(pkg, uid, null, row);
+                startAppDetailsSettingsActivity(pkg, uid, null, row);
             } else {
                 Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
                 intent.setData(Uri.fromParts("package", pkg, null));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
index e953ad5..c8ce392 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -483,7 +483,9 @@
                 R.color.light_mode_icon_color_single_tone);
         float intensity = textColor == Color.WHITE ? 0 : 1;
         mCarrierLabel.setTextColor(iconColor);
-        mIconManager.setTint(iconColor);
+        if (mIconManager != null) {
+            mIconManager.setTint(iconColor);
+        }
 
         applyDarkness(R.id.battery, mEmptyRect, intensity * (1f - mDarkAmount), iconColor);
         applyDarkness(R.id.clock, mEmptyRect, intensity, iconColor);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarTintController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarTintController.java
index 409d60f..2d54970 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarTintController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarTintController.java
@@ -16,203 +16,159 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static android.view.Display.DEFAULT_DISPLAY;
+
 import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
-import android.graphics.Color;
 import android.graphics.Rect;
 import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
 import android.provider.Settings;
-import android.util.DisplayMetrics;
-import android.view.SurfaceControl;
+import android.view.CompositionSamplingListener;
 import android.view.View;
 
-import com.android.systemui.R;
+import java.io.PrintWriter;
 
-public class NavBarTintController {
+/**
+ * Updates the nav bar tint based on the color of the content behind the nav bar.
+ */
+public class NavBarTintController implements View.OnAttachStateChangeListener,
+        View.OnLayoutChangeListener {
+
     public static final int MIN_COLOR_ADAPT_TRANSITION_TIME = 400;
     public static final int DEFAULT_COLOR_ADAPT_TRANSITION_TIME = 1700;
 
-    private final HandlerThread mColorAdaptHandlerThread = new HandlerThread("ColorExtractThread");
-    private Handler mColorAdaptionHandler;
-
-    // Poll time for each iteration to color sample
-    private static final int COLOR_ADAPTION_TIMEOUT = 300;
-
     // Passing the threshold of this luminance value will make the button black otherwise white
     private static final float LUMINANCE_THRESHOLD = 0.3f;
 
-    // The margin from the bounds of the view to color sample around
-    private static final int COLOR_SAMPLE_MARGIN = 10;
-
-    private boolean mRunning;
-
+    private final Handler mHandler = new Handler();
     private final NavigationBarView mNavigationBarView;
     private final LightBarTransitionsController mLightBarController;
-    private final Handler mMainHandler = new Handler(Looper.getMainLooper());
-    private final int mBarRadius;
-    private final int mBarBottom;
+
+    private final CompositionSamplingListener mSamplingListener;
+    private final Runnable mUpdateSamplingListener = this::updateSamplingListener;
+    private final Rect mSamplingBounds = new Rect();
+    private boolean mSamplingEnabled = false;
+    private boolean mSamplingListenerRegistered = false;
+
+    private float mLastMediaLuma;
+    private boolean mUpdateOnNextDraw;
 
     public NavBarTintController(NavigationBarView navigationBarView,
             LightBarTransitionsController lightBarController) {
+        mSamplingListener = new CompositionSamplingListener(
+                navigationBarView.getContext().getMainExecutor()) {
+            @Override
+            public void onSampleCollected(float medianLuma) {
+                updateTint(medianLuma);
+            }
+        };
         mNavigationBarView = navigationBarView;
+        mNavigationBarView.addOnAttachStateChangeListener(this);
+        mNavigationBarView.addOnLayoutChangeListener(this);
         mLightBarController = lightBarController;
-
-        final Resources res = navigationBarView.getResources();
-        mBarRadius = res.getDimensionPixelSize(R.dimen.navigation_handle_radius);
-        mBarBottom = res.getDimensionPixelSize(R.dimen.navigation_handle_bottom);
     }
 
-    public void start() {
+    void onDraw() {
+        if (mUpdateOnNextDraw) {
+            mUpdateOnNextDraw = false;
+            requestUpdateSamplingListener();
+        }
+    }
+
+    void start() {
         if (!isEnabled(mNavigationBarView.getContext())) {
             return;
         }
-        if (mColorAdaptionHandler == null) {
-            mColorAdaptHandlerThread.start();
-            mColorAdaptionHandler = new Handler(mColorAdaptHandlerThread.getLooper());
-        }
-        mColorAdaptionHandler.removeCallbacksAndMessages(null);
-        mColorAdaptionHandler.post(this::updateTint);
-        mRunning = true;
+        mSamplingEnabled = true;
+        // Defer calling updateSamplingListener since we may have just reinflated prior to this
+        requestUpdateSamplingListener();
     }
 
-    public void end() {
-        if (mColorAdaptionHandler != null) {
-            mColorAdaptionHandler.removeCallbacksAndMessages(null);
-        }
-        mRunning = false;
+    void stop() {
+        mSamplingEnabled = false;
+        requestUpdateSamplingListener();
     }
 
-    public void stop() {
-        end();
-        if (mColorAdaptionHandler != null) {
-            mColorAdaptHandlerThread.quitSafely();
-        }
+    @Override
+    public void onViewAttachedToWindow(View view) {
+        requestUpdateSamplingListener();
     }
 
-    private void updateTint() {
-        int[] navPos = new int[2];
-        int[] butPos = new int[2];
+    @Override
+    public void onViewDetachedFromWindow(View view) {
+        // Defer calling updateSamplingListener the attach info has not yet been reset
+        requestUpdateSamplingListener();
+    }
+
+    @Override
+    public void onLayoutChange(View v, int left, int top, int right, int bottom,
+            int oldLeft, int oldTop, int oldRight, int oldBottom) {
+        mSamplingBounds.setEmpty();
+        // TODO: Extend this to 2/3 button layout as well
         View view = mNavigationBarView.getHomeHandle().getCurrentView();
-        if (view == null) {
-            return;
+        if (view != null) {
+            int[] pos = new int[2];
+            view.getLocationOnScreen(pos);
+            final Rect samplingBounds = new Rect(pos[0], pos[1],
+                    pos[0] + view.getWidth(), pos[1] + view.getHeight());
+            if (!samplingBounds.equals(mSamplingBounds)) {
+                mSamplingBounds.set(samplingBounds);
+                requestUpdateSamplingListener();
+            }
         }
-
-        // Determine the area of the icon within its view bounds
-        view.getLocationInSurface(butPos);
-        final int navWidth = view.getWidth();
-        final int navHeight = view.getHeight();
-        int viewBottom = butPos[1] + navHeight - mBarBottom;
-        final Rect viewIconRect = new Rect(butPos[0], viewBottom - mBarRadius * 2,
-                butPos[0] + navWidth, viewBottom);
-
-        if (mNavigationBarView.getCurrentView() == null || viewIconRect.isEmpty()) {
-            scheduleColorAdaption();
-            return;
-        }
-        mNavigationBarView.getCurrentView().getLocationOnScreen(navPos);
-        viewIconRect.offset(navPos[0], navPos[1]);
-
-        // Apply a margin area around the button region to sample the colors, crop from screenshot
-        final Rect cropRect = new Rect(viewIconRect);
-        cropRect.inset(-COLOR_SAMPLE_MARGIN, -COLOR_SAMPLE_MARGIN);
-        if (cropRect.isEmpty()) {
-            scheduleColorAdaption();
-            return;
-        }
-
-        // Determine the size of the home area
-        Rect homeArea = new Rect(COLOR_SAMPLE_MARGIN, COLOR_SAMPLE_MARGIN,
-                viewIconRect.width() + COLOR_SAMPLE_MARGIN,
-                viewIconRect.height() + COLOR_SAMPLE_MARGIN);
-
-        // Get the screenshot around the home button icon to determine the color
-        DisplayMetrics mDisplayMetrics = new DisplayMetrics();
-        mNavigationBarView.getContext().getDisplay().getRealMetrics(mDisplayMetrics);
-        final Bitmap hardBitmap = SurfaceControl
-                .screenshot(new Rect(), mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels,
-                        mNavigationBarView.getContext().getDisplay().getRotation());
-        if (hardBitmap != null && cropRect.bottom <= hardBitmap.getHeight()
-                && cropRect.left + cropRect.width() <= hardBitmap.getWidth()) {
-            final Bitmap cropBitmap = Bitmap.createBitmap(hardBitmap, cropRect.left, cropRect.top,
-                    cropRect.width(), cropRect.height());
-            final Bitmap softBitmap = cropBitmap.copy(Config.ARGB_8888, false);
-
-            // Get the luminance value to determine if the home button should be black or white
-            final int[] pixels = new int[softBitmap.getByteCount() / 4];
-            softBitmap.getPixels(pixels, 0, softBitmap.getWidth(), 0, 0, softBitmap.getWidth(),
-                    softBitmap.getHeight());
-            float r = 0, g = 0, blue = 0;
-
-            int width = cropRect.width();
-            int total = 0;
-            for (int i = 0; i < pixels.length; i += 4) {
-                int x = i % width;
-                int y = i / width;
-                if (!homeArea.contains(x, y)) {
-                    r += Color.red(pixels[i]);
-                    g += Color.green(pixels[i]);
-                    blue += Color.blue(pixels[i]);
-                    total++;
-                }
-            }
-
-            r /= total;
-            g /= total;
-            blue /= total;
-
-            r = Math.max(Math.min(r / 255f, 1), 0);
-            g = Math.max(Math.min(g / 255f, 1), 0);
-            blue = Math.max(Math.min(blue / 255f, 1), 0);
-
-            if (r <= 0.03928) {
-                r /= 12.92;
-            } else {
-                r = (float) Math.pow((r + 0.055) / 1.055, 2.4);
-            }
-            if (g <= 0.03928) {
-                g /= 12.92;
-            } else {
-                g = (float) Math.pow((g + 0.055) / 1.055, 2.4);
-            }
-            if (blue <= 0.03928) {
-                blue /= 12.92;
-            } else {
-                blue = (float) Math.pow((blue + 0.055) / 1.055, 2.4);
-            }
-
-            if (r * 0.2126 + g * 0.7152 + blue * 0.0722 > LUMINANCE_THRESHOLD) {
-                // Black
-                mMainHandler.post(
-                        () -> mLightBarController
-                                .setIconsDark(true /* dark */, true /* animate */));
-            } else {
-                // White
-                mMainHandler.post(
-                        () -> mLightBarController
-                                .setIconsDark(false /* dark */, true /* animate */));
-            }
-            cropBitmap.recycle();
-            hardBitmap.recycle();
-        }
-        scheduleColorAdaption();
     }
 
-    private void scheduleColorAdaption() {
-        mColorAdaptionHandler.removeCallbacksAndMessages(null);
-        if (!mRunning || !isEnabled(mNavigationBarView.getContext())) {
-            return;
+    private void requestUpdateSamplingListener() {
+        mHandler.removeCallbacks(mUpdateSamplingListener);
+        mHandler.post(mUpdateSamplingListener);
+    }
+
+    private void updateSamplingListener() {
+        if (mSamplingListenerRegistered) {
+            mSamplingListenerRegistered = false;
+            CompositionSamplingListener.unregister(mSamplingListener);
         }
-        mColorAdaptionHandler.postDelayed(this::updateTint, COLOR_ADAPTION_TIMEOUT);
+        if (mSamplingEnabled && !mSamplingBounds.isEmpty()
+                && mNavigationBarView.isAttachedToWindow()) {
+            if (!mNavigationBarView.getViewRootImpl().getSurfaceControl().isValid()) {
+                // The view may still be attached, but the surface backing the window can be
+                // destroyed, so wait until the next draw to update the listener again
+                mUpdateOnNextDraw = true;
+                return;
+            }
+            mSamplingListenerRegistered = true;
+            CompositionSamplingListener.register(mSamplingListener, DEFAULT_DISPLAY,
+                    mNavigationBarView.getViewRootImpl().getSurfaceControl().getHandle(),
+                    mSamplingBounds);
+        }
+    }
+
+    private void updateTint(float medianLuma) {
+        mLastMediaLuma = medianLuma;
+        if (medianLuma > LUMINANCE_THRESHOLD) {
+            // Black
+            mLightBarController.setIconsDark(true /* dark */, true /* animate */);
+        } else {
+            // White
+            mLightBarController.setIconsDark(false /* dark */, true /* animate */);
+        }
+    }
+
+    void dump(PrintWriter pw) {
+        pw.println("NavBarTintController:");
+        pw.println("  navBar isAttached: " + mNavigationBarView.isAttachedToWindow());
+        pw.println("  navBar isScValid: " + (mNavigationBarView.isAttachedToWindow()
+                ? mNavigationBarView.getViewRootImpl().getSurfaceControl().isValid()
+                : "false"));
+        pw.println("  mSamplingListenerRegistered: " + mSamplingListenerRegistered);
+        pw.println("  mSamplingBounds: " + mSamplingBounds);
+        pw.println("  mLastMediaLuma: " + mLastMediaLuma);
     }
 
     public static boolean isEnabled(Context context) {
-        return Settings.Global.getInt(context.getContentResolver(),
-                NavigationPrototypeController.NAV_COLOR_ADAPT_ENABLE_SETTING, 0) == 1
-            && Settings.Global.getInt(context.getContentResolver(),
-                NavigationPrototypeController.SHOW_HOME_HANDLE_SETTING, 0) == 1;
+        return context.getDisplayId() == DEFAULT_DISPLAY
+                && Settings.Global.getInt(context.getContentResolver(),
+                        NavigationPrototypeController.NAV_COLOR_ADAPT_ENABLE_SETTING, 0) == 1
+                && Settings.Global.getInt(context.getContentResolver(),
+                        NavigationPrototypeController.SHOW_HOME_HANDLE_SETTING, 0) == 1;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index b68c7c6..0978901 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -991,7 +991,7 @@
                     }
                 } else {
                     // Screen off disable it
-                    mNavigationBarView.getColorAdaptionController().end();
+                    mNavigationBarView.getColorAdaptionController().stop();
                 }
             }
             if (Intent.ACTION_USER_SWITCHED.equals(action)) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
index 2a38f77..faa2ab1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
@@ -63,7 +63,6 @@
     public static final String NAVSPACE = "space";
     public static final String CLIPBOARD = "clipboard";
     public static final String HOME_HANDLE = "home_handle";
-    public static final String ASSISTANT_HANDLE = "assistant_handle";
     public static final String KEY = "key";
     public static final String LEFT = "left";
     public static final String RIGHT = "right";
@@ -399,8 +398,6 @@
             v = inflater.inflate(R.layout.contextual, parent, false);
         } else if (HOME_HANDLE.equals(button)) {
             v = inflater.inflate(R.layout.home_handle, parent, false);
-        } else if (ASSISTANT_HANDLE.equals(button)) {
-            v = inflater.inflate(R.layout.assistant_handle, parent, false);
         } else if (button.startsWith(KEY)) {
             String uri = extractImage(button);
             int code = extractKeycode(button);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index b540fb4..18612c3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -333,7 +333,7 @@
             if (enabled) {
                 mColorAdaptionController.start();
             } else {
-                mColorAdaptionController.end();
+                mColorAdaptionController.stop();
             }
         }
 
@@ -434,7 +434,6 @@
         mButtonDispatchers.put(R.id.back, new ButtonDispatcher(R.id.back));
         mButtonDispatchers.put(R.id.home, new ButtonDispatcher(R.id.home));
         mButtonDispatchers.put(R.id.home_handle, new ButtonDispatcher(R.id.home_handle));
-        mButtonDispatchers.put(R.id.assistant_handle, new ButtonDispatcher(R.id.assistant_handle));
         mButtonDispatchers.put(R.id.recent_apps, new ButtonDispatcher(R.id.recent_apps));
         mButtonDispatchers.put(R.id.menu, menuButton);
         mButtonDispatchers.put(R.id.ime_switcher, imeSwitcherButton);
@@ -486,6 +485,12 @@
         }
     }
 
+    @Override
+    protected void dispatchDraw(Canvas canvas) {
+        super.dispatchDraw(canvas);
+        mColorAdaptionController.onDraw();
+    }
+
     private void updateNavigationGestures() {
         if (mGestureHelper instanceof QuickStepController) {
             final int[] assignedMap = mPrototypeController.getGestureActionMap();
@@ -632,10 +637,6 @@
         return mButtonDispatchers.get(R.id.home_handle);
     }
 
-    public ButtonDispatcher getAssistantHandle() {
-        return mButtonDispatchers.get(R.id.assistant_handle);
-    }
-
     public SparseArray<ButtonDispatcher> getButtonDispatchers() {
         return mButtonDispatchers;
     }
@@ -990,7 +991,7 @@
         if (visible) {
             mColorAdaptionController.start();
         } else {
-            mColorAdaptionController.end();
+            mColorAdaptionController.stop();
         }
     }
 
@@ -1002,7 +1003,6 @@
     // TODO(b/112934365): move this back to NavigationBarFragment when prototype is removed
     private void updateAssistantAvailability() {
         boolean available = mAssistantAvailable && mPrototypeController.isAssistantGestureEnabled();
-        getAssistantHandle().setVisibility(available ? View.VISIBLE : View.GONE);
         if (mOverviewProxyService.getProxy() != null) {
             try {
                 mOverviewProxyService.getProxy().onAssistantAvailable(available);
@@ -1244,7 +1244,7 @@
         if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
             mColorAdaptionController.start();
         } else {
-            mColorAdaptionController.end();
+            mColorAdaptionController.stop();
         }
     }
 
@@ -1330,7 +1330,6 @@
         Dependency.get(PluginManager.class).addPluginListener(this,
                 NavGesture.class, false /* Only one */);
         setUpSwipeUpOnboarding(isQuickStepSwipeUpEnabled());
-        mColorAdaptionController.start();
 
         if (mPrototypeController.isEnabled()) {
             WindowManager wm = (WindowManager) getContext()
@@ -1363,7 +1362,6 @@
             mGestureHelper.destroy();
         }
         mPrototypeController.unregister();
-        mColorAdaptionController.stop();
         setUpSwipeUpOnboarding(false);
         for (int i = 0; i < mButtonDispatchers.size(); ++i) {
             mButtonDispatchers.valueAt(i).onDestroy();
@@ -1454,6 +1452,7 @@
             mGestureHelper.dump(pw);
         }
         mRecentsOnboarding.dump(pw);
+        mColorAdaptionController.dump(pw);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 142f398..babee53 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -326,6 +326,14 @@
             Dependency.get(ShadeController.class);
     private int mDisplayId;
 
+    /**
+     * Cache the resource id of the theme to avoid unnecessary work in onThemeChanged.
+     *
+     * onThemeChanged is forced when the theme might not have changed. So, to avoid unncessary
+     * work, check the current id with the cached id.
+     */
+    private int mThemeResId;
+
     @Inject
     public NotificationPanelView(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
             NotificationWakeUpCoordinator coordinator,
@@ -342,6 +350,7 @@
         mCommandQueue = getComponent(context, CommandQueue.class);
         mDisplayId = context.getDisplayId();
         mPulseExpansionHandler = pulseExpansionHandler;
+        mThemeResId = context.getThemeResId();
     }
 
     /**
@@ -390,6 +399,9 @@
         Dependency.get(StatusBarStateController.class).addCallback(this);
         Dependency.get(ZenModeController.class).addCallback(this);
         Dependency.get(ConfigurationController.class).addCallback(this);
+        // Theme might have changed between inflating this view and attaching it to the window, so
+        // force a call to onThemeChanged
+        onThemeChanged();
     }
 
     @Override
@@ -452,6 +464,12 @@
 
     @Override
     public void onThemeChanged() {
+        final int themeResId = getContext().getThemeResId();
+        if (mThemeResId == themeResId) {
+            return;
+        }
+        mThemeResId = themeResId;
+
         updateShowEmptyShadeView();
 
         // Re-inflate the status view group.
@@ -1217,6 +1235,12 @@
         setQsExpansion(height);
         requestPanelHeightUpdate();
         mNotificationStackScroller.checkSnoozeLeavebehind();
+
+        // When expanding QS, let's authenticate the user if possible,
+        // this will speed up notification actions.
+        if (height == 0) {
+            mStatusBar.requestFaceAuth();
+        }
     }
 
     private void setQsExpanded(boolean expanded) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 60b1659..8db0822 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -538,7 +538,7 @@
     private BatteryController mBatteryController;
     protected boolean mPanelExpanded;
     private UiModeManager mUiModeManager;
-    private boolean mIsKeyguard;
+    protected boolean mIsKeyguard;
     private LogMaker mStatusBarStateLog;
     protected NotificationIconAreaController mNotificationIconAreaController;
     @Nullable private View mAmbientIndicationContainer;
@@ -1315,6 +1315,15 @@
         mEntryManager.updateNotifications();
     }
 
+    /**
+     * Asks {@link KeyguardUpdateMonitor} to run face auth.
+     */
+    public void requestFaceAuth() {
+        if (!mUnlockMethodCache.canSkipBouncer()) {
+            mKeyguardUpdateMonitor.requestFaceAuth();
+        }
+    }
+
     public void updateAreThereNotifications() {
         if (SPEW) {
             final boolean clearable = hasActiveNotifications() &&
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
index b0e006d..74c0018 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -248,7 +248,6 @@
             ActivityManager.getService().resumeAppSwitches();
         } catch (RemoteException e) {
         }
-        int launchResult;
         // If we are launching a work activity and require to launch
         // separate work challenge, we defer the activity action and cancel
         // notification until work challenge is unlocked.
@@ -277,24 +276,7 @@
             fillInIntent = new Intent().putExtra(Notification.EXTRA_REMOTE_INPUT_DRAFT,
                     remoteInputText.toString());
         }
-        RemoteAnimationAdapter adapter = mActivityLaunchAnimator.getLaunchAnimation(
-                row, wasOccluded);
-        try {
-            if (adapter != null) {
-                ActivityTaskManager.getService()
-                        .registerRemoteAnimationForNextActivityStart(
-                                intent.getCreatorPackage(), adapter);
-            }
-            launchResult = intent.sendAndReturnResult(mContext, 0, fillInIntent, null,
-                    null, null, getActivityOptions(adapter));
-            mActivityLaunchAnimator.setLaunchResult(launchResult, isActivityIntent);
-        } catch (RemoteException | PendingIntent.CanceledException e) {
-            // the stack trace isn't very helpful here.
-            // Just log the exception message.
-            Log.w(TAG, "Sending contentIntent failed: " + e);
-
-            // TODO: Dismiss Keyguard.
-        }
+        startNotificationIntent(intent, fillInIntent, row, wasOccluded, isActivityIntent);
         if (isActivityIntent) {
             mAssistManager.hideAssist();
         }
@@ -327,6 +309,27 @@
         mIsCollapsingToShowActivityOverLockscreen = false;
     }
 
+    private void startNotificationIntent(PendingIntent intent, Intent fillInIntent,
+            ExpandableNotificationRow row, boolean wasOccluded, boolean isActivityIntent) {
+        RemoteAnimationAdapter adapter = mActivityLaunchAnimator.getLaunchAnimation(row,
+                wasOccluded);
+        try {
+            if (adapter != null) {
+                ActivityTaskManager.getService()
+                        .registerRemoteAnimationForNextActivityStart(
+                                intent.getCreatorPackage(), adapter);
+            }
+            int launchResult = intent.sendAndReturnResult(mContext, 0, fillInIntent, null,
+                    null, null, getActivityOptions(adapter));
+            mActivityLaunchAnimator.setLaunchResult(launchResult, isActivityIntent);
+        } catch (RemoteException | PendingIntent.CanceledException e) {
+            // the stack trace isn't very helpful here.
+            // Just log the exception message.
+            Log.w(TAG, "Sending contentIntent failed: " + e);
+            // TODO: Dismiss Keyguard.
+        }
+    }
+
     @Override
     public void startNotificationGutsIntent(final Intent intent, final int appUid,
             ExpandableNotificationRow row) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index 0461057..d1a2253 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -26,8 +26,10 @@
 import android.provider.Settings;
 import android.util.ArrayMap;
 import android.util.Log;
+import android.view.accessibility.AccessibilityManager;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.AlertingNotificationManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -55,9 +57,11 @@
     protected int mUser;
 
     private final ArrayMap<String, Long> mSnoozedPackages;
+    private final AccessibilityManagerWrapper mAccessibilityMgr;
 
     public HeadsUpManager(@NonNull final Context context) {
         mContext = context;
+        mAccessibilityMgr = Dependency.get(AccessibilityManagerWrapper.class);
         Resources resources = context.getResources();
         mMinimumDisplayTime = resources.getInteger(R.integer.heads_up_notification_minimum_time);
         mAutoDismissNotificationDecay = resources.getInteger(R.integer.heads_up_notification_decay);
@@ -409,5 +413,22 @@
             // The actual post time will be just after the heads-up really slided in
             return super.calculatePostTime() + mTouchAcceptanceDelay;
         }
+
+        @Override
+        protected long calculateFinishTime() {
+            return mPostTime + getRecommendedTimeoutMillis();
+        }
+
+        /**
+         * Get user-preferred or default timeout duration. The larger one will be returned.
+         * @return milliseconds before auto-dismiss
+         */
+        private int getRecommendedTimeoutMillis() {
+            return mAccessibilityMgr.getRecommendedTimeoutMillis(
+                    mAutoDismissNotificationDecay,
+                    AccessibilityManager.FLAG_CONTENT_CONTROLS
+                            | AccessibilityManager.FLAG_CONTENT_ICONS
+                            | AccessibilityManager.FLAG_CONTENT_TEXT);
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/Events.java b/packages/SystemUI/src/com/android/systemui/volume/Events.java
index 1596ddb..6e740b8 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/Events.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/Events.java
@@ -55,6 +55,7 @@
     public static final int EVENT_RINGER_TOGGLE = 18; // (ringer_mode)
     public static final int EVENT_SHOW_USB_OVERHEAT_ALARM = 19; // (reason|int) (keyguard|bool)
     public static final int EVENT_DISMISS_USB_OVERHEAT_ALARM = 20; // (reason|int) (keyguard|bool)
+    public static final int EVENT_ODI_CAPTIONS_CLICK = 21;
 
     private static final String[] EVENT_TAGS = {
             "show_dialog",
@@ -77,7 +78,8 @@
             "zen_mode_config_changed",
             "ringer_toggle",
             "show_usb_overheat_alarm",
-            "dismiss_usb_overheat_alarm"
+            "dismiss_usb_overheat_alarm",
+            "odi_captions_click"
     };
 
     public static final int DISMISS_REASON_UNKNOWN = 0;
@@ -90,6 +92,7 @@
     public static final int DISMISS_STREAM_GONE = 7;
     public static final int DISMISS_REASON_OUTPUT_CHOOSER = 8;
     public static final int DISMISS_REASON_USB_OVERHEAD_ALARM_CHANGED = 9;
+    public static final int DISMISS_REASON_ODI_CAPTIONS_CLICKED = 10;
     public static final String[] DISMISS_REASONS = {
             "unknown",
             "touch_outside",
@@ -100,7 +103,8 @@
             "done_clicked",
             "a11y_stream_changed",
             "output_chooser",
-            "usb_temperature_below_threshold"
+            "usb_temperature_below_threshold",
+            "odi_captions_clicked"
     };
 
     public static final int SHOW_REASON_UNKNOWN = 0;
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index 4c16297..9192a25 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -48,6 +48,7 @@
 import android.provider.Settings;
 import android.service.notification.Condition;
 import android.service.notification.ZenModeConfig;
+import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.view.accessibility.AccessibilityManager;
@@ -270,6 +271,22 @@
         mWorker.sendEmptyMessage(W.GET_STATE);
     }
 
+    public boolean areCaptionsEnabled() {
+        int currentValue = Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.ODI_CAPTIONS_ENABLED, 0);
+        return currentValue == 1;
+    }
+
+    public void setCaptionsEnabled(boolean isEnabled) {
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.ODI_CAPTIONS_ENABLED, isEnabled ? 1 : 0);
+    }
+
+    public void getCaptionsComponentState() {
+        if (mDestroyed) return;
+        mWorker.sendEmptyMessage(W.GET_CAPTIONS_COMPONENT_STATE);
+    }
+
     public void notifyVisible(boolean visible) {
         if (mDestroyed) return;
         mWorker.obtainMessage(W.NOTIFY_VISIBLE, visible ? 1 : 0, 0).sendToTarget();
@@ -365,6 +382,38 @@
         }
     }
 
+    private void onGetCaptionsComponentStateW() {
+        try {
+            String componentNameString = mContext.getString(
+                    com.android.internal.R.string.config_defaultSystemCaptionsService);
+            if (TextUtils.isEmpty(componentNameString)) {
+                // component doesn't exist
+                mCallbacks.onCaptionComponentStateChanged(false);
+                return;
+            }
+
+            if (D.BUG) {
+                Log.i(TAG, String.format(
+                        "isCaptionsServiceEnabled componentNameString=%s", componentNameString));
+            }
+
+            ComponentName componentName = ComponentName.unflattenFromString(componentNameString);
+            if (componentName == null) {
+                mCallbacks.onCaptionComponentStateChanged(false);
+                return;
+            }
+
+            PackageManager packageManager = mContext.getPackageManager();
+            mCallbacks.onCaptionComponentStateChanged(
+                    packageManager.getComponentEnabledSetting(componentName)
+                    == PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
+        } catch (Exception ex) {
+            Log.e(TAG,
+                    "isCaptionsServiceEnabled failed to check for captions component", ex);
+            mCallbacks.onCaptionComponentStateChanged(false);
+        }
+    }
+
     private void onAccessibilityModeChanged(Boolean showA11yStream) {
         mCallbacks.onAccessibilityModeChanged(showA11yStream);
     }
@@ -718,6 +767,7 @@
         private static final int USER_ACTIVITY = 13;
         private static final int SHOW_SAFETY_WARNING = 14;
         private static final int ACCESSIBILITY_MODE_CHANGED = 15;
+        private static final int GET_CAPTIONS_COMPONENT_STATE = 16;
 
         W(Looper looper) {
             super(looper);
@@ -740,8 +790,8 @@
                 case NOTIFY_VISIBLE: onNotifyVisibleW(msg.arg1 != 0); break;
                 case USER_ACTIVITY: onUserActivityW(); break;
                 case SHOW_SAFETY_WARNING: onShowSafetyWarningW(msg.arg1); break;
+                case GET_CAPTIONS_COMPONENT_STATE: onGetCaptionsComponentStateW(); break;
                 case ACCESSIBILITY_MODE_CHANGED: onAccessibilityModeChanged((Boolean) msg.obj);
-
             }
         }
     }
@@ -881,6 +931,15 @@
                 });
             }
         }
+
+        @Override
+        public void onCaptionComponentStateChanged(Boolean isComponentEnabled) {
+            boolean componentEnabled = isComponentEnabled == null ? false : isComponentEnabled;
+            for (final Map.Entry<Callbacks, Handler> entry : mCallbackMap.entrySet()) {
+                entry.getValue().post(
+                        () -> entry.getKey().onCaptionComponentStateChanged(componentEnabled));
+            }
+        }
     }
 
 
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index ffd8206..398b309 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -29,6 +29,7 @@
 import static android.view.View.GONE;
 import static android.view.View.VISIBLE;
 
+import static com.android.systemui.volume.Events.DISMISS_REASON_ODI_CAPTIONS_CLICKED;
 import static com.android.systemui.volume.Events.DISMISS_REASON_SETTINGS_CLICKED;
 
 import android.animation.ObjectAnimator;
@@ -125,6 +126,8 @@
     private ViewGroup mDialogRowsView;
     private ViewGroup mRinger;
     private ImageButton mRingerIcon;
+    private ViewGroup mODICaptionsView;
+    private ImageButton mODICaptionsIcon;
     private View mSettingsView;
     private ImageButton mSettingsIcon;
     private FrameLayout mZenIcon;
@@ -240,6 +243,10 @@
             mRingerIcon = mRinger.findViewById(R.id.ringer_icon);
             mZenIcon = mRinger.findViewById(R.id.dnd_icon);
         }
+        mODICaptionsView = mDialog.findViewById(R.id.odi_captions);
+        if (mODICaptionsView != null) {
+            mODICaptionsIcon = mODICaptionsView.findViewById(R.id.odi_captions_icon);
+        }
         mSettingsView = mDialog.findViewById(R.id.settings_container);
         mSettingsIcon = mDialog.findViewById(R.id.settings);
 
@@ -270,6 +277,7 @@
         updateRowsH(getActiveRow());
         initRingerH();
         initSettingsH();
+        initODICaptionsH();
     }
 
     protected ViewGroup getDialogView() {
@@ -478,6 +486,42 @@
         updateRingerH();
     }
 
+    private void initODICaptionsH() {
+        if (mODICaptionsIcon != null) {
+            mODICaptionsIcon.setOnClickListener(v -> {
+                onCaptionIconClicked();
+                Events.writeEvent(mContext, Events.EVENT_ODI_CAPTIONS_CLICK);
+                dismissH(DISMISS_REASON_ODI_CAPTIONS_CLICKED);
+            });
+        }
+
+        mController.getCaptionsComponentState();
+    }
+
+    private void updateODICaptionsH(boolean isServiceComponentEnabled) {
+        if (mODICaptionsView != null) {
+            mODICaptionsView.setVisibility(isServiceComponentEnabled ? VISIBLE : GONE);
+        }
+
+        if (!isServiceComponentEnabled) return;
+
+        updateCaptionsIcon();
+    }
+
+    private void updateCaptionsIcon() {
+        mHandler.post(
+                mODICaptionsIcon.setImageResourceAsync(
+                        mController.areCaptionsEnabled()
+                                ? R.drawable.ic_volume_odi_captions
+                                : R.drawable.ic_volume_odi_captions_disabled));
+    }
+
+    private void onCaptionIconClicked() {
+        boolean isEnabled = mController.areCaptionsEnabled();
+        mController.setCaptionsEnabled(!isEnabled);
+        updateCaptionsIcon();
+    }
+
     private void incrementManualToggleCount() {
         ContentResolver cr = mContext.getContentResolver();
         int ringerCount = Settings.Secure.getInt(cr, Settings.Secure.MANUAL_RINGER_TOGGLE_COUNT, 0);
@@ -558,6 +602,7 @@
         mDialog.show();
         Events.writeEvent(mContext, Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked());
         mController.notifyVisible(true);
+        mController.getCaptionsComponentState();
     }
 
     protected void rescheduleTimeoutH() {
@@ -1151,6 +1196,11 @@
             }
 
         }
+
+        @Override
+        public void onCaptionComponentStateChanged(Boolean isComponentEnabled) {
+            updateODICaptionsH(isComponentEnabled);
+        }
     };
 
     private final class H extends Handler {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeDockHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeDockHandlerTest.java
index 4ba2858..df014a4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeDockHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeDockHandlerTest.java
@@ -202,4 +202,16 @@
 
         verify(mMachine).requestState(eq(State.DOZE));
     }
+
+    @Test
+    public void testTransitionToPulsing_whenDockedHide_requestPulseOut() {
+        mDockHandler.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED);
+        when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE_PULSING);
+        when(mMachine.getPulseReason()).thenReturn(DozeLog.PULSE_REASON_DOCKING);
+        mDockManagerFake.setDockEvent(DockManager.STATE_DOCKED_HIDE);
+
+        mDockHandler.transitionTo(DozeMachine.State.INITIALIZED, State.DOZE_PULSING);
+
+        verify(mHost).stopPulsing();
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
index 7797cb3..7bd4158 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
@@ -19,8 +19,10 @@
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
 
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.when;
 
+import android.content.Context;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.view.View;
@@ -31,6 +33,7 @@
 import com.android.systemui.statusbar.AlertingNotificationManagerTest;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -53,15 +56,29 @@
     @Mock private VisualStabilityManager mVSManager;
     @Mock private StatusBar mBar;
 
+    private final class TestableHeadsUpManagerPhone extends HeadsUpManagerPhone {
+        TestableHeadsUpManagerPhone(Context context, View statusBarWindowView,
+                NotificationGroupManager groupManager, StatusBar bar,
+                VisualStabilityManager vsManager) {
+            super(context, statusBarWindowView, groupManager, bar, vsManager);
+            mMinimumDisplayTime = TEST_MINIMUM_DISPLAY_TIME;
+            mAutoDismissNotificationDecay = TEST_AUTO_DISMISS_TIME;
+        }
+    }
+
     protected AlertingNotificationManager createAlertingNotificationManager() {
         return mHeadsUpManager;
     }
 
     @Before
     public void setUp() {
+        AccessibilityManagerWrapper mAccessibilityMgr =
+                mDependency.injectMockDependency(AccessibilityManagerWrapper.class);
+        when(mAccessibilityMgr.getRecommendedTimeoutMillis(anyInt(), anyInt()))
+                .thenReturn(TEST_AUTO_DISMISS_TIME);
         when(mVSManager.isReorderingAllowed()).thenReturn(true);
-        mHeadsUpManager = new HeadsUpManagerPhone(mContext, mStatusBarWindowView, mGroupManager,
-                mBar, mVSManager);
+        mHeadsUpManager = new TestableHeadsUpManagerPhone(mContext, mStatusBarWindowView,
+                mGroupManager, mBar, mVSManager);
         super.setUp();
         mHeadsUpManager.mHandler = mTestHandler;
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java
new file mode 100644
index 0000000..6b83fed
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2019 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.systemui.statusbar.policy;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+
+import android.content.Context;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.statusbar.AlertingNotificationManager;
+import com.android.systemui.statusbar.AlertingNotificationManagerTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class HeadsUpManagerTest extends AlertingNotificationManagerTest {
+    private static final int TEST_A11Y_AUTO_DISMISS_TIME = 600;
+    private static final int TEST_A11Y_TIMEOUT_TIME = 5_000;
+
+    private AccessibilityManagerWrapper mAccessibilityMgr;
+    private HeadsUpManager mHeadsUpManager;
+    private boolean mLivesPastNormalTime;
+
+    private final class TestableHeadsUpManager extends HeadsUpManager {
+        TestableHeadsUpManager(Context context) {
+            super(context);
+            mMinimumDisplayTime = TEST_MINIMUM_DISPLAY_TIME;
+            mAutoDismissNotificationDecay = TEST_AUTO_DISMISS_TIME;
+        }
+    }
+
+    protected AlertingNotificationManager createAlertingNotificationManager() {
+        return mHeadsUpManager;
+    }
+
+    @Before
+    public void setUp() {
+        mAccessibilityMgr = mDependency.injectMockDependency(AccessibilityManagerWrapper.class);
+
+        mHeadsUpManager = new TestableHeadsUpManager(mContext);
+        super.setUp();
+        mHeadsUpManager.mHandler = mTestHandler;
+    }
+
+    @Test
+    public void testShowNotification_autoDismissesWithAccessibilityTimeout() {
+        doReturn(TEST_A11Y_AUTO_DISMISS_TIME).when(mAccessibilityMgr)
+                .getRecommendedTimeoutMillis(anyInt(), anyInt());
+        mHeadsUpManager.showNotification(mEntry);
+        Runnable pastNormalTimeRunnable =
+                () -> mLivesPastNormalTime = mHeadsUpManager.isAlerting(mEntry.key);
+        mTestHandler.postDelayed(pastNormalTimeRunnable,
+                        (TEST_A11Y_AUTO_DISMISS_TIME + TEST_AUTO_DISMISS_TIME) / 2);
+        mTestHandler.postDelayed(TEST_TIMEOUT_RUNNABLE, TEST_A11Y_TIMEOUT_TIME);
+
+        TestableLooper.get(this).processMessages(2);
+
+        assertFalse("Test timed out", mTimedOut);
+        assertTrue("Heads up should live long enough", mLivesPastNormalTime);
+        assertFalse(mHeadsUpManager.isAlerting(mEntry.key));
+    }
+}
+
diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto
index 9673a84..bc42863 100644
--- a/proto/src/metrics_constants/metrics_constants.proto
+++ b/proto/src/metrics_constants/metrics_constants.proto
@@ -260,6 +260,18 @@
     PREVIOUSLY_VISIBLE = 2;
   }
 
+  // Explanations for notification importance, derived from
+  // NotificationRecord.mImportanceExplanation.
+  enum NotificationImportanceExplanation {
+    IMPORTANCE_EXPLANATION_UNKNOWN = 0;
+    IMPORTANCE_EXPLANATION_APP = 1;     // App-specified channel importance.
+    IMPORTANCE_EXPLANATION_USER = 2;    // User-specified channel importance.
+    IMPORTANCE_EXPLANATION_ASST = 3;    // Notification Assistant override.
+    IMPORTANCE_EXPLANATION_SYSTEM = 4;  // System override.
+    // Like _APP, but based on pre-channels priority signal.
+    IMPORTANCE_EXPLANATION_APP_PRE_CHANNELS = 5;
+  }
+
   // Known visual elements: views or controls.
   enum View {
     // Unknown view
@@ -7090,6 +7102,21 @@
     // Panel for Wifi
     PANEL_WIFI = 1687;
 
+    // Custom tag for NotificationItem. A NotificationImportanceExplanation.
+    FIELD_NOTIFICATION_IMPORTANCE_EXPLANATION = 1688;
+
+    // Custom tag for NotificationItem. The initial "natural" importance.
+    FIELD_NOTIFICATION_IMPORTANCE_INITIAL = 1689;
+
+    // Custom tag for NotificationItem.  A NotificationImportanceExplanation.
+    // The source of the "natural" importance, if it was overridden.
+    FIELD_NOTIFICATION_IMPORTANCE_INITIAL_EXPLANATION = 1690;
+
+    // Custom tag for NotificationItem. The Notification Assistant's
+    // override of importance. Logged separately only if it was
+    // overridden by the system.
+    FIELD_NOTIFICATION_IMPORTANCE_ASST = 1691;
+
     // ---- End Q Constants, all Q constants go above this line ----
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS
diff --git a/proto/src/wifi.proto b/proto/src/wifi.proto
index f3953af..0d17f22 100644
--- a/proto/src/wifi.proto
+++ b/proto/src/wifi.proto
@@ -2291,13 +2291,13 @@
   optional int32 count = 3;
 }
 
-// Single entry in a map from int32 => int32
-message MapEntryInt32Int32 {
+// Counts occurrences of a int32 key
+message Int32Count {
   // the key
   optional int32 key = 1;
 
-  // the value
-  optional int32 value = 2;
+  // the count
+  optional int32 count = 2;
 }
 
 message LinkProbeStats {
@@ -2328,16 +2328,16 @@
   }
 
   // Counts the occurrences of RSSI values when a link probe succeeds.
-  repeated MapEntryInt32Int32 success_rssi_counts = 1;
+  repeated Int32Count success_rssi_counts = 1;
 
   // Counts the occurrences of RSSI values when a link probe fails.
-  repeated MapEntryInt32Int32 failure_rssi_counts = 2;
+  repeated Int32Count failure_rssi_counts = 2;
 
   // Counts the occurrences of Link Speed values when a link probe succeeds.
-  repeated MapEntryInt32Int32 success_link_speed_counts = 3;
+  repeated Int32Count success_link_speed_counts = 3;
 
   // Counts the occurrences of Link Speed values when a link probe fails.
-  repeated MapEntryInt32Int32 failure_link_speed_counts = 4;
+  repeated Int32Count failure_link_speed_counts = 4;
 
   // Histogram for the number of seconds since the last TX success when a link probe succeeds.
   repeated HistogramBucketInt32 success_seconds_since_last_tx_success_histogram = 5;
@@ -2364,7 +2364,7 @@
   // same network selection as experiment2.
   // The keys are the number of network choices, and the values are the number of occurrences of
   // this number of network choices when exp1 and exp2 make the same network selection.
-  repeated MapEntryInt32Int32 same_selection_num_choices_counter = 3;
+  repeated Int32Count same_selection_num_choices_counter = 3;
 
   // Counts occurrences of the number of network choices there were when experiment1 makes the
   // same network selection as experiment2.
@@ -2372,7 +2372,7 @@
   // this number of network choices when exp1 and exp2 make different network selections.
   // Note that it is possible for the network selection to be different even when there only exists
   // a single network choice, since choosing not to connect to that network is a valid choice.
-  repeated MapEntryInt32Int32 different_selection_num_choices_counter = 4;
+  repeated Int32Count different_selection_num_choices_counter = 4;
 }
 
 // NetworkRequest API metrics.
diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java
index 4293157..85c82bc 100644
--- a/rs/java/android/renderscript/RenderScript.java
+++ b/rs/java/android/renderscript/RenderScript.java
@@ -16,12 +16,6 @@
 
 package android.renderscript;
 
-import java.io.File;
-import java.lang.reflect.Method;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
 import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.AssetManager;
@@ -32,6 +26,12 @@
 import android.util.Log;
 import android.view.Surface;
 
+import java.io.File;
+import java.lang.reflect.Method;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
 // TODO: Clean up the whitespace that separates methods in this class.
 
 /**
@@ -114,8 +114,9 @@
                 Class<?> vm_runtime = Class.forName("dalvik.system.VMRuntime");
                 Method get_runtime = vm_runtime.getDeclaredMethod("getRuntime");
                 sRuntime = get_runtime.invoke(null);
-                registerNativeAllocation = vm_runtime.getDeclaredMethod("registerNativeAllocation", Integer.TYPE);
-                registerNativeFree = vm_runtime.getDeclaredMethod("registerNativeFree", Integer.TYPE);
+                registerNativeAllocation =
+                        vm_runtime.getDeclaredMethod("registerNativeAllocation", Long.TYPE);
+                registerNativeFree = vm_runtime.getDeclaredMethod("registerNativeFree", Long.TYPE);
             } catch (Exception e) {
                 Log.e(LOG_TAG, "Error loading GC methods: " + e);
                 throw new RSRuntimeException("Error loading GC methods: " + e);
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
index a19a847..3bd6220 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
@@ -91,7 +91,8 @@
         if (userState == null) return;
         final long identity = Binder.clearCallingIdentity();
         try {
-            int flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE;
+            int flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE
+                    | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS;
             if (userState.getBindInstantServiceAllowed()) {
                 flags |= Context.BIND_ALLOW_INSTANT;
             }
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
index c75b4c6..9995d8e 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
@@ -115,7 +115,7 @@
     public ContentCaptureManagerService(@NonNull Context context) {
         super(context, new FrameworkResourcesServiceNameResolver(context,
                 com.android.internal.R.string.config_defaultContentCaptureService),
-                UserManager.DISALLOW_CONTENT_CAPTURE);
+                UserManager.DISALLOW_CONTENT_CAPTURE, /* refreshServiceOnPackageUpdate=*/ false);
         DeviceConfig.addOnPropertyChangedListener(DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
                 ActivityThread.currentApplication().getMainExecutor(),
                 (namespace, key, value) -> onDeviceConfigChange(key, value));
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
index feb1ac1..304ddb2 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
@@ -100,6 +100,13 @@
     @GuardedBy("mLock")
     private final WhitelistHelper mWhitelistHelper = new WhitelistHelper();
 
+    /**
+     * When {@code true}, remote service died but service state is kept so it's restored after
+     * the system re-binds to it.
+     */
+    @GuardedBy("mLock")
+    private boolean mZombie;
+
     // TODO(b/111276913): add mechanism to prune stale sessions, similar to Autofill's
 
     ContentCapturePerUserService(@NonNull ContentCaptureManagerService master,
@@ -179,6 +186,37 @@
     public void onServiceDied(@NonNull RemoteContentCaptureService service) {
         // Don't do anything; eventually the system will bind to it again...
         Slog.w(TAG, "remote service died: " + service);
+        synchronized (mLock) {
+            mZombie = true;
+        }
+    }
+
+    /**
+     * Called after the remote service connected, it's used to restore state from a 'zombie'
+     * service (i.e., after it died).
+     */
+    void onConnected() {
+        synchronized (mLock) {
+            if (mZombie) {
+                // Sanity check - shouldn't happen
+                if (mRemoteService == null) {
+                    Slog.w(TAG, "Cannot ressurect sessions because remote service is null");
+                    return;
+                }
+
+                mZombie = false;
+                final int numSessions = mSessions.size();
+                if (mMaster.debug) {
+                    Slog.d(TAG, "Ressurrecting remote service (" + mRemoteService + ") on "
+                            + numSessions + " sessions");
+                }
+
+                for (int i = 0; i < numSessions; i++) {
+                    final ContentCaptureServerSession session = mSessions.valueAt(i);
+                    session.resurrectLocked();
+                }
+            }
+        }
     }
 
     // TODO(b/119613670): log metrics
@@ -260,7 +298,7 @@
         }
 
         final ContentCaptureServerSession newSession = new ContentCaptureServerSession(
-                activityToken, this, mRemoteService, componentName, taskId,
+                activityToken, this, mRemoteService, componentName, clientReceiver, taskId,
                 displayId, sessionId, uid, flags);
         if (mMaster.verbose) {
             Slog.v(TAG, "startSession(): new session for "
@@ -449,6 +487,8 @@
     protected void dumpLocked(String prefix, PrintWriter pw) {
         super.dumpLocked(prefix, pw);
 
+        pw.print(prefix); pw.print("Zombie: "); pw.println(mZombie);
+
         final String prefix2 = prefix + "  ";
         if (mRemoteService != null) {
             pw.print(prefix); pw.println("remote service:");
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java
index 4094843..da19836 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java
@@ -23,6 +23,7 @@
 import android.util.LocalLog;
 import android.util.Slog;
 import android.view.contentcapture.ContentCaptureContext;
+import android.view.contentcapture.ContentCaptureSession;
 import android.view.contentcapture.ContentCaptureSessionId;
 
 import com.android.internal.annotations.GuardedBy;
@@ -44,6 +45,12 @@
     private final ContentCaptureContext mContentCaptureContext;
 
     /**
+     * Reference to the binder object help at the client-side process and used to set its state.
+     */
+    @NonNull
+    private final IResultReceiver mSessionStateReceiver;
+
+    /**
      * Canonical session id.
      */
     private final String mId;
@@ -56,7 +63,7 @@
     ContentCaptureServerSession(@NonNull IBinder activityToken,
             @NonNull ContentCapturePerUserService service,
             @NonNull RemoteContentCaptureService remoteService,
-            @NonNull ComponentName appComponentName,
+            @NonNull ComponentName appComponentName, @NonNull IResultReceiver sessionStateReceiver,
             int taskId, int displayId, @NonNull String sessionId, int uid, int flags) {
         mActivityToken = activityToken;
         mService = service;
@@ -65,6 +72,7 @@
         mRemoteService = remoteService;
         mContentCaptureContext = new ContentCaptureContext(/* clientContext= */ null,
                 appComponentName, taskId, displayId, flags);
+        mSessionStateReceiver = sessionStateReceiver;
     }
 
     /**
@@ -79,7 +87,8 @@
      */
     @GuardedBy("mLock")
     public void notifySessionStartedLocked(@NonNull IResultReceiver clientReceiver) {
-        mRemoteService.onSessionStarted(mContentCaptureContext, mId, mUid, clientReceiver);
+        mRemoteService.onSessionStarted(mContentCaptureContext, mId, mUid, clientReceiver,
+                ContentCaptureSession.STATE_ACTIVE);
     }
 
     /**
@@ -129,6 +138,17 @@
         }
     }
 
+    /**
+     * Called to restore the active state of a session that was paused while the service died.
+     */
+    @GuardedBy("mLock")
+    public void resurrectLocked() {
+        mRemoteService.onSessionStarted(new ContentCaptureContext(mContentCaptureContext,
+                ContentCaptureContext.FLAG_RECONNECTED), mId, mUid, mSessionStateReceiver,
+                ContentCaptureSession.STATE_ACTIVE
+                        | ContentCaptureSession.STATE_SERVICE_RESURRECTED);
+    }
+
     @GuardedBy("mLock")
     public void dumpLocked(@NonNull String prefix, @NonNull PrintWriter pw) {
         pw.print(prefix); pw.print("id: ");  pw.print(mId); pw.println();
diff --git a/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java b/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java
index 1d2d625..2ce5059 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java
@@ -40,14 +40,16 @@
 
     private final IBinder mServerCallback;
     private final int mIdleUnbindTimeoutMs;
+    private final ContentCapturePerUserService mPerUserService;
 
     RemoteContentCaptureService(Context context, String serviceInterface,
             ComponentName serviceComponentName, IContentCaptureServiceCallback callback, int userId,
-            ContentCaptureServiceCallbacks callbacks, boolean bindInstantServiceAllowed,
+            ContentCapturePerUserService perUserService, boolean bindInstantServiceAllowed,
             boolean verbose, int idleUnbindTimeoutMs) {
-        super(context, serviceInterface, serviceComponentName, userId, callbacks,
+        super(context, serviceInterface, serviceComponentName, userId, perUserService,
                 context.getMainThreadHandler(), bindInstantServiceAllowed, verbose,
                 /* initialCapacity= */ 2);
+        mPerUserService = perUserService;
         mServerCallback = callback.asBinder();
         mIdleUnbindTimeoutMs = idleUnbindTimeoutMs;
 
@@ -65,19 +67,25 @@
         return mIdleUnbindTimeoutMs;
     }
 
-    @Override // from RemoteService
-    protected void handleOnConnectedStateChanged(boolean state) {
-        if (state && getTimeoutIdleBindMillis() != PERMANENT_BOUND_TIMEOUT_MS) {
+    @Override // from AbstractRemoteService
+    protected void handleOnConnectedStateChanged(boolean connected) {
+        if (connected && getTimeoutIdleBindMillis() != PERMANENT_BOUND_TIMEOUT_MS) {
             scheduleUnbind();
         }
         try {
-            if (state) {
-                mService.onConnected(mServerCallback, sVerbose, sDebug);
+            if (connected) {
+                try {
+                    mService.onConnected(mServerCallback, sVerbose, sDebug);
+                } finally {
+                    // Update the system-service state, in case the service reconnected after
+                    // dying
+                    mPerUserService.onConnected();
+                }
             } else {
                 mService.onDisconnected();
             }
         } catch (Exception e) {
-            Slog.w(mTag, "Exception calling onConnectedStateChanged(" + state + "): " + e);
+            Slog.w(mTag, "Exception calling onConnectedStateChanged(" + connected + "): " + e);
         }
     }
 
@@ -86,8 +94,10 @@
      * {@link RemoteContentCaptureService} to indicate the session was created.
      */
     public void onSessionStarted(@Nullable ContentCaptureContext context,
-            @NonNull String sessionId, int uid, @NonNull IResultReceiver clientReceiver) {
-        scheduleAsyncRequest((s) -> s.onSessionStarted(context, sessionId, uid, clientReceiver));
+            @NonNull String sessionId, int uid, @NonNull IResultReceiver clientReceiver,
+            int initialState) {
+        scheduleAsyncRequest(
+                (s) -> s.onSessionStarted(context, sessionId, uid, clientReceiver, initialState));
     }
 
     /**
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 72f7a68..3ed2948 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -299,6 +299,15 @@
     private INetworkPolicyManager mPolicyManager;
     private NetworkPolicyManagerInternal mPolicyManagerInternal;
 
+    /**
+     * TestNetworkService (lazily) created upon first usage. Locked to prevent creation of multiple
+     * instances.
+     */
+    @GuardedBy("mTNSLock")
+    private TestNetworkService mTNS;
+
+    private final Object mTNSLock = new Object();
+
     private String mCurrentTcpBufferSizes;
 
     private static final SparseArray<String> sMagicDecoderRing = MessageUtils.findMessageNames(
@@ -6958,4 +6967,22 @@
             return vpn != null && vpn.getLockdown();
         }
     }
+
+    /**
+     * Returns a IBinder to a TestNetworkService. Will be lazily created as needed.
+     *
+     * <p>The TestNetworkService must be run in the system server due to TUN creation.
+     */
+    @Override
+    public IBinder startOrGetTestNetworkService() {
+        synchronized (mTNSLock) {
+            TestNetworkService.enforceTestNetworkPermissions(mContext);
+
+            if (mTNS == null) {
+                mTNS = new TestNetworkService(mContext, mNMS);
+            }
+
+            return mTNS;
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index e28d484..f416110 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -2717,6 +2717,38 @@
     }
 
     /**
+     * Check whether the device supports filesystem checkpointing.
+     *
+     * @return true if the device supports filesystem checkpointing, false otherwise.
+     */
+    @Override
+    public boolean supportsCheckpoint() throws RemoteException {
+        // Only the system process is permitted to start checkpoints
+        if (Binder.getCallingUid() != android.os.Process.SYSTEM_UID) {
+            throw new SecurityException("no permission to check filesystem checkpoint support");
+        }
+
+        return mVold.supportsCheckpoint();
+    }
+
+    /**
+     * Signal that checkpointing partitions should start a checkpoint on the next boot.
+     *
+     * @param numTries Number of times to try booting in checkpoint mode, before we will boot
+     *                 non-checkpoint mode and commit all changes immediately. Callers are
+     *                 responsible for ensuring that boot is safe (eg, by rolling back updates).
+     */
+    @Override
+    public void startCheckpoint(int numTries) throws RemoteException {
+        // Only the system process is permitted to start checkpoints
+        if (Binder.getCallingUid() != android.os.Process.SYSTEM_UID) {
+            throw new SecurityException("no permission to start filesystem checkpoint");
+        }
+
+        mVold.startCheckpoint(numTries);
+    }
+
+    /**
      * Signal that checkpointing partitions should commit changes
      */
     @Override
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 710a0ba3..3a50aa8 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -30,13 +30,11 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.os.BatteryManager;
 import android.os.Binder;
-import android.os.Build;
 import android.os.Handler;
 import android.os.PowerManager;
 import android.os.PowerManager.ServiceType;
@@ -356,8 +354,8 @@
             try {
                 synchronized (mLock) {
                     if (mNightMode != mode) {
-                        // Only persist setting if not transient night mode or not in car mode
-                        if (!shouldTransientNightWhenInCarMode() || !mCarModeEnabled) {
+                        // Only persist setting if not in car mode
+                        if (!mCarModeEnabled) {
                             Settings.Secure.putIntForUser(getContext().getContentResolver(),
                                     Settings.Secure.UI_NIGHT_MODE, mode, user);
                         }
@@ -444,34 +442,12 @@
         }
     }
 
-    // Night mode settings in car mode are only persisted below Q.
-    // When targeting Q, changes are not saved and night mode will be re-read
-    // from settings when exiting car mode.
-    private boolean shouldTransientNightWhenInCarMode() {
-        int uid = Binder.getCallingUid();
-        PackageManager packageManager = getContext().getPackageManager();
-        String[] packagesForUid = packageManager.getPackagesForUid(uid);
-        if (packagesForUid == null || packagesForUid.length == 0) {
-            return false;
-        }
-
-        try {
-            ApplicationInfo appInfo = packageManager.getApplicationInfoAsUser(
-                    packagesForUid[0], 0, uid);
-
-            return appInfo.targetSdkVersion >= Build.VERSION_CODES.Q;
-        } catch (PackageManager.NameNotFoundException ignored) {
-        }
-
-        return false;
-    }
-
     void setCarModeLocked(boolean enabled, int flags) {
         if (mCarModeEnabled != enabled) {
             mCarModeEnabled = enabled;
 
-            // When transient night mode and exiting car mode, restore night mode from settings
-            if (shouldTransientNightWhenInCarMode() && !mCarModeEnabled) {
+            // When exiting car mode, restore night mode from settings
+            if (!mCarModeEnabled) {
                 Context context = getContext();
                 updateNightModeFromSettings(context,
                         context.getResources(),
@@ -534,9 +510,8 @@
             uiMode |= mNightMode << 4;
         }
 
-        // Override night mode in power save mode if not transient night mode or not in car mode
-        boolean shouldOverrideNight = !mCarModeEnabled || !shouldTransientNightWhenInCarMode();
-        if (mPowerSave && shouldOverrideNight) {
+        // Override night mode in power save mode if not in car mode
+        if (mPowerSave && !mCarModeEnabled) {
             uiMode &= ~Configuration.UI_MODE_NIGHT_NO;
             uiMode |= Configuration.UI_MODE_NIGHT_YES;
         }
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 85ec2dd..6270106 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -131,9 +131,6 @@
     // calling startForeground() before we ANR + stop it.
     static final int SERVICE_START_FOREGROUND_TIMEOUT = 10*1000;
 
-    // For how long after a whitelisted service's start its process can start a background activity
-    private static final int SERVICE_BG_ACTIVITY_START_TIMEOUT_MS = 10*1000;
-
     final ActivityManagerService mAm;
 
     // Maximum number of services that we allow to start in the background
@@ -333,8 +330,8 @@
                             + " delayedStop=" + r.delayedStop);
                 } else {
                     try {
-                        startServiceInnerLocked(this, r.pendingStarts.get(0).intent, r, false, true,
-                                false);
+                        startServiceInnerLocked(this, r.pendingStarts.get(0).intent, r, false,
+                                true);
                     } catch (TransactionTooLargeException e) {
                         // Ignore, nobody upstack cares.
                     }
@@ -637,26 +634,26 @@
         }
 
         if (allowBackgroundActivityStarts) {
-            ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
-            if (proc != null) {
-                proc.addAllowBackgroundActivityStartsToken(r);
-                // schedule removal of the whitelisting token after the timeout
-                removeAllowBackgroundActivityStartsServiceToken(proc, r,
-                        SERVICE_BG_ACTIVITY_START_TIMEOUT_MS);
-            }
+            r.hasStartedWhitelistingBgActivityStarts = true;
+            scheduleCleanUpHasStartedWhitelistingBgActivityStartsLocked(r);
         }
-        ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting,
-                allowBackgroundActivityStarts);
+
+        ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
         return cmp;
     }
 
-    private void removeAllowBackgroundActivityStartsServiceToken(ProcessRecord proc,
-            ServiceRecord r, int delayMillis) {
-        mAm.mHandler.postDelayed(() -> {
-            if (proc != null) {
-                proc.removeAllowBackgroundActivityStartsToken(r);
-            }
-        }, delayMillis);
+    private void scheduleCleanUpHasStartedWhitelistingBgActivityStartsLocked(ServiceRecord r) {
+        // if there's a request pending from the past, drop it before scheduling a new one
+        if (r.startedWhitelistingBgActivityStartsCleanUp == null) {
+            r.startedWhitelistingBgActivityStartsCleanUp = () -> {
+                synchronized(mAm) {
+                    r.setHasStartedWhitelistingBgActivityStarts(false);
+                }
+            };
+        }
+        mAm.mHandler.removeCallbacks(r.startedWhitelistingBgActivityStartsCleanUp);
+        mAm.mHandler.postDelayed(r.startedWhitelistingBgActivityStartsCleanUp,
+                mAm.mConstants.SERVICE_BG_ACTIVITY_START_TIMEOUT);
     }
 
     private boolean requestStartTargetPermissionsReviewIfNeededLocked(ServiceRecord r,
@@ -705,8 +702,7 @@
     }
 
     ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
-            boolean callerFg, boolean addToStarting, boolean allowBackgroundActivityStarts)
-            throws TransactionTooLargeException {
+            boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
         ServiceState stracker = r.getTracker();
         if (stracker != null) {
             stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
@@ -717,8 +713,7 @@
         synchronized (r.stats.getBatteryStats()) {
             r.stats.startRunningLocked();
         }
-        String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false,
-                allowBackgroundActivityStarts);
+        String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
         if (error != null) {
             return new ComponentName("!!", error);
         }
@@ -765,6 +760,12 @@
                     SystemClock.uptimeMillis());
         }
         service.callStart = false;
+
+        // the service will not necessarily be brought down, so only clear the whitelisting state
+        // for start-based bg activity starts now, and drop any existing future cleanup callback
+        service.setHasStartedWhitelistingBgActivityStarts(false);
+        mAm.mHandler.removeCallbacks(service.startedWhitelistingBgActivityStartsCleanUp);
+
         bringDownServiceIfNeededLocked(service, false, false);
     }
 
@@ -788,9 +789,6 @@
             if (r.record != null) {
                 final long origId = Binder.clearCallingIdentity();
                 try {
-                    // immediately remove bg activity whitelisting token if there was one
-                    removeAllowBackgroundActivityStartsServiceToken(callerApp, r.record,
-                            0 /* delayMillis */);
                     stopServiceLocked(r.record);
                 } finally {
                     Binder.restoreCallingIdentity(origId);
@@ -1614,6 +1612,12 @@
                             + ") set BIND_ALLOW_INSTANT when binding service " + service);
         }
 
+        if ((flags & Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS) != 0) {
+            mAm.enforceCallingPermission(
+                    android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND,
+                    "BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS");
+        }
+
         final boolean callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;
         final boolean isBindExternal = (flags & Context.BIND_EXTERNAL_SERVICE) != 0;
         final boolean allowInstant = (flags & Context.BIND_ALLOW_INSTANT) != 0;
@@ -1672,7 +1676,7 @@
                                 try {
                                     bringUpServiceLocked(serviceRecord,
                                             serviceIntent.getFlags(),
-                                            callerFg, false, false, false);
+                                            callerFg, false, false);
                                 } catch (RemoteException e) {
                                     /* ignore - local call */
                                 }
@@ -1762,6 +1766,9 @@
             if ((c.flags&Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
                 s.whitelistManager = true;
             }
+            if ((flags & Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS) != 0) {
+                s.setHasBindingWhitelistingBgActivityStarts(true);
+            }
             if (s.app != null) {
                 updateServiceClientActivitiesLocked(s.app, c, true);
             }
@@ -1775,7 +1782,7 @@
             if ((flags&Context.BIND_AUTO_CREATE) != 0) {
                 s.lastActivity = SystemClock.uptimeMillis();
                 if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
-                        permissionsReviewRequired, false) != null) {
+                        permissionsReviewRequired) != null) {
                     return 0;
                 }
             }
@@ -2445,8 +2452,7 @@
             return;
         }
         try {
-            bringUpServiceLocked(r, r.intent.getIntent().getFlags(), r.createdFromFg, true, false,
-                    false);
+            bringUpServiceLocked(r, r.intent.getIntent().getFlags(), r.createdFromFg, true, false);
         } catch (TransactionTooLargeException e) {
             // Ignore, it's been logged and nothing upstack cares.
         }
@@ -2491,11 +2497,8 @@
     }
 
     private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
-            boolean whileRestarting, boolean permissionsReviewRequired,
-            boolean allowBackgroundActivityStarts) throws TransactionTooLargeException {
-        //Slog.i(TAG, "Bring up service:");
-        //r.dump("  ");
-
+            boolean whileRestarting, boolean permissionsReviewRequired)
+            throws TransactionTooLargeException {
         if (r.app != null && r.app.thread != null) {
             sendServiceArgsLocked(r, execInFg, false);
             return null;
@@ -2603,13 +2606,6 @@
             }
         }
 
-        if (app != null && allowBackgroundActivityStarts) {
-            app.addAllowBackgroundActivityStartsToken(r);
-            // schedule removal of the whitelisting token after the timeout
-            removeAllowBackgroundActivityStartsServiceToken(app, r,
-                    SERVICE_BG_ACTIVITY_START_TIMEOUT_MS);
-        }
-
         if (r.fgRequired) {
             if (DEBUG_FOREGROUND_SERVICE) {
                 Slog.v(TAG, "Whitelisting " + UserHandle.formatUid(r.appInfo.uid)
@@ -2646,6 +2642,11 @@
         }
     }
 
+    /**
+     * Note the name of this method should not be confused with the started services concept.
+     * The "start" here means bring up the instance in the client, and this method is called
+     * from bindService() as well.
+     */
     private final void realStartServiceLocked(ServiceRecord r,
             ProcessRecord app, boolean execInFg) throws RemoteException {
         if (app.thread == null) {
@@ -3085,6 +3086,10 @@
                     updateWhitelistManagerLocked(s.app);
                 }
             }
+            // And do the same for bg activity starts whitelisting.
+            if ((c.flags & Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS) != 0) {
+                s.updateHasBindingWhitelistingBgActivityStarts();
+            }
             if (s.app != null) {
                 updateServiceClientActivitiesLocked(s.app, c, true);
             }
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index f9fcef6..1751856 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -69,6 +69,7 @@
     static final String KEY_SERVICE_MIN_RESTART_TIME_BETWEEN = "service_min_restart_time_between";
     static final String KEY_MAX_SERVICE_INACTIVITY = "service_max_inactivity";
     static final String KEY_BG_START_TIMEOUT = "service_bg_start_timeout";
+    static final String KEY_SERVICE_BG_ACTIVITY_START_TIMEOUT = "service_bg_activity_start_timeout";
     static final String KEY_BOUND_SERVICE_CRASH_RESTART_DURATION = "service_crash_restart_duration";
     static final String KEY_BOUND_SERVICE_CRASH_MAX_RETRY = "service_crash_max_retry";
     static final String KEY_PROCESS_START_ASYNC = "process_start_async";
@@ -99,6 +100,7 @@
     private static final long DEFAULT_SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
     private static final long DEFAULT_MAX_SERVICE_INACTIVITY = 30*60*1000;
     private static final long DEFAULT_BG_START_TIMEOUT = 15*1000;
+    private static final long DEFAULT_SERVICE_BG_ACTIVITY_START_TIMEOUT = 10_000;
     private static final long DEFAULT_BOUND_SERVICE_CRASH_RESTART_DURATION = 30*60_000;
     private static final int DEFAULT_BOUND_SERVICE_CRASH_MAX_RETRY = 16;
     private static final boolean DEFAULT_PROCESS_START_ASYNC = true;
@@ -212,6 +214,9 @@
     // allowing the next pending start to run.
     public long BG_START_TIMEOUT = DEFAULT_BG_START_TIMEOUT;
 
+    // For how long after a whitelisted service's start its process can start a background activity
+    public long SERVICE_BG_ACTIVITY_START_TIMEOUT = DEFAULT_SERVICE_BG_ACTIVITY_START_TIMEOUT;
+
     // Initial backoff delay for retrying bound foreground services
     public long BOUND_SERVICE_CRASH_RESTART_DURATION = DEFAULT_BOUND_SERVICE_CRASH_RESTART_DURATION;
 
@@ -398,6 +403,9 @@
                     DEFAULT_MAX_SERVICE_INACTIVITY);
             BG_START_TIMEOUT = mParser.getLong(KEY_BG_START_TIMEOUT,
                     DEFAULT_BG_START_TIMEOUT);
+            SERVICE_BG_ACTIVITY_START_TIMEOUT = mParser.getLong(
+                    KEY_SERVICE_BG_ACTIVITY_START_TIMEOUT,
+                    DEFAULT_SERVICE_BG_ACTIVITY_START_TIMEOUT);
             BOUND_SERVICE_CRASH_RESTART_DURATION = mParser.getLong(
                 KEY_BOUND_SERVICE_CRASH_RESTART_DURATION,
                 DEFAULT_BOUND_SERVICE_CRASH_RESTART_DURATION);
@@ -518,6 +526,8 @@
         pw.println(MAX_SERVICE_INACTIVITY);
         pw.print("  "); pw.print(KEY_BG_START_TIMEOUT); pw.print("=");
         pw.println(BG_START_TIMEOUT);
+        pw.print("  "); pw.print(KEY_SERVICE_BG_ACTIVITY_START_TIMEOUT); pw.print("=");
+        pw.println(SERVICE_BG_ACTIVITY_START_TIMEOUT);
         pw.print("  "); pw.print(KEY_BOUND_SERVICE_CRASH_RESTART_DURATION); pw.print("=");
         pw.println(BOUND_SERVICE_CRASH_RESTART_DURATION);
         pw.print("  "); pw.print(KEY_BOUND_SERVICE_CRASH_MAX_RETRY); pw.print("=");
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 57ce98c..cc90182 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -65,6 +65,7 @@
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.IProgressListener;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteCallback;
 import android.os.RemoteCallback.OnResultListener;
@@ -103,6 +104,7 @@
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 import javax.microedition.khronos.egl.EGL10;
 import javax.microedition.khronos.egl.EGLConfig;
@@ -114,6 +116,8 @@
     public static final String NO_CLASS_ERROR_CODE = "Error type 3";
     private static final String SHELL_PACKAGE_NAME = "com.android.shell";
 
+    private static final int USER_OPERATION_TIMEOUT_MS = 2 * 60 * 1000; // 2 minutes
+
     // IPC interface to activity manager -- don't need to do additional security checks.
     final IActivityManager mInterface;
     final IActivityTaskManager mTaskInterface;
@@ -377,6 +381,30 @@
         });
     }
 
+    private class ProgressWaiter extends IProgressListener.Stub {
+        private final CountDownLatch mFinishedLatch = new CountDownLatch(1);
+
+        @Override
+        public void onStarted(int id, Bundle extras) {}
+
+        @Override
+        public void onProgress(int id, int progress, Bundle extras) {}
+
+        @Override
+        public void onFinished(int id, Bundle extras) {
+            mFinishedLatch.countDown();
+        }
+
+        public boolean waitForFinish(long timeoutMillis) {
+            try {
+                return mFinishedLatch.await(timeoutMillis, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                System.err.println("Thread interrupted unexpectedly.");
+                return false;
+            }
+        }
+    }
+
     int runStartActivity(PrintWriter pw) throws RemoteException {
         Intent intent;
         try {
@@ -1692,8 +1720,24 @@
     }
 
     int runStartUser(PrintWriter pw) throws RemoteException {
-        String user = getNextArgRequired();
-        boolean success = mInterface.startUserInBackground(Integer.parseInt(user));
+        boolean wait = false;
+        String opt;
+        while ((opt = getNextOption()) != null) {
+            if ("-w".equals(opt)) {
+                wait = true;
+            } else {
+                getErrPrintWriter().println("Error: unknown option: " + opt);
+                return -1;
+            }
+        }
+        int userId = Integer.parseInt(getNextArgRequired());
+
+        final ProgressWaiter waiter = wait ? new ProgressWaiter() : null;
+        boolean success = mInterface.startUserInBackgroundWithListener(userId, waiter);
+        if (wait && success) {
+            success = waiter.waitForFinish(USER_OPERATION_TIMEOUT_MS);
+        }
+
         if (success) {
             pw.println("Success: user started");
         } else {
@@ -3023,9 +3067,10 @@
             pw.println("      execution of that user if it is currently stopped.");
             pw.println("  get-current-user");
             pw.println("      Returns id of the current foreground user.");
-            pw.println("  start-user <USER_ID>");
+            pw.println("  start-user [-w] <USER_ID>");
             pw.println("      Start USER_ID in background if it is currently stopped;");
-            pw.println("      use switch-user if you want to start the user in foreground");
+            pw.println("      use switch-user if you want to start the user in foreground.");
+            pw.println("      -w: wait for start-user to complete and the user to be unlocked.");
             pw.println("  unlock-user <USER_ID> [TOKEN_HEX]");
             pw.println("      Attempt to unlock the given user using the given authorization token.");
             pw.println("  stop-user [-w] [-f] <USER_ID>");
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 70733ef..ea23081 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -477,14 +477,22 @@
         // when processNextBroadcastLocked() next finds this uid as a receiver identity.
         if (!r.timeoutExempt) {
             if (mConstants.SLOW_TIME > 0 && elapsed > mConstants.SLOW_TIME) {
-                if (DEBUG_BROADCAST_DEFERRAL) {
-                    Slog.i(TAG_BROADCAST, "Broadcast receiver " + (r.nextReceiver - 1)
-                            + " was slow: " + receiver + " br=" + r);
-                }
-                if (r.curApp != null) {
-                    mDispatcher.startDeferring(r.curApp.uid);
+                // Core system packages are exempt from deferral policy
+                if (!UserHandle.isCore(r.curApp.uid)) {
+                    if (DEBUG_BROADCAST_DEFERRAL) {
+                        Slog.i(TAG_BROADCAST, "Broadcast receiver " + (r.nextReceiver - 1)
+                                + " was slow: " + receiver + " br=" + r);
+                    }
+                    if (r.curApp != null) {
+                        mDispatcher.startDeferring(r.curApp.uid);
+                    } else {
+                        Slog.d(TAG_BROADCAST, "finish receiver curApp is null? " + r);
+                    }
                 } else {
-                    Slog.d(TAG_BROADCAST, "finish receiver curApp is null? " + r);
+                    if (DEBUG_BROADCAST_DEFERRAL) {
+                        Slog.i(TAG_BROADCAST, "Core uid " + r.curApp.uid
+                                + " receiver was slow but not deferring: " + receiver + " br=" + r);
+                    }
                 }
             }
         } else {
diff --git a/services/core/java/com/android/server/am/MemoryStatUtil.java b/services/core/java/com/android/server/am/MemoryStatUtil.java
index a584914..0d03580 100644
--- a/services/core/java/com/android/server/am/MemoryStatUtil.java
+++ b/services/core/java/com/android/server/am/MemoryStatUtil.java
@@ -57,15 +57,18 @@
     private static final String PROC_STATUS_FILE_FMT = "/proc/%d/status";
     /** Path to procfs cmdline file. Used with pid: /proc/pid/cmdline. */
     private static final String PROC_CMDLINE_FILE_FMT = "/proc/%d/cmdline";
+    /** Path to debugfs file for the system ion heap. */
+    private static final String DEBUG_SYSTEM_ION_HEAP_FILE = "/sys/kernel/debug/ion/heaps/system";
 
     private static final Pattern PGFAULT = Pattern.compile("total_pgfault (\\d+)");
     private static final Pattern PGMAJFAULT = Pattern.compile("total_pgmajfault (\\d+)");
     private static final Pattern RSS_IN_BYTES = Pattern.compile("total_rss (\\d+)");
     private static final Pattern CACHE_IN_BYTES = Pattern.compile("total_cache (\\d+)");
     private static final Pattern SWAP_IN_BYTES = Pattern.compile("total_swap (\\d+)");
-
     private static final Pattern RSS_HIGH_WATERMARK_IN_BYTES =
             Pattern.compile("VmHWM:\\s*(\\d+)\\s*kB");
+    private static final Pattern ION_HEAP_SIZE_IN_BYTES =
+            Pattern.compile("\n\\s*total\\s*(\\d+)\\s*\n");
 
     private static final int PGFAULT_INDEX = 9;
     private static final int PGMAJFAULT_INDEX = 11;
@@ -127,6 +130,16 @@
         return parseCmdlineFromProcfs(readFileContents(path));
     }
 
+    /**
+     * Reads size of the system ion heap from debugfs.
+     *
+     * Returns value of the total size in bytes of the system ion heap from
+     * /sys/kernel/debug/ion/heaps/system.
+     */
+    public static long readSystemIonHeapSizeFromDebugfs() {
+        return parseIonHeapSizeFromDebugfs(readFileContents(DEBUG_SYSTEM_ION_HEAP_FILE));
+    }
+
     private static String readFileContents(String path) {
         final File file = new File(path);
         if (!file.exists()) {
@@ -228,6 +241,19 @@
     }
 
     /**
+     * Parses the ion heap size from the contents of a file under /sys/kernel/debug/ion/heaps in
+     * debugfs. The returned value is in bytes.
+     */
+    @VisibleForTesting
+    static long parseIonHeapSizeFromDebugfs(String contents) {
+        if (contents == null || contents.isEmpty()) {
+            return 0;
+        }
+        Matcher m = ION_HEAP_SIZE_IN_BYTES.matcher(contents);
+        return m.find() ? Long.parseLong(m.group(1)) : 0;
+    }
+
+    /**
      * Returns whether per-app memcg is available on device.
      */
     static boolean hasMemcg() {
diff --git a/services/core/java/com/android/server/am/OWNERS b/services/core/java/com/android/server/am/OWNERS
index e483b26..877bef7 100644
--- a/services/core/java/com/android/server/am/OWNERS
+++ b/services/core/java/com/android/server/am/OWNERS
@@ -23,6 +23,9 @@
 svetoslavganov@google.com
 toddke@google.com
 
+# Battery Stats
+joeo@google.com
+
 # Londoners
 michaelwr@google.com
 narayan@google.com
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 0387774..eeaa7de 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -125,6 +125,14 @@
     int pendingConnectionGroup;        // To be filled in to ProcessRecord once it connects
     int pendingConnectionImportance;   // To be filled in to ProcessRecord once it connects
 
+    // any current binding to this service has BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS flag?
+    private boolean hasBindingWhitelistingBgActivityStarts;
+    // is this service currently whitelisted to start activities from background by providing
+    // allowBackgroundActivityStarts=true to startServiceLocked()?
+    boolean hasStartedWhitelistingBgActivityStarts;
+    // used to clean up the state of hasStartedWhitelistingBgActivityStarts after a timeout
+    Runnable startedWhitelistingBgActivityStartsCleanUp;
+
     String stringName;      // caching of toString
 
     private int lastStartId;    // identifier of most recent start request.
@@ -371,6 +379,14 @@
         if (whitelistManager) {
             pw.print(prefix); pw.print("whitelistManager="); pw.println(whitelistManager);
         }
+        if (hasBindingWhitelistingBgActivityStarts) {
+            pw.print(prefix); pw.print("hasBindingWhitelistingBgActivityStarts=");
+            pw.println(hasBindingWhitelistingBgActivityStarts);
+        }
+        if (hasStartedWhitelistingBgActivityStarts) {
+            pw.print(prefix); pw.print("hasStartedWhitelistingBgActivityStarts=");
+            pw.println(hasStartedWhitelistingBgActivityStarts);
+        }
         if (delayed) {
             pw.print(prefix); pw.print("delayed="); pw.println(delayed);
         }
@@ -518,6 +534,15 @@
     }
 
     public void setProcess(ProcessRecord _proc) {
+        if (_proc != null) {
+            if (hasStartedWhitelistingBgActivityStarts || hasBindingWhitelistingBgActivityStarts) {
+                _proc.addAllowBackgroundActivityStartsToken(this);
+            } else {
+                _proc.removeAllowBackgroundActivityStartsToken(this);
+            }
+        } else if (app != null) {
+            app.removeAllowBackgroundActivityStartsToken(this);
+        }
         app = _proc;
         if (pendingConnectionGroup > 0 && _proc != null) {
             _proc.connectionService = this;
@@ -540,6 +565,62 @@
         }
     }
 
+    void updateHasBindingWhitelistingBgActivityStarts() {
+        boolean hasWhitelistingBinding = false;
+        for (int conni = connections.size() - 1; conni >= 0; conni--) {
+            ArrayList<ConnectionRecord> cr = connections.valueAt(conni);
+            for (int i = 0; i < cr.size(); i++) {
+                if ((cr.get(i).flags & Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS) != 0) {
+                    hasWhitelistingBinding = true;
+                    break;
+                }
+            }
+            if (hasWhitelistingBinding) {
+                break;
+            }
+        }
+        if (hasBindingWhitelistingBgActivityStarts != hasWhitelistingBinding) {
+            hasBindingWhitelistingBgActivityStarts = hasWhitelistingBinding;
+            updateParentProcessBgActivityStartsWhitelistingToken();
+        }
+    }
+
+    void setHasBindingWhitelistingBgActivityStarts(boolean newValue) {
+        if (hasBindingWhitelistingBgActivityStarts != newValue) {
+            hasBindingWhitelistingBgActivityStarts = newValue;
+            updateParentProcessBgActivityStartsWhitelistingToken();
+        }
+    }
+
+    void setHasStartedWhitelistingBgActivityStarts(boolean newValue) {
+        if (hasStartedWhitelistingBgActivityStarts != newValue) {
+            hasStartedWhitelistingBgActivityStarts = newValue;
+            updateParentProcessBgActivityStartsWhitelistingToken();
+        }
+    }
+
+    /**
+     * Whether the process this service runs in should be temporarily whitelisted to start
+     * activities from background depends on the current state of both
+     * {@code hasStartedWhitelistingBgActivityStarts} and
+     * {@code hasBindingWhitelistingBgActivityStarts}. If either is true, this ServiceRecord
+     * should be contributing as a token in parent ProcessRecord.
+     *
+     * @see com.android.server.am.ProcessRecord#mAllowBackgroundActivityStartsTokens
+     */
+    private void updateParentProcessBgActivityStartsWhitelistingToken() {
+        if (app == null) {
+            return;
+        }
+        if (hasStartedWhitelistingBgActivityStarts || hasBindingWhitelistingBgActivityStarts) {
+            // if the token is already there it's safe to "re-add it" - we're deadling with
+            // a set of Binder objects
+            app.addAllowBackgroundActivityStartsToken(this);
+        } else {
+            app.removeAllowBackgroundActivityStartsToken(this);
+        }
+    }
+
     public AppBindRecord retrieveAppBindingLocked(Intent intent,
             ProcessRecord app) {
         Intent.FilterComparison filter = new Intent.FilterComparison(intent);
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 1e406c0..f13c893 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -938,6 +938,7 @@
      *
      * @param userId ID of the user to start
      * @param foreground true if user should be brought to the foreground
+     * @param unlockListener Listener to be informed when the user has started and unlocked.
      * @return true if the user has been successfully started
      */
     boolean startUser(
@@ -962,6 +963,15 @@
         try {
             final int oldUserId = getCurrentUserId();
             if (oldUserId == userId) {
+                final UserState state = getStartedUserState(userId);
+                if (state != null && state.state == STATE_RUNNING_UNLOCKED) {
+                    // We'll skip all later code, so we must tell listener it's already unlocked.
+                    try {
+                        unlockListener.onFinished(userId, null);
+                    } catch (RemoteException ignore) {
+                        // Ignore.
+                    }
+                }
                 return true;
             }
 
@@ -1547,8 +1557,8 @@
                     }
                     builder.append(" asks to run as user ");
                     builder.append(userId);
-                    builder.append(" but is calling from user ");
-                    builder.append(UserHandle.getUserId(callingUid));
+                    builder.append(" but is calling from uid ");
+                    UserHandle.formatUid(builder, callingUid);
                     builder.append("; this requires ");
                     builder.append(INTERACT_ACROSS_USERS_FULL);
                     if (allowMode != ALLOW_FULL_ONLY) {
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index ba7288e..9c26526 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -1742,10 +1742,31 @@
         return checkOperationUnchecked(code, uid, resolvedPackageName, raw);
     }
 
-    private int checkOperationUnchecked(int code, int uid, String packageName,
-                boolean raw) {
+    /**
+     * @see #checkOperationUnchecked(int, int, String, boolean, boolean)
+     */
+    private @Mode int checkOperationUnchecked(int code, int uid, @NonNull String packageName,
+            boolean raw) {
+        return checkOperationUnchecked(code, uid, packageName, raw, true);
+    }
+
+    /**
+     * Get the mode of an app-op.
+     *
+     * @param code The code of the op
+     * @param uid The uid of the package the op belongs to
+     * @param packageName The package the op belongs to
+     * @param raw If the raw state of eval-ed state should be checked.
+     * @param verify If the code should check the package belongs to the uid
+     *
+     * @return The mode of the op
+     */
+    private @Mode int checkOperationUnchecked(int code, int uid, @NonNull String packageName,
+                boolean raw, boolean verify) {
         synchronized (this) {
-            checkPackage(uid, packageName);
+            if (verify) {
+                checkPackage(uid, packageName);
+            }
             if (isOpRestrictedLocked(uid, code, packageName)) {
                 return AppOpsManager.MODE_IGNORED;
             }
@@ -1756,7 +1777,7 @@
                 final int rawMode = uidState.opModes.get(code);
                 return raw ? rawMode : uidState.evalMode(code, rawMode);
             }
-            Op op = getOpLocked(code, uid, packageName, false, true, false);
+            Op op = getOpLocked(code, uid, packageName, false, verify, false);
             if (op == null) {
                 return AppOpsManager.opToDefaultMode(code);
             }
@@ -2359,7 +2380,7 @@
         throw new IllegalArgumentException("Bad operation #" + op);
     }
 
-    private @NonNull UidState getUidStateLocked(int uid, boolean edit) {
+    private @Nullable UidState getUidStateLocked(int uid, boolean edit) {
         UidState uidState = mUidStates.get(uid);
         if (uidState == null) {
             if (!edit) {
@@ -4535,5 +4556,10 @@
         public void setAllPkgModesToDefault(int code, int uid) {
             AppOpsService.this.setAllPkgModesToDefault(code, uid);
         }
+
+        @Override
+        public @Mode int checkOperationUnchecked(int code, int uid, @NonNull String packageName) {
+            return AppOpsService.this.checkOperationUnchecked(code, uid, packageName, true, false);
+        }
     }
 }
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 41a3c98..cb0bbd9 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -858,11 +858,20 @@
         if (musicDevice == AudioSystem.DEVICE_NONE) {
             musicDevice = mDeviceBroker.getDeviceForStream(AudioSystem.STREAM_MUSIC);
         }
-        // ignore condition on device being actually used for music when in communication
+
+        // always ignore condition on device being actually used for music when in communication
         // because music routing is altered in this case.
-        // also checks whether media routing if affected by a dynamic policy
+        // also checks whether media routing if affected by a dynamic policy or mirroring
         if (((device == musicDevice) || mDeviceBroker.isInCommunication())
-                && (device == devices) && !mDeviceBroker.hasMediaDynamicPolicy()) {
+                && (device == devices) && !mDeviceBroker.hasMediaDynamicPolicy()
+                        && ((musicDevice & AudioSystem.DEVICE_OUT_REMOTE_SUBMIX) == 0)) {
+            if (!AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0 /*not looking in past*/)) {
+                // no media playback, not a "becoming noisy" situation, otherwise it could cause
+                // the pausing of some apps that are playing remotely
+                AudioService.sDeviceLogger.log((new AudioEventLogger.StringEvent(
+                        "dropping ACTION_AUDIO_BECOMING_NOISY, no media playback")).printLog(TAG));
+                return 0;
+            }
             mDeviceBroker.postBroadcastBecomingNoisy();
             delay = 1000;
         }
diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
index d84a4d2..123564e 100644
--- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java
+++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
@@ -46,13 +46,11 @@
 import android.util.Slog;
 import android.util.SparseIntArray;
 
-import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
 import com.android.server.LocalServices;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -84,20 +82,14 @@
     // Keys are App IDs. Values are true for SYSTEM permission and false for NETWORK permission.
     private final Map<Integer, Boolean> mApps = new HashMap<>();
 
-    // Keys are App packageNames, Values are app uids. . We need to keep track of this information
-    // because PackageListObserver#onPackageRemoved does not pass the UID.
-    @GuardedBy("mPackageNameUidMap")
-    private final Map<String, Integer> mPackageNameUidMap = new HashMap<>();
-
     private class PackageListObserver implements PackageManagerInternal.PackageListObserver {
         @Override
-        public void onPackageAdded(String packageName) {
+        public void onPackageAdded(String packageName, int uid) {
             final PackageInfo app = getPackageInfo(packageName);
             if (app == null) {
                 Slog.wtf(TAG, "Failed to get information of installed package: " + packageName);
                 return;
             }
-            int uid = (app.applicationInfo != null) ? app.applicationInfo.uid : INVALID_UID;
             if (uid == INVALID_UID) {
                 Slog.wtf(TAG, "Failed to get the uid of installed package: " + packageName
                         + "uid: " + uid);
@@ -107,29 +99,21 @@
                 return;
             }
             sendPackagePermissionsForUid(uid,
-                    filterPermission(Arrays.asList(app.requestedPermissions)));
-            synchronized (mPackageNameUidMap) {
-                mPackageNameUidMap.put(packageName, uid);
-            }
+                    getNetdPermissionMask(app.requestedPermissions));
         }
 
         @Override
-        public void onPackageRemoved(String packageName) {
-            int uid;
-            synchronized (mPackageNameUidMap) {
-                if (!mPackageNameUidMap.containsKey(packageName)) {
-                    return;
-                }
-                uid = mPackageNameUidMap.get(packageName);
-                mPackageNameUidMap.remove(packageName);
-            }
+        public void onPackageRemoved(String packageName, int uid) {
             int permission = 0;
+            // If there are still packages remain under the same uid, check the permission of the
+            // remaining packages. We only remove the permission for a given uid when all packages
+            // for that uid no longer have that permission.
             String[] packages = mPackageManager.getPackagesForUid(uid);
             if (packages != null && packages.length > 0) {
                 for (String name : packages) {
                     final PackageInfo app = getPackageInfo(name);
                     if (app != null && app.requestedPermissions != null) {
-                        permission |= filterPermission(Arrays.asList(app.requestedPermissions));
+                        permission |= getNetdPermissionMask(app.requestedPermissions);
                     }
                 }
             }
@@ -184,12 +168,9 @@
 
             //TODO: unify the management of the permissions into one codepath.
             if (app.requestedPermissions != null) {
-                int otherNetdPerms = filterPermission(Arrays.asList(app.requestedPermissions));
+                int otherNetdPerms = getNetdPermissionMask(app.requestedPermissions);
                 if (otherNetdPerms != 0) {
                     netdPermsUids.put(uid, netdPermsUids.get(uid) | otherNetdPerms);
-                    synchronized (mPackageNameUidMap) {
-                        mPackageNameUidMap.put(app.applicationInfo.packageName, uid);
-                    }
                 }
             }
         }
@@ -422,13 +403,15 @@
         }
     }
 
-    private static int filterPermission(List<String> requestedPermissions) {
+    private static int getNetdPermissionMask(String[] requestedPermissions) {
         int permissions = 0;
-        if (requestedPermissions.contains(INTERNET)) {
-            permissions |= INetd.PERMISSION_INTERNET;
-        }
-        if (requestedPermissions.contains(UPDATE_DEVICE_STATS)) {
-            permissions |= INetd.PERMISSION_UPDATE_DEVICE_STATS;
+        for (String permissionName : requestedPermissions) {
+            if (permissionName.equals(INTERNET)) {
+                permissions |= INetd.PERMISSION_INTERNET;
+            }
+            if (permissionName.equals(UPDATE_DEVICE_STATS)) {
+                permissions |= INetd.PERMISSION_UPDATE_DEVICE_STATS;
+            }
         }
         return permissions;
     }
@@ -439,8 +422,6 @@
                     | MATCH_ANY_USER);
             return app;
         } catch (NameNotFoundException e) {
-            // App not found.
-            loge("NameNotFoundException " + packageName);
             return null;
         }
     }
diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
index d2ccfcc..4cafd4b 100644
--- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
+++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
@@ -126,8 +126,26 @@
     private final SparseArray<S> mServicesCache = new SparseArray<>();
 
     /**
+     * Whether the per-user service should be removed from the cache when its apk is updated.
+     */
+    private final boolean mRefreshServiceOnPackageUpdate;
+
+    /**
+     * Name of the service's package that was active but then was removed because its package
+     * update.
+     *
+     * <p>It's a temporary state set / used by the {@link PackageMonitor} implementation, but
+     * defined here so it can be dumped.
+     */
+    @GuardedBy("mLock")
+    private String mLastActivePackageName;
+
+    /**
      * Default constructor.
      *
+     * <p>When using this constructor, the {@link AbstractPerUserSystemService} is removed from
+     * the cache (and re-added) when the service package is updated.
+     *
      * @param context system context.
      * @param serviceNameResolver resolver for
      * {@link com.android.internal.infra.AbstractRemoteService} instances, or
@@ -139,8 +157,32 @@
     protected AbstractMasterSystemService(@NonNull Context context,
             @Nullable ServiceNameResolver serviceNameResolver,
             @Nullable String disallowProperty) {
+        this(context, serviceNameResolver, disallowProperty,
+                /* refreshServiceOnPackageUpdate=*/ true);
+    }
+
+    /**
+     * Full constructor.
+     *
+     * @param context system context.
+     * @param serviceNameResolver resolver for
+     * {@link com.android.internal.infra.AbstractRemoteService} instances, or
+     * {@code null} when the service doesn't bind to remote services.
+     * @param disallowProperty when not {@code null}, defines a {@link UserManager} restriction that
+     *        disables the service. <b>NOTE: </b> you'll also need to add it to
+     *        {@code UserRestrictionsUtils.USER_RESTRICTIONS}.
+     * @param refreshServiceOnPackageUpdate when {@code true}, the
+     *        {@link AbstractPerUserSystemService} is removed from the cache (and re-added) when the
+     *        service package is updated; when {@code false}, the service is untouched during the
+     *        update.
+     */
+    protected AbstractMasterSystemService(@NonNull Context context,
+            @Nullable ServiceNameResolver serviceNameResolver,
+            @Nullable String disallowProperty, boolean refreshServiceOnPackageUpdate) {
         super(context);
 
+        mRefreshServiceOnPackageUpdate = refreshServiceOnPackageUpdate;
+
         mServiceNameResolver = serviceNameResolver;
         if (mServiceNameResolver != null) {
             mServiceNameResolver
@@ -553,6 +595,8 @@
             final int size = mServicesCache.size();
             pw.print(prefix); pw.print("Debug: "); pw.print(realDebug);
             pw.print(" Verbose: "); pw.println(realVerbose);
+            pw.print(" Refresh on package update: "); pw.println(mRefreshServiceOnPackageUpdate);
+            pw.print(" Last active service on update: "); pw.println(mLastActivePackageName);
             if (mServiceNameResolver != null) {
                 pw.print(prefix); pw.print("Name resolver: ");
                 mServiceNameResolver.dumpShort(pw); pw.println();
@@ -590,21 +634,42 @@
     }
 
     private void startTrackingPackageChanges() {
-        PackageMonitor monitor = new PackageMonitor() {
+        final PackageMonitor monitor = new PackageMonitor() {
+
             @Override
-            public void onSomePackagesChanged() {
+            public void onPackageUpdateStarted(String packageName, int uid) {
                 synchronized (mLock) {
-                    updateCachedServiceLocked(getChangingUserId());
+                    final String activePackageName = getActiveServicePackageNameLocked();
+                    if (packageName.equals(activePackageName)) {
+                        final int userId = getChangingUserId();
+                        if (mRefreshServiceOnPackageUpdate) {
+                            if (debug) {
+                                Slog.d(mTag, "Removing service for user " + userId
+                                        + " because package " + activePackageName
+                                        + " is being updated");
+                            }
+                            mLastActivePackageName = activePackageName;
+                            removeCachedServiceLocked(userId);
+                        } else {
+                            if (debug) {
+                                Slog.d(mTag, "Holding service for user " + userId
+                                        + " while package " + activePackageName
+                                        + " is being updated");
+                            }
+                        }
+                    }
                 }
             }
 
             @Override
             public void onPackageUpdateFinished(String packageName, int uid) {
                 synchronized (mLock) {
-                    final String activePackageName = getActiveServicePackageName();
-                    if (packageName.equals(activePackageName)) {
-                        removeCachedServiceLocked(getChangingUserId());
-                    } else {
+                    String activePackageName = getActiveServicePackageNameLocked();
+                    if (activePackageName == null) {
+                        activePackageName = mLastActivePackageName;
+                        mLastActivePackageName = null;
+                    }
+                    if (!packageName.equals(activePackageName)) {
                         handlePackageUpdateLocked(packageName);
                     }
                 }
@@ -630,7 +695,7 @@
             public boolean onHandleForceStop(Intent intent, String[] packages,
                     int uid, boolean doit) {
                 synchronized (mLock) {
-                    final String activePackageName = getActiveServicePackageName();
+                    final String activePackageName = getActiveServicePackageNameLocked();
                     for (String pkg : packages) {
                         if (pkg.equals(activePackageName)) {
                             if (!doit) {
@@ -646,7 +711,9 @@
             }
 
             private void handleActiveServiceRemoved(@UserIdInt int userId) {
-                removeCachedServiceLocked(userId);
+                synchronized (mLock) {
+                    removeCachedServiceLocked(userId);
+                }
                 final String serviceSettingsProperty = getServiceSettingsProperty();
                 if (serviceSettingsProperty != null) {
                     Settings.Secure.putStringForUser(getContext().getContentResolver(),
@@ -654,7 +721,7 @@
                 }
             }
 
-            private String getActiveServicePackageName() {
+            private String getActiveServicePackageNameLocked() {
                 final int userId = getChangingUserId();
                 final S service = peekServiceForUserLocked(userId);
                 if (service == null) {
diff --git a/services/core/java/com/android/server/lights/Light.java b/services/core/java/com/android/server/lights/Light.java
index b5ec603..717e3da 100644
--- a/services/core/java/com/android/server/lights/Light.java
+++ b/services/core/java/com/android/server/lights/Light.java
@@ -16,8 +16,8 @@
 
 package com.android.server.lights;
 
-import android.hardware.light.V2_0.Flash;
 import android.hardware.light.V2_0.Brightness;
+import android.hardware.light.V2_0.Flash;
 
 public abstract class Light {
     public static final int LIGHT_FLASH_NONE = Flash.NONE;
@@ -39,8 +39,16 @@
      */
     public static final int BRIGHTNESS_MODE_LOW_PERSISTENCE = Brightness.LOW_PERSISTENCE;
 
+    /**
+     * Set the brightness of a display.
+     */
     public abstract void setBrightness(int brightness);
+
+    /**
+     * Set the brightness and mode of a display.
+     */
     public abstract void setBrightness(int brightness, int brightnessMode);
+
     public abstract void setColor(int color);
     public abstract void setFlashing(int color, int mode, int onMS, int offMS);
     public abstract void pulse();
diff --git a/services/core/java/com/android/server/lights/LightsService.java b/services/core/java/com/android/server/lights/LightsService.java
index a94ed60..ac906bb 100644
--- a/services/core/java/com/android/server/lights/LightsService.java
+++ b/services/core/java/com/android/server/lights/LightsService.java
@@ -15,15 +15,18 @@
 
 package com.android.server.lights;
 
-import com.android.server.SystemService;
-
 import android.app.ActivityManager;
 import android.content.Context;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.Message;
+import android.os.PowerManager;
 import android.os.Trace;
 import android.provider.Settings;
 import android.util.Slog;
+import android.view.SurfaceControl;
+
+import com.android.server.SystemService;
 
 public class LightsService extends SystemService {
     static final String TAG = "LightsService";
@@ -33,8 +36,25 @@
 
     private final class LightImpl extends Light {
 
-        private LightImpl(int id) {
+        private final IBinder mDisplayToken;
+        private final int mSurfaceControlMaximumBrightness;
+
+        private LightImpl(Context context, int id) {
             mId = id;
+            mDisplayToken = SurfaceControl.getInternalDisplayToken();
+            final boolean brightnessSupport = SurfaceControl.getDisplayBrightnessSupport(
+                    mDisplayToken);
+            if (DEBUG) {
+                Slog.d(TAG, "Display brightness support: " + brightnessSupport);
+            }
+            int maximumBrightness = 0;
+            if (brightnessSupport) {
+                PowerManager pm = context.getSystemService(PowerManager.class);
+                if (pm != null) {
+                    maximumBrightness = pm.getMaximumScreenBrightnessSetting();
+                }
+            }
+            mSurfaceControlMaximumBrightness = maximumBrightness;
         }
 
         @Override
@@ -51,10 +71,26 @@
                             ": brightness=0x" + Integer.toHexString(brightness));
                     return;
                 }
-
-                int color = brightness & 0x000000ff;
-                color = 0xff000000 | (color << 16) | (color << 8) | color;
-                setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, brightnessMode);
+                // Ideally, we'd like to set the brightness mode through the SF/HWC as well, but
+                // right now we just fall back to the old path through Lights brightessMode is
+                // anything but USER or the device shouldBeInLowPersistenceMode().
+                if (brightnessMode == BRIGHTNESS_MODE_USER && !shouldBeInLowPersistenceMode()
+                        && mSurfaceControlMaximumBrightness == 255) {
+                    // TODO: the last check should be mSurfaceControlMaximumBrightness != 0; the
+                    // reason we enforce 255 right now is to stay consistent with the old path. In
+                    // the future, the framework should be refactored so that brightness is a float
+                    // between 0.0f and 1.0f, and the actual number of supported brightness levels
+                    // is determined in the device-specific implementation.
+                    if (DEBUG) {
+                        Slog.d(TAG, "Using new setBrightness path!");
+                    }
+                    SurfaceControl.setDisplayBrightness(mDisplayToken,
+                            (float) brightness / mSurfaceControlMaximumBrightness);
+                } else {
+                    int color = brightness & 0x000000ff;
+                    color = 0xff000000 | (color << 16) | (color << 8) | color;
+                    setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, brightnessMode);
+                }
             }
         }
 
@@ -172,7 +208,7 @@
         super(context);
 
         for (int i = 0; i < LightsManager.LIGHT_ID_COUNT; i++) {
-            mLights[i] = new LightImpl(i);
+            mLights[i] = new LightImpl(context, i);
         }
     }
 
diff --git a/services/core/java/com/android/server/media/MediaSessionServiceImpl.java b/services/core/java/com/android/server/media/MediaSessionServiceImpl.java
index b86328b..94f289f 100644
--- a/services/core/java/com/android/server/media/MediaSessionServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaSessionServiceImpl.java
@@ -64,6 +64,7 @@
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.Process;
+import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.ServiceManager;
@@ -138,9 +139,9 @@
     private MediaSessionRecord mGlobalPrioritySession;
     private AudioPlayerStateMonitor mAudioPlayerStateMonitor;
 
-    // Used to notify system UI when remote volume was changed. TODO find a
-    // better way to handle this.
-    private IRemoteVolumeController mRvc;
+    // Used to notify System UI and Settings when remote volume was changed.
+    final RemoteCallbackList<IRemoteVolumeController> mRemoteVolumeControllers =
+            new RemoteCallbackList<>();
 
     public MediaSessionServiceImpl(Context context) {
         mContext = context;
@@ -281,20 +282,23 @@
     }
 
     /**
-     * Tells the system UI that volume has changed on an active remote session.
+     * Tells the System UI and Settings app that volume has changed on an active remote session.
      */
     public void notifyRemoteVolumeChanged(int flags, MediaSessionRecord session) {
-        synchronized (mLock) {
-            if (mRvc == null || !session.isActive()) {
-                return;
-            }
+        if (!session.isActive()) {
+            return;
+        }
+        int size = mRemoteVolumeControllers.beginBroadcast();
+        MediaSession.Token token = session.getSessionToken();
+        for (int i = size - 1; i >= 0; i--) {
             try {
-                mRvc.remoteVolumeChanged(session.getSessionToken(), flags);
+                IRemoteVolumeController cb = mRemoteVolumeControllers.getBroadcastItem(i);
+                cb.remoteVolumeChanged(token, flags);
             } catch (Exception e) {
-                Log.w(TAG, "Error sending volume change to system UI.", e);
-                mRvc = null;
+                Log.w(TAG, "Error sending volume change.", e);
             }
         }
+        mRemoteVolumeControllers.finishBroadcast();
     }
 
     @Override
@@ -497,7 +501,7 @@
      */
     private void enforceMediaPermissions(ComponentName compName, int pid, int uid,
             int resolvedUserId) {
-        if (isCurrentVolumeController(pid, uid)) return;
+        if (hasStatusBarServicePermission(pid, uid)) return;
         if (mContext
                 .checkPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL, pid, uid)
                 != PackageManager.PERMISSION_GRANTED
@@ -507,14 +511,14 @@
         }
     }
 
-    private boolean isCurrentVolumeController(int pid, int uid) {
+    private boolean hasStatusBarServicePermission(int pid, int uid) {
         return mContext.checkPermission(android.Manifest.permission.STATUS_BAR_SERVICE,
                 pid, uid) == PackageManager.PERMISSION_GRANTED;
     }
 
-    private void enforceSystemUiPermission(String action, int pid, int uid) {
-        if (!isCurrentVolumeController(pid, uid)) {
-            throw new SecurityException("Only system ui may " + action);
+    private void enforceStatusBarServicePermission(String action, int pid, int uid) {
+        if (!hasStatusBarServicePermission(pid, uid)) {
+            throw new SecurityException("Only System UI and Settings may " + action);
         }
     }
 
@@ -638,20 +642,25 @@
     }
 
     private void pushRemoteVolumeUpdateLocked(int userId) {
-        if (mRvc != null) {
+        FullUserRecord user = getFullUserRecordLocked(userId);
+        if (user == null) {
+            Log.w(TAG, "pushRemoteVolumeUpdateLocked failed. No user with id=" + userId);
+            return;
+        }
+
+        int size = mRemoteVolumeControllers.beginBroadcast();
+        MediaSessionRecord record = user.mPriorityStack.getDefaultRemoteSession(userId);
+        MediaSession.Token token = record == null ? null : record.getSessionToken();
+
+        for (int i = size - 1; i >= 0; i--) {
             try {
-                FullUserRecord user = getFullUserRecordLocked(userId);
-                if (user == null) {
-                    Log.w(TAG, "pushRemoteVolumeUpdateLocked failed. No user with id=" + userId);
-                    return;
-                }
-                MediaSessionRecord record = user.mPriorityStack.getDefaultRemoteSession(userId);
-                mRvc.updateRemoteController(record == null ? null : record.getSessionToken());
-            } catch (RemoteException e) {
-                Log.w(TAG, "Error sending default remote volume to sys ui.", e);
-                mRvc = null;
+                IRemoteVolumeController cb = mRemoteVolumeControllers.getBroadcastItem(i);
+                cb.updateRemoteController(token);
+            } catch (Exception e) {
+                Log.w(TAG, "Error sending default remote volume.", e);
             }
         }
+        mRemoteVolumeControllers.finishBroadcast();
     }
 
     void pushSession2TokensChangedLocked(int userId) {
@@ -1661,15 +1670,26 @@
         }
 
         @Override
-        public void setRemoteVolumeController(IRemoteVolumeController rvc) {
+        public void registerRemoteVolumeController(IRemoteVolumeController rvc) {
             final int pid = Binder.getCallingPid();
             final int uid = Binder.getCallingUid();
             final long token = Binder.clearCallingIdentity();
             try {
-                enforceSystemUiPermission("listen for volume changes", pid, uid);
-                synchronized (mLock) {
-                    mRvc = rvc;
-                }
+                enforceStatusBarServicePermission("listen for volume changes", pid, uid);
+                mRemoteVolumeControllers.register(rvc);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public void unregisterRemoteVolumeController(IRemoteVolumeController rvc) {
+            final int pid = Binder.getCallingPid();
+            final int uid = Binder.getCallingUid();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                enforceStatusBarServicePermission("listen for volume changes", pid, uid);
+                mRemoteVolumeControllers.unregister(rvc);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
@@ -1755,8 +1775,8 @@
 
         private boolean hasMediaControlPermission(int resolvedUserId, String packageName,
                 int pid, int uid) throws RemoteException {
-            // Allow API calls from the System UI
-            if (isCurrentVolumeController(pid, uid)) {
+            // Allow API calls from the System UI and Settings
+            if (hasStatusBarServicePermission(pid, uid)) {
                 return true;
             }
 
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 46ce4bf..d9ab132 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -149,7 +149,10 @@
     private int mImportance = IMPORTANCE_UNSPECIFIED;
     // Field used in global sort key to bypass normal notifications
     private int mCriticality = CriticalNotificationExtractor.NORMAL;
-    private CharSequence mImportanceExplanation = null;
+    // A MetricsEvent.NotificationImportanceExplanation, tracking source of mImportance.
+    private int mImportanceExplanationCode = MetricsEvent.IMPORTANCE_EXPLANATION_UNKNOWN;
+    // A MetricsEvent.NotificationImportanceExplanation for initial importance.
+    private int mInitialImportanceExplanationCode = MetricsEvent.IMPORTANCE_EXPLANATION_UNKNOWN;
 
     private int mSuppressedVisualEffects = 0;
     private String mUserExplanation;
@@ -332,14 +335,18 @@
 
     private int calculateInitialImportance() {
         final Notification n = sbn.getNotification();
-        int importance = getChannel().getImportance();
-        int requestedImportance = IMPORTANCE_DEFAULT;
+        int importance = getChannel().getImportance();  // Post-channels notifications use this
+        mInitialImportanceExplanationCode = getChannel().hasUserSetImportance()
+                ? MetricsEvent.IMPORTANCE_EXPLANATION_USER
+                : MetricsEvent.IMPORTANCE_EXPLANATION_APP;
 
-        // Migrate notification flags to scores
+        // Migrate notification priority flag to a priority value.
         if (0 != (n.flags & Notification.FLAG_HIGH_PRIORITY)) {
             n.priority = Notification.PRIORITY_MAX;
         }
 
+        // Convert priority value to an importance value, used only for pre-channels notifications.
+        int requestedImportance = IMPORTANCE_DEFAULT;
         n.priority = NotificationManagerService.clamp(n.priority, Notification.PRIORITY_MIN,
                 Notification.PRIORITY_MAX);
         switch (n.priority) {
@@ -360,10 +367,11 @@
         stats.requestedImportance = requestedImportance;
         stats.isNoisy = mSound != null || mVibration != null;
 
+        // For pre-channels notifications, apply system overrides and then use requestedImportance
+        // as importance.
         if (mPreChannelsNotification
                 && (importance == IMPORTANCE_UNSPECIFIED
-                || (getChannel().getUserLockedFields()
-                & USER_LOCKED_IMPORTANCE) == 0)) {
+                || (!getChannel().hasUserSetImportance()))) {
             if (!stats.isNoisy && requestedImportance > IMPORTANCE_LOW) {
                 requestedImportance = IMPORTANCE_LOW;
             }
@@ -378,6 +386,8 @@
                 requestedImportance = IMPORTANCE_HIGH;
             }
             importance = requestedImportance;
+            mInitialImportanceExplanationCode =
+                    MetricsEvent.IMPORTANCE_EXPLANATION_APP_PRE_CHANNELS;
         }
 
         stats.naturalImportance = importance;
@@ -540,7 +550,7 @@
                 + NotificationListenerService.Ranking.importanceToString(mAssistantImportance));
         pw.println(prefix + "mImportance="
                 + NotificationListenerService.Ranking.importanceToString(mImportance));
-        pw.println(prefix + "mImportanceExplanation=" + mImportanceExplanation);
+        pw.println(prefix + "mImportanceExplanation=" + getImportanceExplanation());
         pw.println(prefix + "mIsAppImportanceLocked=" + mIsAppImportanceLocked);
         pw.println(prefix + "mIntercept=" + mIntercept);
         pw.println(prefix + "mHidden==" + mHidden);
@@ -760,23 +770,23 @@
     }
 
     /**
-     * Recalculates the importance of the record after fields affecting importance have changed
+     * Recalculates the importance of the record after fields affecting importance have changed,
+     * and records an explanation.
      */
     protected void calculateImportance() {
         mImportance = calculateInitialImportance();
-        mImportanceExplanation = "app";
-        if (getChannel().hasUserSetImportance()) {
-            mImportanceExplanation = "user";
-        }
+        mImportanceExplanationCode = mInitialImportanceExplanationCode;
+
+        // Consider Notification Assistant and system overrides to importance. If both, system wins.
         if (!getChannel().hasUserSetImportance()
                 && mAssistantImportance != IMPORTANCE_UNSPECIFIED
                 && !getChannel().isImportanceLockedByOEM()) {
             mImportance = mAssistantImportance;
-            mImportanceExplanation = "asst";
+            mImportanceExplanationCode = MetricsEvent.IMPORTANCE_EXPLANATION_ASST;
         }
         if (mSystemImportance != IMPORTANCE_UNSPECIFIED) {
             mImportance = mSystemImportance;
-            mImportanceExplanation = "system";
+            mImportanceExplanationCode = MetricsEvent.IMPORTANCE_EXPLANATION_SYSTEM;
         }
     }
 
@@ -785,7 +795,20 @@
     }
 
     public CharSequence getImportanceExplanation() {
-        return mImportanceExplanation;
+        switch (mImportanceExplanationCode) {
+            case MetricsEvent.IMPORTANCE_EXPLANATION_UNKNOWN:
+                return null;
+            case MetricsEvent.IMPORTANCE_EXPLANATION_APP:
+            case MetricsEvent.IMPORTANCE_EXPLANATION_APP_PRE_CHANNELS:
+                return "app";
+            case MetricsEvent.IMPORTANCE_EXPLANATION_USER:
+                return "user";
+            case MetricsEvent.IMPORTANCE_EXPLANATION_ASST:
+                return "asst";
+            case MetricsEvent.IMPORTANCE_EXPLANATION_SYSTEM:
+                return "system";
+        }
+        return null;
     }
 
     public boolean setIntercepted(boolean intercept) {
@@ -1242,14 +1265,37 @@
     }
 
     public LogMaker getLogMaker(long now) {
-        return sbn.getLogMaker()
-                .clearTaggedData(MetricsEvent.NOTIFICATION_SHADE_INDEX)
+        LogMaker lm = sbn.getLogMaker()
                 .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_IMPORTANCE, mImportance)
                 .addTaggedData(MetricsEvent.NOTIFICATION_SINCE_CREATE_MILLIS, getLifespanMs(now))
                 .addTaggedData(MetricsEvent.NOTIFICATION_SINCE_UPDATE_MILLIS, getFreshnessMs(now))
                 .addTaggedData(MetricsEvent.NOTIFICATION_SINCE_VISIBLE_MILLIS, getExposureMs(now))
                 .addTaggedData(MetricsEvent.NOTIFICATION_SINCE_INTERRUPTION_MILLIS,
                         getInterruptionMs(now));
+        // Record results of the calculateImportance() calculation if available.
+        if (mImportanceExplanationCode != MetricsEvent.IMPORTANCE_EXPLANATION_UNKNOWN) {
+            lm.addTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_EXPLANATION,
+                    mImportanceExplanationCode);
+            // To avoid redundancy, we log the initial importance information only if it was
+            // overridden.
+            if (((mImportanceExplanationCode == MetricsEvent.IMPORTANCE_EXPLANATION_ASST)
+                    || (mImportanceExplanationCode == MetricsEvent.IMPORTANCE_EXPLANATION_SYSTEM))
+                    && (stats.naturalImportance != IMPORTANCE_UNSPECIFIED)) {
+                // stats.naturalImportance is due to one of the 3 sources of initial importance.
+                lm.addTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_INITIAL_EXPLANATION,
+                        mInitialImportanceExplanationCode);
+                lm.addTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_INITIAL,
+                        stats.naturalImportance);
+            }
+            // Log Assistant override if it was itself overridden by System. Since System can't be
+            // overridden, it never needs logging.
+            if (mImportanceExplanationCode == MetricsEvent.IMPORTANCE_EXPLANATION_SYSTEM
+                    && mAssistantImportance != IMPORTANCE_UNSPECIFIED) {
+                lm.addTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_ASST,
+                        mAssistantImportance);
+            }
+        }
+        return lm;
     }
 
     public LogMaker getLogMaker() {
diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java
index a4c04b2..5fdd872 100644
--- a/services/core/java/com/android/server/pm/ApexManager.java
+++ b/services/core/java/com/android/server/pm/ApexManager.java
@@ -41,6 +41,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.function.Function;
@@ -135,6 +136,17 @@
     }
 
     /**
+     * Checks if {@code packageName} is an apex package.
+     *
+     * @param packageName package to check.
+     * @return {@code true} if {@code packageName} is an apex package.
+     */
+    boolean isApexPackage(String packageName) {
+        populateActivePackagesCacheIfNeeded();
+        return mActivePackagesCache.containsKey(packageName);
+    }
+
+    /**
      * Retrieves information about an apexd staged session i.e. the internal state used by apexd to
      * track the different states of a session.
      *
@@ -246,6 +258,23 @@
     }
 
     /**
+     * Uninstalls given {@code apexPackage}.
+     *
+     * <p>NOTE. Device must be rebooted in order for uninstall to take effect.
+     *
+     * @param apexPackagePath package to uninstall.
+     * @return {@code true} upon successful uninstall, {@code false} otherwise.
+     */
+    boolean uninstallApex(String apexPackagePath) {
+        try {
+            mApexService.unstagePackages(Collections.singletonList(apexPackagePath));
+            return true;
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    /**
      * Dumps various state information to the provided {@link PrintWriter} object.
      *
      * @param pw the {@link PrintWriter} object to send information to.
diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS
index 3c1ee3e..af9b12a 100644
--- a/services/core/java/com/android/server/pm/OWNERS
+++ b/services/core/java/com/android/server/pm/OWNERS
@@ -10,76 +10,48 @@
 toddke@google.com
 
 # apex support
-per-file ApexManager.java = dariofreni@google.com, narayan@google.com, toddke@android.com, toddke@google.com
-per-file StagingManager.java = dariofreni@google.com, narayan@google.com, toddke@android.com, toddke@google.com
+per-file ApexManager.java = dariofreni@google.com
+per-file StagingManager.java = dariofreni@google.com
 
 # dex
-per-file AbstractStatsBase.java = agampe@google.com, toddke@google.com, svetoslavganov@google.com
-per-file AbstractStatsBase.java = calin@google.com, toddke@google.com, svetoslavganov@google.com
-per-file AbstractStatsBase.java = ngeoffray@google.com, toddke@google.com, svetoslavganov@google.com
-per-file BackgroundDexOptService.java = agampe@google.com, toddke@google.com, svetoslavganov@google.com
-per-file BackgroundDexOptService.java = calin@google.com, toddke@google.com, svetoslavganov@google.com
-per-file BackgroundDexOptService.java = ngeoffray@google.com, toddke@google.com, svetoslavganov@google.com
-per-file CompilerStats.java = agampe@google.com, toddke@google.com, svetoslavganov@google.com
-per-file CompilerStats.java = calin@google.com, toddke@google.com, svetoslavganov@google.com
-per-file CompilerStats.java = ngeoffray@google.com, toddke@google.com, svetoslavganov@google.com
-per-file DynamicCodeLoggingService.java = agampe@google.com, toddke@google.com, svetoslavganov@google.com
-per-file DynamicCodeLoggingService.java = calin@google.com, toddke@google.com, svetoslavganov@google.com
-per-file DynamicCodeLoggingService.java = ngeoffray@google.com, toddke@google.com, svetoslavganov@google.com
-per-file InstructionSets.java = agampe@google.com, toddke@google.com, svetoslavganov@google.com
-per-file InstructionSets.java = calin@google.com, toddke@google.com, svetoslavganov@google.com
-per-file InstructionSets.java = ngeoffray@google.com, toddke@google.com, svetoslavganov@google.com
-per-file OtaDexoptService.java = agampe@google.com, toddke@google.com, svetoslavganov@google.com
-per-file OtaDexoptService.java = calin@google.com, toddke@google.com, svetoslavganov@google.com
-per-file OtaDexoptService.java = ngeoffray@google.com, toddke@google.com, svetoslavganov@google.com
-per-file OtaDexoptShellCommand.java = agampe@google.com, toddke@google.com, svetoslavganov@google.com
-per-file OtaDexoptShellCommand.java = calin@google.com, toddke@google.com, svetoslavganov@google.com
-per-file OtaDexoptShellCommand.java = ngeoffray@google.com, toddke@google.com, svetoslavganov@google.com
-per-file PackageDexOptimizer.java = agampe@google.com, toddke@google.com, svetoslavganov@google.com
-per-file PackageDexOptimizer.java = calin@google.com, toddke@google.com, svetoslavganov@google.com
-per-file PackageDexOptimizer.java = ngeoffray@google.com, toddke@google.com, svetoslavganov@google.com
-per-file PackageManagerServiceCompilerMapping.java = agampe@google.com, toddke@google.com, svetoslavganov@google.com
-per-file PackageManagerServiceCompilerMapping.java = calin@google.com, toddke@google.com, svetoslavganov@google.com
-per-file PackageManagerServiceCompilerMapping.java = ngeoffray@google.com, toddke@google.com, svetoslavganov@google.com
-per-file PackageUsage.java = agampe@google.com, toddke@google.com, svetoslavganov@google.com
-per-file PackageUsage.java = calin@google.com, toddke@google.com, svetoslavganov@google.com
-per-file PackageUsage.java = ngeoffray@google.com, toddke@google.com, svetoslavganov@google.com
+per-file AbstractStatsBase.java = agampe@google.com, calin@google.com, ngeoffray@google.com
+per-file BackgroundDexOptService.java = agampe@google.com, calin@google.com, ngeoffray@google.com
+per-file CompilerStats.java = agampe@google.com, calin@google.com, ngeoffray@google.com
+per-file DynamicCodeLoggingService.java = alanstokes@google.com, agampe@google.com, calin@google.com, ngeoffray@google.com
+per-file InstructionSets.java = agampe@google.com, calin@google.com, ngeoffray@google.com
+per-file OtaDexoptService.java = agampe@google.com, calin@google.com, ngeoffray@google.com
+per-file OtaDexoptShellCommand.java = agampe@google.com, calin@google.com, ngeoffray@google.com
+per-file PackageDexOptimizer.java = agampe@google.com, calin@google.com, ngeoffray@google.com
+per-file PackageManagerServiceCompilerMapping.java = agampe@google.com, calin@google.com, ngeoffray@google.com
+per-file PackageUsage.java = agampe@google.com, calin@google.com, ngeoffray@google.com
 
 # multi user / cross profile
-per-file CrossProfileAppsServiceImpl.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
-per-file CrossProfileAppsServiceImpl.java = yamasani@google.com, omakoto@google.com, hackbod@google.com
-per-file CrossProfileAppsService.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
-per-file CrossProfileAppsService.java = yamasani@google.com, omakoto@google.com, hackbod@google.com
-per-file CrossProfileIntentFilter.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
-per-file CrossProfileIntentFilter.java = yamasani@google.com, omakoto@google.com, hackbod@google.com
-per-file CrossProfileIntentResolver.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
-per-file CrossProfileIntentResolver.java = yamasani@google.com, omakoto@google.com, hackbod@google.com
-per-file UserManagerService.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
-per-file UserManagerService.java = yamasani@google.com, omakoto@google.com, hackbod@google.com
-per-file UserRestrictionsUtils.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
-per-file UserRestrictionsUtils.java = yamasani@google.com, omakoto@google.com, hackbod@google.com
-per-file UserRestrictionsUtils.java = rubinxu@google.com, yamasani@google.com, hackbod@google.com
-per-file UserRestrictionsUtils.java = sandness@google.com, yamasani@google.com, hackbod@google.com
+per-file CrossProfileAppsServiceImpl.java = omakoto@google.com, yamasani@google.com
+per-file CrossProfileAppsService.java = omakoto@google.com, yamasani@google.com
+per-file CrossProfileIntentFilter.java = omakoto@google.com, yamasani@google.com
+per-file CrossProfileIntentResolver.java = omakoto@google.com, yamasani@google.com
+per-file UserManagerService.java = omakoto@google.com, yamasani@google.com
+per-file UserRestrictionsUtils.java = omakoto@google.com, rubinxu@google.com, sandness@google.com, yamasani@google.com
 
 # security
-per-file KeySetHandle.java = cbrubaker@google.com, svetoslavganov@google.com, hackbod@google.com
-per-file KeySetManagerService.java = cbrubaker@google.com, svetoslavganov@google.com, hackbod@google.com
-per-file PackageKeySetData.java = cbrubaker@google.com, svetoslavganov@google.com, hackbod@google.com
-per-file PackageSignatures.java = cbrubaker@google.com, svetoslavganov@google.com, hackbod@google.com
-per-file SELinuxMMAC.java = cbrubaker@google.com, svetoslavganov@google.com, hackbod@google.com
+per-file KeySetHandle.java = cbrubaker@google.com
+per-file KeySetManagerService.java = cbrubaker@google.com
+per-file PackageKeySetData.java = cbrubaker@google.com
+per-file PackageSignatures.java = cbrubaker@google.com
+per-file SELinuxMMAC.java = cbrubaker@google.com
 
 # shortcuts
-per-file LauncherAppsService.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
-per-file ShareTargetInfo.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
-per-file ShortcutBitmapSaver.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
-per-file ShortcutDumpFiles.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
-per-file ShortcutLauncher.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
-per-file ShortcutNonPersistentUser.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
-per-file ShortcutPackage.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
-per-file ShortcutPackageInfo.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
-per-file ShortcutPackageItem.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
-per-file ShortcutParser.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
-per-file ShortcutRequestPinProcessor.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
-per-file ShortcutService.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
-per-file ShortcutUser.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
+per-file LauncherAppsService.java = omakoto@google.com, yamasani@google.com
+per-file ShareTargetInfo.java = omakoto@google.com, yamasani@google.com
+per-file ShortcutBitmapSaver.java = omakoto@google.com, yamasani@google.com
+per-file ShortcutDumpFiles.java = omakoto@google.com, yamasani@google.com
+per-file ShortcutLauncher.java = omakoto@google.com, yamasani@google.com
+per-file ShortcutNonPersistentUser.java = omakoto@google.com, yamasani@google.com
+per-file ShortcutPackage.java = omakoto@google.com, yamasani@google.com
+per-file ShortcutPackageInfo.java = omakoto@google.com, yamasani@google.com
+per-file ShortcutPackageItem.java = omakoto@google.com, yamasani@google.com
+per-file ShortcutParser.java = omakoto@google.com, yamasani@google.com
+per-file ShortcutRequestPinProcessor.java = omakoto@google.com, yamasani@google.com
+per-file ShortcutService.java = omakoto@google.com, yamasani@google.com
+per-file ShortcutUser.java = omakoto@google.com, yamasani@google.com
 
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 3a4bcca..d249b97 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -205,7 +205,7 @@
 
         mApexManager = am;
 
-        mStagingManager = new StagingManager(pm, this, am, context);
+        mStagingManager = new StagingManager(this, am, context);
     }
 
     boolean okToSendBroadcasts()  {
@@ -589,7 +589,7 @@
         session = new PackageInstallerSession(mInternalCallback, mContext, mPm, this,
                 mInstallThread.getLooper(), mStagingManager, sessionId, userId,
                 installerPackageName, callingUid, params, createdMillis, stageDir, stageCid, false,
-                false, null, SessionInfo.INVALID_ID, false, false, false,
+                false, false, null, SessionInfo.INVALID_ID, false, false, false,
                 SessionInfo.STAGED_SESSION_NO_ERROR, "");
 
         synchronized (mSessions) {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 45b3b5b..81c0a97 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -145,6 +145,7 @@
     private static final String ATTR_SESSION_STAGE_DIR = "sessionStageDir";
     private static final String ATTR_SESSION_STAGE_CID = "sessionStageCid";
     private static final String ATTR_PREPARED = "prepared";
+    private static final String ATTR_COMMITTED = "committed";
     private static final String ATTR_SEALED = "sealed";
     private static final String ATTR_MULTI_PACKAGE = "multiPackage";
     private static final String ATTR_PARENT_SESSION_ID = "parentSessionId";
@@ -401,7 +402,7 @@
             PackageSessionProvider sessionProvider, Looper looper, StagingManager stagingManager,
             int sessionId, int userId,
             String installerPackageName, int installerUid, SessionParams params, long createdMillis,
-            File stageDir, String stageCid, boolean prepared, boolean sealed,
+            File stageDir, String stageCid, boolean prepared, boolean committed, boolean sealed,
             @Nullable int[] childSessionIds, int parentSessionId, boolean isReady,
             boolean isFailed, boolean isApplied, int stagedSessionErrorCode,
             String stagedSessionErrorMessage) {
@@ -434,6 +435,7 @@
         }
 
         mPrepared = prepared;
+        mCommitted = committed;
         mStagedSessionReady = isReady;
         mStagedSessionFailed = isFailed;
         mStagedSessionApplied = isApplied;
@@ -510,6 +512,13 @@
         }
     }
 
+    /** {@hide} */
+    boolean isCommitted() {
+        synchronized (mLock) {
+            return mCommitted;
+        }
+    }
+
     @GuardedBy("mLock")
     private void assertPreparedAndNotSealedLocked(String cookie) {
         assertPreparedAndNotCommittedOrDestroyedLocked(cookie);
@@ -1064,7 +1073,13 @@
 
     private void handleCommit() {
         if (params.isStaged) {
-            mStagingManager.commitSession(this);
+            try {
+                mStagingManager.commitSession(this);
+            } catch (StagingManager.AlreadyInProgressStagedSessionException e) {
+                dispatchSessionFinished(
+                        PackageManager.INSTALL_FAILED_OTHER_STAGED_SESSION_IN_PROGRESS,
+                        e.getMessage(), null);
+            }
             destroyInternal();
             dispatchSessionFinished(PackageManager.INSTALL_SUCCEEDED, "Session staged", null);
             return;
@@ -2143,6 +2158,7 @@
 
         pw.printPair("mClientProgress", mClientProgress);
         pw.printPair("mProgress", mProgress);
+        pw.printPair("mCommitted", mCommitted);
         pw.printPair("mSealed", mSealed);
         pw.printPair("mPermissionsManuallyAccepted", mPermissionsManuallyAccepted);
         pw.printPair("mRelinquished", mRelinquished);
@@ -2201,6 +2217,7 @@
                 writeStringAttribute(out, ATTR_SESSION_STAGE_CID, stageCid);
             }
             writeBooleanAttribute(out, ATTR_PREPARED, isPrepared());
+            writeBooleanAttribute(out, ATTR_COMMITTED, isCommitted());
             writeBooleanAttribute(out, ATTR_SEALED, isSealed());
 
             writeBooleanAttribute(out, ATTR_MULTI_PACKAGE, params.isMultiPackage);
@@ -2298,6 +2315,7 @@
         final File stageDir = (stageDirRaw != null) ? new File(stageDirRaw) : null;
         final String stageCid = readStringAttribute(in, ATTR_SESSION_STAGE_CID);
         final boolean prepared = readBooleanAttribute(in, ATTR_PREPARED, true);
+        final boolean committed = readBooleanAttribute(in, ATTR_COMMITTED);
         final boolean sealed = readBooleanAttribute(in, ATTR_SEALED);
         final int parentSessionId = readIntAttribute(in, ATTR_PARENT_SESSION_ID,
                 SessionInfo.INVALID_ID);
@@ -2374,8 +2392,8 @@
 
         return new PackageInstallerSession(callback, context, pm, sessionProvider,
                 installerThread, stagingManager, sessionId, userId, installerPackageName,
-                installerUid, params, createdMillis, stageDir, stageCid, prepared, sealed,
-                childSessionIdsArray, parentSessionId, isReady, isFailed, isApplied,
+                installerUid, params, createdMillis, stageDir, stageCid, prepared, committed,
+                sealed, childSessionIdsArray, parentSessionId, isReady, isFailed, isApplied,
                 stagedSessionErrorCode, stagedSessionErrorMessage);
     }
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 4dcab5e..e5b6397 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -160,6 +160,7 @@
 import android.content.pm.InstantAppRequest;
 import android.content.pm.InstrumentationInfo;
 import android.content.pm.IntentFilterVerificationInfo;
+import android.content.pm.PackageBackwardCompatibility;
 import android.content.pm.KeySet;
 import android.content.pm.ModuleInfo;
 import android.content.pm.PackageInfo;
@@ -1952,7 +1953,7 @@
             }
 
             if (allNewUsers && !update) {
-                notifyPackageAdded(packageName);
+                notifyPackageAdded(packageName, res.uid);
             }
 
             // Log current value of "unknown sources" setting
@@ -11058,6 +11059,8 @@
             pkg.mRealPackage = null;
             pkg.mAdoptPermissions = null;
         }
+
+        PackageBackwardCompatibility.modifySharedLibraries(pkg);
     }
 
     private static @NonNull <T> T assertNotNull(@Nullable T object, String message)
@@ -12317,7 +12320,7 @@
     }
 
     @Override
-    public void notifyPackageAdded(String packageName) {
+    public void notifyPackageAdded(String packageName, int uid) {
         final PackageListObserver[] observers;
         synchronized (mPackages) {
             if (mPackageListObservers.size() == 0) {
@@ -12328,7 +12331,7 @@
             observers = mPackageListObservers.toArray(observerArray);
         }
         for (int i = observers.length - 1; i >= 0; --i) {
-            observers[i].onPackageAdded(packageName);
+            observers[i].onPackageAdded(packageName, uid);
         }
     }
 
@@ -12339,7 +12342,7 @@
     };
 
     @Override
-    public void notifyPackageRemoved(String packageName) {
+    public void notifyPackageRemoved(String packageName, int uid) {
         final PackageListObserver[] observers;
         synchronized (mPackages) {
             if (mPackageListObservers.size() == 0) {
@@ -12350,7 +12353,7 @@
             observers = mPackageListObservers.toArray(observerArray);
         }
         for (int i = observers.length - 1; i >= 0; --i) {
-            observers[i].onPackageRemoved(packageName);
+            observers[i].onPackageRemoved(packageName, uid);
         }
     }
 
@@ -12937,6 +12940,8 @@
         final List<String> changedPackagesList = new ArrayList<>(packageNames.length);
         final IntArray changedUids = new IntArray(packageNames.length);
         final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
+        final boolean[] canRestrict = (restrictionFlags != 0) ? canSuspendPackageForUserInternal(
+                packageNames, userId) : null;
 
         for (int i = 0; i < packageNames.length; i++) {
             final String packageName = packageNames[i];
@@ -12950,7 +12955,7 @@
                     continue;
                 }
             }
-            if (restrictionFlags != 0 && !canSuspendPackageForUserInternal(packageName, userId)) {
+            if (canRestrict != null && !canRestrict[i]) {
                 unactionedPackages.add(packageName);
                 continue;
             }
@@ -13007,6 +13012,8 @@
         final List<String> changedPackagesList = new ArrayList<>(packageNames.length);
         final IntArray changedUids = new IntArray(packageNames.length);
         final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
+        final boolean[] canSuspend = suspended ? canSuspendPackageForUserInternal(packageNames,
+                userId) : null;
 
         for (int i = 0; i < packageNames.length; i++) {
             final String packageName = packageNames[i];
@@ -13026,7 +13033,7 @@
                     continue;
                 }
             }
-            if (suspended && !canSuspendPackageForUserInternal(packageName, userId)) {
+            if (canSuspend != null && !canSuspend[i]) {
                 unactionedPackages.add(packageName);
                 continue;
             }
@@ -13190,87 +13197,97 @@
                     + " cannot query getUnsuspendablePackagesForUser for user " + userId);
         }
         final ArraySet<String> unactionablePackages = new ArraySet<>();
-        for (String packageName : packageNames) {
-            if (!canSuspendPackageForUserInternal(packageName, userId)) {
-                unactionablePackages.add(packageName);
+        final boolean[] canSuspend = canSuspendPackageForUserInternal(packageNames, userId);
+        for (int i = 0; i < packageNames.length; i++) {
+            if (!canSuspend[i]) {
+                unactionablePackages.add(packageNames[i]);
             }
         }
         return unactionablePackages.toArray(new String[unactionablePackages.size()]);
     }
 
-    private boolean canSuspendPackageForUserInternal(String packageName, int userId) {
+    /**
+     * Returns an array of booleans, such that the ith boolean denotes whether the ith package can
+     * be suspended or not.
+     *
+     * @param packageNames  The package names to check suspendability for.
+     * @param userId The user to check in
+     * @return An array containing results of the checks
+     */
+    @NonNull
+    private boolean[] canSuspendPackageForUserInternal(@NonNull String[] packageNames, int userId) {
+        final boolean[] canSuspend = new boolean[packageNames.length];
         final long callingId = Binder.clearCallingIdentity();
         try {
-            if (isPackageDeviceAdmin(packageName, userId)) {
-                Slog.w(TAG, "Cannot suspend package \"" + packageName
-                        + "\": has an active device admin");
-                return false;
-            }
+            final String activeLauncherPackageName = getActiveLauncherPackageName(userId);
+            final String dialerPackageName = getDefaultDialerPackageName(userId);
+            for (int i = 0; i < packageNames.length; i++) {
+                canSuspend[i] = false;
+                final String packageName = packageNames[i];
 
-            String activeLauncherPackageName = getActiveLauncherPackageName(userId);
-            if (packageName.equals(activeLauncherPackageName)) {
-                Slog.w(TAG, "Cannot suspend package \"" + packageName
-                        + "\": contains the active launcher");
-                return false;
-            }
-
-            if (packageName.equals(mRequiredInstallerPackage)) {
-                Slog.w(TAG, "Cannot suspend package \"" + packageName
-                        + "\": required for package installation");
-                return false;
-            }
-
-            if (packageName.equals(mRequiredUninstallerPackage)) {
-                Slog.w(TAG, "Cannot suspend package \"" + packageName
-                        + "\": required for package uninstallation");
-                return false;
-            }
-
-            if (packageName.equals(mRequiredVerifierPackage)) {
-                Slog.w(TAG, "Cannot suspend package \"" + packageName
-                        + "\": required for package verification");
-                return false;
-            }
-
-            if (packageName.equals(getDefaultDialerPackageName(userId))) {
-                Slog.w(TAG, "Cannot suspend package \"" + packageName
-                        + "\": is the default dialer");
-                return false;
-            }
-
-            if (packageName.equals(mRequiredPermissionControllerPackage)) {
-                Slog.w(TAG, "Cannot suspend package \"" + packageName
-                        + "\": required for permissions management");
-                return false;
-            }
-
-            synchronized (mPackages) {
-                if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
+                if (isPackageDeviceAdmin(packageName, userId)) {
                     Slog.w(TAG, "Cannot suspend package \"" + packageName
-                            + "\": protected package");
-                    return false;
+                            + "\": has an active device admin");
+                    continue;
                 }
-
-                // Cannot suspend static shared libs as they are considered
-                // a part of the using app (emulating static linking). Also
-                // static libs are installed always on internal storage.
-                PackageParser.Package pkg = mPackages.get(packageName);
-                if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
-                    Slog.w(TAG, "Cannot suspend package: " + packageName
-                            + " providing static shared library: "
-                            + pkg.staticSharedLibName);
-                    return false;
+                if (packageName.equals(activeLauncherPackageName)) {
+                    Slog.w(TAG, "Cannot suspend package \"" + packageName
+                            + "\": contains the active launcher");
+                    continue;
                 }
-            }
+                if (packageName.equals(mRequiredInstallerPackage)) {
+                    Slog.w(TAG, "Cannot suspend package \"" + packageName
+                            + "\": required for package installation");
+                    continue;
+                }
+                if (packageName.equals(mRequiredUninstallerPackage)) {
+                    Slog.w(TAG, "Cannot suspend package \"" + packageName
+                            + "\": required for package uninstallation");
+                    continue;
+                }
+                if (packageName.equals(mRequiredVerifierPackage)) {
+                    Slog.w(TAG, "Cannot suspend package \"" + packageName
+                            + "\": required for package verification");
+                    continue;
+                }
+                if (packageName.equals(dialerPackageName)) {
+                    Slog.w(TAG, "Cannot suspend package \"" + packageName
+                            + "\": is the default dialer");
+                    continue;
+                }
+                if (packageName.equals(mRequiredPermissionControllerPackage)) {
+                    Slog.w(TAG, "Cannot suspend package \"" + packageName
+                            + "\": required for permissions management");
+                    continue;
+                }
+                synchronized (mPackages) {
+                    if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
+                        Slog.w(TAG, "Cannot suspend package \"" + packageName
+                                + "\": protected package");
+                        continue;
+                    }
 
-            if (PLATFORM_PACKAGE_NAME.equals(packageName)) {
-                Slog.w(TAG, "Cannot suspend the platform package: " + packageName);
-                return false;
+                    // Cannot suspend static shared libs as they are considered
+                    // a part of the using app (emulating static linking). Also
+                    // static libs are installed always on internal storage.
+                    PackageParser.Package pkg = mPackages.get(packageName);
+                    if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
+                        Slog.w(TAG, "Cannot suspend package: " + packageName
+                                + " providing static shared library: "
+                                + pkg.staticSharedLibName);
+                        continue;
+                    }
+                }
+                if (PLATFORM_PACKAGE_NAME.equals(packageName)) {
+                    Slog.w(TAG, "Cannot suspend the platform package: " + packageName);
+                    continue;
+                }
+                canSuspend[i] = true;
             }
-            return true;
         } finally {
             Binder.restoreCallingIdentity(callingId);
         }
+        return canSuspend;
     }
 
     private String getActiveLauncherPackageName(int userId) {
@@ -17904,7 +17921,8 @@
                 return;
             }
             Bundle extras = new Bundle(2);
-            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
+            final int removedUid = removedAppId >= 0  ? removedAppId : uid;
+            extras.putInt(Intent.EXTRA_UID, removedUid);
             extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
             extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
             if (isUpdate || isRemovedPackageSystemUpdate) {
@@ -17925,7 +17943,7 @@
                         removedPackage, extras,
                         Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
                         null, null, broadcastUsers, instantUserIds);
-                    packageSender.notifyPackageRemoved(removedPackage);
+                    packageSender.notifyPackageRemoved(removedPackage, removedUid);
                 }
             }
             if (removedAppId >= 0) {
@@ -23901,6 +23919,50 @@
                 mDefaultHomeProvider = provider;
             }
         }
+
+        @Override
+        public boolean isApexPackage(String packageName) {
+            return PackageManagerService.this.mApexManager.isApexPackage(packageName);
+        }
+
+        @Override
+        public void uninstallApex(String packageName, long versionCode, int userId,
+                IntentSender intentSender) {
+            final int callerUid = Binder.getCallingUid();
+            if (callerUid != Process.ROOT_UID && callerUid != Process.SHELL_UID) {
+                throw new SecurityException("Not allowed to uninstall apexes");
+            }
+            PackageInstallerService.PackageDeleteObserverAdapter adapter =
+                    new PackageInstallerService.PackageDeleteObserverAdapter(
+                            PackageManagerService.this.mContext, intentSender, packageName,
+                            false, userId);
+            if (userId != UserHandle.USER_ALL) {
+                adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
+                        "Can't uninstall an apex for a single user");
+                return;
+            }
+            final ApexManager am = PackageManagerService.this.mApexManager;
+            PackageInfo activePackage = am.getActivePackage(packageName);
+            if (activePackage == null) {
+                adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
+                        packageName + " is not an apex package");
+                return;
+            }
+            if (versionCode != PackageManager.VERSION_CODE_HIGHEST
+                    && activePackage.getLongVersionCode() != versionCode) {
+                adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
+                        "Active version " + activePackage.getLongVersionCode()
+                                + " is not equal to " + versionCode + "]");
+                return;
+            }
+            if (!am.uninstallApex(activePackage.applicationInfo.sourceDir)) {
+                adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
+                        "Failed to uninstall apex " + packageName);
+            } else {
+                adapter.onPackageDeleted(packageName, PackageManager.DELETE_SUCCEEDED,
+                        null);
+            }
+        }
     }
 
     @GuardedBy("mPackages")
@@ -24410,6 +24472,6 @@
         final IIntentReceiver finishedReceiver, final int[] userIds, int[] instantUserIds);
     void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
         boolean includeStopped, int appId, int[] userIds, int[] instantUserIds);
-    void notifyPackageAdded(String packageName);
-    void notifyPackageRemoved(String packageName);
+    void notifyPackageAdded(String packageName, int uid);
+    void notifyPackageRemoved(String packageName, int uid);
 }
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 912a50e..2d1afa7 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -1619,30 +1619,36 @@
         }
 
         userId = translateUserId(userId, true /*allowAll*/, "runUninstall");
-        if (userId == UserHandle.USER_ALL) {
-            userId = UserHandle.USER_SYSTEM;
-            flags |= PackageManager.DELETE_ALL_USERS;
-        } else {
-            final PackageInfo info = mInterface.getPackageInfo(packageName,
-                    PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
-            if (info == null) {
-                pw.println("Failure [not installed for " + userId + "]");
-                return 1;
-            }
-            final boolean isSystem =
-                    (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
-            // If we are being asked to delete a system app for just one
-            // user set flag so it disables rather than reverting to system
-            // version of the app.
-            if (isSystem) {
-                flags |= PackageManager.DELETE_SYSTEM_APP;
-            }
-        }
-
         final LocalIntentReceiver receiver = new LocalIntentReceiver();
-        mInterface.getPackageInstaller().uninstall(new VersionedPackage(packageName,
-                versionCode), null /*callerPackageName*/, flags,
-                receiver.getIntentSender(), userId);
+        PackageManagerInternal internal = LocalServices.getService(PackageManagerInternal.class);
+
+        if (internal.isApexPackage(packageName)) {
+            internal.uninstallApex(packageName, versionCode, userId, receiver.getIntentSender());
+        } else {
+            if (userId == UserHandle.USER_ALL) {
+                userId = UserHandle.USER_SYSTEM;
+                flags |= PackageManager.DELETE_ALL_USERS;
+            } else {
+                final PackageInfo info = mInterface.getPackageInfo(packageName,
+                        PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
+                if (info == null) {
+                    pw.println("Failure [not installed for " + userId + "]");
+                    return 1;
+                }
+                final boolean isSystem =
+                        (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
+                // If we are being asked to delete a system app for just one
+                // user set flag so it disables rather than reverting to system
+                // version of the app.
+                if (isSystem) {
+                    flags |= PackageManager.DELETE_SYSTEM_APP;
+                }
+            }
+
+            mInterface.getPackageInstaller().uninstall(new VersionedPackage(packageName,
+                            versionCode), null /*callerPackageName*/, flags,
+                    receiver.getIntentSender(), userId);
+        }
 
         final Intent result = receiver.getResult();
         final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index 4ee6eaf..fce9bb1 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -17,6 +17,7 @@
 package com.android.server.pm;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.apex.ApexInfo;
 import android.apex.ApexInfoList;
 import android.apex.ApexSessionInfo;
@@ -68,7 +69,6 @@
     private static final String TAG = "StagingManager";
 
     private final PackageInstallerService mPi;
-    private final PackageManagerService mPm;
     private final ApexManager mApexManager;
     private final PowerManager mPowerManager;
     private final Handler mBgHandler;
@@ -76,9 +76,7 @@
     @GuardedBy("mStagedSessions")
     private final SparseArray<PackageInstallerSession> mStagedSessions = new SparseArray<>();
 
-    StagingManager(PackageManagerService pm, PackageInstallerService pi, ApexManager am,
-            Context context) {
-        mPm = pm;
+    StagingManager(PackageInstallerService pi, ApexManager am, Context context) {
         mPi = pi;
         mApexManager = am;
         mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
@@ -479,11 +477,42 @@
         return true;
     }
 
-    void commitSession(@NonNull PackageInstallerSession session) {
+    void commitSession(@NonNull PackageInstallerSession session)
+            throws AlreadyInProgressStagedSessionException {
+        PackageInstallerSession activeSession = getActiveSession();
+        boolean anotherSessionAlreadyInProgress =
+                activeSession != null && session.sessionId != activeSession.sessionId;
         updateStoredSession(session);
+        if (anotherSessionAlreadyInProgress) {
+            session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
+                    "There is already in-progress committed staged session "
+                            + activeSession.sessionId);
+            throw new AlreadyInProgressStagedSessionException(activeSession.sessionId);
+        }
         mBgHandler.post(() -> preRebootVerification(session));
     }
 
+    @Nullable
+    private PackageInstallerSession getActiveSession() {
+        synchronized (mStagedSessions) {
+            for (int i = 0; i < mStagedSessions.size(); i++) {
+                final PackageInstallerSession session = mStagedSessions.valueAt(i);
+                if (!session.isCommitted()) {
+                    continue;
+                }
+                if (session.hasParentSessionId()) {
+                    // Staging manager will finalize only parent session. Ignore child sessions
+                    // picking the active.
+                    continue;
+                }
+                if (!session.isStagedSessionApplied() && !session.isStagedSessionFailed()) {
+                    return session;
+                }
+            }
+        }
+        return null;
+    }
+
     void createSession(@NonNull PackageInstallerSession sessionInfo) {
         synchronized (mStagedSessions) {
             mStagedSessions.append(sessionInfo.sessionId, sessionInfo);
@@ -498,7 +527,7 @@
 
     void abortCommittedSession(@NonNull PackageInstallerSession session) {
         if (session.isStagedSessionApplied()) {
-            Slog.w(TAG, "Cannot abort applied session!");
+            Slog.w(TAG, "Cannot abort applied session : " + session.sessionId);
             return;
         }
         abortSession(session);
@@ -574,6 +603,10 @@
     }
 
     private void checkStateAndResume(@NonNull PackageInstallerSession session) {
+        if (!session.isCommitted()) {
+            // Session hasn't been committed yet, ignore.
+            return;
+        }
         // Check the state of the session and decide what to do next.
         if (session.isStagedSessionFailed() || session.isStagedSessionApplied()) {
             // Final states, nothing to do.
@@ -618,4 +651,12 @@
             }
         }
     }
+
+    static final class AlreadyInProgressStagedSessionException extends Exception {
+
+        AlreadyInProgressStagedSessionException(int sessionId) {
+            super("There is already in-progress committed staged session "
+                    + sessionId);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java
index 3b805d51..f56231f 100644
--- a/services/core/java/com/android/server/pm/dex/DexManager.java
+++ b/services/core/java/com/android/server/pm/dex/DexManager.java
@@ -16,7 +16,7 @@
 
 package com.android.server.pm.dex;
 
-import static android.provider.DeviceConfig.DexBoot;
+import static android.provider.DeviceConfig.NAMESPACE_DEX_BOOT;
 
 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
 import static com.android.server.pm.dex.PackageDexUsage.DexUseInfo;
@@ -72,6 +72,10 @@
     private static final String PROPERTY_NAME_PM_DEXOPT_PRIV_APPS_OOB_LIST =
             "pm.dexopt.priv-apps-oob-list";
 
+    // flags for Device Config API
+    private static final String PRIV_APPS_OOB_ENABLED = "priv_apps_oob_enabled";
+    private static final String PRIV_APPS_OOB_WHITELIST = "priv_apps_oob_whitelist";
+
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     private final Context mContext;
@@ -713,8 +717,8 @@
         return isPackageSelectedToRunOobInternal(
                 SystemProperties.getBoolean(PROPERTY_NAME_PM_DEXOPT_PRIV_APPS_OOB, false),
                 SystemProperties.get(PROPERTY_NAME_PM_DEXOPT_PRIV_APPS_OOB_LIST, "ALL"),
-                DeviceConfig.getProperty(DexBoot.NAMESPACE, DexBoot.PRIV_APPS_OOB_ENABLED),
-                DeviceConfig.getProperty(DexBoot.NAMESPACE, DexBoot.PRIV_APPS_OOB_WHITELIST),
+                DeviceConfig.getProperty(NAMESPACE_DEX_BOOT, PRIV_APPS_OOB_ENABLED),
+                DeviceConfig.getProperty(NAMESPACE_DEX_BOOT, PRIV_APPS_OOB_WHITELIST),
                 packageNamesInSameProcess);
     }
 
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index b877fe7..f97dd3b 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -155,11 +155,6 @@
         ACTIVITY_RECOGNITION_PERMISSIONS.add(Manifest.permission.ACTIVITY_RECOGNITION);
     }
 
-    private static final Set<String> COARSE_LOCATION_PERMISSIONS = new ArraySet<>();
-    static {
-        COARSE_LOCATION_PERMISSIONS.add(Manifest.permission.ACCESS_COARSE_LOCATION);
-    }
-
     private static final Set<String> CALENDAR_PERMISSIONS = new ArraySet<>();
     static {
         CALENDAR_PERMISSIONS.add(Manifest.permission.READ_CALENDAR);
@@ -803,8 +798,7 @@
 
     private void grantDefaultPermissionsToDefaultSystemUseOpenWifiApp(
             String useOpenWifiPackage, int userId) {
-        grantPermissionsToSystemPackage(
-                useOpenWifiPackage, userId, COARSE_LOCATION_PERMISSIONS);
+        grantPermissionsToSystemPackage(useOpenWifiPackage, userId, ALWAYS_LOCATION_PERMISSIONS);
     }
 
     public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
@@ -824,7 +818,7 @@
 
     public void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName, int userId) {
         Log.i(TAG, "Granting permissions to default Use Open WiFi app for user:" + userId);
-        grantIgnoringSystemPackage(packageName, userId, COARSE_LOCATION_PERMISSIONS);
+        grantIgnoringSystemPackage(packageName, userId, ALWAYS_LOCATION_PERMISSIONS);
     }
 
     public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index f7d8e0e..897b885 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -1273,7 +1273,7 @@
             @NonNull ArraySet<String> sourcePerms, @NonNull String newPerm,
             @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
             @UserIdInt int userId) {
-        AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
+        AppOpsManagerInternal appOpsManager = LocalServices.getService(AppOpsManagerInternal.class);
         String pkgName = pkg.packageName;
 
         if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
@@ -1287,10 +1287,10 @@
                     String sourcePerm = sourcePerms.valueAt(i);
 
                     if (ps.hasRuntimePermission(sourcePerm, userId)) {
-                        String sourceOp = permissionToOp(sourcePerm);
+                        int sourceOp = permissionToOpCode(sourcePerm);
 
-                        if (sourceOp != null) {
-                            int mode = appOpsManager.unsafeCheckOpRaw(sourceOp,
+                        if (sourceOp != OP_NONE) {
+                            int mode = appOpsManager.checkOperationUnchecked(sourceOp,
                                     getUid(userId, getAppId(pkg.applicationInfo.uid)), pkgName);
 
                             if (mode == MODE_FOREGROUND || mode == MODE_ERRORED) {
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index c0e5974..5810636 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -44,7 +44,6 @@
 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.LAST_SYSTEM_WINDOW;
-import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
@@ -127,7 +126,6 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.database.ContentObserver;
-import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.hardware.display.DisplayManager;
@@ -211,7 +209,6 @@
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.ScreenshotHelper;
-import com.android.internal.widget.PointerLocationView;
 import com.android.server.ExtconStateObserver;
 import com.android.server.ExtconUEventObserver;
 import com.android.server.GestureLauncherService;
@@ -494,9 +491,6 @@
 
     private boolean mHandleVolumeKeysInWM;
 
-    int mPointerLocationMode = 0; // guarded by mLock
-    PointerLocationView mPointerLocationView;
-
     private boolean mPendingKeyguardOccluded;
     private boolean mKeyguardOccludedChanged;
     private boolean mNotifyUserActivity;
@@ -619,8 +613,6 @@
     private boolean mPerDisplayFocusEnabled = false;
     private volatile int mTopFocusedDisplayId = INVALID_DISPLAY;
 
-    private static final int MSG_ENABLE_POINTER_LOCATION = 1;
-    private static final int MSG_DISABLE_POINTER_LOCATION = 2;
     private static final int MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK = 3;
     private static final int MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK = 4;
     private static final int MSG_KEYGUARD_DRAWN_COMPLETE = 5;
@@ -651,12 +643,6 @@
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
-                case MSG_ENABLE_POINTER_LOCATION:
-                    enablePointerLocation();
-                    break;
-                case MSG_DISABLE_POINTER_LOCATION:
-                    disablePointerLocation();
-                    break;
                 case MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK:
                     dispatchMediaKeyWithWakeLock((KeyEvent)msg.obj);
                     break;
@@ -779,9 +765,6 @@
             resolver.registerContentObserver(Settings.System.getUriFor(
                     Settings.System.SCREEN_OFF_TIMEOUT), false, this,
                     UserHandle.USER_ALL);
-            resolver.registerContentObserver(Settings.System.getUriFor(
-                    Settings.System.POINTER_LOCATION), false, this,
-                    UserHandle.USER_ALL);
             resolver.registerContentObserver(Settings.Secure.getUriFor(
                     Settings.Secure.DEFAULT_INPUT_METHOD), false, this,
                     UserHandle.USER_ALL);
@@ -2007,15 +1990,6 @@
                 updateWakeGestureListenerLp();
             }
 
-            if (mSystemReady) {
-                int pointerLocation = Settings.System.getIntForUser(resolver,
-                        Settings.System.POINTER_LOCATION, 0, UserHandle.USER_CURRENT);
-                if (mPointerLocationMode != pointerLocation) {
-                    mPointerLocationMode = pointerLocation;
-                    mHandler.sendEmptyMessage(pointerLocation != 0 ?
-                            MSG_ENABLE_POINTER_LOCATION : MSG_DISABLE_POINTER_LOCATION);
-                }
-            }
             // use screen off timeout setting as the timeout for the lockscreen
             mLockScreenTimeout = Settings.System.getIntForUser(resolver,
                     Settings.System.SCREEN_OFF_TIMEOUT, 0, UserHandle.USER_CURRENT);
@@ -2047,46 +2021,6 @@
                 && mWakeGestureListener.isSupported();
     }
 
-    private void enablePointerLocation() {
-        if (mPointerLocationView == null) {
-            mPointerLocationView = new PointerLocationView(mContext);
-            mPointerLocationView.setPrintCoords(false);
-            WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
-                    WindowManager.LayoutParams.MATCH_PARENT,
-                    WindowManager.LayoutParams.MATCH_PARENT);
-            lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
-            lp.flags = WindowManager.LayoutParams.FLAG_FULLSCREEN
-                    | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
-                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                    | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
-            lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
-            if (ActivityManager.isHighEndGfx()) {
-                lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
-                lp.privateFlags |=
-                        WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED;
-            }
-            lp.format = PixelFormat.TRANSLUCENT;
-            lp.setTitle("PointerLocation");
-            WindowManager wm = (WindowManager) mContext.getSystemService(WINDOW_SERVICE);
-            lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
-            wm.addView(mPointerLocationView, lp);
-            //TODO (b/111365687) : make system context per display.
-            mWindowManagerFuncs.registerPointerEventListener(mPointerLocationView, DEFAULT_DISPLAY);
-        }
-    }
-
-    private void disablePointerLocation() {
-        if (mPointerLocationView != null) {
-            //TODO (b/111365687) : make system context per display.
-            mWindowManagerFuncs.unregisterPointerEventListener(mPointerLocationView,
-                    DEFAULT_DISPLAY);
-            WindowManager wm = (WindowManager) mContext.getSystemService(WINDOW_SERVICE);
-            wm.removeView(mPointerLocationView);
-            mPointerLocationView = null;
-        }
-    }
-
-
     /** {@inheritDoc} */
     @Override
     public int checkAddPermission(WindowManager.LayoutParams attrs, int[] outAppOp) {
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index d58707c..2af2342 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -443,7 +443,7 @@
          * Returns true if the window is current in multi-windowing mode. i.e. it shares the
          * screen with other application windows.
          */
-        public boolean isInMultiWindowMode();
+        boolean inMultiWindowMode();
 
         public int getRotationAnimationHint();
 
diff --git a/services/core/java/com/android/server/rollback/RollbackData.java b/services/core/java/com/android/server/rollback/RollbackData.java
index 8a95877..b37e268 100644
--- a/services/core/java/com/android/server/rollback/RollbackData.java
+++ b/services/core/java/com/android/server/rollback/RollbackData.java
@@ -23,9 +23,11 @@
 import java.io.File;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.text.ParseException;
 import java.time.Instant;
 import java.util.ArrayList;
 
+
 /**
  * Information about a rollback available for a set of atomically installed
  * packages.
@@ -138,4 +140,27 @@
     public boolean isStaged() {
         return info.isStaged();
     }
+
+    static String rollbackStateToString(@RollbackState int state) {
+        switch (state) {
+            case RollbackData.ROLLBACK_STATE_ENABLING: return "enabling";
+            case RollbackData.ROLLBACK_STATE_AVAILABLE: return "available";
+            case RollbackData.ROLLBACK_STATE_COMMITTED: return "committed";
+        }
+        throw new AssertionError("Invalid rollback state: " + state);
+    }
+
+    static @RollbackState int rollbackStateFromString(String state)
+            throws ParseException {
+        switch (state) {
+            case "enabling": return RollbackData.ROLLBACK_STATE_ENABLING;
+            case "available": return RollbackData.ROLLBACK_STATE_AVAILABLE;
+            case "committed": return RollbackData.ROLLBACK_STATE_COMMITTED;
+        }
+        throw new ParseException("Invalid rollback state: " + state, 0);
+    }
+
+    public String getStateAsString() {
+        return rollbackStateToString(state);
+    }
 }
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index 952399b..83d18a6 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -50,11 +50,14 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.LocalServices;
 import com.android.server.pm.Installer;
 
 import java.io.File;
+import java.io.FileDescriptor;
 import java.io.IOException;
+import java.io.PrintWriter;
 import java.security.SecureRandom;
 import java.time.Instant;
 import java.time.temporal.ChronoUnit;
@@ -873,6 +876,11 @@
             return false;
         }
 
+        if (session.resolvedBaseCodePath == null) {
+            Log.e(TAG, "Session code path has not been resolved.");
+            return false;
+        }
+
         // Get information about the package to be installed.
         PackageParser.PackageLite newPackage = null;
         try {
@@ -1268,4 +1276,39 @@
                     + rollbackData.info.getRollbackId(), ioe);
         }
     }
+
+    @Override
+    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
+        synchronized (mLock) {
+            for (RollbackData data : mRollbacks) {
+                RollbackInfo info = data.info;
+                ipw.println(info.getRollbackId() + ":");
+                ipw.increaseIndent();
+                ipw.println("-state: " + data.getStateAsString());
+                ipw.println("-timestamp: " + data.timestamp);
+                if (data.stagedSessionId != -1) {
+                    ipw.println("-stagedSessionId: " + data.stagedSessionId);
+                }
+                ipw.println("-packages:");
+                ipw.increaseIndent();
+                for (PackageRollbackInfo pkg : info.getPackages()) {
+                    ipw.println(pkg.getPackageName()
+                            + " " + pkg.getVersionRolledBackFrom().getLongVersionCode()
+                            + " -> " + pkg.getVersionRolledBackTo().getLongVersionCode());
+                }
+                ipw.decreaseIndent();
+                if (data.state == RollbackData.ROLLBACK_STATE_COMMITTED) {
+                    ipw.println("-causePackages:");
+                    ipw.increaseIndent();
+                    for (VersionedPackage cPkg : info.getCausePackages()) {
+                        ipw.println(cPkg.getPackageName() + " " + cPkg.getLongVersionCode());
+                    }
+                    ipw.decreaseIndent();
+                    ipw.println("-committedSessionId: " + info.getCommittedSessionId());
+                }
+                ipw.decreaseIndent();
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/rollback/RollbackStore.java b/services/core/java/com/android/server/rollback/RollbackStore.java
index 4f8f685..2cfa465 100644
--- a/services/core/java/com/android/server/rollback/RollbackStore.java
+++ b/services/core/java/com/android/server/rollback/RollbackStore.java
@@ -16,6 +16,9 @@
 
 package com.android.server.rollback;
 
+import static com.android.server.rollback.RollbackData.rollbackStateFromString;
+import static com.android.server.rollback.RollbackData.rollbackStateToString;
+
 import android.annotation.NonNull;
 import android.content.pm.VersionedPackage;
 import android.content.rollback.PackageRollbackInfo;
@@ -401,23 +404,4 @@
             file.delete();
         }
     }
-
-    private static String rollbackStateToString(@RollbackData.RollbackState int state) {
-        switch (state) {
-            case RollbackData.ROLLBACK_STATE_ENABLING: return "enabling";
-            case RollbackData.ROLLBACK_STATE_AVAILABLE: return "available";
-            case RollbackData.ROLLBACK_STATE_COMMITTED: return "committed";
-        }
-        throw new AssertionError("Invalid rollback state: " + state);
-    }
-
-    private static @RollbackData.RollbackState int rollbackStateFromString(String state)
-            throws ParseException {
-        switch (state) {
-            case "enabling": return RollbackData.ROLLBACK_STATE_ENABLING;
-            case "available": return RollbackData.ROLLBACK_STATE_AVAILABLE;
-            case "committed": return RollbackData.ROLLBACK_STATE_COMMITTED;
-        }
-        throw new ParseException("Invalid rollback state: " + state, 0);
-    }
 }
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index 4815e5c..2b17d19 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -24,6 +24,7 @@
 import static com.android.server.am.MemoryStatUtil.readCmdlineFromProcfs;
 import static com.android.server.am.MemoryStatUtil.readMemoryStatFromProcfs;
 import static com.android.server.am.MemoryStatUtil.readRssHighWaterMarkFromProcfs;
+import static com.android.server.am.MemoryStatUtil.readSystemIonHeapSizeFromDebugfs;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -1182,6 +1183,15 @@
         SystemProperties.set("sys.rss_hwm_reset.on", "1");
     }
 
+    private void pullSystemIonHeapSize(
+            int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
+        final long systemIonHeapSizeInBytes = readSystemIonHeapSizeFromDebugfs();
+        StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
+        e.writeLong(systemIonHeapSizeInBytes);
+        pulledData.add(e);
+    }
+
     private void pullBinderCallsStats(
             int tagId, long elapsedNanos, long wallClockNanos,
             List<StatsLogEventWrapper> pulledData) {
@@ -2068,6 +2078,10 @@
                 pullProcessMemoryHighWaterMark(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
+            case StatsLog.SYSTEM_ION_HEAP_SIZE: {
+                pullSystemIonHeapSize(tagId, elapsedNanos, wallClockNanos, ret);
+                break;
+            }
             case StatsLog.BINDER_CALLS: {
                 pullBinderCallsStats(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index bb5a221..af05a27 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -2237,6 +2237,10 @@
                 || transit == TRANSIT_ACTIVITY_RELAUNCH;
     }
 
+    static boolean isChangeTransit(int transit) {
+        return transit == TRANSIT_TASK_CHANGE_WINDOWING_MODE;
+    }
+
     /**
      * @return whether the transition should show the thumbnail being scaled down.
      */
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index 8f0a7c0..f6326957 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -513,8 +513,11 @@
         // Given no app transition pass it through instead of a wallpaper transition.
         // Never convert the crashing transition.
         // Never update the transition for the wallpaper if we are just docking from recents
+        // Never convert a change transition since the top activity isn't changing and will likely
+        // still be above an opening wallpaper.
         if (transit == TRANSIT_NONE || transit == TRANSIT_CRASHING_ACTIVITY_CLOSE
-                || transit == TRANSIT_DOCK_TASK_FROM_RECENTS) {
+                || transit == TRANSIT_DOCK_TASK_FROM_RECENTS
+                || AppTransition.isChangeTransit(transit)) {
             return transit;
         }
 
@@ -601,6 +604,10 @@
      */
     @VisibleForTesting
     int maybeUpdateTransitToTranslucentAnim(int transit) {
+        if (AppTransition.isChangeTransit(transit)) {
+            // There's no special animation to handle change animations with translucent apps
+            return transit;
+        }
         final boolean taskOrActivity = AppTransition.isTaskTransit(transit)
                 || AppTransition.isActivityTransit(transit);
         boolean allOpeningVisible = true;
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 220370c..ea3a7d5 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -1747,7 +1747,7 @@
     }
 
     boolean isInChangeTransition() {
-        return mTransitChangeLeash != null || isChangeTransition(mTransit);
+        return mTransitChangeLeash != null || AppTransition.isChangeTransit(mTransit);
     }
 
     @VisibleForTesting
@@ -1979,7 +1979,14 @@
                 mLetterbox.attachInput(w);
             }
             getPosition(mTmpPoint);
-            mLetterbox.layout(getParent().getBounds(), w.getFrameLw(), mTmpPoint);
+            // Get the bounds of the "space-to-fill". We union the Task and the Stack bounds here
+            // to handle both split window (where task-bounds can be larger) and orientation
+            // letterbox (where the task is letterboxed within stack).
+            Rect spaceToFill = getTask().getBounds();
+            if (getStack() != null) {
+                spaceToFill.union(getStack().getBounds());
+            }
+            mLetterbox.layout(spaceToFill, w.getFrameLw(), mTmpPoint);
         } else if (mLetterbox != null) {
             mLetterbox.hide();
         }
@@ -2448,30 +2455,6 @@
         return boundsLayer;
     }
 
-    /** Get position and crop region of animation. */
-    @VisibleForTesting
-    void getAnimationBounds(Point outPosition, Rect outBounds) {
-        outPosition.set(0, 0);
-        outBounds.setEmpty();
-
-        final TaskStack stack = getStack();
-        final Task task = getTask();
-        if (task != null && task.inFreeformWindowingMode()) {
-            task.getRelativeDisplayedPosition(outPosition);
-        } else if (stack != null) {
-            stack.getRelativeDisplayedPosition(outPosition);
-        }
-
-        // Always use stack bounds in order to have the ability to animate outside the task region.
-        // It also needs to be consistent when {@link #mNeedsAnimationBoundsLayer} is set that crops
-        // according to the bounds.
-        if (stack != null) {
-            stack.getBounds(outBounds);
-        }
-        // We have the relative position so the local position can be removed from bounds.
-        outBounds.offsetTo(0, 0);
-    }
-
     @Override
     Rect getDisplayedBounds() {
         final Task task = getTask();
@@ -2484,10 +2467,6 @@
         return getBounds();
     }
 
-    private static boolean isChangeTransition(int transit) {
-        return transit == TRANSIT_TASK_CHANGE_WINDOWING_MODE;
-    }
-
     boolean applyAnimationLocked(WindowManager.LayoutParams lp, int transit, boolean enter,
             boolean isVoiceInteraction) {
 
@@ -2507,9 +2486,15 @@
         if (okToAnimate()) {
             final AnimationAdapter adapter;
             AnimationAdapter thumbnailAdapter = null;
-            getAnimationBounds(mTmpPoint, mTmpRect);
 
-            boolean isChanging = isChangeTransition(transit) && enter;
+            // Separate position and size for use in animators. Use task-bounds for now so
+            // that activity-level letterbox (maxAspectRatio) is included in the animation.
+            mTmpRect.set(getTask() != null ? getTask().getBounds() : getBounds());
+            mTmpPoint.set(mTmpRect.left, mTmpRect.top);
+            mTmpRect.offsetTo(0, 0);
+
+            final boolean isChanging = AppTransition.isChangeTransit(transit) && enter
+                    && getDisplayContent().mChangingApps.contains(this);
 
             // Delaying animation start isn't compatible with remote animations at all.
             if (getDisplayContent().mAppTransition.getRemoteAnimationController() != null
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index e48361f..ba1dfbb 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -44,8 +44,8 @@
 import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
-import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INHERIT_TRANSLUCENT_DECOR;
@@ -113,6 +113,7 @@
 import android.content.Intent;
 import android.content.res.Resources;
 import android.graphics.Insets;
+import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.hardware.input.InputManager;
 import android.hardware.power.V1_0.PowerHint;
@@ -149,6 +150,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ScreenShapeHelper;
 import com.android.internal.util.ScreenshotHelper;
+import com.android.internal.widget.PointerLocationView;
 import com.android.server.LocalServices;
 import com.android.server.UiThread;
 import com.android.server.policy.WindowManagerPolicy;
@@ -343,6 +345,8 @@
 
     private InputConsumer mInputConsumer = null;
 
+    private PointerLocationView mPointerLocationView;
+
     /**
      * The area covered by system windows which belong to another display. Forwarded insets is set
      * in case this is a virtual display, this is displayed on another display that has insets, and
@@ -357,6 +361,8 @@
     private static final int MSG_UPDATE_DREAMING_SLEEP_TOKEN = 1;
     private static final int MSG_REQUEST_TRANSIENT_BARS = 2;
     private static final int MSG_DISPOSE_INPUT_CONSUMER = 3;
+    private static final int MSG_ENABLE_POINTER_LOCATION = 4;
+    private static final int MSG_DISABLE_POINTER_LOCATION = 5;
 
     private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS = 0;
     private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION = 1;
@@ -383,6 +389,12 @@
                 case MSG_DISPOSE_INPUT_CONSUMER:
                     disposeInputConsumer((InputConsumer) msg.obj);
                     break;
+                case MSG_ENABLE_POINTER_LOCATION:
+                    enablePointerLocation();
+                    break;
+                case MSG_DISABLE_POINTER_LOCATION:
+                    disablePointerLocation();
+                    break;
             }
         }
     }
@@ -541,6 +553,9 @@
 
     void systemReady() {
         mSystemGestures.systemReady();
+        if (mService.mPointerLocationEnabled) {
+            setPointerLocationEnabled(true);
+        }
     }
 
     private int getDisplayId() {
@@ -747,7 +762,7 @@
             case TYPE_WALLPAPER:
                 // Dreams and wallpapers don't have an app window token and can thus not be
                 // letterboxed. Hence always let them extend under the cutout.
-                attrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+                attrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
                 break;
             case TYPE_STATUS_BAR:
 
@@ -2095,7 +2110,7 @@
 
         // Ensure that windows with a DEFAULT or NEVER display cutout mode are laid out in
         // the cutout safe zone.
-        if (cutoutMode != LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS) {
+        if (cutoutMode != LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES) {
             final Rect displayCutoutSafeExceptMaybeBars = sTmpDisplayCutoutSafeExceptMaybeBarsRect;
             displayCutoutSafeExceptMaybeBars.set(displayFrames.mDisplayCutoutSafe);
             if (layoutInScreen && layoutInsetDecor && !requestedFullscreen
@@ -2146,7 +2161,7 @@
         // TYPE_SYSTEM_ERROR is above the NavigationBar so it can't be allowed to extend over it.
         // Also, we don't allow windows in multi-window mode to extend out of the screen.
         if ((fl & FLAG_LAYOUT_NO_LIMITS) != 0 && type != TYPE_SYSTEM_ERROR
-                && !win.isInMultiWindowMode()) {
+                && !win.inMultiWindowMode()) {
             df.left = df.top = -10000;
             df.right = df.bottom = 10000;
             if (type != TYPE_WALLPAPER) {
@@ -3414,4 +3429,57 @@
         pw.print(prefix); pw.println("Looper state:");
         mHandler.getLooper().dump(new PrintWriterPrinter(pw), prefix + "  ");
     }
+
+    private boolean supportsPointerLocation() {
+        return mDisplayContent.isDefaultDisplay || !mDisplayContent.isPrivate();
+    }
+
+    void setPointerLocationEnabled(boolean pointerLocationEnabled) {
+        if (!supportsPointerLocation()) {
+            return;
+        }
+
+        mHandler.sendEmptyMessage(pointerLocationEnabled
+                ? MSG_ENABLE_POINTER_LOCATION : MSG_DISABLE_POINTER_LOCATION);
+    }
+
+    private void enablePointerLocation() {
+        if (mPointerLocationView != null) {
+            return;
+        }
+
+        mPointerLocationView = new PointerLocationView(mContext);
+        mPointerLocationView.setPrintCoords(false);
+        final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+                WindowManager.LayoutParams.MATCH_PARENT,
+                WindowManager.LayoutParams.MATCH_PARENT);
+        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
+        lp.flags = WindowManager.LayoutParams.FLAG_FULLSCREEN
+                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+        lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
+        if (ActivityManager.isHighEndGfx()) {
+            lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+            lp.privateFlags |=
+                    WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED;
+        }
+        lp.format = PixelFormat.TRANSLUCENT;
+        lp.setTitle("PointerLocation - display " + getDisplayId());
+        lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
+        final WindowManager wm = mContext.getSystemService(WindowManager.class);
+        wm.addView(mPointerLocationView, lp);
+        mDisplayContent.registerPointerEventListener(mPointerLocationView);
+    }
+
+    private void disablePointerLocation() {
+        if (mPointerLocationView == null) {
+            return;
+        }
+
+        mDisplayContent.unregisterPointerEventListener(mPointerLocationView);
+        final WindowManager wm = mContext.getSystemService(WindowManager.class);
+        wm.removeView(mPointerLocationView);
+        mPointerLocationView = null;
+    }
 }
diff --git a/services/core/java/com/android/server/wm/LaunchParamsPersister.java b/services/core/java/com/android/server/wm/LaunchParamsPersister.java
index 86dc66d..d364a37 100644
--- a/services/core/java/com/android/server/wm/LaunchParamsPersister.java
+++ b/services/core/java/com/android/server/wm/LaunchParamsPersister.java
@@ -306,10 +306,10 @@
 
     private class PackageListObserver implements PackageManagerInternal.PackageListObserver {
         @Override
-        public void onPackageAdded(String packageName) { }
+        public void onPackageAdded(String packageName, int uid) { }
 
         @Override
-        public void onPackageRemoved(String packageName) {
+        public void onPackageRemoved(String packageName, int uid) {
             removeRecordForPackage(packageName);
         }
     }
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 300cd17..db7613a 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -193,8 +193,8 @@
     }
 
     DisplayContent getTopFocusedDisplayContent() {
-        return getDisplayContent(mTopFocusedDisplayId == INVALID_DISPLAY
-                ? DEFAULT_DISPLAY : mTopFocusedDisplayId);
+        final DisplayContent dc = getDisplayContent(mTopFocusedDisplayId);
+        return dc != null ? dc : getDisplayContent(DEFAULT_DISPLAY);
     }
 
     @Override
@@ -1045,6 +1045,15 @@
         mWmService.scheduleAnimationLocked();
     }
 
+    @Override
+    protected void removeChild(DisplayContent dc) {
+        super.removeChild(dc);
+        if (mTopFocusedDisplayId == dc.getDisplayId()) {
+            mWmService.updateFocusedWindowLocked(
+                    UPDATE_FOCUS_NORMAL, true /* updateInputWindows */);
+        }
+    }
+
     /**
      * For all display at or below this call the callback.
      *
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 499cbaf..bb7867c 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -433,29 +433,6 @@
         }
     }
 
-    /** Return true if the current bound can get outputted to the rest of the system as-is. */
-    private boolean useCurrentBounds() {
-        final DisplayContent displayContent = getDisplayContent();
-        return matchParentBounds()
-                || !inSplitScreenSecondaryWindowingMode()
-                || displayContent == null
-                || displayContent.getSplitScreenPrimaryStackIgnoringVisibility() != null;
-    }
-
-    @Override
-    public void getBounds(Rect out) {
-        if (useCurrentBounds()) {
-            // No need to adjust the output bounds if fullscreen or the docked stack is visible
-            // since it is already what we want to represent to the rest of the system.
-            super.getBounds(out);
-            return;
-        }
-
-        // The bounds has been adjusted to accommodate for a docked stack, but the docked stack is
-        // not currently visible. Go ahead a represent it as fullscreen to the rest of the system.
-        mStack.getDisplayContent().getBounds(out);
-    }
-
     @Override
     public Rect getDisplayedBounds() {
         if (mOverrideDisplayedBounds.isEmpty()) {
@@ -506,36 +483,28 @@
         // a DimLayer anyway if we weren't visible.
         final boolean dockedResizing = displayContent != null
                 && displayContent.mDividerControllerLocked.isResizing();
-        if (useCurrentBounds()) {
-            if (inFreeformWindowingMode() && getMaxVisibleBounds(out)) {
-                return;
-            }
-
-            if (!matchParentBounds()) {
-                // When minimizing the docked stack when going home, we don't adjust the task bounds
-                // so we need to intersect the task bounds with the stack bounds here.
-                //
-                // If we are Docked Resizing with snap points, the task bounds could be smaller than the stack
-                // bounds and so we don't even want to use them. Even if the app should not be resized the Dim
-                // should keep up with the divider.
-                if (dockedResizing) {
-                    mStack.getBounds(out);
-                } else {
-                    mStack.getBounds(mTmpRect);
-                    mTmpRect.intersect(getBounds());
-                    out.set(mTmpRect);
-                }
-            } else {
-                out.set(getBounds());
-            }
+        if (inFreeformWindowingMode() && getMaxVisibleBounds(out)) {
             return;
         }
 
-        // The bounds has been adjusted to accommodate for a docked stack, but the docked stack is
-        // not currently visible. Go ahead a represent it as fullscreen to the rest of the system.
-        if (displayContent != null) {
-            displayContent.getBounds(out);
+        if (!matchParentBounds()) {
+            // When minimizing the docked stack when going home, we don't adjust the task bounds
+            // so we need to intersect the task bounds with the stack bounds here.
+            //
+            // If we are Docked Resizing with snap points, the task bounds could be smaller than the
+            // stack bounds and so we don't even want to use them. Even if the app should not be
+            // resized the Dim should keep up with the divider.
+            if (dockedResizing) {
+                mStack.getBounds(out);
+            } else {
+                mStack.getBounds(mTmpRect);
+                mTmpRect.intersect(getBounds());
+                out.set(mTmpRect);
+            }
+        } else {
+            out.set(getBounds());
         }
+        return;
     }
 
     void setDragResizing(boolean dragResizing, int dragResizeMode) {
@@ -702,16 +671,6 @@
         positionChildAt(position, aToken, false /* includeParents */);
     }
 
-    boolean isFullscreen() {
-        if (useCurrentBounds()) {
-            return matchParentBounds();
-        }
-        // The bounds has been adjusted to accommodate for a docked stack, but the docked stack
-        // is not currently visible. Go ahead a represent it as fullscreen to the rest of the
-        // system.
-        return true;
-    }
-
     void forceWindowsScaleable(boolean force) {
         mWmService.openSurfaceTransaction();
         try {
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 241f14e..e6b8112 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -303,17 +303,6 @@
         return super.getBounds();
     }
 
-    /** Return true if the current bound can get outputted to the rest of the system as-is. */
-    private boolean useCurrentBounds() {
-        if (matchParentBounds()
-                || !inSplitScreenSecondaryWindowingMode()
-                || mDisplayContent == null
-                || mDisplayContent.getSplitScreenPrimaryStackIgnoringVisibility() != null) {
-            return true;
-        }
-        return false;
-    }
-
     @Override
     public void getBounds(Rect bounds) {
         bounds.set(getBounds());
@@ -321,22 +310,15 @@
 
     @Override
     public Rect getBounds() {
-        if (useCurrentBounds()) {
-            // If we're currently adjusting for IME or minimized docked stack, we use the adjusted
-            // bounds; otherwise, no need to adjust the output bounds if fullscreen or the docked
-            // stack is visible since it is already what we want to represent to the rest of the
-            // system.
-            if (!mAdjustedBounds.isEmpty()) {
-                return mAdjustedBounds;
-            } else {
-                return super.getBounds();
-            }
-        }
-
-        // The bounds has been adjusted to accommodate for a docked stack, but the docked stack
-        // is not currently visible. Go ahead a represent it as fullscreen to the rest of the
+        // If we're currently adjusting for IME or minimized docked stack, we use the adjusted
+        // bounds; otherwise, no need to adjust the output bounds if fullscreen or the docked
+        // stack is visible since it is already what we want to represent to the rest of the
         // system.
-        return mDisplayContent.getBounds();
+        if (!mAdjustedBounds.isEmpty()) {
+            return mAdjustedBounds;
+        } else {
+            return super.getBounds();
+        }
     }
 
     /**
@@ -1425,13 +1407,7 @@
 
     @Override
     boolean fillsParent() {
-        if (useCurrentBounds()) {
-            return matchParentBounds();
-        }
-        // The bounds has been adjusted to accommodate for a docked stack, but the docked stack
-        // is not currently visible. Go ahead a represent it as fullscreen to the rest of the
-        // system.
-        return true;
+        return matchParentBounds();
     }
 
     @Override
@@ -1516,7 +1492,7 @@
 
         for (int i = mChildren.size() - 1; i >= 0; --i) {
             final Task task = mChildren.get(i);
-            if (task.isFullscreen()) {
+            if (task.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
                 results.searchDone = true;
                 return;
             }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index e3a8be5..b973ed5 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -689,6 +689,8 @@
                 Settings.Secure.getUriFor(Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS);
         private final Uri mPolicyControlUri =
                 Settings.Global.getUriFor(Settings.Global.POLICY_CONTROL);
+        private final Uri mPointerLocationUri =
+                Settings.System.getUriFor(Settings.System.POINTER_LOCATION);
 
         public SettingsObserver() {
             super(new Handler());
@@ -703,8 +705,8 @@
                     UserHandle.USER_ALL);
             resolver.registerContentObserver(mImmersiveModeConfirmationsUri, false, this,
                     UserHandle.USER_ALL);
-            resolver.registerContentObserver(mPolicyControlUri, false, this,
-                    UserHandle.USER_ALL);
+            resolver.registerContentObserver(mPolicyControlUri, false, this, UserHandle.USER_ALL);
+            resolver.registerContentObserver(mPointerLocationUri, false, this, UserHandle.USER_ALL);
         }
 
         @Override
@@ -723,6 +725,11 @@
                 return;
             }
 
+            if (mPointerLocationUri.equals(uri)) {
+                updatePointerLocation();
+                return;
+            }
+
             @UpdateAnimationScaleMode
             final int mode;
             if (mWindowAnimationScaleUri.equals(uri)) {
@@ -749,6 +756,22 @@
                 updateRotation(false /* alwaysSendConfiguration */, false /* forceRelayout */);
             }
         }
+
+        void updatePointerLocation() {
+            ContentResolver resolver = mContext.getContentResolver();
+            final boolean enablePointerLocation = Settings.System.getIntForUser(resolver,
+                    Settings.System.POINTER_LOCATION, 0, UserHandle.USER_CURRENT) != 0;
+
+            if (mPointerLocationEnabled == enablePointerLocation) {
+                return;
+            }
+            mPointerLocationEnabled = enablePointerLocation;
+            synchronized (mGlobalLock) {
+                mRoot.forAllDisplayPolicies(PooledLambda.obtainConsumer(
+                        DisplayPolicy::setPointerLocationEnabled, PooledLambda.__(),
+                        mPointerLocationEnabled));
+            }
+        }
     }
 
     PowerManager mPowerManager;
@@ -758,6 +781,7 @@
     private float mTransitionAnimationScaleSetting = 1.0f;
     private float mAnimatorDurationScaleSetting = 1.0f;
     private boolean mAnimationsDisabled = false;
+    boolean mPointerLocationEnabled = false;
 
     final InputManagerService mInputManager;
     final DisplayManagerInternal mDisplayManagerInternal;
@@ -4363,6 +4387,7 @@
         mHasWideColorGamutSupport = queryWideColorGamutSupport();
         mHasHdrSupport = queryHdrSupport();
         UiThread.getHandler().post(mSettingsObserver::updateSystemUiSettings);
+        UiThread.getHandler().post(mSettingsObserver::updatePointerLocation);
         IVrManager vrManager = IVrManager.Stub.asInterface(
                 ServiceManager.getService(Context.VR_SERVICE));
         if (vrManager != null) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 20cca66..ee445d8 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -826,7 +826,7 @@
         mHaveFrame = true;
 
         final Task task = getTask();
-        final boolean inFullscreenContainer = inFullscreenContainer();
+        final boolean isFullscreenAndFillsDisplay = !inMultiWindowMode() && matchesDisplayBounds();
         final boolean windowsAreFloating = task != null && task.isFloating();
         final DisplayContent dc = getDisplayContent();
 
@@ -845,7 +845,7 @@
         final WindowState imeWin = mWmService.mRoot.getCurrentInputMethodWindow();
         final boolean isImeTarget =
                 imeWin != null && imeWin.isVisibleNow() && isInputMethodTarget();
-        if (inFullscreenContainer || layoutInParentFrame()) {
+        if (isFullscreenAndFillsDisplay || layoutInParentFrame()) {
             // We use the parent frame as the containing frame for fullscreen and child windows
             mWindowFrames.mContainingFrame.set(mWindowFrames.mParentFrame);
             layoutDisplayFrame = mWindowFrames.mDisplayFrame;
@@ -983,7 +983,7 @@
                     Math.min(mWindowFrames.mStableFrame.bottom, mWindowFrames.mFrame.bottom));
         }
 
-        if (inFullscreenContainer && !windowsAreFloating) {
+        if (isFullscreenAndFillsDisplay && !windowsAreFloating) {
             // Windows that are not fullscreen can be positioned outside of the display frame,
             // but that is not a reason to provide them with overscan insets.
             InsetUtils.insetsBetweenFrames(layoutContainingFrame, mWindowFrames.mOverscanFrame,
@@ -996,7 +996,8 @@
             mWindowFrames.calculateDockedDividerInsets(c.getDisplayCutout().getSafeInsets());
         } else {
             getDisplayContent().getBounds(mTmpRect);
-            mWindowFrames.calculateInsets(windowsAreFloating, inFullscreenContainer, mTmpRect);
+            mWindowFrames.calculateInsets(
+                    windowsAreFloating, isFullscreenAndFillsDisplay, mTmpRect);
         }
 
         mWindowFrames.setDisplayCutout(
@@ -1038,9 +1039,7 @@
     // TODO: Look into whether this override is still necessary.
     @Override
     public Rect getBounds() {
-        if (isInMultiWindowMode()) {
-            return getTask().getBounds();
-        } else if (mAppToken != null){
+        if (mAppToken != null) {
             return mAppToken.getBounds();
         } else {
             return super.getBounds();
@@ -1751,6 +1750,10 @@
                 && mWindowFrames.mFrame.bottom >= displayInfo.appHeight;
     }
 
+    private boolean matchesDisplayBounds() {
+        return getDisplayContent().getBounds().equals(getBounds());
+    }
+
     /** Returns true if last applied config was not yet requested by client. */
     boolean isConfigChanged() {
         return !getLastReportedConfiguration().equals(getConfiguration());
@@ -3114,20 +3117,16 @@
         return getDisplayContent().mCurrentFocus == this;
     }
 
-    @Override
-    public boolean isInMultiWindowMode() {
-        final Task task = getTask();
-        return task != null && !task.isFullscreen();
-    }
 
     /** Is this window in a container that takes up the entire screen space? */
-    private boolean inFullscreenContainer() {
-        return mAppToken == null || (mAppToken.matchParentBounds() && !isInMultiWindowMode());
+    private boolean inAppWindowThatMatchesParentBounds() {
+        return mAppToken == null || (mAppToken.matchParentBounds() && !inMultiWindowMode());
     }
 
-    /** @return true when the window is in fullscreen task, but has non-fullscreen bounds set. */
+    /** @return true when the window is in fullscreen mode, but has non-fullscreen bounds set, or
+     *          is transitioning into/out-of fullscreen. */
     boolean isLetterboxedAppWindow() {
-        return !isInMultiWindowMode() && mAppToken != null && !mAppToken.matchParentBounds()
+        return !inMultiWindowMode() && !matchesDisplayBounds()
                 || isLetterboxedForDisplayCutoutLw();
     }
 
@@ -3494,7 +3493,7 @@
         final int pw = containingFrame.width();
         final int ph = containingFrame.height();
         final Task task = getTask();
-        final boolean inNonFullscreenContainer = !inFullscreenContainer();
+        final boolean inNonFullscreenContainer = !inAppWindowThatMatchesParentBounds();
         final boolean noLimits = (mAttrs.flags & FLAG_LAYOUT_NO_LIMITS) != 0;
 
         // We need to fit it to the display if either
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 92bb082..780d471 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -26,7 +26,6 @@
 
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
-import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_FREEFORM;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
@@ -792,16 +791,10 @@
         if (DEBUG_WINDOW_CROP) Slog.d(TAG, "Applying decor to crop win=" + w + " mDecorFrame="
                 + w.getDecorFrame() + " mSystemDecorRect=" + mSystemDecorRect);
 
-        final Task task = w.getTask();
-        final boolean fullscreen = w.fillsDisplay() || (task != null && task.isFullscreen());
-        final boolean isFreeformResizing =
-                w.isDragResizing() && w.getResizeMode() == DRAG_RESIZE_MODE_FREEFORM;
-
         // We use the clip rect as provided by the tranformation for non-fullscreen windows to
         // avoid premature clipping with the system decor rect.
         clipRect.set(mSystemDecorRect);
-        if (DEBUG_WINDOW_CROP) Slog.d(TAG, "win=" + w + " Initial clip rect: " + clipRect
-                + " fullscreen=" + fullscreen);
+        if (DEBUG_WINDOW_CROP) Slog.d(TAG, "win=" + w + " Initial clip rect: " + clipRect);
 
         w.expandForSurfaceInsets(clipRect);
 
diff --git a/services/core/java/com/android/server/wm/WindowTraceBuffer.java b/services/core/java/com/android/server/wm/WindowTraceBuffer.java
index a4ee907..8c65884 100644
--- a/services/core/java/com/android/server/wm/WindowTraceBuffer.java
+++ b/services/core/java/com/android/server/wm/WindowTraceBuffer.java
@@ -93,8 +93,8 @@
     void writeTraceToFile(File traceFile) throws IOException {
         synchronized (mBufferLock) {
             traceFile.delete();
-            traceFile.setReadable(true, false);
             try (OutputStream os = new FileOutputStream(traceFile)) {
+                traceFile.setReadable(true /* readable */, false /* ownerOnly */);
                 ProtoOutputStream proto = new ProtoOutputStream();
                 proto.write(MAGIC_NUMBER, MAGIC_NUMBER_VALUE);
                 os.write(proto.getBytes());
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java
index 66d9345..2ed25ea 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java
@@ -99,8 +99,8 @@
     public void bind_requestsContextToBindService() {
         mConnection.bindLocked();
         verify(mMockContext).bindServiceAsUser(any(Intent.class), eq(mConnection),
-                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE),
-                any(UserHandle.class));
+                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE
+                | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS), any(UserHandle.class));
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java b/services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java
index 93cac08..71b4397 100644
--- a/services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java
@@ -21,6 +21,7 @@
 import static com.android.server.am.MemoryStatUtil.MemoryStat;
 import static com.android.server.am.MemoryStatUtil.PAGE_SIZE;
 import static com.android.server.am.MemoryStatUtil.parseCmdlineFromProcfs;
+import static com.android.server.am.MemoryStatUtil.parseIonHeapSizeFromDebugfs;
 import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromMemcg;
 import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromProcfs;
 import static com.android.server.am.MemoryStatUtil.parseVmHWMFromProcfs;
@@ -178,6 +179,33 @@
             + "voluntary_ctxt_switches:\t903\n"
             + "nonvoluntary_ctxt_switches:\t104\n";
 
+    private static final String DEBUG_SYSTEM_ION_HEAP_CONTENTS = String.join(
+            "          client              pid             size\n",
+            "----------------------------------------------------\n",
+            " audio@2.0-servi              765             4096\n",
+            " audio@2.0-servi              765            61440\n",
+            " audio@2.0-servi              765             4096\n",
+            "     voip_client               96             8192\n",
+            "     voip_client               96             4096\n",
+            "   system_server             1232         16728064\n",
+            "  surfaceflinger              611         50642944\n",
+            "----------------------------------------------------\n",
+            "orphaned allocations (info is from last known client):\n",
+            "----------------------------------------------------\n",
+            "  total orphaned                0\n",
+            "          total          55193600\n",
+            "   deferred free                0\n",
+            "----------------------------------------------------\n",
+            "0 order 4 highmem pages in uncached pool = 0 total\n",
+            "0 order 4 lowmem pages in uncached pool = 0 total\n",
+            "1251 order 4 lowmem pages in cached pool = 81985536 total\n",
+            "VMID 8: 0 order 4 highmem pages in secure pool = 0 total\n",
+            "VMID  8: 0 order 4 lowmem pages in secure pool = 0 total\n",
+            "--------------------------------------------\n",
+            "uncached pool = 4096 cached pool = 83566592 secure pool = 0\n",
+            "pool total (uncached + cached + secure) = 83570688\n",
+            "--------------------------------------------\n");
+
     @Test
     public void testParseMemoryStatFromMemcg_parsesCorrectValues() {
         MemoryStat stat = parseMemoryStatFromMemcg(MEMORY_STAT_CONTENTS);
@@ -271,4 +299,21 @@
         output.write(bytes, 0, bytes.length);
         return output.toString();
     }
+
+    @Test
+    public void testParseIonHeapSizeFromDebugfs_emptyContents() {
+        assertEquals(0, parseIonHeapSizeFromDebugfs(""));
+
+        assertEquals(0, parseIonHeapSizeFromDebugfs(null));
+    }
+
+    @Test
+    public void testParseIonHeapSizeFromDebugfs_invalidValue() {
+        assertEquals(0, parseIonHeapSizeFromDebugfs("<<no-value>>"));
+    }
+
+    @Test
+    public void testParseIonHeapSizeFromDebugfs_correctValue() {
+        assertEquals(55193600, parseIonHeapSizeFromDebugfs(DEBUG_SYSTEM_ION_HEAP_CONTENTS));
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 28a815e..bd7774a 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -5021,8 +5021,7 @@
         configureContextForAccess(mContext, false);
 
         assertExpectException(SecurityException.class, /* messageRegex= */ null,
-                () -> dpm.setProfileOwnerCanAccessDeviceIdsForUser(admin2,
-                        UserHandle.of(DpmMockContext.CALLER_UID)));
+                () -> dpm.setProfileOwnerCanAccessDeviceIds(admin2));
     }
 
     public void testGrantDeviceIdsAccess_notByAuthorizedCaller() throws Exception {
@@ -5030,8 +5029,7 @@
         configureContextForAccess(mContext, false);
 
         assertExpectException(SecurityException.class, /* messageRegex= */ null,
-                () -> dpm.setProfileOwnerCanAccessDeviceIdsForUser(admin1,
-                        UserHandle.of(DpmMockContext.CALLER_UID)));
+                () -> dpm.setProfileOwnerCanAccessDeviceIds(admin1));
     }
 
     public void testGrantDeviceIdsAccess_byAuthorizedSystemCaller() throws Exception {
@@ -5060,8 +5058,7 @@
                         DpmMockContext.CALLER_MANAGED_PROVISIONING_UID);
         try {
             runAsCaller(mServiceContext, dpms, dpm -> {
-                dpm.setProfileOwnerCanAccessDeviceIdsForUser(admin1,
-                        UserHandle.of(DpmMockContext.CALLER_USER_HANDLE));
+                dpm.setProfileOwnerCanAccessDeviceIds(admin1);
             });
         } finally {
             mServiceContext.binder.restoreCallingIdentity(ident);
@@ -5314,7 +5311,7 @@
         mServiceContext.binder.callingUid =
                 UserHandle.getUid(DpmMockContext.CALLER_USER_HANDLE, DpmMockContext.SYSTEM_UID);
         runAsCaller(mServiceContext, dpms, dpm -> {
-            dpm.setProfileOwnerCanAccessDeviceIdsForUser(who, UserHandle.of(userId));
+            dpm.setProfileOwnerCanAccessDeviceIds(who);
         });
         mServiceContext.binder.restoreCallingIdentity(ident);
     }
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java
index 26722fd..d3f33a1 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java
@@ -167,6 +167,7 @@
                 /* stageDir */ mTmpDir,
                 /* stageCid */ null,
                 /* prepared */ true,
+                /* committed */ true,
                 /* sealed */ false,  // Setting to true would trigger some PM logic.
                 /* childSessionIds */ childSessionIds != null ? childSessionIds : new int[0],
                 /* parentSessionId */ parentSessionId,
@@ -300,6 +301,7 @@
         assertEquals(expected.getStagedSessionErrorMessage(),
                 actual.getStagedSessionErrorMessage());
         assertEquals(expected.isPrepared(), actual.isPrepared());
+        assertEquals(expected.isCommitted(), actual.isCommitted());
         assertEquals(expected.isSealed(), actual.isSealed());
         assertEquals(expected.isMultiPackage(), actual.isMultiPackage());
         assertEquals(expected.hasParentSessionId(), actual.hasParentSessionId());
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
index 111fb74..4cfd098 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
@@ -56,11 +56,11 @@
             }
 
             @Override
-            public void notifyPackageAdded(String packageName) {
+            public void notifyPackageAdded(String packageName, int uid) {
             }
 
             @Override
-            public void notifyPackageRemoved(String packageName) {
+            public void notifyPackageRemoved(String packageName, int uid) {
             }
         }
 
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppTimeLimitControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppTimeLimitControllerTests.java
index 1f86171..958b23f 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppTimeLimitControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppTimeLimitControllerTests.java
@@ -175,9 +175,9 @@
     /** Verify app usage limit observer is added */
     @Test
     public void testAppUsageLimitObserver_AddObserver() {
-        addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN);
+        addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0);
         assertTrue("Observer wasn't added", hasAppUsageLimitObserver(UID, OBS_ID1));
-        addAppUsageLimitObserver(OBS_ID2, GROUP_GAME, TIME_30_MIN, TIME_30_MIN);
+        addAppUsageLimitObserver(OBS_ID2, GROUP_GAME, TIME_30_MIN, 0);
         assertTrue("Observer wasn't added", hasAppUsageLimitObserver(UID, OBS_ID2));
         assertTrue("Observer wasn't added", hasAppUsageLimitObserver(UID, OBS_ID1));
     }
@@ -203,7 +203,7 @@
     /** Verify app usage limit observer is removed */
     @Test
     public void testAppUsageLimitObserver_RemoveObserver() {
-        addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN);
+        addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0);
         assertTrue("Observer wasn't added", hasAppUsageLimitObserver(UID, OBS_ID1));
         mController.removeAppUsageLimitObserver(UID, OBS_ID1, USER_ID);
         assertFalse("Observer wasn't removed", hasAppUsageLimitObserver(UID, OBS_ID1));
@@ -290,9 +290,9 @@
     /** Re-adding an observer should result in only one copy */
     @Test
     public void testAppUsageLimitObserver_ObserverReAdd() {
-        addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN);
+        addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0);
         assertTrue("Observer wasn't added", hasAppUsageLimitObserver(UID, OBS_ID1));
-        addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_10_MIN, TIME_10_MIN);
+        addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_10_MIN, 0);
         assertTrue("Observer wasn't added",
                 getAppUsageLimitObserver(UID, OBS_ID1).getTimeLimitMs() == TIME_10_MIN);
         mController.removeAppUsageLimitObserver(UID, OBS_ID1, USER_ID);
@@ -304,7 +304,7 @@
     public void testAllObservers_ExclusiveObserverIds() {
         addAppUsageObserver(OBS_ID1, GROUP1, TIME_10_MIN);
         addUsageSessionObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_1_MIN);
-        addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_10_MIN, TIME_10_MIN);
+        addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_10_MIN, 0);
         assertTrue("Observer wasn't added", hasAppUsageObserver(UID, OBS_ID1));
         assertTrue("Observer wasn't added", hasUsageSessionObserver(UID, OBS_ID1));
         assertTrue("Observer wasn't added", hasAppUsageLimitObserver(UID, OBS_ID1));
@@ -396,7 +396,7 @@
     @Test
     public void testAppUsageLimitObserver_Accumulation() throws Exception {
         setTime(0L);
-        addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN);
+        addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0);
         startUsage(PKG_SOC1);
         // Add 10 mins
         setTime(TIME_10_MIN);
@@ -456,7 +456,7 @@
     @Test
     public void testAppUsageLimitObserver_TimeoutOtherApp() throws Exception {
         setTime(0L);
-        addAppUsageLimitObserver(OBS_ID1, GROUP1, 4_000L, 4_000L);
+        addAppUsageLimitObserver(OBS_ID1, GROUP1, 4_000L, 0);
         startUsage(PKG_SOC2);
         assertFalse(mLimitReachedLatch.await(6_000L, TimeUnit.MILLISECONDS));
         setTime(6_000L);
@@ -498,7 +498,7 @@
     @Test
     public void testAppUsageLimitObserver_Timeout() throws Exception {
         setTime(0L);
-        addAppUsageLimitObserver(OBS_ID1, GROUP1, 4_000L, 4_000L);
+        addAppUsageLimitObserver(OBS_ID1, GROUP1, 4_000L, 0);
         startUsage(PKG_SOC1);
         setTime(6_000L);
         assertTrue(mLimitReachedLatch.await(6_000L, TimeUnit.MILLISECONDS));
@@ -551,7 +551,7 @@
         setTime(TIME_10_MIN);
         startUsage(PKG_GAME1);
         setTime(TIME_30_MIN);
-        addAppUsageLimitObserver(OBS_ID2, GROUP_GAME, TIME_30_MIN, TIME_30_MIN);
+        addAppUsageLimitObserver(OBS_ID2, GROUP_GAME, TIME_30_MIN, 0);
         setTime(TIME_30_MIN + TIME_10_MIN);
         stopUsage(PKG_GAME1);
         assertFalse(mLimitReachedLatch.await(1_000L, TimeUnit.MILLISECONDS));
@@ -612,7 +612,7 @@
         startUsage(PKG_SOC1);
         setTime(TIME_10_MIN);
         // 10 second time limit
-        addAppUsageLimitObserver(OBS_ID1, GROUP_SOC, 10_000L, 10_000L);
+        addAppUsageLimitObserver(OBS_ID1, GROUP_SOC, 10_000L, 0);
         setTime(TIME_10_MIN + 5_000L);
         // Shouldn't call back in 6 seconds
         assertFalse(mLimitReachedLatch.await(6_000L, TimeUnit.MILLISECONDS));
@@ -692,23 +692,23 @@
     public void testAppUsageLimitObserver_MaxObserverLimit() throws Exception {
         boolean receivedException = false;
         int ANOTHER_UID = UID + 1;
-        addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN);
-        addAppUsageLimitObserver(OBS_ID2, GROUP1, TIME_30_MIN, TIME_30_MIN);
-        addAppUsageLimitObserver(OBS_ID3, GROUP1, TIME_30_MIN, TIME_30_MIN);
-        addAppUsageLimitObserver(OBS_ID4, GROUP1, TIME_30_MIN, TIME_30_MIN);
-        addAppUsageLimitObserver(OBS_ID5, GROUP1, TIME_30_MIN, TIME_30_MIN);
-        addAppUsageLimitObserver(OBS_ID6, GROUP1, TIME_30_MIN, TIME_30_MIN);
-        addAppUsageLimitObserver(OBS_ID7, GROUP1, TIME_30_MIN, TIME_30_MIN);
-        addAppUsageLimitObserver(OBS_ID8, GROUP1, TIME_30_MIN, TIME_30_MIN);
-        addAppUsageLimitObserver(OBS_ID9, GROUP1, TIME_30_MIN, TIME_30_MIN);
-        addAppUsageLimitObserver(OBS_ID10, GROUP1, TIME_30_MIN, TIME_30_MIN);
+        addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0);
+        addAppUsageLimitObserver(OBS_ID2, GROUP1, TIME_30_MIN, 0);
+        addAppUsageLimitObserver(OBS_ID3, GROUP1, TIME_30_MIN, 0);
+        addAppUsageLimitObserver(OBS_ID4, GROUP1, TIME_30_MIN, 0);
+        addAppUsageLimitObserver(OBS_ID5, GROUP1, TIME_30_MIN, 0);
+        addAppUsageLimitObserver(OBS_ID6, GROUP1, TIME_30_MIN, 0);
+        addAppUsageLimitObserver(OBS_ID7, GROUP1, TIME_30_MIN, 0);
+        addAppUsageLimitObserver(OBS_ID8, GROUP1, TIME_30_MIN, 0);
+        addAppUsageLimitObserver(OBS_ID9, GROUP1, TIME_30_MIN, 0);
+        addAppUsageLimitObserver(OBS_ID10, GROUP1, TIME_30_MIN, 0);
         // Readding an observer should not cause an IllegalStateException
-        addAppUsageLimitObserver(OBS_ID5, GROUP1, TIME_30_MIN, TIME_30_MIN);
+        addAppUsageLimitObserver(OBS_ID5, GROUP1, TIME_30_MIN, 0);
         // Adding an observer for a different uid shouldn't cause an IllegalStateException
         mController.addAppUsageLimitObserver(
-                ANOTHER_UID, OBS_ID11, GROUP1, TIME_30_MIN, TIME_30_MIN, null, USER_ID);
+                ANOTHER_UID, OBS_ID11, GROUP1, TIME_30_MIN, 0, null, USER_ID);
         try {
-            addAppUsageLimitObserver(OBS_ID11, GROUP1, TIME_30_MIN, TIME_30_MIN);
+            addAppUsageLimitObserver(OBS_ID11, GROUP1, TIME_30_MIN, 0);
         } catch (IllegalStateException ise) {
             receivedException = true;
         }
@@ -748,9 +748,9 @@
     public void testAppUsageLimitObserver_MinimumTimeLimit() throws Exception {
         boolean receivedException = false;
         // adding an observer with a one minute time limit should not cause an exception
-        addAppUsageLimitObserver(OBS_ID1, GROUP1, MIN_TIME_LIMIT, MIN_TIME_LIMIT);
+        addAppUsageLimitObserver(OBS_ID1, GROUP1, MIN_TIME_LIMIT, 0);
         try {
-            addAppUsageLimitObserver(OBS_ID1, GROUP1, MIN_TIME_LIMIT - 1, MIN_TIME_LIMIT - 1);
+            addAppUsageLimitObserver(OBS_ID1, GROUP1, MIN_TIME_LIMIT - 1, 0);
         } catch (IllegalArgumentException iae) {
             receivedException = true;
         }
@@ -807,7 +807,7 @@
     @Test
     public void testAppUsageLimitObserver_ConcurrentUsage() throws Exception {
         setTime(0L);
-        addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN);
+        addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0);
         AppTimeLimitController.UsageGroup group = getAppUsageLimitObserver(UID, OBS_ID1);
         startUsage(PKG_SOC1);
         // Add 10 mins
@@ -967,7 +967,7 @@
     /** Verify app usage limit observer added correctly reports its total usage limit */
     @Test
     public void testAppUsageLimitObserver_GetTotalUsageLimit() {
-        addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN);
+        addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0);
         AppTimeLimitController.AppUsageLimitGroup group = getAppUsageLimitObserver(UID, OBS_ID1);
         assertNotNull("Observer wasn't added", group);
         assertEquals("Observer didn't correctly report total usage limit",
@@ -978,7 +978,7 @@
     @Test
     public void testAppUsageLimitObserver_GetUsageRemaining() {
         setTime(0L);
-        addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN);
+        addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0);
         startUsage(PKG_SOC1);
         setTime(TIME_10_MIN);
         stopUsage(PKG_SOC1);
@@ -993,8 +993,8 @@
      */
     @Test
     public void testAppUsageLimitObserver_GetAppUsageLimit() {
-        addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN);
-        addAppUsageLimitObserver(OBS_ID2, GROUP_SOC, TIME_10_MIN, TIME_10_MIN);
+        addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0);
+        addAppUsageLimitObserver(OBS_ID2, GROUP_SOC, TIME_10_MIN, 0);
         UsageStatsManagerInternal.AppUsageLimitData group = getAppUsageLimit(PKG_SOC1);
         assertEquals("Observer with the smallest usage limit remaining wasn't returned",
                 TIME_10_MIN, group.getTotalUsageLimit());
@@ -1006,8 +1006,8 @@
     @Test
     public void testAppUsageLimitObserver_GetAppUsageLimitUsed() {
         setTime(0L);
-        addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN);
-        addAppUsageLimitObserver(OBS_ID2, GROUP_SOC, TIME_10_MIN, TIME_10_MIN);
+        addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0);
+        addAppUsageLimitObserver(OBS_ID2, GROUP_SOC, TIME_10_MIN, 0);
         startUsage(PKG_GAME1);
         setTime(TIME_10_MIN * 2 + TIME_1_MIN);
         stopUsage(PKG_GAME1);
@@ -1024,8 +1024,8 @@
     @Test
     public void testAppUsageLimitObserver_GetAppUsageLimitAllUsed() {
         setTime(0L);
-        addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_30_MIN);
-        addAppUsageLimitObserver(OBS_ID2, GROUP_SOC, TIME_10_MIN, TIME_10_MIN);
+        addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0);
+        addAppUsageLimitObserver(OBS_ID2, GROUP_SOC, TIME_10_MIN, 0);
         startUsage(PKG_SOC1);
         setTime(TIME_10_MIN);
         stopUsage(PKG_SOC1);
@@ -1046,10 +1046,10 @@
         }
     }
 
-    /** Verify that a limit of 0 is allowed for the special case of re-registering an observer. */
+    /** Verify that timeUsed can be the same as timeLimit (for re-registering observers). */
     @Test
     public void testAppUsageLimitObserver_ZeroTimeRemainingIsAllowed() {
-        addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_1_MIN, 0);
+        addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_1_MIN, TIME_1_MIN);
         AppTimeLimitController.AppUsageLimitGroup group = getAppUsageLimitObserver(UID, OBS_ID1);
         assertNotNull("Observer wasn't added", group);
         assertEquals("Usage remaining was not 0.", 0, group.getUsageRemaining());
@@ -1078,8 +1078,8 @@
     }
 
     private void addAppUsageLimitObserver(int observerId, String[] packages, long timeLimit,
-            long timeRemaining) {
-        mController.addAppUsageLimitObserver(UID, observerId, packages, timeLimit, timeRemaining,
+            long timeUsed) {
+        mController.addAppUsageLimitObserver(UID, observerId, packages, timeLimit, timeUsed,
                 null, USER_ID);
     }
 
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 7df52b2..4626840 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -117,6 +117,7 @@
 import android.util.AtomicFile;
 
 import androidx.annotation.Nullable;
+import androidx.test.InstrumentationRegistry;
 
 import com.android.internal.R;
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
@@ -311,6 +312,9 @@
 
     @Before
     public void setUp() throws Exception {
+        InstrumentationRegistry.getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
+                "android.permission.WRITE_DEVICE_CONFIG", "android.permission.READ_DEVICE_CONFIG");
+
         MockitoAnnotations.initMocks(this);
 
         LocalServices.removeServiceForTest(UriGrantsManagerInternal.class);
@@ -392,6 +396,8 @@
     public void tearDown() throws Exception {
         mFile.delete();
         clearDeviceConfig();
+        InstrumentationRegistry.getInstrumentation()
+                .getUiAutomation().dropShellPermissionIdentity();
     }
 
     public void waitForIdle() {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
index 9f11472..e375195 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
@@ -19,6 +19,7 @@
 import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
 import static android.app.NotificationManager.IMPORTANCE_HIGH;
 import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.service.notification.Adjustment.KEY_IMPORTANCE;
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL;
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_POSITIVE;
@@ -423,6 +424,138 @@
                 (int) logMaker.getTaggedData(MetricsEvent.NOTIFICATION_SINCE_VISIBLE_MILLIS));
         assertEquals(record.getInterruptionMs(timestamp),
                 (int) logMaker.getTaggedData(MetricsEvent.NOTIFICATION_SINCE_INTERRUPTION_MILLIS));
+        // If no importance calculation has been run, no explanation is available.
+        assertNull(logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_EXPLANATION));
+        assertNull(logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_INITIAL));
+        assertNull(logMaker.getTaggedData(
+                MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_INITIAL_EXPLANATION));
+        assertNull(logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_ASST));
+    }
+
+    @Test
+    public void testLogMakerImportanceApp() {
+        long timestamp = 1000L;
+        StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
+                true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
+                false /* lights */, false /* defaultLights */, null /* group */);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+
+        record.calculateImportance();  // This importance calculation will yield 'app'
+        final LogMaker logMaker = record.getLogMaker(timestamp);
+        assertEquals(MetricsEvent.IMPORTANCE_EXPLANATION_APP,
+                logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_EXPLANATION));
+        assertEquals(channel.getImportance(),
+                logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_IMPORTANCE));
+        // The additional information is only populated if the initial importance is overridden.
+        assertNull(logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_INITIAL));
+        assertNull(logMaker.getTaggedData(
+                MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_INITIAL_EXPLANATION));
+        assertNull(logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_ASST));
+    }
+
+    @Test
+    public void testLogMakerImportanceAsst() {
+        long timestamp = 1000L;
+        StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
+                true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
+                false /* lights */, false /* defaultLights */, null /* group */);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+        Bundle signals = new Bundle();
+        signals.putInt(KEY_IMPORTANCE, IMPORTANCE_LOW);
+        record.addAdjustment(new Adjustment(PKG_O, KEY_IMPORTANCE, signals, "", uid));
+        record.applyAdjustments();
+        record.calculateImportance();  // This importance calculation will yield 'asst'
+        final LogMaker logMaker = record.getLogMaker(timestamp);
+        assertEquals(MetricsEvent.IMPORTANCE_EXPLANATION_ASST,
+                logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_EXPLANATION));
+        // Therefore this is the assistant-set importance
+        assertEquals(IMPORTANCE_LOW,
+                logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_IMPORTANCE));
+        // Initial importance is populated so we know what it was, since it didn't get used.
+        assertEquals(channel.getImportance(),
+                logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_INITIAL));
+        assertEquals(MetricsEvent.IMPORTANCE_EXPLANATION_APP,
+                logMaker.getTaggedData(
+                        MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_INITIAL_EXPLANATION));
+        // This field is only populated if the assistant was itself overridden by the system.
+        assertNull(logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_ASST));
+    }
+
+    @Test
+    public void testLogMakerImportanceSystem() {
+        long timestamp = 1000L;
+        StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
+                true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
+                false /* lights */, false /* defaultLights */, null /* group */);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+        record.setSystemImportance(IMPORTANCE_HIGH);
+        record.calculateImportance();  // This importance calculation will yield 'system'
+        final LogMaker logMaker = record.getLogMaker(timestamp);
+        assertEquals(MetricsEvent.IMPORTANCE_EXPLANATION_SYSTEM,
+                logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_EXPLANATION));
+        // Therefore this is the system-set importance
+        assertEquals(IMPORTANCE_HIGH,
+                logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_IMPORTANCE));
+        // Initial importance is populated so we know what it was, since it didn't get used.
+        assertEquals(channel.getImportance(),
+                logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_INITIAL));
+        assertEquals(MetricsEvent.IMPORTANCE_EXPLANATION_APP,
+                logMaker.getTaggedData(
+                        MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_INITIAL_EXPLANATION));
+        assertNull(logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_ASST));
+    }
+
+    @Test
+    public void testLogMakerImportanceUser() {
+        long timestamp = 1000L;
+        channel.lockFields(channel.USER_LOCKED_IMPORTANCE);
+        StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
+                true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
+                false /* lights */, false /* defaultLights */, null /* group */);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+        record.calculateImportance();  // This importance calculation will yield 'user'
+        final LogMaker logMaker = record.getLogMaker(timestamp);
+        assertEquals(MetricsEvent.IMPORTANCE_EXPLANATION_USER,
+                logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_EXPLANATION));
+        // Therefore this is the user-set importance
+        assertEquals(channel.getImportance(),
+                logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_IMPORTANCE));
+        // The additional information is only populated if the initial importance is overridden.
+        assertNull(logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_INITIAL));
+        assertNull(logMaker.getTaggedData(
+                MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_INITIAL_EXPLANATION));
+        assertNull(logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_ASST));
+    }
+
+    @Test
+    public void testLogMakerImportanceMulti() {
+        long timestamp = 1000L;
+        channel.lockFields(channel.USER_LOCKED_IMPORTANCE);
+        StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
+                true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
+                false /* lights */, false /* defaultLights */, null /* group */);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+        // Add all 3 ways of overriding the app-set importance of the notification
+        Bundle signals = new Bundle();
+        signals.putInt(KEY_IMPORTANCE, IMPORTANCE_LOW);
+        record.addAdjustment(new Adjustment(PKG_O, KEY_IMPORTANCE, signals, "", uid));
+        record.applyAdjustments();
+        record.setSystemImportance(IMPORTANCE_HIGH);
+        record.calculateImportance();  // This importance calculation will yield 'system'
+        final LogMaker logMaker = record.getLogMaker(timestamp);
+        assertEquals(MetricsEvent.IMPORTANCE_EXPLANATION_SYSTEM,
+                logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_EXPLANATION));
+        // Therefore this is the system-set importance
+        assertEquals(IMPORTANCE_HIGH,
+                logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_IMPORTANCE));
+        // Initial importance is populated so we know what it was, since it didn't get used.
+        assertEquals(channel.getImportance(),
+                logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_INITIAL));
+        assertEquals(MetricsEvent.IMPORTANCE_EXPLANATION_USER, logMaker.getTaggedData(
+                MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_INITIAL_EXPLANATION));
+        // Assistant importance is populated so we know what it was, since it didn't get used.
+        assertEquals(IMPORTANCE_LOW, logMaker.getTaggedData(
+                MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_ASST));
     }
 
     @Test
@@ -807,7 +940,7 @@
         assertEquals(IMPORTANCE_DEFAULT, record.getImportance());
 
         Bundle bundle = new Bundle();
-        bundle.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_LOW);
+        bundle.putInt(KEY_IMPORTANCE, IMPORTANCE_LOW);
         Adjustment adjustment = new Adjustment(
                 PKG_O, record.getKey(), bundle, "", record.getUserId());
 
@@ -831,7 +964,7 @@
         assertEquals(IMPORTANCE_DEFAULT, record.getImportance());
 
         Bundle bundle = new Bundle();
-        bundle.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_LOW);
+        bundle.putInt(KEY_IMPORTANCE, IMPORTANCE_LOW);
         Adjustment adjustment = new Adjustment(
                 PKG_O, record.getKey(), bundle, "", record.getUserId());
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
index c072d4e..83c0af9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
@@ -59,7 +59,7 @@
     public void setUpOnDisplay(DisplayContent dc) {
         mStack = createTaskStackOnDisplay(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, dc);
         mTask = createTaskInStack(mStack, 0 /* userId */);
-        mToken = WindowTestUtils.createTestAppWindowToken(dc, false /* skipOnParentChanged */);
+        mToken = WindowTestUtils.createTestAppWindowToken(dc);
 
         mTask.addChild(mToken, 0);
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
index 5e12a95..81133d1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -18,6 +18,7 @@
 
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.view.WindowManager.TRANSIT_TASK_CHANGE_WINDOWING_MODE;
 import static android.view.WindowManager.TRANSIT_TASK_CLOSE;
 import static android.view.WindowManager.TRANSIT_TASK_OPEN;
 
@@ -77,4 +78,21 @@
                             TRANSIT_TASK_CLOSE));
         }
     }
+
+    @Test
+    public void testChangeIsNotOverwritten() {
+        synchronized (mWm.mGlobalLock) {
+            final AppWindowToken behind = createAppWindowToken(mDisplayContent,
+                    WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+            final AppWindowToken translucentOpening = createAppWindowToken(mDisplayContent,
+                    WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+            translucentOpening.setFillsParent(false);
+            translucentOpening.setHidden(true);
+            mDisplayContent.mOpeningApps.add(behind);
+            mDisplayContent.mOpeningApps.add(translucentOpening);
+            assertEquals(TRANSIT_TASK_CHANGE_WINDOWING_MODE,
+                    mAppTransitionController.maybeUpdateTransitToTranslucentAnim(
+                            TRANSIT_TASK_CHANGE_WINDOWING_MODE));
+        }
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java
index a98a604..db04f11 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java
@@ -60,7 +60,7 @@
         MockitoAnnotations.initMocks(this);
 
         mToken = createTestAppWindowToken(mDisplayContent, WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, false /* skipOnParentChanged */);
+                ACTIVITY_TYPE_STANDARD);
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
index 68b40b9..d17e5c3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -16,8 +16,6 @@
 
 package com.android.server.wm;
 
-import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
@@ -48,7 +46,6 @@
 import static org.mockito.Mockito.verify;
 
 import android.content.res.Configuration;
-import android.graphics.Point;
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
 import android.view.Display;
@@ -81,8 +78,7 @@
     public void setUp() throws Exception {
         mStack = createTaskStackOnDisplay(mDisplayContent);
         mTask = createTaskInStack(mStack, 0 /* userId */);
-        mToken = WindowTestUtils.createTestAppWindowToken(mDisplayContent,
-                false /* skipOnParentChanged */);
+        mToken = WindowTestUtils.createTestAppWindowToken(mDisplayContent);
 
         mTask.addChild(mToken, 0);
     }
@@ -219,9 +215,6 @@
 
     @Test
     public void testSizeCompatBounds() {
-        // The real surface transaction is unnecessary.
-        mToken.setSkipPrepareSurfaces(true);
-
         final Rect fixedBounds = mToken.getRequestedOverrideConfiguration().windowConfiguration
                 .getBounds();
         fixedBounds.set(0, 0, 1200, 1600);
@@ -479,32 +472,6 @@
         assertHasStartingWindow(tokenBottom);
     }
 
-    @Test
-    public void testTransitionAnimationPositionAndBounds() {
-        final Rect stackBounds = new Rect(
-                0/* left */, 0 /* top */, 1000 /* right */, 1000 /* bottom */);
-        final Rect taskBounds = new Rect(
-                100/* left */, 200 /* top */, 600 /* right */, 600 /* bottom */);
-        mStack.setBounds(stackBounds);
-        mTask.setBounds(taskBounds);
-
-        mTask.setWindowingMode(WINDOWING_MODE_FREEFORM);
-        assertTransitionAnimationPositionAndBounds(taskBounds.left, taskBounds.top, stackBounds);
-
-        mTask.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
-        assertTransitionAnimationPositionAndBounds(stackBounds.left, stackBounds.top, stackBounds);
-    }
-
-    private void assertTransitionAnimationPositionAndBounds(int expectedX, int expectedY,
-            Rect expectedBounds) {
-        final Point outPosition = new Point();
-        final Rect outBounds = new Rect();
-        mToken.getAnimationBounds(outPosition, outBounds);
-        assertEquals(expectedX, outPosition.x);
-        assertEquals(expectedY, outPosition.y);
-        assertEquals(expectedBounds, outBounds);
-    }
-
     private void assertHasStartingWindow(AppWindowToken atoken) {
         assertNotNull(atoken.startingSurface);
         assertNotNull(atoken.startingData);
diff --git a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
index aeda473..e4d3770 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
@@ -316,7 +316,7 @@
     public void testClearsRecordInMemoryOnPackageUninstalled() {
         mTarget.saveTask(mTestTask);
 
-        mObserver.onPackageRemoved(TEST_COMPONENT.getPackageName());
+        mObserver.onPackageRemoved(TEST_COMPONENT.getPackageName(), TEST_USER_ID);
 
         mTarget.getLaunchParams(mTestTask, null, mResult);
 
@@ -327,7 +327,7 @@
     public void testClearsWriteQueueItemOnPackageUninstalled() {
         mTarget.saveTask(mTestTask);
 
-        mObserver.onPackageRemoved(TEST_COMPONENT.getPackageName());
+        mObserver.onPackageRemoved(TEST_COMPONENT.getPackageName(), TEST_USER_ID);
 
         final LaunchParamsPersister target = new LaunchParamsPersister(mPersisterQueue, mSupervisor,
                 mUserFolderGetter);
@@ -344,7 +344,7 @@
         mTarget.saveTask(mTestTask);
         mPersisterQueue.flush();
 
-        mObserver.onPackageRemoved(TEST_COMPONENT.getPackageName());
+        mObserver.onPackageRemoved(TEST_COMPONENT.getPackageName(), TEST_USER_ID);
 
         final LaunchParamsPersister target = new LaunchParamsPersister(mPersisterQueue, mSupervisor,
                 mUserFolderGetter);
diff --git a/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java b/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
index 8327440..a166444 100644
--- a/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
@@ -28,6 +28,7 @@
 import android.os.SystemClock;
 import android.platform.test.annotations.Presubmit;
 
+import androidx.test.filters.FlakyTest;
 import androidx.test.filters.MediumTest;
 
 import org.junit.After;
@@ -157,6 +158,7 @@
     }
 
     @Test
+    @FlakyTest(bugId = 128526085)
     public void testProcessTwoItems_OneAfterAnother() throws Exception {
         // First item
         mLatch = new CountDownLatch(1);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
index b140da5..b9e9909 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
@@ -100,6 +100,7 @@
     }
 
     @Test
+    @Presubmit
     public void testTaskDescriptionChanged() throws Exception {
         final Object[] params = new Object[2];
         final CountDownLatch latch = new CountDownLatch(1);
@@ -132,6 +133,7 @@
     }
 
     @Test
+    @Presubmit
     public void testActivityRequestedOrientationChanged() throws Exception {
         final int[] params = new int[2];
         final CountDownLatch latch = new CountDownLatch(1);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
index 2ccdb9e..78fca0f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
@@ -19,6 +19,7 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 import static android.view.DisplayCutout.BOUNDS_POSITION_TOP;
 import static android.view.DisplayCutout.fromBoundingRect;
 import static android.view.WindowManager.LayoutParams.MATCH_PARENT;
@@ -27,7 +28,6 @@
 import static org.junit.Assert.assertEquals;
 import static org.mockito.Mockito.mock;
 
-import android.app.ActivityManager.TaskDescription;
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
@@ -54,23 +54,15 @@
 @Presubmit
 public class WindowFrameTests extends WindowTestsBase {
 
-    private WindowToken mWindowToken;
     private final IWindow mIWindow = new TestIWindow();
     private final Rect mEmptyRect = new Rect();
 
-    static class WindowStateWithTask extends WindowState {
-        final Task mTask;
+    static class FrameTestWindowState extends WindowState {
         boolean mDockedResizingForTest = false;
-        WindowStateWithTask(WindowManagerService wm, IWindow iWindow, WindowToken windowToken,
-                WindowManager.LayoutParams attrs, Task t) {
+        FrameTestWindowState(WindowManagerService wm, IWindow iWindow, WindowToken windowToken,
+                WindowManager.LayoutParams attrs) {
             super(wm, mock(Session.class), iWindow, windowToken, null, 0, 0, attrs, 0, 0,
                     false /* ownerCanAddInternalSystemWindow */);
-            mTask = t;
-        }
-
-        @Override
-        Task getTask() {
-            return mTask;
         }
 
         @Override
@@ -79,52 +71,10 @@
         }
     }
 
-    private static class TaskWithBounds extends Task {
-        Rect mBounds;
-        final Rect mOverrideDisplayedBounds = new Rect();
-        boolean mFullscreenForTest = true;
-
-        TaskWithBounds(TaskStack stack, WindowManagerService wm, Rect bounds) {
-            super(0, stack, 0, wm, 0, false, new TaskDescription(), null);
-            setBounds(bounds);
-        }
-
-        @Override
-        public int setBounds(Rect bounds) {
-            mBounds = bounds;
-            return super.setBounds(bounds);
-        }
-
-        @Override
-        public Rect getBounds() {
-            return mBounds;
-        }
-
-        @Override
-        public void getBounds(Rect out) {
-            out.set(mBounds);
-        }
-
-        @Override
-        public void getRequestedOverrideBounds(Rect outBounds) {
-            outBounds.set(mBounds);
-        }
-        @Override
-        Rect getOverrideDisplayedBounds() {
-            return mOverrideDisplayedBounds;
-        }
-        @Override
-        boolean isFullscreen() {
-            return mFullscreenForTest;
-        }
-    }
-
     TaskStack mStubStack;
 
     @Before
     public void setUp() throws Exception {
-        mWindowToken = createAppWindowToken(mWm.getDefaultDisplayContentLocked(),
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
         mStubStack = mock(TaskStack.class);
     }
 
@@ -168,7 +118,8 @@
                 expectedRect.bottom);
     }
 
-    private void assertPolicyCrop(WindowStateWithTask w, int left, int top, int right, int bottom) {
+    private void assertPolicyCrop(
+            FrameTestWindowState w, int left, int top, int right, int bottom) {
         Rect policyCrop = new Rect();
         w.calculatePolicyCrop(policyCrop);
         assertRect(policyCrop, left, top, right, bottom);
@@ -177,8 +128,7 @@
     @Test
     public void testLayoutInFullscreenTaskInsets() {
         // fullscreen task doesn't use bounds for computeFrame
-        final Task task = new TaskWithBounds(mStubStack, mWm, null);
-        WindowState w = createWindow(task, MATCH_PARENT, MATCH_PARENT);
+        WindowState w = createWindow(MATCH_PARENT, MATCH_PARENT);
         w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
 
         final int bottomContentInset = 100;
@@ -235,8 +185,7 @@
     @Test
     public void testLayoutInFullscreenTaskNoInsets() {
         // fullscreen task doesn't use bounds for computeFrame
-        final Task task = new TaskWithBounds(mStubStack, mWm, null);
-        WindowState w = createWindow(task, MATCH_PARENT, MATCH_PARENT);
+        WindowState w = createWindow(MATCH_PARENT, MATCH_PARENT);
         w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
 
         // With no insets or system decor all the frames incoming from PhoneWindowManager
@@ -323,9 +272,11 @@
         final int taskRight = logicalWidth / 4 * 3;
         final int taskBottom = logicalHeight / 4 * 3;
         final Rect taskBounds = new Rect(taskLeft, taskTop, taskRight, taskBottom);
-        final TaskWithBounds task = new TaskWithBounds(mStubStack, mWm, taskBounds);
-        task.mFullscreenForTest = false;
-        WindowState w = createWindow(task, MATCH_PARENT, MATCH_PARENT);
+        WindowState w = createWindow(MATCH_PARENT, MATCH_PARENT);
+        final Task task = w.getTask();
+        // Use split-screen because it is non-fullscreen, but also not floating
+        task.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
+        task.setBounds(taskBounds);
         w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
 
         final Rect pf = new Rect(0, 0, logicalWidth, logicalHeight);
@@ -359,8 +310,8 @@
         final int insetTop = logicalHeight / 5;
         final int insetRight = insetLeft + (taskRight - taskLeft);
         final int insetBottom = insetTop + (taskBottom - taskTop);
-        task.mOverrideDisplayedBounds.set(taskBounds);
-        task.mBounds.set(insetLeft, insetTop, insetRight, insetBottom);
+        task.setOverrideDisplayedBounds(taskBounds);
+        task.setBounds(insetLeft, insetTop, insetRight, insetBottom);
         windowFrames.setFrames(pf, pf, pf, cf, cf, pf, cf, mEmptyRect);
         w.computeFrameLw();
         assertFrame(w, taskLeft, taskTop, taskRight, taskBottom);
@@ -373,8 +324,7 @@
 
     @Test
     public void testCalculatePolicyCrop() {
-        final WindowStateWithTask w = createWindow(
-                new TaskWithBounds(mStubStack, mWm, null), MATCH_PARENT, MATCH_PARENT);
+        final FrameTestWindowState w = createWindow(MATCH_PARENT, MATCH_PARENT);
         w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
 
         final DisplayInfo displayInfo = w.getDisplayContent().getDisplayInfo();
@@ -439,9 +389,11 @@
         final int taskRight = logicalWidth / 4 * 3;
         final int taskBottom = logicalHeight / 4 * 3;
         final Rect taskBounds = new Rect(taskLeft, taskTop, taskRight, taskBottom);
-        final TaskWithBounds task = new TaskWithBounds(mStubStack, mWm, taskBounds);
-        task.mFullscreenForTest = false;
-        WindowState w = createWindow(task, MATCH_PARENT, MATCH_PARENT);
+        WindowState w = createWindow(MATCH_PARENT, MATCH_PARENT);
+        final Task task = w.getTask();
+        // Use split-screen because it is non-fullscreen, but also not floating
+        task.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
+        task.setBounds(taskBounds);
         w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
 
         final Rect pf = new Rect(0, 0, logicalWidth, logicalHeight);
@@ -461,7 +413,8 @@
         config.windowConfiguration.setBounds(cf);
         w.mAppToken.onRequestedOverrideConfigurationChanged(config);
         pf.set(0, 0, logicalWidth, logicalHeight);
-        task.mFullscreenForTest = true;
+        task.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+        task.setBounds(null);
         windowFrames.setFrames(pf, pf, pf, cf, cf, pf, cf, mEmptyRect);
         w.computeFrameLw();
         assertFrame(w, cf.left, cf.top, cf.right, cf.bottom);
@@ -472,8 +425,7 @@
     @Test
     public void testDisplayCutout() {
         // Regular fullscreen task and window
-        final Task task = new TaskWithBounds(mStubStack, mWm, null);
-        WindowState w = createWindow(task, MATCH_PARENT, MATCH_PARENT);
+        WindowState w = createWindow(MATCH_PARENT, MATCH_PARENT);
         w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
 
         final Rect pf = new Rect(0, 0, 1000, 2000);
@@ -496,11 +448,10 @@
     @Test
     public void testDisplayCutout_tempDisplayedBounds() {
         // Regular fullscreen task and window
-        final TaskWithBounds task = new TaskWithBounds(mStubStack, mWm,
-                new Rect(0, 0, 1000, 2000));
-        task.mFullscreenForTest = false;
+        WindowState w = createWindow(MATCH_PARENT, MATCH_PARENT);
+        final Task task = w.getTask();
+        task.setBounds(new Rect(0, 0, 1000, 2000));
         task.setOverrideDisplayedBounds(new Rect(0, -500, 1000, 1500));
-        WindowState w = createWindow(task, MATCH_PARENT, MATCH_PARENT);
         w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
 
         final Rect pf = new Rect(0, -500, 1000, 1500);
@@ -523,12 +474,10 @@
     @Test
     public void testFreeformContentInsets() {
         // fullscreen task doesn't use bounds for computeFrame
-        final Task task = new TaskWithBounds(mStubStack, mWm, null);
-        WindowState w = createWindow(task, MATCH_PARENT, MATCH_PARENT);
+        WindowState w = createWindow(MATCH_PARENT, MATCH_PARENT);
+        final Task task = w.getTask();
         w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
         task.setWindowingMode(WINDOWING_MODE_FREEFORM);
-        ((TaskWithBounds) task).mFullscreenForTest = false;
-        w.setWindowingMode(WINDOWING_MODE_FREEFORM);
 
         DisplayContent dc = mWm.getDefaultDisplayContentLocked();
         dc.mInputMethodTarget = w;
@@ -551,7 +500,6 @@
         final Rect winRect = new Rect(200, 200, 300, 500);
 
         task.setBounds(winRect);
-        w.setBounds(winRect);
         w.getWindowFrames().setFrames(pf, df, of, cf, vf, dcf, sf, mEmptyRect);
         w.computeFrameLw();
 
@@ -580,11 +528,16 @@
         assertEquals(winRect, w.getFrameLw());
     }
 
-    private WindowStateWithTask createWindow(Task task, int width, int height) {
+    private FrameTestWindowState createWindow(int width, int height) {
         final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(TYPE_APPLICATION);
         attrs.width = width;
         attrs.height = height;
 
-        return new WindowStateWithTask(mWm, mIWindow, mWindowToken, attrs, task);
+        AppWindowToken token = createAppWindowToken(mWm.getDefaultDisplayContentLocked(),
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+
+        FrameTestWindowState ws = new FrameTestWindowState(mWm, mIWindow, token, attrs);
+        token.addWindow(ws);
+        return ws;
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java
index 0dec8ee..a7a785d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java
@@ -56,24 +56,15 @@
 
     static TestAppWindowToken createTestAppWindowToken(DisplayContent dc) {
         synchronized (dc.mWmService.mGlobalLock) {
-            return new TestAppWindowToken(dc, true /* skipOnParentChanged */);
-        }
-    }
-
-    static TestAppWindowToken createTestAppWindowToken(DisplayContent dc,
-            boolean skipOnParentChanged) {
-        synchronized (dc.mWmService.mGlobalLock) {
-            return new TestAppWindowToken(dc, skipOnParentChanged);
+            return new TestAppWindowToken(dc);
         }
     }
 
     /** Used so we can gain access to some protected members of the {@link AppWindowToken} class. */
     static class TestAppWindowToken extends AppWindowToken {
         boolean mOnTop = false;
-        private boolean mSkipPrepareSurfaces;
-        boolean mSkipOnParentChanged = true;
 
-        private TestAppWindowToken(DisplayContent dc, boolean skipOnParentChanged) {
+        private TestAppWindowToken(DisplayContent dc) {
             super(dc.mWmService, new IApplicationToken.Stub() {
                 @Override
                 public String getName() {
@@ -81,7 +72,6 @@
                 }
             }, new ComponentName("", ""), false, dc, true /* fillsParent */);
             mTargetSdk = Build.VERSION_CODES.CUR_DEVELOPMENT;
-            mSkipOnParentChanged = skipOnParentChanged;
             mActivityRecord = mock(ActivityRecord.class);
             mActivityRecord.app = mock(WindowProcessController.class);
         }
@@ -103,44 +93,10 @@
         }
 
         @Override
-        void onParentChanged() {
-            if (!mSkipOnParentChanged) {
-                super.onParentChanged();
-            } else {
-                updateConfigurationFromParent(this);
-            }
-        }
-
-        @Override
         boolean isOnTop() {
             return mOnTop;
         }
 
-        @Override
-        void prepareSurfaces() {
-            if (!mSkipPrepareSurfaces) {
-                super.prepareSurfaces();
-            }
-        }
-
-        void setSkipPrepareSurfaces(boolean ignore) {
-            mSkipPrepareSurfaces = ignore;
-        }
-    }
-
-    /**
-     * Used when we don't want to perform surface related operation in
-     * {@link WindowContainer#onParentChanged} or the overridden method, but the configuration
-     * still needs to propagate from parent.
-     *
-     * @see ConfigurationContainer#onParentChanged
-     */
-    static void updateConfigurationFromParent(WindowContainer container) {
-        final WindowContainer parent = container.getParent();
-        if (parent != null) {
-            container.onConfigurationChanged(parent.getConfiguration());
-            container.onMergedOverrideConfigurationChanged();
-        }
     }
 
     static TestWindowToken createTestWindowToken(int type, DisplayContent dc) {
@@ -246,10 +202,5 @@
 
             mHasSurface = hadSurface;
         }
-
-        @Override
-        void onParentChanged() {
-            updateConfigurationFromParent(this);
-        }
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 032eba1..8c37ca5e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -229,10 +229,11 @@
         } catch (Exception e) {
             Log.e(TAG, "Failed to tear down test", e);
             throw e;
+        } finally {
+            mMockTracker.close();
+            mMockTracker = null;
         }
 
-        mMockTracker.close();
-        mMockTracker = null;
     }
 
     private WindowState createCommonWindow(WindowState parent, int type, String name) {
@@ -269,16 +270,10 @@
 
     WindowTestUtils.TestAppWindowToken createTestAppWindowToken(DisplayContent dc, int
             windowingMode, int activityType) {
-        return createTestAppWindowToken(dc, windowingMode, activityType,
-                false /*skipOnParentChanged */);
-    }
-
-    WindowTestUtils.TestAppWindowToken createTestAppWindowToken(DisplayContent dc, int
-            windowingMode, int activityType, boolean skipOnParentChanged) {
         final TaskStack stack = createTaskStackOnDisplay(windowingMode, activityType, dc);
         final Task task = createTaskInStack(stack, 0 /* userId */);
         final WindowTestUtils.TestAppWindowToken appWindowToken =
-                WindowTestUtils.createTestAppWindowToken(dc, skipOnParentChanged);
+                WindowTestUtils.createTestAppWindowToken(dc);
         task.addChild(appWindowToken, 0);
         return appWindowToken;
     }
diff --git a/services/usage/java/com/android/server/usage/AppTimeLimitController.java b/services/usage/java/com/android/server/usage/AppTimeLimitController.java
index f3d6387..6861ad1 100644
--- a/services/usage/java/com/android/server/usage/AppTimeLimitController.java
+++ b/services/usage/java/com/android/server/usage/AppTimeLimitController.java
@@ -511,10 +511,10 @@
 
     class AppUsageLimitGroup extends UsageGroup {
         public AppUsageLimitGroup(UserData user, ObserverAppData observerApp, int observerId,
-                String[] observed, long timeLimitMs, long timeRemainingMs,
+                String[] observed, long timeLimitMs, long timeUsedMs,
                 PendingIntent limitReachedCallback) {
             super(user, observerApp, observerId, observed, timeLimitMs, limitReachedCallback);
-            mUsageTimeMs = timeLimitMs - timeRemainingMs;
+            mUsageTimeMs = timeUsedMs;
         }
 
         @Override
@@ -841,7 +841,7 @@
      * Existing app usage limit observer with the same observerId will be removed.
      */
     public void addAppUsageLimitObserver(int requestingUid, int observerId, String[] observed,
-            long timeLimit, long timeRemaining, PendingIntent callbackIntent,
+            long timeLimit, long timeUsed, PendingIntent callbackIntent,
             @UserIdInt int userId) {
         if (timeLimit < getMinTimeLimit()) {
             throw new IllegalArgumentException("Time limit must be >= " + getMinTimeLimit());
@@ -861,7 +861,7 @@
                         "Too many app usage observers added by uid " + requestingUid);
             }
             group = new AppUsageLimitGroup(user, observerApp, observerId, observed, timeLimit,
-                    timeRemaining, timeRemaining == 0L ? null : callbackIntent);
+                    timeUsed, timeUsed >= timeLimit ? null : callbackIntent);
             observerApp.appUsageLimitGroups.append(observerId, group);
 
             if (DEBUG) {
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 27fdbcb..1ec680f 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -1399,7 +1399,7 @@
 
         @Override
         public void registerAppUsageLimitObserver(int observerId, String[] packages,
-                long timeLimitMs, long timeRemainingMs, PendingIntent callbackIntent,
+                long timeLimitMs, long timeUsedMs, PendingIntent callbackIntent,
                 String callingPackage) {
             if (!hasPermissions(callingPackage,
                     Manifest.permission.SUSPEND_APPS, Manifest.permission.OBSERVE_APP_USAGE)) {
@@ -1410,11 +1410,7 @@
             if (packages == null || packages.length == 0) {
                 throw new IllegalArgumentException("Must specify at least one package");
             }
-            if (timeRemainingMs > timeLimitMs) {
-                throw new IllegalArgumentException(
-                        "Remaining time can't be greater than total time.");
-            }
-            if (callbackIntent == null && timeRemainingMs != 0L) {
+            if (callbackIntent == null && timeUsedMs < timeLimitMs) {
                 throw new NullPointerException("callbackIntent can't be null");
             }
             final int callingUid = Binder.getCallingUid();
@@ -1422,7 +1418,7 @@
             final long token = Binder.clearCallingIdentity();
             try {
                 UsageStatsService.this.registerAppUsageLimitObserver(callingUid, observerId,
-                        packages, timeLimitMs, timeRemainingMs, callbackIntent, userId);
+                        packages, timeLimitMs, timeUsedMs, callbackIntent, userId);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
@@ -1550,9 +1546,9 @@
     }
 
     void registerAppUsageLimitObserver(int callingUid, int observerId, String[] packages,
-            long timeLimitMs, long timeRemainingMs, PendingIntent callbackIntent, int userId) {
+            long timeLimitMs, long timeUsedMs, PendingIntent callbackIntent, int userId) {
         mAppTimeLimit.addAppUsageLimitObserver(callingUid, observerId, packages,
-                timeLimitMs, timeRemainingMs, callbackIntent, userId);
+                timeLimitMs, timeUsedMs, callbackIntent, userId);
     }
 
     void unregisterAppUsageLimitObserver(int callingUid, int observerId, int userId) {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 61d7d6c..8d2cbca 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -357,7 +357,8 @@
         Intent intent = new Intent(VoiceInteractionService.SERVICE_INTERFACE);
         intent.setComponent(mComponent);
         mBound = mContext.bindServiceAsUser(intent, mConnection,
-                Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, new UserHandle(mUser));
+                Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE
+                | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS, new UserHandle(mUser));
         if (!mBound) {
             Slog.w(TAG, "Failed binding to voice interaction service " + mComponent);
         }
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index 1bf0723..24690f5 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -159,7 +159,8 @@
         mBindIntent.setComponent(mSessionComponentName);
         mBound = mContext.bindServiceAsUser(mBindIntent, this,
                 Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY
-                        | Context.BIND_ALLOW_OOM_MANAGEMENT, new UserHandle(mUser));
+                        | Context.BIND_ALLOW_OOM_MANAGEMENT
+                        | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS, new UserHandle(mUser));
         if (mBound) {
             try {
                 mIWindowManager.addWindowToken(mToken, TYPE_VOICE_INTERACTION, DEFAULT_DISPLAY);
@@ -191,7 +192,8 @@
             if (!mFullyBound) {
                 mFullyBound = mContext.bindServiceAsUser(mBindIntent, mFullConnection,
                         Context.BIND_AUTO_CREATE | Context.BIND_TREAT_LIKE_ACTIVITY
-                                | Context.BIND_FOREGROUND_SERVICE,
+                                | Context.BIND_FOREGROUND_SERVICE
+                                | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS,
                         new UserHandle(mUser));
             }
 
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index ae12a17..28e6596 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -555,6 +555,15 @@
     public static final String EVENT_CALL_MERGE_FAILED = "android.telecom.event.CALL_MERGE_FAILED";
 
     /**
+     * Connection event used to inform Telecom when a hold operation on a call has failed.
+     * Not intended for use by the UI at this time.
+     * Sent via {@link #sendConnectionEvent(String, Bundle)}.  The {@link Bundle} parameter is
+     * expected to be null when this connection event is used.
+     * @hide
+     */
+    public static final String EVENT_CALL_HOLD_FAILED = "android.telecom.event.CALL_HOLD_FAILED";
+
+    /**
      * Connection event used to inform {@link InCallService}s when the process of merging a
      * Connection into a conference has begun.
      * <p>
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 52c5425..3d0a3c5 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -1589,7 +1589,7 @@
                                 Build.VERSION_CODES.O_MR1) {
                     Log.e("TAG", "addNewIncomingCall failed. Use public api " +
                             "acceptHandover for API > O-MR1");
-                    // TODO add "return" after DUO team adds support for new handover API
+                    return;
                 }
                 getTelecomService().addNewIncomingCall(
                         phoneAccount, extras == null ? new Bundle() : extras);
diff --git a/telephony/java/android/telephony/DebugEventReporter.java b/telephony/java/android/telephony/AnomalyReporter.java
similarity index 82%
rename from telephony/java/android/telephony/DebugEventReporter.java
rename to telephony/java/android/telephony/AnomalyReporter.java
index 14b7dd6..9753d8b 100644
--- a/telephony/java/android/telephony/DebugEventReporter.java
+++ b/telephony/java/android/telephony/AnomalyReporter.java
@@ -29,7 +29,6 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.List;
-import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 import java.util.concurrent.ConcurrentHashMap;
@@ -37,7 +36,7 @@
 /**
  * A Simple Surface for Telephony to notify a loosely-coupled debugger of particular issues.
  *
- * DebugEventReporter allows an optional external logging component to receive events detected by
+ * AnomalyReporter allows an optional external logging component to receive events detected by
  * the framework and take action. This log surface is designed to provide maximium flexibility
  * to the receiver of these events. Envisioned use cases of this include notifying a vendor
  * component of: an event that necessitates (timely) log collection on non-AOSP components;
@@ -49,8 +48,8 @@
  *
  * @hide
  */
-public final class DebugEventReporter {
-    private static final String TAG = "DebugEventReporter";
+public final class AnomalyReporter {
+    private static final String TAG = "AnomalyReporter";
 
     private static Context sContext = null;
 
@@ -63,12 +62,12 @@
      */
     private static String sDebugPackageName = null;
 
-    private DebugEventReporter() {};
+    private AnomalyReporter() {};
 
     /**
      * If enabled, build and send an intent to a Debug Service for logging.
      *
-     * This method sends the {@link TelephonyManager#DEBUG_EVENT DEBUG_EVENT} broadcast, which is
+     * This method sends the {@link TelephonyManager#ACTION_ANOMALY_REPORTED} broadcast, which is
      * system protected. Invoking this method unless you are the system will result in an error.
      *
      * @param eventId a fixed event ID that will be sent for each instance of the same event. This
@@ -77,9 +76,9 @@
      *        identification and discussion of this event. This description should ideally be
      *        static and must not contain any sensitive information (especially PII).
      */
-    public static void sendEvent(@NonNull UUID eventId, String description) {
+    public static void reportAnomaly(@NonNull UUID eventId, String description) {
         if (sContext == null) {
-            Rlog.w(TAG, "DebugEventReporter not yet initialized, dropping event=" + eventId);
+            Rlog.w(TAG, "AnomalyReporter not yet initialized, dropping event=" + eventId);
             return;
         }
 
@@ -94,28 +93,28 @@
         // so drop these events silently.
         if (sDebugPackageName == null) return;
 
-        Intent dbgIntent = new Intent(TelephonyManager.ACTION_DEBUG_EVENT);
-        dbgIntent.putExtra(TelephonyManager.EXTRA_DEBUG_EVENT_ID, new ParcelUuid(eventId));
+        Intent dbgIntent = new Intent(TelephonyManager.ACTION_ANOMALY_REPORTED);
+        dbgIntent.putExtra(TelephonyManager.EXTRA_ANOMALY_ID, new ParcelUuid(eventId));
         if (description != null) {
-            dbgIntent.putExtra(TelephonyManager.EXTRA_DEBUG_EVENT_DESCRIPTION, description);
+            dbgIntent.putExtra(TelephonyManager.EXTRA_ANOMALY_DESCRIPTION, description);
         }
         dbgIntent.setPackage(sDebugPackageName);
         sContext.sendBroadcast(dbgIntent, android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
     }
 
     /**
-     * Initialize the DebugEventReporter with the current context.
+     * Initialize the AnomalyReporter with the current context.
      *
-     * This method must be invoked before any calls to sendEvent() will succeed. This method should
-     * only be invoked at most once.
+     * This method must be invoked before any calls to reportAnomaly() will succeed. This method
+     * should only be invoked at most once.
      *
-     * @param context a Context object used to initialize this singleton DebugEventReporter in
+     * @param context a Context object used to initialize this singleton AnomalyReporter in
      *        the current process.
      */
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     public static void initialize(@NonNull Context context) {
         if (context == null) {
-            throw new IllegalArgumentException("DebugEventReporter needs a non-null context.");
+            throw new IllegalArgumentException("AnomalyReporter needs a non-null context.");
         }
 
         // Ensure that this context has sufficient permissions to send debug events.
@@ -129,13 +128,13 @@
         PackageManager pm = sContext.getPackageManager();
         if (pm == null) return;
         List<ResolveInfo> packages = pm.queryBroadcastReceivers(
-                new Intent(TelephonyManager.ACTION_DEBUG_EVENT),
+                new Intent(TelephonyManager.ACTION_ANOMALY_REPORTED),
                 PackageManager.MATCH_SYSTEM_ONLY
                         | PackageManager.MATCH_DIRECT_BOOT_AWARE
                         | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
         if (packages == null || packages.isEmpty()) return;
         if (packages.size() > 1) {
-            Rlog.e(TAG, "Multiple DebugEvent Receivers installed.");
+            Rlog.e(TAG, "Multiple Anomaly Receivers installed.");
         }
 
         for (ResolveInfo r : packages) {
@@ -156,14 +155,14 @@
         // Initialization may only be performed once.
     }
 
-    /** Dump the contents of the DebugEventReporter */
+    /** Dump the contents of the AnomalyReporter */
     public static void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
         if (sContext == null) return;
         IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
         sContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, "Requires DUMP");
         pw.println("Initialized=" + (sContext != null ? "Yes" : "No"));
         pw.println("Debug Package=" + sDebugPackageName);
-        pw.println("Event Counts:");
+        pw.println("Anomaly Counts:");
         pw.increaseIndent();
         for (UUID event : sEvents.keySet()) {
             pw.println(event + ": " + sEvents.get(event));
diff --git a/telephony/java/android/telephony/CellIdentity.java b/telephony/java/android/telephony/CellIdentity.java
index 6c835dc..e5aadad 100644
--- a/telephony/java/android/telephony/CellIdentity.java
+++ b/telephony/java/android/telephony/CellIdentity.java
@@ -86,7 +86,7 @@
         }
 
         if ((mMccStr != null && mMncStr == null) || (mMccStr == null && mMncStr != null)) {
-            DebugEventReporter.sendEvent(
+            AnomalyReporter.reportAnomaly(
                     UUID.fromString("a3ab0b9d-f2aa-4baf-911d-7096c0d4645a"),
                     "CellIdentity Missing Half of PLMN ID");
         }
diff --git a/telephony/java/android/telephony/RadioAccessFamily.java b/telephony/java/android/telephony/RadioAccessFamily.java
index 48c07e8..28f6515 100644
--- a/telephony/java/android/telephony/RadioAccessFamily.java
+++ b/telephony/java/android/telephony/RadioAccessFamily.java
@@ -397,81 +397,4 @@
         }
         return result;
     }
-
-    /**
-     * convert RAF from {@link android.hardware.radio.V1_0.RadioAccessFamily} to
-     * {@link TelephonyManager.NetworkTypeBitMask}, the bitmask represented by
-     * {@link TelephonyManager.NetworkType}.
-     *
-     * @param raf {@link android.hardware.radio.V1_0.RadioAccessFamily}
-     * @return {@link TelephonyManager.NetworkTypeBitMask}
-     */
-    public static int convertToNetworkTypeBitMask(int raf) {
-        int networkTypeRaf = 0;
-
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.GSM) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_GSM;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.GPRS) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_GPRS;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EDGE) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EDGE;
-        }
-        // convert both IS95A/IS95B to CDMA as network mode doesn't support CDMA
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.IS95A) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_CDMA;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.IS95B) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_CDMA;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.ONE_X_RTT) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EVDO_0) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_0;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EVDO_A) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_A;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EVDO_B) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_B;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EHRPD) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EHRPD;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.HSUPA) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_HSUPA;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.HSDPA) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_HSDPA;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.HSPA) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_HSPA;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.HSPAP) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_HSPAP;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.UMTS) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_UMTS;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.TD_SCDMA) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_TD_SCDMA;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.LTE) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_LTE;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.LTE_CA) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_LTE_CA;
-        }
-        if ((raf & android.hardware.radio.V1_4.RadioAccessFamily.NR) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_NR;
-        }
-        // TODO: need hal definition
-        if ((raf & (1 << ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN)) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN;
-        }
-
-        return (networkTypeRaf == 0) ? TelephonyManager.NETWORK_TYPE_UNKNOWN : networkTypeRaf;
-    }
 }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 16dafd6..f07ac5a 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1383,41 +1383,42 @@
      * in the application manifest. For performance reasons, if no application to receive these
      * events is detected at boot, then these events will not be sent.
      *
-     * <p>Each event will include an {@link EXTRA_DEBUG_EVENT_ID} that will uniquely identify the
+     * <p>Each event will include an {@link EXTRA_ANOMALY_ID} that will uniquely identify the
      * event that has occurred. Each event will be sent to the diagnostic monitor only once per
      * boot cycle (as another optimization).
      *
-     * @see #EXTRA_DEBUG_EVENT_ID
-     * @see #EXTRA_DEBUG_EVENT_DESCRIPTION
+     * @see #EXTRA_ANOMALY_ID
+     * @see #EXTRA_ANOMALY_DESCRIPTION
      * @hide
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-    public static final String ACTION_DEBUG_EVENT = "android.telephony.action.DEBUG_EVENT";
+    public static final String ACTION_ANOMALY_REPORTED =
+            "android.telephony.action.ANOMALY_REPORTED";
 
     /**
      * An arbitrary ParcelUuid which should be consistent for each occurrence of a DebugEvent.
      *
-     * This field must be included in all {@link ACTION_DEBUG_EVENT} events.
+     * This field must be included in all {@link ACTION_ANOMALY_REPORTED} events.
      *
-     * @see #ACTION_DEBUG_EVENT
+     * @see #ACTION_ANOMALY_REPORTED
      * @hide
      */
     @SystemApi
-    public static final String EXTRA_DEBUG_EVENT_ID = "android.telephony.extra.DEBUG_EVENT_ID";
+    public static final String EXTRA_ANOMALY_ID = "android.telephony.extra.ANOMALY_ID";
 
     /**
-     * A freeform string description of the DebugEvent.
+     * A freeform string description of the Anomaly.
      *
-     * This field is optional for all {@link ACTION_DEBUG_EVENT}s, as a guideline should not
+     * This field is optional for all {@link ACTION_ANOMALY_REPORTED}s, as a guideline should not
      * exceed 80 characters, and should be as short as possible to convey the essence of the event.
      *
-     * @see #ACTION_DEBUG_EVENT
+     * @see #ACTION_ANOMALY_REPORTED
      * @hide
      */
     @SystemApi
-    public static final String EXTRA_DEBUG_EVENT_DESCRIPTION =
-            "android.telephony.extra.DEBUG_EVENT_DESCRIPTION";
+    public static final String EXTRA_ANOMALY_DESCRIPTION =
+            "android.telephony.extra.ANOMALY_DESCRIPTION";
 
     //
     //
@@ -5188,6 +5189,40 @@
     }
 
     /**
+     * Opens a logical channel to the ICC card using the physical slot index.
+     *
+     * Use this method when no subscriptions are available on the SIM and the operation must be
+     * performed using the physical slot index.
+     *
+     * Input parameters equivalent to TS 27.007 AT+CCHO command.
+     *
+     * <p>Requires Permission:
+     * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
+     *
+     * @param slotIndex the physical slot index of the ICC card
+     * @param aid Application id. See ETSI 102.221 and 101.220.
+     * @param p2 P2 parameter (described in ISO 7816-4).
+     * @return an IccOpenLogicalChannelResponse object.
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    @SystemApi
+    @Nullable
+    public IccOpenLogicalChannelResponse iccOpenLogicalChannelBySlot(int slotIndex,
+            @Nullable String aid, int p2) {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.iccOpenLogicalChannelBySlot(slotIndex, getOpPackageName(), aid,
+                        p2);
+            }
+        } catch (RemoteException ex) {
+        } catch (NullPointerException ex) {
+        }
+        return null;
+    }
+
+    /**
      * Opens a logical channel to the ICC card.
      *
      * Input parameters equivalent to TS 27.007 AT+CCHO command.
@@ -5231,6 +5266,38 @@
     }
 
     /**
+     * Closes a previously opened logical channel to the ICC card using the physical slot index.
+     *
+     * Use this method when no subscriptions are available on the SIM and the operation must be
+     * performed using the physical slot index.
+     *
+     * Input parameters equivalent to TS 27.007 AT+CCHC command.
+     *
+     * <p>Requires Permission:
+     * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
+     *
+     * @param slotIndex the physical slot index of the ICC card
+     * @param channel is the channel id to be closed as returned by a successful
+     *            iccOpenLogicalChannel.
+     * @return true if the channel was closed successfully.
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    @SystemApi
+    @Nullable
+    public boolean iccCloseLogicalChannelBySlot(int slotIndex, int channel) {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.iccCloseLogicalChannelBySlot(slotIndex, channel);
+            }
+        } catch (RemoteException ex) {
+        } catch (NullPointerException ex) {
+        }
+        return false;
+    }
+
+    /**
      * Closes a previously opened logical channel to the ICC card.
      *
      * Input parameters equivalent to TS 27.007 AT+CCHC command.
@@ -5239,7 +5306,7 @@
      * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling
      * app has carrier privileges (see {@link #hasCarrierPrivileges}).
      *
-     * @param channel is the channel id to be closed as retruned by a successful
+     * @param channel is the channel id to be closed as returned by a successful
      *            iccOpenLogicalChannel.
      * @return true if the channel was closed successfully.
      */
@@ -5257,7 +5324,7 @@
      * app has carrier privileges (see {@link #hasCarrierPrivileges}).
      *
      * @param subId The subscription to use.
-     * @param channel is the channel id to be closed as retruned by a successful
+     * @param channel is the channel id to be closed as returned by a successful
      *            iccOpenLogicalChannel.
      * @return true if the channel was closed successfully.
      * @hide
@@ -5274,6 +5341,48 @@
     }
 
     /**
+     * Transmit an APDU to the ICC card over a logical channel using the physical slot index.
+     *
+     * Use this method when no subscriptions are available on the SIM and the operation must be
+     * performed using the physical slot index.
+     *
+     * Input parameters equivalent to TS 27.007 AT+CGLA command.
+     *
+     * <p>Requires Permission:
+     * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
+     *
+     * @param slotIndex the physical slot index of the ICC card
+     * @param channel is the channel id to be closed as returned by a successful
+     *            iccOpenLogicalChannel.
+     * @param cla Class of the APDU command.
+     * @param instruction Instruction of the APDU command.
+     * @param p1 P1 value of the APDU command.
+     * @param p2 P2 value of the APDU command.
+     * @param p3 P3 value of the APDU command. If p3 is negative a 4 byte APDU
+     *            is sent to the SIM.
+     * @param data Data to be sent with the APDU.
+     * @return The APDU response from the ICC card with the status appended at
+     *            the end.
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    @SystemApi
+    @Nullable
+    public String iccTransmitApduLogicalChannelBySlot(int slotIndex, int channel, int cla,
+            int instruction, int p1, int p2, int p3, @Nullable String data) {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.iccTransmitApduLogicalChannelBySlot(slotIndex, channel, cla,
+                        instruction, p1, p2, p3, data);
+            }
+        } catch (RemoteException ex) {
+        } catch (NullPointerException ex) {
+        }
+        return null;
+    }
+
+    /**
      * Transmit an APDU to the ICC card over a logical channel.
      *
      * Input parameters equivalent to TS 27.007 AT+CGLA command.
@@ -5337,6 +5446,46 @@
     }
 
     /**
+     * Transmit an APDU to the ICC card over the basic channel using the physical slot index.
+     *
+     * Use this method when no subscriptions are available on the SIM and the operation must be
+     * performed using the physical slot index.
+     *
+     * Input parameters equivalent to TS 27.007 AT+CSIM command.
+     *
+     * <p>Requires Permission:
+     * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
+     *
+     * @param slotIndex the physical slot index of the ICC card to target
+     * @param cla Class of the APDU command.
+     * @param instruction Instruction of the APDU command.
+     * @param p1 P1 value of the APDU command.
+     * @param p2 P2 value of the APDU command.
+     * @param p3 P3 value of the APDU command. If p3 is negative a 4 byte APDU
+     *            is sent to the SIM.
+     * @param data Data to be sent with the APDU.
+     * @return The APDU response from the ICC card with the status appended at
+     *            the end.
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    @SystemApi
+    @NonNull
+    public String iccTransmitApduBasicChannelBySlot(int slotIndex, int cla, int instruction, int p1,
+            int p2, int p3, @Nullable String data) {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.iccTransmitApduBasicChannelBySlot(slotIndex, getOpPackageName(),
+                        cla, instruction, p1, p2, p3, data);
+            }
+        } catch (RemoteException ex) {
+        } catch (NullPointerException ex) {
+        }
+        return null;
+    }
+
+    /**
      * Transmit an APDU to the ICC card over the basic channel.
      *
      * Input parameters equivalent to TS 27.007 AT+CSIM command.
@@ -6003,7 +6152,7 @@
         // FIXME Need to get it from Telephony Dev Controller when that gets implemented!
         // and then this method shouldn't be used at all!
         if(isMultiSimEnabled()) {
-            return 2;
+            return getPhoneCount();
         } else {
             return 1;
         }
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index 0b1d1fb..d0b52c9 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -1641,6 +1641,7 @@
          *
          * @param entryName the entry name to set for the APN
          */
+        @NonNull
         public Builder setEntryName(String entryName) {
             this.mEntryName = entryName;
             return this;
@@ -1651,6 +1652,7 @@
          *
          * @param apnName the name to set for the APN
          */
+        @NonNull
         public Builder setApnName(String apnName) {
             this.mApnName = apnName;
             return this;
@@ -1681,6 +1683,7 @@
          *
          * @param proxy the proxy address to set for the APN
          */
+        @NonNull
         public Builder setProxyAddress(String proxy) {
             this.mProxyAddress = proxy;
             return this;
@@ -1691,6 +1694,7 @@
          *
          * @param port the proxy port to set for the APN
          */
+        @NonNull
         public Builder setProxyPort(int port) {
             this.mProxyPort = port;
             return this;
@@ -1701,6 +1705,7 @@
          *
          * @param mmsc the MMSC Uri to set for the APN
          */
+        @NonNull
         public Builder setMmsc(Uri mmsc) {
             this.mMmsc = mmsc;
             return this;
@@ -1732,6 +1737,7 @@
          *
          * @param mmsProxy the MMS proxy address to set for the APN
          */
+        @NonNull
         public Builder setMmsProxyAddress(String mmsProxy) {
             this.mMmsProxyAddress = mmsProxy;
             return this;
@@ -1742,6 +1748,7 @@
          *
          * @param mmsPort the MMS proxy port to set for the APN
          */
+        @NonNull
         public Builder setMmsProxyPort(int mmsPort) {
             this.mMmsProxyPort = mmsPort;
             return this;
@@ -1752,6 +1759,7 @@
          *
          * @param user the APN username to set for the APN
          */
+        @NonNull
         public Builder setUser(String user) {
             this.mUser = user;
             return this;
@@ -1763,6 +1771,7 @@
          * @see android.provider.Telephony.Carriers#PASSWORD
          * @param password the APN password to set for the APN
          */
+        @NonNull
         public Builder setPassword(String password) {
             this.mPassword = password;
             return this;
@@ -1773,6 +1782,7 @@
          *
          * @param authType the authentication type to set for the APN
          */
+        @NonNull
         public Builder setAuthType(@AuthType int authType) {
             this.mAuthType = authType;
             return this;
@@ -1789,6 +1799,7 @@
          *
          * @param apnTypeBitmask a bitmask describing the types of the APN
          */
+        @NonNull
         public Builder setApnTypeBitmask(@ApnType int apnTypeBitmask) {
             this.mApnTypeBitmask = apnTypeBitmask;
             return this;
@@ -1801,6 +1812,7 @@
          *
          * @param operatorNumeric the numeric operator ID to set for this entry
          */
+        @NonNull
         public Builder setOperatorNumeric(String operatorNumeric) {
             this.mOperatorNumeric = operatorNumeric;
             return this;
@@ -1813,6 +1825,7 @@
          *
          * @param protocol the protocol to set to use to connect to this APN
          */
+        @NonNull
         public Builder setProtocol(@ProtocolType int protocol) {
             this.mProtocol = protocol;
             return this;
@@ -1825,6 +1838,7 @@
          *
          * @param roamingProtocol the protocol to set to use to connect to this APN when roaming
          */
+        @NonNull
         public Builder setRoamingProtocol(@ProtocolType  int roamingProtocol) {
             this.mRoamingProtocol = roamingProtocol;
             return this;
@@ -1835,6 +1849,7 @@
          *
          * @param carrierEnabled the current status to set for this APN
          */
+        @NonNull
         public Builder setCarrierEnabled(boolean carrierEnabled) {
             this.mCarrierEnabled = carrierEnabled;
             return this;
@@ -1845,6 +1860,7 @@
          *
          * @param networkTypeBitmask the Radio Technology (Network Type) info
          */
+        @NonNull
         public Builder setNetworkTypeBitmask(int networkTypeBitmask) {
             this.mNetworkTypeBitmask = networkTypeBitmask;
             return this;
@@ -1855,6 +1871,7 @@
          *
          * @param mvnoType the MVNO match type to set for this APN
          */
+        @NonNull
         public Builder setMvnoType(@MvnoType int mvnoType) {
             this.mMvnoType = mvnoType;
             return this;
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 122747a65..62b92fd 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -553,6 +553,20 @@
     void setCellInfoListRate(int rateInMillis);
 
     /**
+     * Opens a logical channel to the ICC card using the physical slot index.
+     *
+     * Input parameters equivalent to TS 27.007 AT+CCHO command.
+     *
+     * @param slotIndex The physical slot index of the target ICC card
+     * @param callingPackage the name of the package making the call.
+     * @param AID Application id. See ETSI 102.221 and 101.220.
+     * @param p2 P2 parameter (described in ISO 7816-4).
+     * @return an IccOpenLogicalChannelResponse object.
+     */
+    IccOpenLogicalChannelResponse iccOpenLogicalChannelBySlot(
+            int slotIndex, String callingPackage, String AID, int p2);
+
+    /**
      * Opens a logical channel to the ICC card.
      *
      * Input parameters equivalent to TS 27.007 AT+CCHO command.
@@ -567,12 +581,24 @@
             int subId, String callingPackage, String AID, int p2);
 
     /**
+     * Closes a previously opened logical channel to the ICC card using the physical slot index.
+     *
+     * Input parameters equivalent to TS 27.007 AT+CCHC command.
+     *
+     * @param slotIndex The physical slot index of the target ICC card
+     * @param channel is the channel id to be closed as returned by a
+     *            successful iccOpenLogicalChannel.
+     * @return true if the channel was closed successfully.
+     */
+    boolean iccCloseLogicalChannelBySlot(int slotIndex, int channel);
+
+    /**
      * Closes a previously opened logical channel to the ICC card.
      *
      * Input parameters equivalent to TS 27.007 AT+CCHC command.
      *
      * @param subId The subscription to use.
-     * @param channel is the channel id to be closed as retruned by a
+     * @param channel is the channel id to be closed as returned by a
      *            successful iccOpenLogicalChannel.
      * @return true if the channel was closed successfully.
      */
@@ -580,12 +606,33 @@
     boolean iccCloseLogicalChannel(int subId, int channel);
 
     /**
+     * Transmit an APDU to the ICC card over a logical channel using the physical slot index.
+     *
+     * Input parameters equivalent to TS 27.007 AT+CGLA command.
+     *
+     * @param slotIndex The physical slot index of the target ICC card
+     * @param channel is the channel id to be closed as returned by a
+     *            successful iccOpenLogicalChannel.
+     * @param cla Class of the APDU command.
+     * @param instruction Instruction of the APDU command.
+     * @param p1 P1 value of the APDU command.
+     * @param p2 P2 value of the APDU command.
+     * @param p3 P3 value of the APDU command. If p3 is negative a 4 byte APDU
+     *            is sent to the SIM.
+     * @param data Data to be sent with the APDU.
+     * @return The APDU response from the ICC card with the status appended at
+     *            the end.
+     */
+    String iccTransmitApduLogicalChannelBySlot(int slotIndex, int channel, int cla, int instruction,
+            int p1, int p2, int p3, String data);
+
+    /**
      * Transmit an APDU to the ICC card over a logical channel.
      *
      * Input parameters equivalent to TS 27.007 AT+CGLA command.
      *
      * @param subId The subscription to use.
-     * @param channel is the channel id to be closed as retruned by a
+     * @param channel is the channel id to be closed as returned by a
      *            successful iccOpenLogicalChannel.
      * @param cla Class of the APDU command.
      * @param instruction Instruction of the APDU command.
@@ -602,6 +649,26 @@
             int p1, int p2, int p3, String data);
 
     /**
+     * Transmit an APDU to the ICC card over the basic channel using the physical slot index.
+     *
+     * Input parameters equivalent to TS 27.007 AT+CSIM command.
+     *
+     * @param slotIndex The physical slot index of the target ICC card
+     * @param callingPackage the name of the package making the call.
+     * @param cla Class of the APDU command.
+     * @param instruction Instruction of the APDU command.
+     * @param p1 P1 value of the APDU command.
+     * @param p2 P2 value of the APDU command.
+     * @param p3 P3 value of the APDU command. If p3 is negative a 4 byte APDU
+     *            is sent to the SIM.
+     * @param data Data to be sent with the APDU.
+     * @return The APDU response from the ICC card with the status appended at
+     *            the end.
+     */
+    String iccTransmitApduBasicChannelBySlot(int slotIndex, String callingPackage, int cla,
+            int instruction, int p1, int p2, int p3, String data);
+
+    /**
      * Transmit an APDU to the ICC card over the basic channel.
      *
      * Input parameters equivalent to TS 27.007 AT+CSIM command.
diff --git a/tests/ActivityManagerPerfTests/test-app/Android.bp b/tests/ActivityManagerPerfTests/test-app/Android.bp
new file mode 100644
index 0000000..ef9d587
--- /dev/null
+++ b/tests/ActivityManagerPerfTests/test-app/Android.bp
@@ -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.
+
+android_test {
+    name: "ActivityManagerPerfTestsTestApp",
+    srcs: ["src/**/*.java"],
+    static_libs: ["ActivityManagerPerfTestsUtils"],
+    min_sdk_version: "25",
+    sdk_version: "current",
+}
diff --git a/tests/ActivityManagerPerfTests/test-app/Android.mk b/tests/ActivityManagerPerfTests/test-app/Android.mk
deleted file mode 100644
index 33d15d2..0000000
--- a/tests/ActivityManagerPerfTests/test-app/Android.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-# 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.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := \
-    $(call all-java-files-under, src)
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    ActivityManagerPerfTestsUtils
-
-LOCAL_MIN_SDK_VERSION := 25
-
-LOCAL_PACKAGE_NAME := ActivityManagerPerfTestsTestApp
-LOCAL_SDK_VERSION := current
-
-include $(BUILD_PACKAGE)
diff --git a/tests/ActivityManagerPerfTests/tests/Android.bp b/tests/ActivityManagerPerfTests/tests/Android.bp
new file mode 100644
index 0000000..2ae2cc4
--- /dev/null
+++ b/tests/ActivityManagerPerfTests/tests/Android.bp
@@ -0,0 +1,27 @@
+// 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.
+
+android_test {
+    name: "ActivityManagerPerfTests",
+    srcs: ["src/**/*.java"],
+    static_libs: [
+        "androidx.test.rules",
+        "apct-perftests-utils",
+        "ActivityManagerPerfTestsUtils",
+    ],
+    platform_apis: true,
+    min_sdk_version: "25",
+    // For android.permission.FORCE_STOP_PACKAGES permission
+    certificate: "platform",
+}
diff --git a/tests/ActivityManagerPerfTests/tests/Android.mk b/tests/ActivityManagerPerfTests/tests/Android.mk
deleted file mode 100644
index e1f56b8..0000000
--- a/tests/ActivityManagerPerfTests/tests/Android.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-# 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.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := \
-    $(call all-java-files-under, src)
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    androidx.test.rules \
-    apct-perftests-utils \
-    ActivityManagerPerfTestsUtils
-
-LOCAL_PACKAGE_NAME := ActivityManagerPerfTests
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_MIN_SDK_VERSION := 25
-
-# For android.permission.FORCE_STOP_PACKAGES permission
-LOCAL_CERTIFICATE := platform
-
-include $(BUILD_PACKAGE)
diff --git a/tests/ActivityManagerPerfTests/utils/Android.bp b/tests/ActivityManagerPerfTests/utils/Android.bp
new file mode 100644
index 0000000..300b7ea
--- /dev/null
+++ b/tests/ActivityManagerPerfTests/utils/Android.bp
@@ -0,0 +1,27 @@
+// 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.
+
+java_test {
+    name: "ActivityManagerPerfTestsUtils",
+    sdk_version: "current",
+    srcs: [
+        "src/**/*.java",
+        "src/com/android/frameworks/perftests/am/util/ITimeReceiverCallback.aidl",
+    ],
+    static_libs: [
+        "androidx.test.rules",
+        "junit",
+        "ub-uiautomator",
+    ],
+}
diff --git a/tests/ActivityManagerPerfTests/utils/Android.mk b/tests/ActivityManagerPerfTests/utils/Android.mk
deleted file mode 100644
index 7a7471d..0000000
--- a/tests/ActivityManagerPerfTests/utils/Android.mk
+++ /dev/null
@@ -1,32 +0,0 @@
-# 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.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-LOCAL_SDK_VERSION := current
-
-LOCAL_SRC_FILES := \
-    $(call all-java-files-under, src) \
-    src/com/android/frameworks/perftests/am/util/ITimeReceiverCallback.aidl
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    androidx.test.rules \
-    junit \
-    ub-uiautomator
-
-LOCAL_MODULE := ActivityManagerPerfTestsUtils
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/tests/ActivityViewTest/Android.bp b/tests/ActivityViewTest/Android.bp
new file mode 100644
index 0000000..e7b8c8e
--- /dev/null
+++ b/tests/ActivityViewTest/Android.bp
@@ -0,0 +1,6 @@
+android_test {
+    name: "ActivityViewTest",
+    srcs: ["src/**/*.java"],
+    platform_apis: true,
+    certificate: "platform",
+}
diff --git a/tests/ActivityViewTest/Android.mk b/tests/ActivityViewTest/Android.mk
deleted file mode 100644
index 9c7ca7e..0000000
--- a/tests/ActivityViewTest/Android.mk
+++ /dev/null
@@ -1,12 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := ActivityViewTest
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_MODULE_TAGS := tests
-LOCAL_CERTIFICATE := platform
-
-include $(BUILD_PACKAGE)
diff --git a/tests/AppLaunch/Android.bp b/tests/AppLaunch/Android.bp
new file mode 100644
index 0000000..f90f26f
--- /dev/null
+++ b/tests/AppLaunch/Android.bp
@@ -0,0 +1,13 @@
+android_test {
+    name: "AppLaunch",
+    // Only compile source java files in this apk.
+    srcs: ["src/**/*.java"],
+    platform_apis: true,
+    certificate: "platform",
+    libs: [
+        "android.test.base",
+        "android.test.runner",
+    ],
+    static_libs: ["androidx.test.rules"],
+    test_suites: ["device-tests"],
+}
diff --git a/tests/AppLaunch/Android.mk b/tests/AppLaunch/Android.mk
deleted file mode 100644
index f50bca5..0000000
--- a/tests/AppLaunch/Android.mk
+++ /dev/null
@@ -1,22 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-# Only compile source java files in this apk.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := AppLaunch
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_CERTIFICATE := platform
-LOCAL_JAVA_LIBRARIES := android.test.base android.test.runner
-
-LOCAL_STATIC_JAVA_LIBRARIES := androidx.test.rules
-
-LOCAL_COMPATIBILITY_SUITE := device-tests
-
-include $(BUILD_PACKAGE)
-
-# Use the following include to make our test apk.
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/AppLaunchWear/Android.bp b/tests/AppLaunchWear/Android.bp
new file mode 100644
index 0000000..8d34b6e
--- /dev/null
+++ b/tests/AppLaunchWear/Android.bp
@@ -0,0 +1,13 @@
+android_test {
+    name: "AppLaunchWear",
+    // Only compile source java files in this apk.
+    srcs: ["src/**/*.java"],
+    platform_apis: true,
+    certificate: "platform",
+    libs: [
+        "android.test.base",
+        "android.test.runner",
+    ],
+    static_libs: ["androidx.test.rules"],
+    test_suites: ["device-tests"],
+}
diff --git a/tests/AppLaunchWear/Android.mk b/tests/AppLaunchWear/Android.mk
deleted file mode 100644
index 332b680..0000000
--- a/tests/AppLaunchWear/Android.mk
+++ /dev/null
@@ -1,22 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-# Only compile source java files in this apk.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := AppLaunchWear
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_CERTIFICATE := platform
-LOCAL_JAVA_LIBRARIES := android.test.base android.test.runner
-
-LOCAL_STATIC_JAVA_LIBRARIES := androidx.test.rules
-
-LOCAL_COMPATIBILITY_SUITE := device-tests
-
-include $(BUILD_PACKAGE)
-
-# Use the following include to make our test apk.
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/BackgroundDexOptServiceIntegrationTests/Android.bp b/tests/BackgroundDexOptServiceIntegrationTests/Android.bp
new file mode 100644
index 0000000..a85d129
--- /dev/null
+++ b/tests/BackgroundDexOptServiceIntegrationTests/Android.bp
@@ -0,0 +1,24 @@
+//
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+android_test {
+    name: "BackgroundDexOptServiceIntegrationTests",
+    srcs: ["src/**/*.java"],
+    static_libs: ["androidx.test.rules"],
+    platform_apis: true,
+    test_suites: ["device-tests"],
+    certificate: "platform",
+}
diff --git a/tests/BackgroundDexOptServiceIntegrationTests/Android.mk b/tests/BackgroundDexOptServiceIntegrationTests/Android.mk
deleted file mode 100644
index f47cf96..0000000
--- a/tests/BackgroundDexOptServiceIntegrationTests/Android.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# Copyright (C) 2017 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# We only want this apk build for tests.
-LOCAL_MODULE_TAGS := tests
-
-# Include all test java files.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    androidx.test.rules \
-
-LOCAL_PACKAGE_NAME := BackgroundDexOptServiceIntegrationTests
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_COMPATIBILITY_SUITE := device-tests
-
-LOCAL_CERTIFICATE := platform
-
-include $(BUILD_PACKAGE)
diff --git a/tests/Compatibility/Android.bp b/tests/Compatibility/Android.bp
new file mode 100644
index 0000000..4ca406e
--- /dev/null
+++ b/tests/Compatibility/Android.bp
@@ -0,0 +1,22 @@
+// Copyright (C) 2012 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.
+
+android_test {
+    name: "AppCompatibilityTest",
+    static_libs: ["androidx.test.rules"],
+    // Include all test java files.
+    srcs: ["src/**/*.java"],
+    platform_apis: true,
+    certificate: "platform",
+}
diff --git a/tests/Compatibility/Android.mk b/tests/Compatibility/Android.mk
deleted file mode 100644
index 643f9eb..0000000
--- a/tests/Compatibility/Android.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2012 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.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-# We only want this apk build for tests.
-LOCAL_MODULE_TAGS := tests
-LOCAL_STATIC_JAVA_LIBRARIES := androidx.test.rules
-# Include all test java files.
-LOCAL_SRC_FILES := \
-	$(call all-java-files-under, src)
-
-
-LOCAL_PACKAGE_NAME := AppCompatibilityTest
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_CERTIFICATE := platform
-include $(BUILD_PACKAGE)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/FlickerTests/Android.bp b/tests/FlickerTests/Android.bp
new file mode 100644
index 0000000..05f0a8e7
--- /dev/null
+++ b/tests/FlickerTests/Android.bp
@@ -0,0 +1,30 @@
+//
+// 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.
+//
+
+android_test {
+    name: "FlickerTests",
+    srcs: ["src/**/*.java"],
+    platform_apis: true,
+    certificate: "platform",
+    test_suites: ["device-tests"],
+    libs: ["android.test.runner"],
+    static_libs: [
+        "flickertestapplib",
+        "flickerlib",
+        "truth-prebuilt",
+        "app-helpers-core",
+    ],
+}
diff --git a/tests/FlickerTests/Android.mk b/tests/FlickerTests/Android.mk
deleted file mode 100644
index 3c70f8b..0000000
--- a/tests/FlickerTests/Android.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# 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.
-#
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_PACKAGE_NAME := FlickerTests
-LOCAL_MODULE_TAGS := tests optional
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_CERTIFICATE := platform
-LOCAL_COMPATIBILITY_SUITE := device-tests
-
-LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    flickertestapplib \
-    flickerlib \
-    truth-prebuilt \
-    app-helpers-core
-
-include $(BUILD_PACKAGE)
-include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file
diff --git a/tests/FlickerTests/lib/Android.bp b/tests/FlickerTests/lib/Android.bp
new file mode 100644
index 0000000..982fcba
--- /dev/null
+++ b/tests/FlickerTests/lib/Android.bp
@@ -0,0 +1,44 @@
+//
+// 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.
+//
+
+java_test {
+    name: "flickerlib",
+    platform_apis: true,
+    srcs: ["src/**/*.java"],
+    static_libs: [
+        "androidx.test.janktesthelper",
+        "cts-amwm-util",
+        "platformprotosnano",
+        "layersprotosnano",
+        "truth-prebuilt",
+        "sysui-helper",
+        "launcher-helper-lib",
+    ],
+}
+
+java_library {
+    name: "flickerautomationhelperlib",
+    sdk_version: "test_current",
+    srcs: [
+        "src/com/android/server/wm/flicker/AutomationUtils.java",
+        "src/com/android/server/wm/flicker/WindowUtils.java",
+    ],
+    static_libs: [
+        "sysui-helper",
+        "launcher-helper-lib",
+        "compatibility-device-util-axt",
+    ],
+}
diff --git a/tests/FlickerTests/lib/Android.mk b/tests/FlickerTests/lib/Android.mk
deleted file mode 100644
index e438822..0000000
--- a/tests/FlickerTests/lib/Android.mk
+++ /dev/null
@@ -1,48 +0,0 @@
-#
-# 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.
-#
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := flickerlib
-LOCAL_MODULE_TAGS := tests optional
-# sign this with platform cert, so this test is allowed to call private platform apis
-LOCAL_CERTIFICATE := platform
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_STATIC_JAVA_LIBRARIES := \
-   androidx.test.janktesthelper \
-   cts-amwm-util \
-   platformprotosnano \
-   layersprotosnano \
-   truth-prebuilt \
-   sysui-helper \
-   launcher-helper-lib \
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := flickerautomationhelperlib
-LOCAL_SDK_VERSION := current
-LOCAL_SRC_FILES := src/com/android/server/wm/flicker/AutomationUtils.java \
-    src/com/android/server/wm/flicker/WindowUtils.java
-LOCAL_STATIC_JAVA_LIBRARIES := sysui-helper \
-    launcher-helper-lib \
-    compatibility-device-util-axt
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/FlickerTests/lib/test/Android.bp b/tests/FlickerTests/lib/test/Android.bp
new file mode 100644
index 0000000..bfeb75b2
--- /dev/null
+++ b/tests/FlickerTests/lib/test/Android.bp
@@ -0,0 +1,33 @@
+//
+// 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.
+//
+
+android_test {
+    name: "FlickerLibTest",
+    // sign this with platform cert, so this test is allowed to call private platform apis
+    certificate: "platform",
+    platform_apis: true,
+    test_suites: ["tests"],
+    srcs: ["src/**/*.java"],
+    libs: ["android.test.runner"],
+    static_libs: [
+        "androidx.test.rules",
+        "platform-test-annotations",
+        "truth-prebuilt",
+        "platformprotosnano",
+        "layersprotosnano",
+        "flickerlib",
+    ],
+}
diff --git a/tests/FlickerTests/lib/test/Android.mk b/tests/FlickerTests/lib/test/Android.mk
deleted file mode 100644
index 5be89ba..0000000
--- a/tests/FlickerTests/lib/test/Android.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# 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.
-#
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := FlickerLibTest
-LOCAL_MODULE_TAGS := tests optional
-# sign this with platform cert, so this test is allowed to call private platform apis
-LOCAL_CERTIFICATE := platform
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_COMPATIBILITY_SUITE := tests
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    androidx.test.rules \
-    platform-test-annotations \
-    truth-prebuilt \
-    platformprotosnano \
-    layersprotosnano \
-    flickerlib
-
-include $(BUILD_PACKAGE)
-include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file
diff --git a/tests/FlickerTests/test-apps/Android.bp b/tests/FlickerTests/test-apps/Android.bp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/FlickerTests/test-apps/Android.bp
diff --git a/tests/FlickerTests/test-apps/Android.mk b/tests/FlickerTests/test-apps/Android.mk
deleted file mode 100644
index 9af9f444..0000000
--- a/tests/FlickerTests/test-apps/Android.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# 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.
-
-include $(call all-subdir-makefiles)
diff --git a/tests/FlickerTests/test-apps/flickerapp/Android.bp b/tests/FlickerTests/test-apps/flickerapp/Android.bp
new file mode 100644
index 0000000..0bea209
--- /dev/null
+++ b/tests/FlickerTests/test-apps/flickerapp/Android.bp
@@ -0,0 +1,26 @@
+// 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.
+
+android_test {
+    name: "FlickerTestApp",
+    srcs: ["**/*.java"],
+    sdk_version: "current",
+    test_suites: ["device-tests"],
+}
+
+java_test {
+    name: "flickertestapplib",
+    sdk_version: "current",
+    srcs: ["src/com/android/server/wm/flicker/testapp/ActivityOptions.java"],
+}
diff --git a/tests/FlickerTests/test-apps/flickerapp/Android.mk b/tests/FlickerTests/test-apps/flickerapp/Android.mk
deleted file mode 100644
index b916900..0000000
--- a/tests/FlickerTests/test-apps/flickerapp/Android.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-# 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.
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := FlickerTestApp
-LOCAL_MODULE_TAGS := tests optional
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_SDK_VERSION := current
-LOCAL_COMPATIBILITY_SUITE := device-tests
-include $(BUILD_PACKAGE)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := flickertestapplib
-LOCAL_MODULE_TAGS := tests optional
-LOCAL_SDK_VERSION := current
-LOCAL_SRC_FILES := src/com/android/server/wm/flicker/testapp/ActivityOptions.java
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file
diff --git a/tests/Internal/Android.bp b/tests/Internal/Android.bp
new file mode 100644
index 0000000..4cb9f8d
--- /dev/null
+++ b/tests/Internal/Android.bp
@@ -0,0 +1,18 @@
+android_test {
+    name: "InternalTests",
+    proto: {
+        type: "nano",
+    },
+    // Include some source files directly to be able to access package members
+    srcs: ["src/**/*.java"],
+    libs: ["android.test.runner"],
+    static_libs: [
+        "junit",
+        "androidx.test.rules",
+        "mockito-target-minus-junit4",
+    ],
+    java_resource_dirs: ["res"],
+    certificate: "platform",
+    platform_apis: true,
+    test_suites: ["device-tests"],
+}
diff --git a/tests/Internal/Android.mk b/tests/Internal/Android.mk
deleted file mode 100644
index 2e26ef1..0000000
--- a/tests/Internal/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_USE_AAPT2 := true
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := nano
-
-# Include some source files directly to be able to access package members
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := junit \
-    androidx.test.rules \
-    mockito-target-minus-junit4
-
-LOCAL_JAVA_RESOURCE_DIRS := res
-LOCAL_CERTIFICATE := platform
-
-LOCAL_PACKAGE_NAME := InternalTests
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_COMPATIBILITY_SUITE := device-tests
-
-include $(BUILD_PACKAGE)
diff --git a/tests/PackageWatchdog/Android.bp b/tests/PackageWatchdog/Android.bp
new file mode 100644
index 0000000..b079965
--- /dev/null
+++ b/tests/PackageWatchdog/Android.bp
@@ -0,0 +1,28 @@
+// Copyright (C) 2019 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.
+
+// PackageWatchdogTest
+android_test {
+    name: "PackageWatchdogTest",
+    srcs: ["src/**/*.java"],
+    static_libs: [
+        "junit",
+        "frameworks-base-testutils",
+        "androidx.test.rules",
+        "services.core",
+    ],
+    libs: ["android.test.runner"],
+    platform_apis: true,
+    test_suites: ["device-tests"],
+}
diff --git a/tests/PackageWatchdog/Android.mk b/tests/PackageWatchdog/Android.mk
deleted file mode 100644
index 1e4aacc..0000000
--- a/tests/PackageWatchdog/Android.mk
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (C) 2019 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-# PackageWatchdogTest
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_PACKAGE_NAME := PackageWatchdogTest
-LOCAL_MODULE_TAGS := tests
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    junit \
-    frameworks-base-testutils \
-    androidx.test.rules \
-    services.core
-
-LOCAL_JAVA_LIBRARIES := \
-    android.test.runner
-
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_COMPATIBILITY_SUITE := device-tests
-
-include $(BUILD_PACKAGE)
diff --git a/tests/RcsTests/Android.bp b/tests/RcsTests/Android.bp
new file mode 100644
index 0000000..8ee4960
--- /dev/null
+++ b/tests/RcsTests/Android.bp
@@ -0,0 +1,17 @@
+android_test {
+    name: "RcsTests",
+    // Only compile source java files in this apk.
+    srcs: ["src/**/*.java"],
+    platform_apis: true,
+    certificate: "platform",
+    libs: [
+        "android.test.runner",
+        "android.test.base",
+    ],
+    static_libs: [
+        "junit",
+        "androidx.test.rules",
+        "mockito-target-minus-junit4",
+        "truth-prebuilt",
+    ],
+}
diff --git a/tests/RcsTests/Android.mk b/tests/RcsTests/Android.mk
deleted file mode 100644
index a276584..0000000
--- a/tests/RcsTests/Android.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-# Only compile source java files in this apk.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := RcsTests
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_CERTIFICATE := platform
-LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
-LOCAL_STATIC_JAVA_LIBRARIES := junit androidx.test.rules mockito-target-minus-junit4 truth-prebuilt
-
-include $(BUILD_PACKAGE)
-
-# Use the following include to make our test apk.
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java
index a03fae0..9aed074 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java
@@ -340,16 +340,26 @@
     }
 
     /**
-     * Asserts that the given RollbackInfo has a single package with expected
-     * package name and versions.
+     * Asserts that the given RollbackInfo has the given packages with expected
+     * package names and all are rolled to and from the same given versions.
      */
-    static void assertRollbackInfoEquals(String packageName,
+    static void assertRollbackInfoEquals(String[] packageNames,
             long versionRolledBackFrom, long versionRolledBackTo,
             RollbackInfo info, VersionedPackage... causePackages) {
         assertNotNull(info);
-        assertEquals(1, info.getPackages().size());
-        assertPackageRollbackInfoEquals(packageName, versionRolledBackFrom, versionRolledBackTo,
-                info.getPackages().get(0));
+        assertEquals(packageNames.length, info.getPackages().size());
+        int foundPackages = 0;
+        for (String packageName : packageNames) {
+            for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) {
+                if (packageName.equals(pkgRollbackInfo.getPackageName())) {
+                    foundPackages++;
+                    assertPackageRollbackInfoEquals(packageName, versionRolledBackFrom,
+                            versionRolledBackTo, pkgRollbackInfo);
+                    break;
+                }
+            }
+        }
+        assertEquals(packageNames.length, foundPackages);
         assertEquals(causePackages.length, info.getCausePackages().size());
         for (int i = 0; i < causePackages.length; ++i) {
             assertEquals(causePackages[i].getPackageName(),
@@ -360,6 +370,18 @@
     }
 
     /**
+     * Asserts that the given RollbackInfo has a single package with expected
+     * package name and versions.
+     */
+    static void assertRollbackInfoEquals(String packageName,
+            long versionRolledBackFrom, long versionRolledBackTo,
+            RollbackInfo info, VersionedPackage... causePackages) {
+        String[] packageNames = {packageName};
+        assertRollbackInfoEquals(packageNames, versionRolledBackFrom, versionRolledBackTo, info,
+                causePackages);
+    }
+
+    /**
      * Waits for the given session to be marked as ready.
      * Throws an assertion if the session fails.
      */
@@ -453,4 +475,17 @@
             fail(result);
         }
     }
+
+    /**
+     * Return the rollback info for a recently committed rollback, by matching the rollback id, or
+     * return null if no matching rollback is found.
+     */
+    static RollbackInfo getRecentlyCommittedRollbackInfoById(int getRollbackId) {
+        for (RollbackInfo info : getRollbackManager().getRecentlyCommittedRollbacks()) {
+            if (info.getRollbackId() == getRollbackId) {
+                return info;
+            }
+        }
+        return null;
+    }
 }
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
index 59ae8d9..047451b 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
@@ -17,6 +17,7 @@
 package com.android.tests.rollback;
 
 import static com.android.tests.rollback.RollbackTestUtils.assertRollbackInfoEquals;
+import static com.android.tests.rollback.RollbackTestUtils.getRecentlyCommittedRollbackInfoById;
 import static com.android.tests.rollback.RollbackTestUtils.getUniqueRollbackInfoForPackage;
 
 import android.Manifest;
@@ -25,7 +26,6 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
 import org.junit.After;
@@ -47,6 +47,8 @@
 
     private static final String TAG = "RollbackTest";
     private static final String TEST_APP_A = "com.android.tests.rollback.testapp.A";
+    private static final String TEST_APP_A_V1 = "RollbackTestAppAv1.apk";
+    private static final String TEST_APP_A_V2 = "RollbackTestAppAv2.apk";
     private static final String TEST_APEX_PKG = "com.android.tests.rollback.testapex";
     private static final String TEST_APEX_V1 =
             "com.android.tests.rollback.testapex.RollbackTestApexV1.apex";
@@ -82,11 +84,11 @@
         RollbackTestUtils.uninstall(TEST_APP_A);
         assertEquals(-1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
 
-        RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
+        RollbackTestUtils.install(TEST_APP_A_V1, false);
         assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
         RollbackTestUtils.processUserData(TEST_APP_A);
 
-        RollbackTestUtils.installStaged(true, "RollbackTestAppAv2.apk");
+        RollbackTestUtils.installStaged(true, TEST_APP_A_V2);
 
         // At this point, the host test driver will reboot the device and run
         // testApkOnlyCommitRollback().
@@ -142,6 +144,86 @@
     }
 
     /**
+     * Test rollbacks of staged installs an apk and an apex.
+     * Prepare apex (and apk) phase.
+     */
+    @Test
+    public void testApkAndApexPrepare() throws Exception {
+        RollbackTestUtils.uninstall(TEST_APP_A);
+        assertEquals(-1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+
+        // Note: can't uninstall the apex. See note in #testApexOnlyPrepareApex().
+        RollbackTestUtils.installStaged(false, TEST_APP_A_V1, TEST_APEX_V1);
+
+        // At this point, the host test driver will reboot the device and run
+        // testApkAndApexEnableRollback().
+    }
+
+    /**
+     * Test rollbacks of staged installs an apk and an apex.
+     * Enable rollback phase.
+     */
+    @Test
+    public void testApkAndApexEnableRollback() throws Exception {
+        assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APEX_PKG));
+        assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+
+        RollbackTestUtils.installStaged(true, TEST_APP_A_V2, TEST_APEX_V2);
+
+        // At this point, the host test driver will reboot the device and run
+        // testApkAndApexCommitRollback().
+    }
+
+    /**
+     * Test rollbacks of staged installs an apk and an apex.
+     * Commit rollback phase.
+     */
+    @Test
+    public void testApkAndApexCommitRollback() throws Exception {
+        assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APEX_PKG));
+        assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+
+        RollbackTestUtils.processUserData(TEST_APP_A);
+
+        RollbackManager rm = RollbackTestUtils.getRollbackManager();
+
+        RollbackInfo rollback = getUniqueRollbackInfoForPackage(
+                rm.getAvailableRollbacks(), TEST_APP_A);
+        String[] packagesNames = {TEST_APEX_PKG, TEST_APP_A};
+        assertRollbackInfoEquals(packagesNames, 2, 1, rollback);
+        assertTrue(rollback.isStaged());
+
+        RollbackTestUtils.rollback(rollback.getRollbackId());
+
+        RollbackInfo committed = getRecentlyCommittedRollbackInfoById(rollback.getRollbackId());
+
+        assertRollbackInfoEquals(packagesNames, 2, 1, committed);
+        assertTrue(committed.isStaged());
+        assertNotEquals(-1, committed.getCommittedSessionId());
+
+        RollbackTestUtils.waitForSessionReady(committed.getCommittedSessionId());
+
+        // The apex and apk should not be rolled back until after reboot.
+        assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APEX_PKG));
+        assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+
+        // At this point, the host test driver will reboot the device and run
+        // testApkAndApexConfirmRollback().
+    }
+
+    /**
+     * Test rollbacks of staged installs an apk and an apex.
+     * Confirm rollback phase.
+     */
+    @Test
+    public void testApkAndApexConfirmRollback() throws Exception {
+        assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APEX_PKG));
+        assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+
+        RollbackTestUtils.processUserData(TEST_APP_A);
+    }
+
+    /**
      * Test rollbacks of staged installs involving only apex.
      * Prepare apex phase.
      */
@@ -171,7 +253,7 @@
     }
 
     /**
-     * Test rollbacks of staged installs involving only apks.
+     * Test rollbacks of staged installs involving only apex.
      * Commit rollback phase.
      */
     @Test
@@ -186,18 +268,8 @@
 
         RollbackTestUtils.rollback(rollback.getRollbackId());
 
-        // Note: We can't use getUniqueRollbackInfoForPackage for the apex,
-        // because we can't uninstall the apex (b/123667725), which means
-        // there's no way to clear info about rollbacks from previous tests
-        // run on the device. Look up the info by rollback id instead.
-        RollbackInfo committed = null;
-        for (RollbackInfo info : rm.getRecentlyCommittedRollbacks()) {
-            if (info.getRollbackId() == rollback.getRollbackId()) {
-                assertNull(committed);
-                committed = info;
-                break;
-            }
-        }
+        RollbackInfo committed = getRecentlyCommittedRollbackInfoById(rollback.getRollbackId());
+
         assertRollbackInfoEquals(TEST_APEX_PKG, 2, 1, committed);
         assertTrue(committed.isStaged());
         assertNotEquals(-1, committed.getCommittedSessionId());
@@ -212,7 +284,7 @@
     }
 
     /**
-     * Test rollbacks of staged installs involving only apks.
+     * Test rollbacks of staged installs involving only apex.
      * Confirm rollback phase.
      */
     @Test
diff --git a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
index 24a51dc..ac7f634 100644
--- a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
+++ b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
@@ -67,4 +67,18 @@
         getDevice().reboot();
         runPhase("testApexOnlyConfirmRollback");
     }
+
+    /**
+     * Tests staged rollbacks involving apk and apex.
+     */
+    @Test
+    public void testApkAndApex() throws Exception {
+        runPhase("testApkAndApexPrepare");
+        getDevice().reboot();
+        runPhase("testApkAndApexEnableRollback");
+        getDevice().reboot();
+        runPhase("testApkAndApexCommitRollback");
+        getDevice().reboot();
+        runPhase("testApkAndApexConfirmRollback");
+    }
 }
diff --git a/tests/ServiceCrashTest/Android.bp b/tests/ServiceCrashTest/Android.bp
new file mode 100644
index 0000000..40a377d
--- /dev/null
+++ b/tests/ServiceCrashTest/Android.bp
@@ -0,0 +1,12 @@
+android_test {
+    name: "ServiceCrashTest",
+    // Only compile source java files in this apk.
+    srcs: ["src/**/*.java"],
+    platform_apis: true,
+    certificate: "platform",
+    libs: ["android.test.base"],
+    static_libs: [
+        "compatibility-device-util-axt",
+        "androidx.test.rules",
+    ],
+}
diff --git a/tests/ServiceCrashTest/Android.mk b/tests/ServiceCrashTest/Android.mk
deleted file mode 100644
index 617ee7c..0000000
--- a/tests/ServiceCrashTest/Android.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-# Only compile source java files in this apk.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := ServiceCrashTest
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_CERTIFICATE := platform
-LOCAL_JAVA_LIBRARIES := android.test.base
-
-LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util-axt androidx.test.rules
-
-include $(BUILD_PACKAGE)
-
-# Use the following include to make our test apk.
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/SurfaceComposition/Android.bp b/tests/SurfaceComposition/Android.bp
new file mode 100644
index 0000000..53e4d52
--- /dev/null
+++ b/tests/SurfaceComposition/Android.bp
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 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.
+
+android_test {
+    name: "SurfaceComposition",
+    // Don't include this package in any target
+    // When built, explicitly put it in the data partition.
+    dex_preopt: {
+        enabled: false,
+    },
+    optimize: {
+        enabled: false,
+    },
+    srcs: ["src/**/*.java"],
+    static_libs: ["junit"],
+    libs: [
+        "android.test.runner.stubs",
+        "android.test.base.stubs",
+    ],
+    sdk_version: "current",
+}
diff --git a/tests/SurfaceComposition/Android.mk b/tests/SurfaceComposition/Android.mk
deleted file mode 100644
index f59458d..0000000
--- a/tests/SurfaceComposition/Android.mk
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (C) 2015 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-# Don't include this package in any target
-LOCAL_MODULE_TAGS := tests
-# When built, explicitly put it in the data partition.
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_DEX_PREOPT := false
-
-LOCAL_PROGUARD_ENABLED := disabled
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_STATIC_JAVA_LIBRARIES := junit
-
-LOCAL_JAVA_LIBRARIES := android.test.runner.stubs android.test.base.stubs
-
-LOCAL_PACKAGE_NAME := SurfaceComposition
-
-LOCAL_SDK_VERSION := current
-
-include $(BUILD_PACKAGE)
diff --git a/tests/SystemMemoryTest/Android.mk b/tests/SystemMemoryTest/Android.mk
deleted file mode 100644
index 09a1618..0000000
--- a/tests/SystemMemoryTest/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(call all-subdir-makefiles)
diff --git a/tests/SystemMemoryTest/device/Android.bp b/tests/SystemMemoryTest/device/Android.bp
new file mode 100644
index 0000000..2bf0fec
--- /dev/null
+++ b/tests/SystemMemoryTest/device/Android.bp
@@ -0,0 +1,20 @@
+// 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.
+
+android_test_helper_app {
+    name: "SystemMemoryTestDevice",
+    sdk_version: "current",
+    srcs: ["src/**/*.java"],
+    test_suites: ["general-tests"],
+}
diff --git a/tests/SystemMemoryTest/device/Android.mk b/tests/SystemMemoryTest/device/Android.mk
deleted file mode 100644
index 75408df..0000000
--- a/tests/SystemMemoryTest/device/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-# 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.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_PACKAGE_NAME := SystemMemoryTestDevice
-LOCAL_SDK_VERSION := current
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_COMPATIBILITY_SUITE := general-tests
-include $(BUILD_PACKAGE)
diff --git a/tests/SystemMemoryTest/host/Android.bp b/tests/SystemMemoryTest/host/Android.bp
new file mode 100644
index 0000000..3bb5489
--- /dev/null
+++ b/tests/SystemMemoryTest/host/Android.bp
@@ -0,0 +1,20 @@
+// 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.
+
+java_test_host {
+    name: "system-memory-test",
+    srcs: ["src/**/*.java"],
+    libs: ["tradefed"],
+    test_suites: ["general-tests"],
+}
diff --git a/tests/SystemMemoryTest/host/Android.mk b/tests/SystemMemoryTest/host/Android.mk
deleted file mode 100644
index a516e38..0000000
--- a/tests/SystemMemoryTest/host/Android.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-# 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.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_MODULE := system-memory-test
-LOCAL_MODULE_TAGS := optional
-LOCAL_JAVA_LIBRARIES := tradefed
-LOCAL_COMPATIBILITY_SUITE := general-tests
-include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tests/UsageReportingTest/Android.bp b/tests/UsageReportingTest/Android.bp
new file mode 100644
index 0000000..0bac5a2
--- /dev/null
+++ b/tests/UsageReportingTest/Android.bp
@@ -0,0 +1,8 @@
+android_test {
+    name: "UsageReportingTest",
+    // Only compile source java files in this apk.
+    srcs: ["src/**/*.java"],
+    static_libs: ["androidx.legacy_legacy-support-v4"],
+    certificate: "platform",
+    platform_apis: true,
+}
diff --git a/tests/UsageReportingTest/Android.mk b/tests/UsageReportingTest/Android.mk
deleted file mode 100644
index afb6e16b1..0000000
--- a/tests/UsageReportingTest/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-# Only compile source java files in this apk.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_USE_AAPT2 := true
-LOCAL_STATIC_ANDROID_LIBRARIES := androidx.legacy_legacy-support-v4
-
-LOCAL_CERTIFICATE := platform
-
-LOCAL_PACKAGE_NAME := UsageReportingTest
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-include $(BUILD_PACKAGE)
diff --git a/tests/UsageStatsPerfTests/Android.bp b/tests/UsageStatsPerfTests/Android.bp
new file mode 100644
index 0000000..3991fb8
--- /dev/null
+++ b/tests/UsageStatsPerfTests/Android.bp
@@ -0,0 +1,26 @@
+// 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.
+
+android_test {
+    name: "UsageStatsPerfTests",
+    srcs: ["src/**/*.java"],
+    static_libs: [
+        "androidx.test.rules",
+        "apct-perftests-utils",
+        "services.usage",
+    ],
+    platform_apis: true,
+    // For android.permission.FORCE_STOP_PACKAGES permission
+    certificate: "platform",
+}
diff --git a/tests/UsageStatsPerfTests/Android.mk b/tests/UsageStatsPerfTests/Android.mk
deleted file mode 100644
index 4304fb0..0000000
--- a/tests/UsageStatsPerfTests/Android.mk
+++ /dev/null
@@ -1,34 +0,0 @@
-# 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.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := \
-    $(call all-java-files-under, src)
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    androidx.test.rules \
-    apct-perftests-utils \
-    services.usage
-
-LOCAL_PACKAGE_NAME := UsageStatsPerfTests
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-# For android.permission.FORCE_STOP_PACKAGES permission
-LOCAL_CERTIFICATE := platform
-
-include $(BUILD_PACKAGE)
diff --git a/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageStatsActivity.java b/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageStatsActivity.java
index adcd11a..bb985d7 100644
--- a/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageStatsActivity.java
+++ b/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageStatsActivity.java
@@ -197,7 +197,7 @@
                     intent.setPackage(getPackageName());
                     intent.putExtra(EXTRA_KEY_TIMEOUT, true);
                     mUsageStatsManager.registerAppUsageLimitObserver(1, packages,
-                            Duration.ofSeconds(60), Duration.ofSeconds(60),
+                            Duration.ofSeconds(60), Duration.ofSeconds(0),
                             PendingIntent.getActivity(UsageStatsActivity.this, 1, intent, 0));
                 }
             }
diff --git a/tests/UsbHostExternalManagmentTest/AoapTestDevice/Android.bp b/tests/UsbHostExternalManagmentTest/AoapTestDevice/Android.bp
new file mode 100644
index 0000000..c7e9df0
--- /dev/null
+++ b/tests/UsbHostExternalManagmentTest/AoapTestDevice/Android.bp
@@ -0,0 +1,27 @@
+// Copyright (C) 2016 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.
+//
+//
+
+//#################################################
+
+android_test {
+    name: "AoapTestDeviceApp",
+    srcs: ["src/**/*.java"],
+    resource_dirs: ["res"],
+    platform_apis: true,
+    optimize: {
+        enabled: false,
+    },
+}
diff --git a/tests/UsbHostExternalManagmentTest/AoapTestDevice/Android.mk b/tests/UsbHostExternalManagmentTest/AoapTestDevice/Android.mk
deleted file mode 100644
index cd7aaed..0000000
--- a/tests/UsbHostExternalManagmentTest/AoapTestDevice/Android.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) 2016 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.
-#
-#
-
-LOCAL_PATH:= $(call my-dir)
-
-##################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-
-LOCAL_PACKAGE_NAME := AoapTestDeviceApp
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_MODULE_TAGS := tests
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_PROGUARD_ENABLED := disabled
-
-include $(BUILD_PACKAGE)
-
diff --git a/tests/UsbHostExternalManagmentTest/AoapTestHost/Android.bp b/tests/UsbHostExternalManagmentTest/AoapTestHost/Android.bp
new file mode 100644
index 0000000..6fa58cb
--- /dev/null
+++ b/tests/UsbHostExternalManagmentTest/AoapTestHost/Android.bp
@@ -0,0 +1,27 @@
+// Copyright (C) 2016 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.
+//
+//
+
+//#################################################
+
+android_test {
+    name: "AoapTestHostApp",
+    srcs: ["src/**/*.java"],
+    resource_dirs: ["res"],
+    platform_apis: true,
+    optimize: {
+        enabled: false,
+    },
+}
diff --git a/tests/UsbHostExternalManagmentTest/AoapTestHost/Android.mk b/tests/UsbHostExternalManagmentTest/AoapTestHost/Android.mk
deleted file mode 100644
index bd8a51b..0000000
--- a/tests/UsbHostExternalManagmentTest/AoapTestHost/Android.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) 2016 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.
-#
-#
-
-LOCAL_PATH:= $(call my-dir)
-
-##################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-
-LOCAL_PACKAGE_NAME := AoapTestHostApp
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_MODULE_TAGS := tests
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_PROGUARD_ENABLED := disabled
-
-include $(BUILD_PACKAGE)
-
diff --git a/tests/UsbHostExternalManagmentTest/UsbHostExternalManagmentTestApp/Android.bp b/tests/UsbHostExternalManagmentTest/UsbHostExternalManagmentTestApp/Android.bp
new file mode 100644
index 0000000..edd4205
--- /dev/null
+++ b/tests/UsbHostExternalManagmentTest/UsbHostExternalManagmentTestApp/Android.bp
@@ -0,0 +1,32 @@
+// Copyright (C) 2016 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.
+//
+//
+
+//#################################################
+
+// TODO: should this be android_helper_test_app?
+android_app {
+    name: "UsbHostExternalManagementTestApp",
+    srcs: ["src/**/*.java"],
+    resource_dirs: ["res"],
+    platform_apis: true,
+    privileged: true,
+    // TODO remove tests tag
+    //LOCAL_MODULE_TAGS := tests
+    //LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+    optimize: {
+        enabled: false,
+    },
+}
diff --git a/tests/UsbHostExternalManagmentTest/UsbHostExternalManagmentTestApp/Android.mk b/tests/UsbHostExternalManagmentTest/UsbHostExternalManagmentTestApp/Android.mk
deleted file mode 100644
index fed454e..0000000
--- a/tests/UsbHostExternalManagmentTest/UsbHostExternalManagmentTestApp/Android.mk
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (C) 2016 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.
-#
-#
-
-LOCAL_PATH:= $(call my-dir)
-
-##################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-
-LOCAL_PACKAGE_NAME := UsbHostExternalManagementTestApp
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_PRIVILEGED_MODULE := true
-# TODO remove tests tag
-#LOCAL_MODULE_TAGS := tests
-#LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_PROGUARD_ENABLED := disabled
-
-include $(BUILD_PACKAGE)
-
diff --git a/tests/UsbTests/Android.bp b/tests/UsbTests/Android.bp
new file mode 100644
index 0000000..1b2cf63
--- /dev/null
+++ b/tests/UsbTests/Android.bp
@@ -0,0 +1,34 @@
+//
+// 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.
+//
+
+android_test {
+    name: "UsbTests",
+    srcs: ["**/*.java"],
+    static_libs: [
+        "frameworks-base-testutils",
+        "androidx.test.rules",
+        "mockito-target-inline-minus-junit4",
+        "platform-test-annotations",
+        "services.core",
+        "services.net",
+        "services.usb",
+        "truth-prebuilt",
+    ],
+    jni_libs: ["libdexmakerjvmtiagent"],
+    certificate: "platform",
+    platform_apis: true,
+    test_suites: ["device-tests"],
+}
diff --git a/tests/UsbTests/Android.mk b/tests/UsbTests/Android.mk
deleted file mode 100644
index aef993b..0000000
--- a/tests/UsbTests/Android.mk
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# 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.
-#
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    frameworks-base-testutils \
-    androidx.test.rules \
-    mockito-target-inline-minus-junit4 \
-    platform-test-annotations \
-    services.core \
-    services.net \
-    services.usb \
-    truth-prebuilt \
-
-LOCAL_JNI_SHARED_LIBRARIES := \
-    libdexmakerjvmtiagent \
-
-LOCAL_CERTIFICATE := platform
-
-LOCAL_PACKAGE_NAME := UsbTests
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_COMPATIBILITY_SUITE := device-tests
-
-include $(BUILD_PACKAGE)
diff --git a/tests/WindowAnimationJank/Android.bp b/tests/WindowAnimationJank/Android.bp
new file mode 100644
index 0000000..50b2297
--- /dev/null
+++ b/tests/WindowAnimationJank/Android.bp
@@ -0,0 +1,25 @@
+// Copyright (C) 2015 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.
+
+android_test {
+    name: "WindowAnimationJank",
+    srcs: ["src/**/*.java"],
+    static_libs: [
+        "ub-uiautomator",
+        "androidx.test.janktesthelper",
+        "junit",
+    ],
+    libs: ["android.test.base.stubs"],
+    sdk_version: "current",
+}
diff --git a/tests/WindowAnimationJank/Android.mk b/tests/WindowAnimationJank/Android.mk
deleted file mode 100644
index 1c2d167..0000000
--- a/tests/WindowAnimationJank/Android.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) 2015 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := WindowAnimationJank
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    ub-uiautomator \
-    androidx.test.janktesthelper \
-    junit
-
-LOCAL_JAVA_LIBRARIES := android.test.base.stubs
-
-LOCAL_SDK_VERSION := current
-
-include $(BUILD_PACKAGE)
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 985d667..dc11bf3 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -190,6 +190,8 @@
 
 import java.net.Inet4Address;
 import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -206,6 +208,7 @@
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
 import java.util.function.Predicate;
 
 /**
@@ -2549,7 +2552,8 @@
         verifyActiveNetwork(TRANSPORT_CELLULAR);
     }
 
-    @Test
+    // TODO: deflake and re-enable
+    // @Test
     public void testPartialConnectivity() {
         // Register network callback.
         NetworkRequest request = new NetworkRequest.Builder()
@@ -4018,17 +4022,24 @@
         callback3.expectStopped();
     }
 
-    @Test
-    public void testNattSocketKeepalives_SingleThreadExecutor() throws Exception {
+    // Helper method to prepare the executor and run test
+    private void runTestWithSerialExecutors(Consumer<Executor> functor) {
         final ExecutorService executorSingleThread = Executors.newSingleThreadExecutor();
-        doTestNattSocketKeepalivesWithExecutor(executorSingleThread);
+        final Executor executorInline = (Runnable r) -> r.run();
+        functor.accept(executorSingleThread);
         executorSingleThread.shutdown();
+        functor.accept(executorInline);
     }
 
     @Test
-    public void testNattSocketKeepalives_InlineExecutor() throws Exception {
-        final Executor executorInline = (Runnable r) -> r.run();
-        doTestNattSocketKeepalivesWithExecutor(executorInline);
+    public void testNattSocketKeepalives() {
+        runTestWithSerialExecutors(executor -> {
+            try {
+                doTestNattSocketKeepalivesWithExecutor(executor);
+            } catch (Exception e) {
+                fail(e.getMessage());
+            }
+        });
     }
 
     private void doTestNattSocketKeepalivesWithExecutor(Executor executor) throws Exception {
@@ -4169,6 +4180,81 @@
 
         mWiFiNetworkAgent.disconnect();
         waitFor(mWiFiNetworkAgent.getDisconnectedCV());
+        mWiFiNetworkAgent = null;
+    }
+
+    @Test
+    public void testTcpSocketKeepalives() {
+        runTestWithSerialExecutors(executor -> {
+            try {
+                doTestTcpSocketKeepalivesWithExecutor(executor);
+            } catch (Exception e) {
+                fail(e.getMessage());
+            }
+        });
+    }
+
+    private void doTestTcpSocketKeepalivesWithExecutor(Executor executor) throws Exception {
+        final int srcPortV4 = 12345;
+        final int srcPortV6 = 23456;
+        final InetAddress myIPv4 = InetAddress.getByName("127.0.0.1");
+        final InetAddress myIPv6 = InetAddress.getByName("::1");
+
+        final int validKaInterval = 15;
+        final int invalidKaInterval = 9;
+
+        final LinkProperties lp = new LinkProperties();
+        lp.setInterfaceName("wlan12");
+        lp.addLinkAddress(new LinkAddress(myIPv6, 64));
+        lp.addLinkAddress(new LinkAddress(myIPv4, 25));
+        lp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234")));
+        lp.addRoute(new RouteInfo(InetAddress.getByName("127.0.0.254")));
+
+        final Network notMyNet = new Network(61234);
+        final Network myNet = connectKeepaliveNetwork(lp);
+
+        final Socket testSocketV4 = new Socket();
+        final Socket testSocketV6 = new Socket();
+
+        TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback();
+        SocketKeepalive ka;
+
+        // Attempt to start Tcp keepalives with invalid parameters and check for errors.
+        // Invalid network.
+        ka = mCm.createSocketKeepalive(notMyNet, testSocketV4, executor, callback);
+        ka.start(validKaInterval);
+        callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK);
+
+        // Invalid Socket (socket is not bound with IPv4 address).
+        ka = mCm.createSocketKeepalive(myNet, testSocketV4, executor, callback);
+        ka.start(validKaInterval);
+        callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET);
+
+        // Invalid Socket (socket is not bound with IPv6 address).
+        ka = mCm.createSocketKeepalive(myNet, testSocketV6, executor, callback);
+        ka.start(validKaInterval);
+        callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET);
+
+        // Bind the socket address
+        testSocketV4.bind(new InetSocketAddress(myIPv4, srcPortV4));
+        testSocketV6.bind(new InetSocketAddress(myIPv6, srcPortV6));
+
+        // Invalid Socket (socket is bound with IPv4 address).
+        ka = mCm.createSocketKeepalive(myNet, testSocketV4, executor, callback);
+        ka.start(validKaInterval);
+        callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET);
+
+        // Invalid Socket (socket is bound with IPv6 address).
+        ka = mCm.createSocketKeepalive(myNet, testSocketV6, executor, callback);
+        ka.start(validKaInterval);
+        callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET);
+
+        testSocketV4.close();
+        testSocketV6.close();
+
+        mWiFiNetworkAgent.disconnect();
+        waitFor(mWiFiNetworkAgent.getDisconnectedCV());
+        mWiFiNetworkAgent = null;
     }
 
     @Test
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 315f83a..52e03ce 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -65,6 +65,7 @@
 import java.net.InetAddress;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -1000,8 +1001,9 @@
     /**
      * In this Wi-Fi lock mode, Wi-Fi will not go to power save.
      * This results in operating with low packet latency.
-     * The lock is active  even when the device screen is off or
-     * the acquiring application is running in the background.
+     * The lock is only active when the device is connected to an access point.
+     * The lock is active even when the device screen is off or the acquiring application is
+     * running in the background.
      * This mode will consume more power and hence should be used only
      * when there is a need for this tradeoff.
      * <p>
@@ -1019,6 +1021,7 @@
      * In this Wi-Fi lock mode, Wi-Fi will operate with a priority to achieve low latency.
      * {@link #WIFI_MODE_FULL_LOW_LATENCY} lock has the following limitations:
      * <ol>
+     * <li>The lock is only active when the device is connected to an access point.</li>
      * <li>The lock is only active when the screen is on.</li>
      * <li>The lock is only active when the acquiring app is running in the foreground.</li>
      * </ol>
@@ -1272,7 +1275,10 @@
     })
     @NonNull
     public Map<OsuProvider, List<ScanResult>> getMatchingOsuProviders(
-            List<ScanResult> scanResults) {
+            @Nullable List<ScanResult> scanResults) {
+        if (scanResults == null) {
+            return new HashMap<>();
+        }
         try {
             return mService.getMatchingOsuProviders(scanResults);
         } catch (RemoteException e) {