Snap for 5386257 from e7f50e16f28e528f2a9e09df63dde24c39957274 to qt-release

Change-Id: Ib8c45d600455ea8bad35d9fc2e5908ddb7d8416e
diff --git a/Android.bp b/Android.bp
index f4e8b63..4219d36 100644
--- a/Android.bp
+++ b/Android.bp
@@ -903,14 +903,8 @@
         "core/java/android/net/INetworkStackConnector.aidl",
         "core/java/android/net/INetworkStackStatusCallback.aidl",
         "core/java/android/net/InitialConfigurationParcelable.aidl",
-        "core/java/android/net/IpPrefixParcelable.aidl",
-        "core/java/android/net/LinkAddressParcelable.aidl",
-        "core/java/android/net/LinkPropertiesParcelable.aidl",
-        "core/java/android/net/NetworkParcelable.aidl",
         "core/java/android/net/PrivateDnsConfigParcel.aidl",
         "core/java/android/net/ProvisioningConfigurationParcelable.aidl",
-        "core/java/android/net/ProxyInfoParcelable.aidl",
-        "core/java/android/net/RouteInfoParcelable.aidl",
         "core/java/android/net/StaticIpConfigurationParcelable.aidl",
         "core/java/android/net/TcpKeepalivePacketDataParcelable.aidl",
         "core/java/android/net/dhcp/DhcpServingParamsParcel.aidl",
@@ -919,6 +913,14 @@
         "core/java/android/net/ip/IIpClient.aidl",
         "core/java/android/net/ip/IIpClientCallbacks.aidl",
     ],
+    backend: {
+        ndk: {
+            enabled: false,
+        },
+        cpp: {
+            enabled: false,
+        },
+    },
     api_dir: "aidl/networkstack",
 }
 
@@ -931,6 +933,11 @@
         "core/java/android/net/ipmemorystore/**/*.aidl",
     ],
     api_dir: "aidl/networkstack",
+    backend: {
+        java: {
+            sdk_version: "28",
+        },
+    },
 }
 
 filegroup {
@@ -1132,6 +1139,7 @@
         "core/java/android/annotation/Nullable.java",
         "core/java/android/annotation/SystemApi.java",
         "core/java/android/annotation/TestApi.java",
+        "core/java/android/annotation/UnsupportedAppUsage.java",
         "core/java/android/os/HwBinder.java",
         "core/java/android/os/HwBlob.java",
         "core/java/android/os/HwParcel.java",
diff --git a/api/current.txt b/api/current.txt
index d1b77f2..9190a13 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6623,7 +6623,7 @@
     method @Nullable public String[] getAccountTypesWithManagementDisabled();
     method @Nullable public java.util.List<android.content.ComponentName> getActiveAdmins();
     method @NonNull public java.util.Set<java.lang.String> getAffiliationIds(@NonNull android.content.ComponentName);
-    method @Nullable public java.util.List<java.lang.String> getAlwaysOnVpnLockdownWhitelist(@NonNull android.content.ComponentName);
+    method @Nullable public java.util.Set<java.lang.String> getAlwaysOnVpnLockdownWhitelist(@NonNull android.content.ComponentName);
     method @Nullable public String getAlwaysOnVpnPackage(@NonNull android.content.ComponentName);
     method @WorkerThread @NonNull public android.os.Bundle getApplicationRestrictions(@Nullable android.content.ComponentName, String);
     method @Deprecated @Nullable public String getApplicationRestrictionsManagingPackage(@NonNull android.content.ComponentName);
@@ -6736,7 +6736,7 @@
     method public void setAccountManagementDisabled(@NonNull android.content.ComponentName, String, boolean);
     method public void setAffiliationIds(@NonNull android.content.ComponentName, @NonNull java.util.Set<java.lang.String>);
     method public void setAlwaysOnVpnPackage(@NonNull android.content.ComponentName, @Nullable String, boolean) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public void setAlwaysOnVpnPackage(@NonNull android.content.ComponentName, @Nullable String, boolean, @Nullable java.util.List<java.lang.String>) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public void setAlwaysOnVpnPackage(@NonNull android.content.ComponentName, @Nullable String, boolean, @Nullable java.util.Set<java.lang.String>) throws android.content.pm.PackageManager.NameNotFoundException;
     method public boolean setApplicationHidden(@NonNull android.content.ComponentName, String, boolean);
     method @WorkerThread public void setApplicationRestrictions(@Nullable android.content.ComponentName, String, android.os.Bundle);
     method @Deprecated public void setApplicationRestrictionsManagingPackage(@NonNull android.content.ComponentName, @Nullable String) throws android.content.pm.PackageManager.NameNotFoundException;
@@ -15953,7 +15953,6 @@
   public class MeasuredText {
     method public void getBounds(@IntRange(from=0) int, @IntRange(from=0) int, @NonNull android.graphics.Rect);
     method @FloatRange(from=0.0f) @Px public float getCharWidthAt(@IntRange(from=0) int);
-    method @NonNull public char[] getChars();
     method @FloatRange(from=0.0) @Px public float getWidth(@IntRange(from=0) int, @IntRange(from=0) int);
   }
 
@@ -17367,15 +17366,16 @@
     method @Nullable public java.util.Set<android.util.Size> getInputSizes(int);
     method @NonNull public java.util.Set<java.lang.Integer> getOutputFormats();
     method @IntRange(from=0) public long getOutputMinFrameDuration(int, @NonNull android.util.Size);
-    method public <T> long getOutputMinFrameDuration(@NonNull Class<T>, @NonNull android.util.Size);
+    method @IntRange(from=0) public <T> long getOutputMinFrameDuration(@NonNull Class<T>, @NonNull android.util.Size);
     method @Nullable public java.util.Set<android.util.Size> getOutputSizes(int);
-    method public <T> java.util.Set<android.util.Size> getOutputSizes(@NonNull Class<T>);
+    method @Nullable public <T> java.util.Set<android.util.Size> getOutputSizes(@NonNull Class<T>);
     method @IntRange(from=0) public long getOutputStallDuration(int, @NonNull android.util.Size);
-    method public <T> long getOutputStallDuration(@NonNull Class<T>, @NonNull android.util.Size);
+    method @IntRange(from=0) public <T> long getOutputStallDuration(@NonNull Class<T>, @NonNull android.util.Size);
     method public int getRecommendedUseCase();
     method @Nullable public java.util.Set<java.lang.Integer> getValidOutputFormatsForInput(int);
     method public boolean isOutputSupportedFor(int);
     method public boolean isOutputSupportedFor(@NonNull android.view.Surface);
+    field public static final int USECASE_LOW_LATENCY_SNAPSHOT = 6; // 0x6
     field public static final int USECASE_PREVIEW = 0; // 0x0
     field public static final int USECASE_RAW = 5; // 0x5
     field public static final int USECASE_RECORD = 1; // 0x1
@@ -22966,6 +22966,7 @@
     method public void unregisterGnssMeasurementsCallback(@NonNull android.location.GnssMeasurementsEvent.Callback);
     method public void unregisterGnssNavigationMessageCallback(@NonNull android.location.GnssNavigationMessage.Callback);
     method public void unregisterGnssStatusCallback(@NonNull android.location.GnssStatus.Callback);
+    field public static final String EXTRA_PROVIDER_NAME = "android.location.extra.PROVIDER_NAME";
     field public static final String GPS_PROVIDER = "gps";
     field public static final String KEY_LOCATION_CHANGED = "location";
     field public static final String KEY_PROVIDER_ENABLED = "providerEnabled";
@@ -39006,10 +39007,12 @@
     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";
@@ -43189,6 +43192,7 @@
     method public void unregisterCallback(android.telecom.Call.Callback);
     field @Deprecated public static final String AVAILABLE_PHONE_ACCOUNTS = "selectPhoneAccountAccounts";
     field public static final String EXTRA_LAST_EMERGENCY_CALLBACK_TIME_MILLIS = "android.telecom.extra.LAST_EMERGENCY_CALLBACK_TIME_MILLIS";
+    field public static final String EXTRA_SILENT_RINGING_REQUESTED = "android.telecom.extra.SILENT_RINGING_REQUESTED";
     field public static final String EXTRA_SUGGESTED_PHONE_ACCOUNTS = "android.telecom.extra.SUGGESTED_PHONE_ACCOUNTS";
     field public static final int STATE_ACTIVE = 4; // 0x4
     field public static final int STATE_CONNECTING = 9; // 0x9
@@ -43376,6 +43380,7 @@
   public static class CallScreeningService.CallResponse {
     method public boolean getDisallowCall();
     method public boolean getRejectCall();
+    method public boolean getSilenceCall();
     method public boolean getSkipCallLog();
     method public boolean getSkipNotification();
   }
@@ -43385,6 +43390,7 @@
     method public android.telecom.CallScreeningService.CallResponse build();
     method public android.telecom.CallScreeningService.CallResponse.Builder setDisallowCall(boolean);
     method public android.telecom.CallScreeningService.CallResponse.Builder setRejectCall(boolean);
+    method @NonNull public android.telecom.CallScreeningService.CallResponse.Builder setSilenceCall(boolean);
     method public android.telecom.CallScreeningService.CallResponse.Builder setSkipCallLog(boolean);
     method public android.telecom.CallScreeningService.CallResponse.Builder setSkipNotification(boolean);
   }
@@ -45242,7 +45248,7 @@
     field public static final String EXTRA_CARRIER_ID = "android.telephony.extra.CARRIER_ID";
     field public static final String EXTRA_CARRIER_NAME = "android.telephony.extra.CARRIER_NAME";
     field public static final String EXTRA_HIDE_PUBLIC_SETTINGS = "android.telephony.extra.HIDE_PUBLIC_SETTINGS";
-    field public static final String EXTRA_INCOMING_NUMBER = "incoming_number";
+    field @Deprecated public static final String EXTRA_INCOMING_NUMBER = "incoming_number";
     field public static final String EXTRA_IS_REFRESH = "android.telephony.extra.IS_REFRESH";
     field public static final String EXTRA_LAUNCH_VOICEMAIL_SETTINGS_INTENT = "android.telephony.extra.LAUNCH_VOICEMAIL_SETTINGS_INTENT";
     field public static final String EXTRA_NETWORK_COUNTRY = "android.telephony.extra.NETWORK_COUNTRY";
diff --git a/api/removed.txt b/api/removed.txt
index 5108dd0..fa07094 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -314,17 +314,11 @@
 package android.net {
 
   public class ConnectivityManager {
-    method @Deprecated public void getLatestTetheringEntitlementValue(int, boolean, @NonNull android.net.ConnectivityManager.TetheringEntitlementValueListener, @Nullable android.os.Handler);
     method @Deprecated public boolean requestRouteToHost(int, int);
     method @Deprecated public int startUsingNetworkFeature(int, String);
     method @Deprecated public int stopUsingNetworkFeature(int, String);
   }
 
-  @Deprecated public abstract static class ConnectivityManager.TetheringEntitlementValueListener {
-    ctor public ConnectivityManager.TetheringEntitlementValueListener();
-    method public void onEntitlementResult(int);
-  }
-
   @Deprecated public class NetworkBadging {
     method @NonNull public static android.graphics.drawable.Drawable getWifiIcon(@IntRange(from=0, to=4) int, int, @Nullable android.content.res.Resources.Theme);
     field public static final int BADGING_4K = 30; // 0x1e
@@ -553,11 +547,6 @@
     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 61a7f58..2724133 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -924,8 +924,10 @@
     method public int restoreAll(long, android.app.backup.RestoreObserver);
     method public int restorePackage(String, android.app.backup.RestoreObserver, android.app.backup.BackupManagerMonitor);
     method public int restorePackage(String, android.app.backup.RestoreObserver);
-    method public int restoreSome(long, android.app.backup.RestoreObserver, android.app.backup.BackupManagerMonitor, String[]);
-    method public int restoreSome(long, android.app.backup.RestoreObserver, String[]);
+    method public int restorePackages(long, @Nullable android.app.backup.RestoreObserver, @NonNull java.util.Set<java.lang.String>, @Nullable android.app.backup.BackupManagerMonitor);
+    method public int restorePackages(long, @Nullable android.app.backup.RestoreObserver, @NonNull java.util.Set<java.lang.String>);
+    method @Deprecated public int restoreSome(long, android.app.backup.RestoreObserver, android.app.backup.BackupManagerMonitor, String[]);
+    method @Deprecated public int restoreSome(long, android.app.backup.RestoreObserver, String[]);
   }
 
   public class RestoreSet implements android.os.Parcelable {
@@ -5603,7 +5605,7 @@
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public android.os.PersistableBundle getSeedAccountOptions();
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public String getSeedAccountType();
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public long[] getSerialNumbersOfUsers(boolean);
-    method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public android.graphics.Bitmap getUserIcon();
+    method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED}) public android.graphics.Bitmap getUserIcon();
     method @Deprecated @android.os.UserManager.UserRestrictionSource @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public int getUserRestrictionSource(String, android.os.UserHandle);
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public java.util.List<android.os.UserManager.EnforcingUser> getUserRestrictionSources(String, android.os.UserHandle);
     method @RequiresPermission(allOf={android.Manifest.permission.READ_PHONE_STATE, android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional=true) public int getUserSwitchability();
@@ -7679,8 +7681,8 @@
     field public static final String MBMS_STREAMING_SERVICE_ACTION = "android.telephony.action.EmbmsStreaming";
   }
 
-  public class NetworkRegistrationState implements android.os.Parcelable {
-    ctor public NetworkRegistrationState(int, int, int, int, int, boolean, @NonNull int[], @Nullable android.telephony.CellIdentity);
+  public class NetworkRegistrationInfo implements android.os.Parcelable {
+    ctor public NetworkRegistrationInfo(int, int, int, int, int, boolean, @NonNull int[], @Nullable android.telephony.CellIdentity);
     method public int describeContents();
     method public int getAccessNetworkTechnology();
     method @NonNull public int[] getAvailableServices();
@@ -7694,7 +7696,7 @@
     method public boolean isEmergencyEnabled();
     method public boolean isRoaming();
     method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.NetworkRegistrationState> CREATOR;
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.NetworkRegistrationInfo> CREATOR;
     field public static final int DOMAIN_CS = 1; // 0x1
     field public static final int DOMAIN_PS = 2; // 0x2
     field public static final int REG_STATE_DENIED = 3; // 0x3
@@ -7710,19 +7712,19 @@
     field public static final int SERVICE_TYPE_VOICE = 1; // 0x1
   }
 
-  public static class NetworkRegistrationState.Builder {
-    ctor public NetworkRegistrationState.Builder();
-    method @NonNull public android.telephony.NetworkRegistrationState build();
-    method @NonNull public android.telephony.NetworkRegistrationState.Builder setAccessNetworkTechnology(int);
-    method @NonNull public android.telephony.NetworkRegistrationState.Builder setAvailableServices(@NonNull int[]);
-    method @NonNull public android.telephony.NetworkRegistrationState.Builder setCellIdentity(@Nullable android.telephony.CellIdentity);
-    method @NonNull public android.telephony.NetworkRegistrationState.Builder setDomain(int);
-    method @NonNull public android.telephony.NetworkRegistrationState.Builder setEmergencyOnly(boolean);
-    method @NonNull public android.telephony.NetworkRegistrationState.Builder setNrStatus(int);
-    method @NonNull public android.telephony.NetworkRegistrationState.Builder setRegState(int);
-    method @NonNull public android.telephony.NetworkRegistrationState.Builder setRejectCause(int);
-    method @NonNull public android.telephony.NetworkRegistrationState.Builder setRoamingType(int);
-    method @NonNull public android.telephony.NetworkRegistrationState.Builder setTransportType(int);
+  public static class NetworkRegistrationInfo.Builder {
+    ctor public NetworkRegistrationInfo.Builder();
+    method @NonNull public android.telephony.NetworkRegistrationInfo build();
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setAccessNetworkTechnology(int);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setAvailableServices(@NonNull int[]);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setCellIdentity(@Nullable android.telephony.CellIdentity);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setDomain(int);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setEmergencyOnly(boolean);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setNrStatus(int);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegState(int);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRejectCause(int);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRoamingType(int);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setTransportType(int);
   }
 
   public abstract class NetworkService extends android.app.Service {
@@ -7735,13 +7737,13 @@
   public abstract class NetworkService.NetworkServiceProvider implements java.lang.AutoCloseable {
     ctor public NetworkService.NetworkServiceProvider(int);
     method public abstract void close();
-    method public void getNetworkRegistrationState(int, @NonNull android.telephony.NetworkServiceCallback);
+    method public void getNetworkRegistrationInfo(int, @NonNull android.telephony.NetworkServiceCallback);
     method public final int getSlotIndex();
-    method public final void notifyNetworkRegistrationStateChanged();
+    method public final void notifyNetworkRegistrationInfoChanged();
   }
 
   public class NetworkServiceCallback {
-    method public void onGetNetworkRegistrationStateComplete(int, @Nullable android.telephony.NetworkRegistrationState);
+    method public void onGetNetworkRegistrationInfoComplete(int, @Nullable android.telephony.NetworkRegistrationInfo);
     field public static final int RESULT_ERROR_BUSY = 3; // 0x3
     field public static final int RESULT_ERROR_FAILED = 5; // 0x5
     field public static final int RESULT_ERROR_ILLEGAL_STATE = 4; // 0x4
@@ -7916,12 +7918,10 @@
   }
 
   public class ServiceState implements android.os.Parcelable {
-    method @Nullable public android.telephony.NetworkRegistrationState getNetworkRegistrationState(int, int);
-    method @NonNull public java.util.List<android.telephony.NetworkRegistrationState> getNetworkRegistrationStates();
-    method @Deprecated @NonNull public java.util.List<android.telephony.NetworkRegistrationState> getNetworkRegistrationStates(int);
-    method @Deprecated @Nullable public android.telephony.NetworkRegistrationState getNetworkRegistrationStates(int, int);
-    method @NonNull public java.util.List<android.telephony.NetworkRegistrationState> getNetworkRegistrationStatesForDomain(int);
-    method @NonNull public java.util.List<android.telephony.NetworkRegistrationState> getNetworkRegistrationStatesForTransportType(int);
+    method @Nullable public android.telephony.NetworkRegistrationInfo getNetworkRegistrationInfo(int, int);
+    method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoList();
+    method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForDomain(int);
+    method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForTransportType(int);
     field public static final int ROAMING_TYPE_DOMESTIC = 2; // 0x2
     field public static final int ROAMING_TYPE_INTERNATIONAL = 3; // 0x3
     field public static final int ROAMING_TYPE_NOT_ROAMING = 0; // 0x0
diff --git a/api/test-current.txt b/api/test-current.txt
index 4ccfa1c..5cb918f 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -2548,7 +2548,8 @@
     method public int getCarrierIdListVersion();
     method public android.util.Pair<java.lang.Integer,java.lang.Integer> getRadioHalVersion();
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void refreshUiccProfile();
-    method public void setCarrierTestOverride(String, String, String, String, String, String, String);
+    method @Deprecated public void setCarrierTestOverride(String, String, String, String, String, String, String);
+    method public void setCarrierTestOverride(String, String, String, String, String, String, String, String, String);
     field public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2; // 0xfffffffe
     field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1
     field public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; // 0x0
diff --git a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
index 062ba65..98ab666 100644
--- a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
+++ b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
@@ -803,8 +803,8 @@
                             } else {
                                 String[] names = new String[filter.size()];
                                 filter.toArray(names);
-                                didRestore = (mRestore.restoreSome(token, observer,
-                                        null, names) == 0);
+                                didRestore = (mRestore.restorePackages(token, observer, names,
+                                        null) == 0);
                             }
                             break;
                         }
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 3246d19..7a753aec 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -45,6 +45,7 @@
 import "frameworks/base/core/proto/android/stats/devicepolicy/device_policy.proto";
 import "frameworks/base/core/proto/android/stats/devicepolicy/device_policy_enums.proto";
 import "frameworks/base/core/proto/android/stats/launcher/launcher.proto";
+import "frameworks/base/core/proto/android/stats/storage/storage_enums.proto";
 import "frameworks/base/core/proto/android/stats/style/style_enums.proto";
 import "frameworks/base/core/proto/android/telecomm/enums.proto";
 import "frameworks/base/core/proto/android/telephony/enums.proto";
@@ -250,6 +251,7 @@
         HiddenApiUsed hidden_api_used = 178 [(allow_from_any_uid) = true];
         StyleUIChanged style_ui_changed = 179;
         PrivacyIndicatorsInteracted privacy_indicators_interacted = 180;
+        AppInstallOnExternalStorageReported app_install_on_external_storage_reported = 181;
     }
 
     // Pulled events will start at field 10000.
@@ -2558,6 +2560,18 @@
 }
 
 /**
+ * Logs whenever an app is installed on external storage.
+ * Logged from:
+        frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
+ */
+message AppInstallOnExternalStorageReported {
+    // The type of external storage.
+    optional android.stats.storage.ExternalStorageType storage_type = 1;
+    // The name of the package that is installed on the sd card.
+    optional string package_name = 2;
+}
+
+/**
  * Logs when an app crashes.
  * Logged from:
  *      frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -4913,7 +4927,7 @@
   // since boot, not including sleep (see SystemClock.uptimeMillis()).
   optional int64 last_compact_timestamp_ms_since_boot = 14;
 
-  // The oom_score_adj at the time of compaction.
+  // The "setAdj" (i.e. previous) oom_score_adj at the time of compaction.
   optional int32 oom_score_adj = 15;
 
   // The process state at the time of compaction.
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
index 254d7d5..c023e6f 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp
@@ -319,10 +319,11 @@
         return;
     }
 
-    flushCurrentBucketLocked(eventTimeNs, eventTimeNs);
     // Setup the bucket start time and number.
     int64_t numBucketsForward = 1 + (eventTimeNs - currentBucketEndTimeNs) / mBucketSizeNs;
-    mCurrentBucketStartTimeNs = currentBucketEndTimeNs + (numBucketsForward - 1) * mBucketSizeNs;
+    int64_t nextBucketNs = currentBucketEndTimeNs + (numBucketsForward - 1) * mBucketSizeNs;
+    flushCurrentBucketLocked(eventTimeNs, nextBucketNs);
+
     mCurrentBucketNum += numBucketsForward;
     VLOG("metric %lld: new bucket start time: %lld", (long long)mMetricId,
          (long long)mCurrentBucketStartTimeNs);
@@ -375,6 +376,7 @@
     // Only resets the counters, but doesn't setup the times nor numbers.
     // (Do not clear since the old one is still referenced in mAnomalyTrackers).
     mCurrentSlicedCounter = std::make_shared<DimToValMap>();
+    mCurrentBucketStartTimeNs = nextBucketStartTimeNs;
 }
 
 // Rough estimate of CountMetricProducer buffer stored. This number will be
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index 7dc4e2d..615c7f2 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -559,26 +559,10 @@
         return;
     }
     VLOG("flushing...........");
-    for (auto whatIt = mCurrentSlicedDurationTrackerMap.begin();
-            whatIt != mCurrentSlicedDurationTrackerMap.end();) {
-        for (auto it = whatIt->second.begin(); it != whatIt->second.end();) {
-            if (it->second->flushIfNeeded(eventTimeNs, &mPastBuckets)) {
-                VLOG("erase bucket for key %s %s",
-                     whatIt->first.toString().c_str(), it->first.toString().c_str());
-                it = whatIt->second.erase(it);
-            } else {
-                ++it;
-            }
-        }
-        if (whatIt->second.empty()) {
-            whatIt = mCurrentSlicedDurationTrackerMap.erase(whatIt);
-        } else {
-            whatIt++;
-        }
-    }
-
     int numBucketsForward = 1 + (eventTimeNs - currentBucketEndTimeNs) / mBucketSizeNs;
-    mCurrentBucketStartTimeNs = currentBucketEndTimeNs + (numBucketsForward - 1) * mBucketSizeNs;
+    int64_t nextBucketNs = currentBucketEndTimeNs + (numBucketsForward - 1) * mBucketSizeNs;
+    flushCurrentBucketLocked(eventTimeNs, nextBucketNs);
+
     mCurrentBucketNum += numBucketsForward;
 }
 
@@ -602,6 +586,7 @@
         }
     }
     StatsdStats::getInstance().noteBucketCount(mMetricId);
+    mCurrentBucketStartTimeNs = nextBucketStartTimeNs;
 }
 
 void DurationMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const {
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index 2b6cac8..2f9afa5 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -529,11 +529,11 @@
         return;
     }
 
-    flushCurrentBucketLocked(eventTimeNs, eventTimeNs);
-
     // Adjusts the bucket start and end times.
     int64_t numBucketsForward = 1 + (eventTimeNs - currentBucketEndTimeNs) / mBucketSizeNs;
-    mCurrentBucketStartTimeNs = currentBucketEndTimeNs + (numBucketsForward - 1) * mBucketSizeNs;
+    int64_t nextBucketNs = currentBucketEndTimeNs + (numBucketsForward - 1) * mBucketSizeNs;
+    flushCurrentBucketLocked(eventTimeNs, nextBucketNs);
+
     mCurrentBucketNum += numBucketsForward;
     VLOG("Gauge metric %lld: new bucket start time: %lld", (long long)mMetricId,
          (long long)mCurrentBucketStartTimeNs);
@@ -578,6 +578,7 @@
 
     StatsdStats::getInstance().noteBucketCount(mMetricId);
     mCurrentSlicedBucket = std::make_shared<DimToGaugeAtomsMap>();
+    mCurrentBucketStartTimeNs = nextBucketStartTimeNs;
 }
 
 size_t GaugeMetricProducer::byteSizeLocked() const {
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index a0a1348..12cec5d 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -178,7 +178,7 @@
 
     void pullAndMatchEventsLocked(const int64_t timestampNs, ConditionState condition);
 
-    void accumulateEvents(const std::vector<std::shared_ptr<LogEvent>>& allData, 
+    void accumulateEvents(const std::vector<std::shared_ptr<LogEvent>>& allData,
                           int64_t originalPullTimeNs, int64_t eventElapsedTimeNs,
                           ConditionState condition);
 
diff --git a/cmds/statsd/src/shell/ShellSubscriber.cpp b/cmds/statsd/src/shell/ShellSubscriber.cpp
index 52d5ffc..f7e32d4 100644
--- a/cmds/statsd/src/shell/ShellSubscriber.cpp
+++ b/cmds/statsd/src/shell/ShellSubscriber.cpp
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#define DEBUG true  // STOPSHIP if true
+#define DEBUG false  // STOPSHIP if true
 #include "Log.h"
 
 #include "ShellSubscriber.h"
diff --git a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
index ef3643f..3dff7f5 100644
--- a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
@@ -46,7 +46,7 @@
     IPCThreadState* ipc = IPCThreadState::self();
     ConfigKey configKey(ipc->getCallingUid(), kConfigKey);
     processor->onDumpReport(configKey, timestamp, include_current /* include_current_bucket*/,
-                            true /* erase_data */, ADB_DUMP, FAST, &output);
+                            true /* erase_data */, ADB_DUMP, NO_TIME_CONSTRAINTS, &output);
     ConfigMetricsReportList reports;
     reports.ParseFromArray(output.data(), output.size());
     EXPECT_EQ(1, reports.reports_size());
diff --git a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
index cdb5a78..b316562 100644
--- a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
@@ -75,7 +75,7 @@
             mAllMetricProducers[0]->getCurrentBucketNum();
     EXPECT_GT(startBucketNum, (int64_t)0);
 
-    // When creating the config, the gauge metric producer should register the alarm at the
+    // When creating the config, the value metric producer should register the alarm at the
     // end of the current bucket.
     EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
     EXPECT_EQ(bucketSizeNs,
@@ -140,32 +140,30 @@
     EXPECT_EQ(1 /* subsystem name field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
-    EXPECT_EQ(5, data.bucket_info_size());
+    // We have 4 buckets, the first one was incomplete since the condition was unknown.
+    EXPECT_EQ(4, data.bucket_info_size());
 
-    EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
+    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
     EXPECT_EQ(1, data.bucket_info(0).values_size());
 
-    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
+    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
+    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
     EXPECT_EQ(1, data.bucket_info(1).values_size());
 
-    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
+    EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
+    EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
     EXPECT_EQ(1, data.bucket_info(2).values_size());
 
-    EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(3).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(3).end_bucket_elapsed_nanos());
+    EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(3).start_bucket_elapsed_nanos());
+    EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(3).end_bucket_elapsed_nanos());
     EXPECT_EQ(1, data.bucket_info(3).values_size());
-
-    EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(4).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(4).end_bucket_elapsed_nanos());
-    EXPECT_EQ(1, data.bucket_info(4).values_size());
 }
 
 TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm) {
     auto config = CreateStatsdConfig();
     int64_t baseTimeNs = getElapsedRealtimeNs();
+    // 10 mins == 2 bucket durations.
     int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
     int64_t bucketSizeNs =
         TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000;
@@ -181,7 +179,7 @@
             mAllMetricProducers[0]->getCurrentBucketNum();
     EXPECT_GT(startBucketNum, (int64_t)0);
 
-    // When creating the config, the gauge metric producer should register the alarm at the
+    // When creating the config, the value metric producer should register the alarm at the
     // end of the current bucket.
     EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
     EXPECT_EQ(bucketSizeNs,
@@ -203,15 +201,18 @@
                                                    configAddedTimeNs + 75);
     processor->OnLogEvent(screenOffEvent.get());
 
-    // Pulling alarm arrives late by 2 buckets and 1 ns.
+    // Pulling alarm arrives late by 2 buckets and 1 ns. 2 buckets late is too far away in the
+    // future, data will be skipped.
     processor->informPullAlarmFired(expectedPullTimeNs + 2 * bucketSizeNs + 1);
     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, expectedPullTimeNs);
 
+    // This screen state change will start a new bucket.
     screenOnEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
                                                        configAddedTimeNs + 4 * bucketSizeNs + 65);
     processor->OnLogEvent(screenOnEvent.get());
 
-    // Pulling alarm arrives late by one bucket size + 21ns.
+    // The alarm is delayed but we already created a bucket thanks to the screen state condition.
+    // This bucket does not have to be skipped since the alarm arrives in time for the next bucket.
     processor->informPullAlarmFired(expectedPullTimeNs + bucketSizeNs + 21);
     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 6 * bucketSizeNs, expectedPullTimeNs);
 
@@ -249,8 +250,8 @@
     EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
     EXPECT_EQ(3, data.bucket_info_size());
 
-    EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
+    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
     EXPECT_EQ(1, data.bucket_info(0).values_size());
 
     EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt
index c6a3d80..b3f0037 100644
--- a/config/hiddenapi-greylist.txt
+++ b/config/hiddenapi-greylist.txt
@@ -278,227 +278,16 @@
 Landroid/net/wifi/IWifiScanner$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/IWifiScanner;
 Landroid/net/wifi/p2p/IWifiP2pManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/p2p/IWifiP2pManager;
 Landroid/nfc/INfcAdapter$Stub;->TRANSACTION_enable:I
-Landroid/os/AsyncResult;-><init>(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Throwable;)V
-Landroid/os/AsyncResult;->exception:Ljava/lang/Throwable;
-Landroid/os/AsyncResult;->forMessage(Landroid/os/Message;)Landroid/os/AsyncResult;
-Landroid/os/AsyncResult;->forMessage(Landroid/os/Message;Ljava/lang/Object;Ljava/lang/Throwable;)Landroid/os/AsyncResult;
-Landroid/os/AsyncResult;->result:Ljava/lang/Object;
-Landroid/os/AsyncResult;->userObj:Ljava/lang/Object;
-Landroid/os/AsyncTask;->mFuture:Ljava/util/concurrent/FutureTask;
-Landroid/os/AsyncTask;->mStatus:Landroid/os/AsyncTask$Status;
-Landroid/os/AsyncTask;->mTaskInvoked:Ljava/util/concurrent/atomic/AtomicBoolean;
-Landroid/os/AsyncTask;->mWorker:Landroid/os/AsyncTask$WorkerRunnable;
-Landroid/os/AsyncTask;->sDefaultExecutor:Ljava/util/concurrent/Executor;
-Landroid/os/AsyncTask;->setDefaultExecutor(Ljava/util/concurrent/Executor;)V
-Landroid/os/BaseBundle;->isParcelled()Z
-Landroid/os/BaseBundle;->mMap:Landroid/util/ArrayMap;
-Landroid/os/BaseBundle;->mParcelledData:Landroid/os/Parcel;
-Landroid/os/BaseBundle;->unparcel()V
-Landroid/os/BatteryManager;->EXTRA_CHARGE_COUNTER:Ljava/lang/String;
-Landroid/os/BatteryManager;->EXTRA_INVALID_CHARGER:Ljava/lang/String;
-Landroid/os/BatteryManager;->EXTRA_MAX_CHARGING_CURRENT:Ljava/lang/String;
-Landroid/os/BatteryManager;->EXTRA_MAX_CHARGING_VOLTAGE:Ljava/lang/String;
-Landroid/os/BatteryStats$Counter;->getCountLocked(I)I
-Landroid/os/BatteryStats$HistoryItem;-><init>()V
-Landroid/os/BatteryStats$HistoryItem;->batteryHealth:B
-Landroid/os/BatteryStats$HistoryItem;->batteryLevel:B
-Landroid/os/BatteryStats$HistoryItem;->batteryPlugType:B
-Landroid/os/BatteryStats$HistoryItem;->batteryStatus:B
-Landroid/os/BatteryStats$HistoryItem;->batteryVoltage:C
-Landroid/os/BatteryStats$HistoryItem;->cmd:B
-Landroid/os/BatteryStats$HistoryItem;->CMD_UPDATE:B
-Landroid/os/BatteryStats$HistoryItem;->states2:I
-Landroid/os/BatteryStats$HistoryItem;->states:I
-Landroid/os/BatteryStats$HistoryItem;->time:J
-Landroid/os/BatteryStats$Timer;->getCountLocked(I)I
-Landroid/os/BatteryStats$Timer;->getTotalTimeLocked(JI)J
-Landroid/os/BatteryStats$Uid$Pkg$Serv;->getLaunches(I)I
-Landroid/os/BatteryStats$Uid$Pkg$Serv;->getStarts(I)I
-Landroid/os/BatteryStats$Uid$Pkg$Serv;->getStartTime(JI)J
-Landroid/os/BatteryStats$Uid$Pkg;->getServiceStats()Landroid/util/ArrayMap;
-Landroid/os/BatteryStats$Uid$Pkg;->getWakeupAlarmStats()Landroid/util/ArrayMap;
 Landroid/os/BatteryStats$Uid$Proc$ExcessivePower;-><init>()V
-Landroid/os/BatteryStats$Uid$Proc$ExcessivePower;->overTime:J
-Landroid/os/BatteryStats$Uid$Proc$ExcessivePower;->type:I
-Landroid/os/BatteryStats$Uid$Proc$ExcessivePower;->usedTime:J
-Landroid/os/BatteryStats$Uid$Proc;->countExcessivePowers()I
-Landroid/os/BatteryStats$Uid$Proc;->getExcessivePower(I)Landroid/os/BatteryStats$Uid$Proc$ExcessivePower;
-Landroid/os/BatteryStats$Uid$Proc;->getForegroundTime(I)J
-Landroid/os/BatteryStats$Uid$Proc;->getStarts(I)I
-Landroid/os/BatteryStats$Uid$Proc;->getSystemTime(I)J
-Landroid/os/BatteryStats$Uid$Proc;->getUserTime(I)J
-Landroid/os/BatteryStats$Uid$Sensor;->getHandle()I
-Landroid/os/BatteryStats$Uid$Sensor;->getSensorTime()Landroid/os/BatteryStats$Timer;
-Landroid/os/BatteryStats$Uid$Sensor;->GPS:I
-Landroid/os/BatteryStats$Uid$Wakelock;->getWakeTime(I)Landroid/os/BatteryStats$Timer;
 Landroid/os/BatteryStats$Uid;-><init>()V
-Landroid/os/BatteryStats$Uid;->getAudioTurnedOnTimer()Landroid/os/BatteryStats$Timer;
-Landroid/os/BatteryStats$Uid;->getFullWifiLockTime(JI)J
-Landroid/os/BatteryStats$Uid;->getMobileRadioActiveTime(I)J
-Landroid/os/BatteryStats$Uid;->getNetworkActivityBytes(II)J
-Landroid/os/BatteryStats$Uid;->getPackageStats()Landroid/util/ArrayMap;
-Landroid/os/BatteryStats$Uid;->getProcessStats()Landroid/util/ArrayMap;
-Landroid/os/BatteryStats$Uid;->getSensorStats()Landroid/util/SparseArray;
-Landroid/os/BatteryStats$Uid;->getUid()I
-Landroid/os/BatteryStats$Uid;->getVideoTurnedOnTimer()Landroid/os/BatteryStats$Timer;
-Landroid/os/BatteryStats$Uid;->getWakelockStats()Landroid/util/ArrayMap;
-Landroid/os/BatteryStats$Uid;->getWifiBatchedScanTime(IJI)J
-Landroid/os/BatteryStats$Uid;->getWifiMulticastTime(JI)J
-Landroid/os/BatteryStats$Uid;->getWifiRunningTime(JI)J
-Landroid/os/BatteryStats$Uid;->getWifiScanTime(JI)J
-Landroid/os/BatteryStats;->computeBatteryRealtime(JI)J
-Landroid/os/BatteryStats;->computeBatteryTimeRemaining(J)J
-Landroid/os/BatteryStats;->computeBatteryUptime(JI)J
-Landroid/os/BatteryStats;->computeChargeTimeRemaining(J)J
-Landroid/os/BatteryStats;->dumpLine(Ljava/io/PrintWriter;ILjava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
-Landroid/os/BatteryStats;->getBatteryUptime(J)J
-Landroid/os/BatteryStats;->getGlobalWifiRunningTime(JI)J
-Landroid/os/BatteryStats;->getNextHistoryLocked(Landroid/os/BatteryStats$HistoryItem;)Z
-Landroid/os/BatteryStats;->getPhoneOnTime(JI)J
-Landroid/os/BatteryStats;->getPhoneSignalStrengthTime(IJI)J
-Landroid/os/BatteryStats;->getScreenBrightnessTime(IJI)J
-Landroid/os/BatteryStats;->getScreenOnTime(JI)J
-Landroid/os/BatteryStats;->getUidStats()Landroid/util/SparseArray;
-Landroid/os/BatteryStats;->getWifiOnTime(JI)J
-Landroid/os/BatteryStats;->NUM_DATA_CONNECTION_TYPES:I
-Landroid/os/BatteryStats;->NUM_SCREEN_BRIGHTNESS_BINS:I
-Landroid/os/BatteryStats;->startIteratingHistoryLocked()Z
-Landroid/os/BatteryStats;->STATS_CURRENT:I
-Landroid/os/BatteryStats;->WAKE_TYPE_PARTIAL:I
-Landroid/os/Binder;->execTransact(IJJI)Z
-Landroid/os/Binder;->mObject:J
-Landroid/os/Broadcaster;-><init>()V
-Landroid/os/Broadcaster;->broadcast(Landroid/os/Message;)V
-Landroid/os/Broadcaster;->cancelRequest(ILandroid/os/Handler;I)V
-Landroid/os/Broadcaster;->request(ILandroid/os/Handler;I)V
-Landroid/os/Build$VERSION;->ACTIVE_CODENAMES:[Ljava/lang/String;
-Landroid/os/Build;->getLong(Ljava/lang/String;)J
-Landroid/os/Build;->getString(Ljava/lang/String;)Ljava/lang/String;
-Landroid/os/Build;->IS_DEBUGGABLE:Z
-Landroid/os/Bundle;->filterValues()Landroid/os/Bundle;
-Landroid/os/Bundle;->forPair(Ljava/lang/String;Ljava/lang/String;)Landroid/os/Bundle;
-Landroid/os/Bundle;->getIBinder(Ljava/lang/String;)Landroid/os/IBinder;
-Landroid/os/Bundle;->getSize()I
-Landroid/os/Bundle;->putIBinder(Ljava/lang/String;Landroid/os/IBinder;)V
-Landroid/os/Bundle;->putParcelableList(Ljava/lang/String;Ljava/util/List;)V
-Landroid/os/Bundle;->setDefusable(Landroid/os/Bundle;Z)Landroid/os/Bundle;
-Landroid/os/Debug$MemoryInfo;->dalvikPrivateClean:I
-Landroid/os/Debug$MemoryInfo;->dalvikRss:I
-Landroid/os/Debug$MemoryInfo;->dalvikSharedClean:I
-Landroid/os/Debug$MemoryInfo;->dalvikSwappablePss:I
-Landroid/os/Debug$MemoryInfo;->dalvikSwappedOut:I
-Landroid/os/Debug$MemoryInfo;->dalvikSwappedOutPss:I
-Landroid/os/Debug$MemoryInfo;->getOtherLabel(I)Ljava/lang/String;
-Landroid/os/Debug$MemoryInfo;->getOtherPrivate(I)I
-Landroid/os/Debug$MemoryInfo;->getOtherPrivateDirty(I)I
-Landroid/os/Debug$MemoryInfo;->getOtherPss(I)I
-Landroid/os/Debug$MemoryInfo;->getOtherSharedDirty(I)I
-Landroid/os/Debug$MemoryInfo;->getSummaryCode()I
-Landroid/os/Debug$MemoryInfo;->getSummaryGraphics()I
-Landroid/os/Debug$MemoryInfo;->getSummaryJavaHeap()I
-Landroid/os/Debug$MemoryInfo;->getSummaryNativeHeap()I
-Landroid/os/Debug$MemoryInfo;->getSummaryPrivateOther()I
-Landroid/os/Debug$MemoryInfo;->getSummaryStack()I
-Landroid/os/Debug$MemoryInfo;->getSummarySystem()I
-Landroid/os/Debug$MemoryInfo;->getTotalUss()I
-Landroid/os/Debug$MemoryInfo;->hasSwappedOutPss:Z
-Landroid/os/Debug$MemoryInfo;->nativePrivateClean:I
-Landroid/os/Debug$MemoryInfo;->nativeRss:I
-Landroid/os/Debug$MemoryInfo;->nativeSharedClean:I
-Landroid/os/Debug$MemoryInfo;->nativeSwappablePss:I
-Landroid/os/Debug$MemoryInfo;->nativeSwappedOut:I
-Landroid/os/Debug$MemoryInfo;->nativeSwappedOutPss:I
-Landroid/os/Debug$MemoryInfo;->NUM_DVK_STATS:I
-Landroid/os/Debug$MemoryInfo;->NUM_OTHER_STATS:I
-Landroid/os/Debug$MemoryInfo;->otherPrivateClean:I
-Landroid/os/Debug$MemoryInfo;->otherRss:I
-Landroid/os/Debug$MemoryInfo;->otherSharedClean:I
-Landroid/os/Debug$MemoryInfo;->otherStats:[I
-Landroid/os/Debug$MemoryInfo;->otherSwappablePss:I
-Landroid/os/Debug$MemoryInfo;->otherSwappedOut:I
-Landroid/os/Debug$MemoryInfo;->otherSwappedOutPss:I
-Landroid/os/Debug;-><init>()V
-Landroid/os/Debug;->countInstancesOfClass(Ljava/lang/Class;)J
-Landroid/os/Debug;->dumpNativeHeap(Ljava/io/FileDescriptor;)V
-Landroid/os/Debug;->dumpReferenceTables()V
-Landroid/os/Debug;->getCaller()Ljava/lang/String;
-Landroid/os/Debug;->getCallers(I)Ljava/lang/String;
-Landroid/os/Debug;->getMemInfo([J)V
-Landroid/os/Debug;->getMemoryInfo(ILandroid/os/Debug$MemoryInfo;)V
-Landroid/os/DropBoxManager;->mService:Lcom/android/internal/os/IDropBoxManagerService;
-Landroid/os/Environment$UserEnvironment;-><init>(I)V
-Landroid/os/Environment$UserEnvironment;->getExternalDirs()[Ljava/io/File;
-Landroid/os/Environment$UserEnvironment;->getExternalStorageDirectory()Ljava/io/File;
-Landroid/os/Environment$UserEnvironment;->getExternalStoragePublicDirectory(Ljava/lang/String;)Ljava/io/File;
-Landroid/os/Environment;->buildExternalStorageAndroidDataDirs()[Ljava/io/File;
-Landroid/os/Environment;->buildExternalStorageAppCacheDirs(Ljava/lang/String;)[Ljava/io/File;
-Landroid/os/Environment;->buildExternalStorageAppDataDirs(Ljava/lang/String;)[Ljava/io/File;
-Landroid/os/Environment;->buildExternalStorageAppFilesDirs(Ljava/lang/String;)[Ljava/io/File;
-Landroid/os/Environment;->buildExternalStorageAppMediaDirs(Ljava/lang/String;)[Ljava/io/File;
-Landroid/os/Environment;->buildExternalStorageAppObbDirs(Ljava/lang/String;)[Ljava/io/File;
-Landroid/os/Environment;->buildPaths([Ljava/io/File;[Ljava/lang/String;)[Ljava/io/File;
-Landroid/os/Environment;->getDataSystemDirectory()Ljava/io/File;
-Landroid/os/Environment;->getLegacyExternalStorageDirectory()Ljava/io/File;
-Landroid/os/Environment;->getLegacyExternalStorageObbDirectory()Ljava/io/File;
-Landroid/os/Environment;->initForCurrentUser()V
-Landroid/os/Environment;->maybeTranslateEmulatedPathToInternal(Ljava/io/File;)Ljava/io/File;
-Landroid/os/Environment;->sCurrentUser:Landroid/os/Environment$UserEnvironment;
-Landroid/os/FileObserver$ObserverThread;->onEvent(IILjava/lang/String;)V
-Landroid/os/FileObserver;->s_observerThread:Landroid/os/FileObserver$ObserverThread;
-Landroid/os/FileUtils;-><init>()V
-Landroid/os/FileUtils;->checksumCrc32(Ljava/io/File;)J
-Landroid/os/FileUtils;->copyFile(Ljava/io/File;Ljava/io/File;)Z
-Landroid/os/FileUtils;->copyToFile(Ljava/io/InputStream;Ljava/io/File;)Z
-Landroid/os/FileUtils;->deleteContents(Ljava/io/File;)Z
-Landroid/os/FileUtils;->deleteOlderFiles(Ljava/io/File;IJ)Z
-Landroid/os/FileUtils;->isFilenameSafe(Ljava/io/File;)Z
-Landroid/os/FileUtils;->readTextFile(Ljava/io/File;ILjava/lang/String;)Ljava/lang/String;
-Landroid/os/FileUtils;->setPermissions(Ljava/io/File;III)I
-Landroid/os/FileUtils;->setPermissions(Ljava/io/FileDescriptor;III)I
-Landroid/os/FileUtils;->setPermissions(Ljava/lang/String;III)I
-Landroid/os/FileUtils;->stringToFile(Ljava/io/File;Ljava/lang/String;)V
-Landroid/os/FileUtils;->stringToFile(Ljava/lang/String;Ljava/lang/String;)V
-Landroid/os/FileUtils;->sync(Ljava/io/FileOutputStream;)Z
-Landroid/os/Handler;-><init>(Landroid/os/Looper;Landroid/os/Handler$Callback;Z)V
-Landroid/os/Handler;-><init>(Z)V
-Landroid/os/Handler;->getIMessenger()Landroid/os/IMessenger;
-Landroid/os/Handler;->getMain()Landroid/os/Handler;
-Landroid/os/Handler;->getPostMessage(Ljava/lang/Runnable;Ljava/lang/Object;)Landroid/os/Message;
-Landroid/os/Handler;->mCallback:Landroid/os/Handler$Callback;
-Landroid/os/Handler;->mLooper:Landroid/os/Looper;
-Landroid/os/Handler;->mMessenger:Landroid/os/IMessenger;
-Landroid/os/HwBinder;->reportSyspropChanged()V
-Landroid/os/HwParcel;-><init>(Z)V
-Landroid/os/HwRemoteBinder;-><init>()V
 Landroid/os/IBatteryPropertiesRegistrar$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/os/IBinder;->SYSPROPS_TRANSACTION:I
 Landroid/os/IDeviceIdentifiersPolicyService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IDeviceIdentifiersPolicyService;
 Landroid/os/IDeviceIdleController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IDeviceIdleController;
-Landroid/os/IDeviceIdleController;->addPowerSaveTempWhitelistApp(Ljava/lang/String;JILjava/lang/String;)V
 Landroid/os/IDeviceIdleController;->getAppIdTempWhitelist()[I
 Landroid/os/IDeviceIdleController;->getFullPowerWhitelistExceptIdle()[Ljava/lang/String;
 Landroid/os/INetworkManagementService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/os/INetworkManagementService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/INetworkManagementService;
-Landroid/os/INetworkManagementService;->clearInterfaceAddresses(Ljava/lang/String;)V
-Landroid/os/INetworkManagementService;->disableIpv6(Ljava/lang/String;)V
-Landroid/os/INetworkManagementService;->disableNat(Ljava/lang/String;Ljava/lang/String;)V
-Landroid/os/INetworkManagementService;->enableIpv6(Ljava/lang/String;)V
-Landroid/os/INetworkManagementService;->enableNat(Ljava/lang/String;Ljava/lang/String;)V
-Landroid/os/INetworkManagementService;->getInterfaceConfig(Ljava/lang/String;)Landroid/net/InterfaceConfiguration;
-Landroid/os/INetworkManagementService;->getIpForwardingEnabled()Z
-Landroid/os/INetworkManagementService;->isBandwidthControlEnabled()Z
-Landroid/os/INetworkManagementService;->isTetheringStarted()Z
 Landroid/os/INetworkManagementService;->listTetheredInterfaces()[Ljava/lang/String;
-Landroid/os/INetworkManagementService;->registerObserver(Landroid/net/INetworkManagementEventObserver;)V
-Landroid/os/INetworkManagementService;->setInterfaceConfig(Ljava/lang/String;Landroid/net/InterfaceConfiguration;)V
-Landroid/os/INetworkManagementService;->setInterfaceIpv6PrivacyExtensions(Ljava/lang/String;Z)V
-Landroid/os/INetworkManagementService;->setIpForwardingEnabled(Z)V
-Landroid/os/INetworkManagementService;->setIPv6AddrGenMode(Ljava/lang/String;I)V
-Landroid/os/INetworkManagementService;->startTethering([Ljava/lang/String;)V
-Landroid/os/INetworkManagementService;->stopTethering()V
-Landroid/os/INetworkManagementService;->tetherInterface(Ljava/lang/String;)V
-Landroid/os/INetworkManagementService;->unregisterObserver(Landroid/net/INetworkManagementEventObserver;)V
-Landroid/os/INetworkManagementService;->untetherInterface(Ljava/lang/String;)V
 Landroid/os/IPermissionController$Stub$Proxy;->checkPermission(Ljava/lang/String;II)Z
 Landroid/os/IPermissionController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IPermissionController;
 Landroid/os/IPowerManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
@@ -506,282 +295,21 @@
 Landroid/os/IPowerManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IPowerManager;
 Landroid/os/IPowerManager$Stub;->TRANSACTION_acquireWakeLock:I
 Landroid/os/IPowerManager$Stub;->TRANSACTION_goToSleep:I
-Landroid/os/IPowerManager;->goToSleep(JII)V
-Landroid/os/IPowerManager;->isInteractive()Z
-Landroid/os/IPowerManager;->reboot(ZLjava/lang/String;Z)V
 Landroid/os/IPowerManager;->releaseWakeLock(Landroid/os/IBinder;I)V
-Landroid/os/IPowerManager;->userActivity(JII)V
 Landroid/os/IRecoverySystem$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IRecoverySystem;
 Landroid/os/IRemoteCallback$Stub;-><init>()V
-Landroid/os/IRemoteCallback;->sendResult(Landroid/os/Bundle;)V
-Landroid/os/IServiceManager;->checkService(Ljava/lang/String;)Landroid/os/IBinder;
-Landroid/os/IServiceManager;->getService(Ljava/lang/String;)Landroid/os/IBinder;
 Landroid/os/IUpdateEngine$Stub;-><init>()V
 Landroid/os/IUpdateEngineCallback;->onStatusUpdate(IF)V
 Landroid/os/IUserManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/os/IUserManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IUserManager;
-Landroid/os/IUserManager;->getUserInfo(I)Landroid/content/pm/UserInfo;
 Landroid/os/IVibratorService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IVibratorService;
-Landroid/os/LocaleList;->setDefault(Landroid/os/LocaleList;I)V
-Landroid/os/Looper;->mLogging:Landroid/util/Printer;
-Landroid/os/Looper;->mQueue:Landroid/os/MessageQueue;
-Landroid/os/Looper;->setTraceTag(J)V
-Landroid/os/Looper;->sMainLooper:Landroid/os/Looper;
-Landroid/os/Looper;->sThreadLocal:Ljava/lang/ThreadLocal;
-Landroid/os/MemoryFile;->deactivate()V
-Landroid/os/MemoryFile;->getFileDescriptor()Ljava/io/FileDescriptor;
-Landroid/os/MemoryFile;->getSize(Ljava/io/FileDescriptor;)I
-Landroid/os/MemoryFile;->native_get_size(Ljava/io/FileDescriptor;)I
-Landroid/os/MemoryFile;->native_pin(Ljava/io/FileDescriptor;Z)Z
-Landroid/os/Message;->callback:Ljava/lang/Runnable;
-Landroid/os/Message;->flags:I
-Landroid/os/Message;->markInUse()V
-Landroid/os/Message;->next:Landroid/os/Message;
-Landroid/os/Message;->recycleUnchecked()V
-Landroid/os/Message;->setCallback(Ljava/lang/Runnable;)Landroid/os/Message;
-Landroid/os/Message;->target:Landroid/os/Handler;
-Landroid/os/Message;->toString(J)Ljava/lang/String;
-Landroid/os/Message;->when:J
-Landroid/os/MessageQueue;->dispatchEvents(II)I
-Landroid/os/MessageQueue;->hasMessages(Landroid/os/Handler;Ljava/lang/Runnable;Ljava/lang/Object;)Z
-Landroid/os/MessageQueue;->mIdleHandlers:Ljava/util/ArrayList;
-Landroid/os/MessageQueue;->mMessages:Landroid/os/Message;
-Landroid/os/MessageQueue;->mNextBarrierToken:I
-Landroid/os/MessageQueue;->mPtr:J
-Landroid/os/MessageQueue;->mQuitAllowed:Z
-Landroid/os/MessageQueue;->nativePollOnce(JI)V
-Landroid/os/MessageQueue;->next()Landroid/os/Message;
 Landroid/os/Parcel$ReadWriteHelper;-><init>()V
-Landroid/os/Parcel;->getGlobalAllocCount()J
-Landroid/os/Parcel;->getGlobalAllocSize()J
-Landroid/os/Parcel;->mNativePtr:J
-Landroid/os/Parcel;->readArrayMap(Landroid/util/ArrayMap;Ljava/lang/ClassLoader;)V
-Landroid/os/Parcel;->readArraySet(Ljava/lang/ClassLoader;)Landroid/util/ArraySet;
-Landroid/os/Parcel;->readBlob()[B
-Landroid/os/Parcel;->readCharSequence()Ljava/lang/CharSequence;
-Landroid/os/Parcel;->readCreator(Landroid/os/Parcelable$Creator;Ljava/lang/ClassLoader;)Landroid/os/Parcelable;
-Landroid/os/Parcel;->readExceptionCode()I
-Landroid/os/Parcel;->readParcelableCreator(Ljava/lang/ClassLoader;)Landroid/os/Parcelable$Creator;
-Landroid/os/Parcel;->readRawFileDescriptor()Ljava/io/FileDescriptor;
-Landroid/os/Parcel;->readStringArray()[Ljava/lang/String;
-Landroid/os/Parcel;->writeArrayMap(Landroid/util/ArrayMap;)V
-Landroid/os/Parcel;->writeArraySet(Landroid/util/ArraySet;)V
-Landroid/os/Parcel;->writeBlob([B)V
-Landroid/os/Parcel;->writeCharSequence(Ljava/lang/CharSequence;)V
-Landroid/os/Parcel;->writeParcelableCreator(Landroid/os/Parcelable;)V
-Landroid/os/ParcelableParcel;-><init>(Ljava/lang/ClassLoader;)V
-Landroid/os/ParcelableParcel;->CREATOR:Landroid/os/Parcelable$ClassLoaderCreator;
-Landroid/os/ParcelableParcel;->getClassLoader()Ljava/lang/ClassLoader;
-Landroid/os/ParcelableParcel;->getParcel()Landroid/os/Parcel;
-Landroid/os/ParcelFileDescriptor;-><init>(Ljava/io/FileDescriptor;)V
-Landroid/os/ParcelFileDescriptor;->fromData([BLjava/lang/String;)Landroid/os/ParcelFileDescriptor;
-Landroid/os/ParcelFileDescriptor;->seekTo(J)J
-Landroid/os/PerformanceCollector;-><init>()V
-Landroid/os/PerformanceCollector;->beginSnapshot(Ljava/lang/String;)V
-Landroid/os/PerformanceCollector;->endSnapshot()Landroid/os/Bundle;
-Landroid/os/PerformanceCollector;->startTiming(Ljava/lang/String;)V
-Landroid/os/PerformanceCollector;->stopTiming(Ljava/lang/String;)Landroid/os/Bundle;
-Landroid/os/PowerManager$WakeLock;->mFlags:I
-Landroid/os/PowerManager$WakeLock;->mTag:Ljava/lang/String;
-Landroid/os/PowerManager;->ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED:Ljava/lang/String;
-Landroid/os/PowerManager;->ACTION_POWER_SAVE_MODE_CHANGING:Ljava/lang/String;
-Landroid/os/PowerManager;->BRIGHTNESS_ON:I
-Landroid/os/PowerManager;->EXTRA_POWER_SAVE_MODE:Ljava/lang/String;
-Landroid/os/PowerManager;->getDefaultScreenBrightnessSetting()I
-Landroid/os/PowerManager;->getMaximumScreenBrightnessSetting()I
-Landroid/os/PowerManager;->getMinimumScreenBrightnessSetting()I
-Landroid/os/PowerManager;->goToSleep(JII)V
-Landroid/os/PowerManager;->GO_TO_SLEEP_REASON_TIMEOUT:I
-Landroid/os/PowerManager;->isLightDeviceIdleMode()Z
-Landroid/os/PowerManager;->mService:Landroid/os/IPowerManager;
-Landroid/os/PowerManager;->validateWakeLockParameters(ILjava/lang/String;)V
-Landroid/os/PowerManager;->wakeUp(JLjava/lang/String;)V
-Landroid/os/Process;->DRM_UID:I
-Landroid/os/Process;->getFreeMemory()J
-Landroid/os/Process;->getParentPid(I)I
-Landroid/os/Process;->getPids(Ljava/lang/String;[I)[I
-Landroid/os/Process;->getPidsForCommands([Ljava/lang/String;)[I
-Landroid/os/Process;->getPss(I)J
-Landroid/os/Process;->getTotalMemory()J
-Landroid/os/Process;->getUidForPid(I)I
-Landroid/os/Process;->isIsolated(I)Z
-Landroid/os/Process;->LOG_UID:I
-Landroid/os/Process;->MEDIA_UID:I
-Landroid/os/Process;->myPpid()I
-Landroid/os/Process;->NFC_UID:I
-Landroid/os/Process;->parseProcLine([BII[I[Ljava/lang/String;[J[F)Z
-Landroid/os/Process;->PROC_COMBINE:I
-Landroid/os/Process;->PROC_OUT_FLOAT:I
-Landroid/os/Process;->PROC_OUT_LONG:I
-Landroid/os/Process;->PROC_OUT_STRING:I
-Landroid/os/Process;->PROC_PARENS:I
-Landroid/os/Process;->PROC_QUOTES:I
-Landroid/os/Process;->PROC_SPACE_TERM:I
-Landroid/os/Process;->PROC_TAB_TERM:I
-Landroid/os/Process;->PROC_TERM_MASK:I
-Landroid/os/Process;->PROC_ZERO_TERM:I
-Landroid/os/Process;->readProcFile(Ljava/lang/String;[I[Ljava/lang/String;[J[F)Z
-Landroid/os/Process;->readProcLines(Ljava/lang/String;[Ljava/lang/String;[J)V
-Landroid/os/Process;->setArgV0(Ljava/lang/String;)V
-Landroid/os/Process;->setProcessGroup(II)V
-Landroid/os/Process;->VPN_UID:I
-Landroid/os/Process;->WIFI_UID:I
-Landroid/os/RecoverySystem;->verifyPackageCompatibility(Ljava/io/InputStream;)Z
-Landroid/os/Registrant;-><init>(Landroid/os/Handler;ILjava/lang/Object;)V
-Landroid/os/Registrant;->clear()V
-Landroid/os/Registrant;->messageForRegistrant()Landroid/os/Message;
-Landroid/os/Registrant;->notifyRegistrant()V
-Landroid/os/Registrant;->notifyRegistrant(Landroid/os/AsyncResult;)V
-Landroid/os/Registrant;->notifyResult(Ljava/lang/Object;)V
 Landroid/os/RegistrantList;-><init>()V
-Landroid/os/RegistrantList;->add(Landroid/os/Handler;ILjava/lang/Object;)V
-Landroid/os/RegistrantList;->add(Landroid/os/Registrant;)V
-Landroid/os/RegistrantList;->addUnique(Landroid/os/Handler;ILjava/lang/Object;)V
-Landroid/os/RegistrantList;->notifyRegistrants()V
-Landroid/os/RegistrantList;->notifyRegistrants(Landroid/os/AsyncResult;)V
-Landroid/os/RegistrantList;->notifyResult(Ljava/lang/Object;)V
-Landroid/os/RegistrantList;->remove(Landroid/os/Handler;)V
-Landroid/os/RegistrantList;->removeCleared()V
-Landroid/os/RegistrantList;->size()I
-Landroid/os/RemoteCallbackList;->mCallbacks:Landroid/util/ArrayMap;
-Landroid/os/RemoteException;->rethrowFromSystemServer()Ljava/lang/RuntimeException;
-Landroid/os/SELinux;->checkSELinuxAccess(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z
-Landroid/os/SELinux;->getContext()Ljava/lang/String;
-Landroid/os/SELinux;->getFileContext(Ljava/lang/String;)Ljava/lang/String;
-Landroid/os/SELinux;->getPidContext(I)Ljava/lang/String;
-Landroid/os/SELinux;->isSELinuxEnabled()Z
-Landroid/os/SELinux;->isSELinuxEnforced()Z
-Landroid/os/SELinux;->restoreconRecursive(Ljava/io/File;)Z
 Landroid/os/ServiceManager;-><init>()V
-Landroid/os/ServiceManager;->addService(Ljava/lang/String;Landroid/os/IBinder;)V
-Landroid/os/ServiceManager;->addService(Ljava/lang/String;Landroid/os/IBinder;Z)V
-Landroid/os/ServiceManager;->addService(Ljava/lang/String;Landroid/os/IBinder;ZI)V
-Landroid/os/ServiceManager;->checkService(Ljava/lang/String;)Landroid/os/IBinder;
-Landroid/os/ServiceManager;->getIServiceManager()Landroid/os/IServiceManager;
-Landroid/os/ServiceManager;->getService(Ljava/lang/String;)Landroid/os/IBinder;
-Landroid/os/ServiceManager;->listServices()[Ljava/lang/String;
-Landroid/os/ServiceManager;->sCache:Ljava/util/Map;
-Landroid/os/ServiceManager;->sServiceManager:Landroid/os/IServiceManager;
-Landroid/os/ServiceManagerNative;->asInterface(Landroid/os/IBinder;)Landroid/os/IServiceManager;
-Landroid/os/ServiceManagerProxy;->getService(Ljava/lang/String;)Landroid/os/IBinder;
-Landroid/os/ServiceManagerProxy;->mRemote:Landroid/os/IBinder;
-Landroid/os/SharedMemory;->getFd()I
-Landroid/os/ShellCommand;->peekNextArg()Ljava/lang/String;
-Landroid/os/StatFs;->mStat:Landroid/system/StructStatVfs;
 Landroid/os/storage/IObbActionListener$Stub;-><init>()V
 Landroid/os/storage/IStorageManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/os/storage/IStorageManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/storage/IStorageManager;
 Landroid/os/storage/StorageEventListener;-><init>()V
-Landroid/os/StrictMode$Span;->finish()V
-Landroid/os/StrictMode$ThreadPolicy;->mask:I
-Landroid/os/StrictMode$VmPolicy$Builder;->mMask:I
-Landroid/os/StrictMode$VmPolicy;->mask:I
-Landroid/os/StrictMode;->disableDeathOnFileUriExposure()V
-Landroid/os/StrictMode;->enableDeathOnFileUriExposure()V
-Landroid/os/StrictMode;->enterCriticalSpan(Ljava/lang/String;)Landroid/os/StrictMode$Span;
-Landroid/os/StrictMode;->getThreadPolicyMask()I
-Landroid/os/StrictMode;->incrementExpectedActivityCount(Ljava/lang/Class;)V
-Landroid/os/StrictMode;->onBinderStrictModePolicyChange(I)V
-Landroid/os/StrictMode;->onWebViewMethodCalledOnWrongThread(Ljava/lang/Throwable;)V
-Landroid/os/StrictMode;->sLastVmViolationTime:Ljava/util/HashMap;
-Landroid/os/StrictMode;->sWindowManager:Landroid/util/Singleton;
-Landroid/os/StrictMode;->violationsBeingTimed:Ljava/lang/ThreadLocal;
-Landroid/os/SystemClock;-><init>()V
-Landroid/os/SystemClock;->currentThreadTimeMicro()J
-Landroid/os/SystemClock;->currentTimeMicro()J
-Landroid/os/SystemProperties;-><init>()V
-Landroid/os/SystemProperties;->addChangeCallback(Ljava/lang/Runnable;)V
-Landroid/os/SystemProperties;->native_get(Ljava/lang/String;)Ljava/lang/String;
-Landroid/os/SystemProperties;->native_get_long(Ljava/lang/String;J)J
-Landroid/os/SystemProperties;->PROP_NAME_MAX:I
-Landroid/os/SystemProperties;->reportSyspropChanged()V
-Landroid/os/SystemProperties;->sChangeCallbacks:Ljava/util/ArrayList;
-Landroid/os/SystemProperties;->set(Ljava/lang/String;Ljava/lang/String;)V
-Landroid/os/SystemService;->start(Ljava/lang/String;)V
-Landroid/os/SystemService;->stop(Ljava/lang/String;)V
-Landroid/os/SystemVibrator;-><init>()V
-Landroid/os/SystemVibrator;-><init>(Landroid/content/Context;)V
-Landroid/os/Trace;->asyncTraceBegin(JLjava/lang/String;I)V
-Landroid/os/Trace;->asyncTraceEnd(JLjava/lang/String;I)V
-Landroid/os/Trace;->isTagEnabled(J)Z
-Landroid/os/Trace;->nativeGetEnabledTags()J
-Landroid/os/Trace;->sEnabledTags:J
-Landroid/os/Trace;->setAppTracingAllowed(Z)V
-Landroid/os/Trace;->traceBegin(JLjava/lang/String;)V
-Landroid/os/Trace;->traceCounter(JLjava/lang/String;I)V
-Landroid/os/Trace;->traceEnd(J)V
-Landroid/os/Trace;->TRACE_TAG_APP:J
-Landroid/os/Trace;->TRACE_TAG_VIEW:J
-Landroid/os/UEventObserver$UEvent;->get(Ljava/lang/String;)Ljava/lang/String;
-Landroid/os/UEventObserver$UEvent;->get(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
-Landroid/os/UEventObserver;-><init>()V
-Landroid/os/UEventObserver;->onUEvent(Landroid/os/UEventObserver$UEvent;)V
-Landroid/os/UEventObserver;->startObserving(Ljava/lang/String;)V
-Landroid/os/UEventObserver;->stopObserving()V
-Landroid/os/UpdateLock;->acquire()V
-Landroid/os/UpdateLock;->isHeld()Z
-Landroid/os/UpdateLock;->NOW_IS_CONVENIENT:Ljava/lang/String;
-Landroid/os/UpdateLock;->release()V
-Landroid/os/UpdateLock;->TIMESTAMP:Ljava/lang/String;
-Landroid/os/UpdateLock;->UPDATE_LOCK_CHANGED:Ljava/lang/String;
-Landroid/os/UserHandle;-><init>(I)V
-Landroid/os/UserHandle;->AID_APP_END:I
-Landroid/os/UserHandle;->AID_APP_START:I
-Landroid/os/UserHandle;->AID_CACHE_GID_START:I
-Landroid/os/UserHandle;->AID_ROOT:I
-Landroid/os/UserHandle;->AID_SHARED_GID_START:I
-Landroid/os/UserHandle;->CURRENT_OR_SELF:Landroid/os/UserHandle;
-Landroid/os/UserHandle;->ERR_GID:I
-Landroid/os/UserHandle;->getAppIdFromSharedAppGid(I)I
-Landroid/os/UserHandle;->getCallingUserId()I
-Landroid/os/UserHandle;->getUid(II)I
-Landroid/os/UserHandle;->getUserId(I)I
-Landroid/os/UserHandle;->isIsolated(I)Z
-Landroid/os/UserHandle;->isSameApp(II)Z
-Landroid/os/UserHandle;->mHandle:I
-Landroid/os/UserHandle;->MU_ENABLED:Z
-Landroid/os/UserHandle;->OWNER:Landroid/os/UserHandle;
-Landroid/os/UserHandle;->PER_USER_RANGE:I
-Landroid/os/UserHandle;->USER_ALL:I
-Landroid/os/UserHandle;->USER_CURRENT:I
-Landroid/os/UserHandle;->USER_CURRENT_OR_SELF:I
-Landroid/os/UserHandle;->USER_OWNER:I
-Landroid/os/UserHandle;->USER_SERIAL_SYSTEM:I
-Landroid/os/UserHandle;->USER_SYSTEM:I
-Landroid/os/UserManager;->createProfileForUser(Ljava/lang/String;II)Landroid/content/pm/UserInfo;
-Landroid/os/UserManager;->createUser(Ljava/lang/String;I)Landroid/content/pm/UserInfo;
-Landroid/os/UserManager;->DISALLOW_RECORD_AUDIO:Ljava/lang/String;
-Landroid/os/UserManager;->get(Landroid/content/Context;)Landroid/os/UserManager;
-Landroid/os/UserManager;->getEnabledProfiles(I)Ljava/util/List;
-Landroid/os/UserManager;->getMaxSupportedUsers()I
-Landroid/os/UserManager;->getProfileIdsWithDisabled(I)[I
-Landroid/os/UserManager;->getProfileParent(I)Landroid/content/pm/UserInfo;
-Landroid/os/UserManager;->getProfiles(I)Ljava/util/List;
-Landroid/os/UserManager;->getUserHandle()I
-Landroid/os/UserManager;->getUserHandle(I)I
-Landroid/os/UserManager;->getUserIcon(I)Landroid/graphics/Bitmap;
-Landroid/os/UserManager;->getUserInfo(I)Landroid/content/pm/UserInfo;
-Landroid/os/UserManager;->getUsers()Ljava/util/List;
-Landroid/os/UserManager;->getUsers(Z)Ljava/util/List;
-Landroid/os/UserManager;->getUserSerialNumber(I)I
-Landroid/os/UserManager;->getUserStartRealtime()J
-Landroid/os/UserManager;->getUserUnlockRealtime()J
-Landroid/os/UserManager;->hasBaseUserRestriction(Ljava/lang/String;Landroid/os/UserHandle;)Z
-Landroid/os/UserManager;->hasUserRestriction(Ljava/lang/String;Landroid/os/UserHandle;)Z
-Landroid/os/UserManager;->isDeviceInDemoMode(Landroid/content/Context;)Z
-Landroid/os/UserManager;->isGuestUser(I)Z
-Landroid/os/UserManager;->isLinkedUser()Z
-Landroid/os/UserManager;->isUserAdmin(I)Z
-Landroid/os/UserManager;->isUserUnlocked(I)Z
-Landroid/os/UserManager;->mService:Landroid/os/IUserManager;
-Landroid/os/UserManager;->removeUser(I)Z
-Landroid/os/Vibrator;-><init>()V
-Landroid/os/WorkSource;-><init>(Landroid/os/Parcel;)V
-Landroid/os/WorkSource;->mNames:[Ljava/lang/String;
-Landroid/os/WorkSource;->mNum:I
-Landroid/os/WorkSource;->mUids:[I
-Landroid/os/ZygoteStartFailedEx;-><init>(Ljava/lang/String;)V
-Landroid/os/ZygoteStartFailedEx;-><init>(Ljava/lang/Throwable;)V
 Landroid/preference/PreferenceGroupAdapter;->getItem(I)Landroid/preference/Preference;
 Landroid/R$styleable;->ActionBar:[I
 Landroid/R$styleable;->ActionBar_background:I
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 664f0a3..f6cfe48 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -329,6 +329,9 @@
     /** Returns true if the given uid is the app in the foreground. */
     public abstract boolean isAppForeground(int uid);
 
+    /** Returns true if the given uid is currently marked 'bad' */
+    public abstract boolean isAppBad(ApplicationInfo info);
+
     /** Remove pending backup for the given userId. */
     public abstract void clearPendingBackup(int userId);
 
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 29e6807..15084de 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -193,7 +193,7 @@
 
     void setNotificationDelegate(String callingPkg, String delegate);
     String getNotificationDelegate(String callingPkg);
-    boolean canNotifyAsPackage(String callingPkg, String targetPkg);
+    boolean canNotifyAsPackage(String callingPkg, String targetPkg, int userId);
 
     void setPrivateNotificationsAllowed(boolean allow);
     boolean getPrivateNotificationsAllowed();
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index a8a34d2..23f64b8 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1203,7 +1203,7 @@
 
     /**
      * {@link #extras} key: whether the notification should be colorized as
-     * supplied to {@link Builder#setColorized(boolean)}}.
+     * supplied to {@link Builder#setColorized(boolean)}.
      */
     public static final String EXTRA_COLORIZED = "android.colorized";
 
@@ -1358,7 +1358,7 @@
          *
          * This is intended for {@link RemoteInput}s that only accept data, meaning
          * {@link RemoteInput#getAllowFreeFormInput} is false, {@link RemoteInput#getChoices}
-         * is null or empty, and {@link RemoteInput#getAllowedDataTypes is non-null and not
+         * is null or empty, and {@link RemoteInput#getAllowedDataTypes} is non-null and not
          * empty. These {@link RemoteInput}s will be ignored by devices that do not
          * support non-text-based {@link RemoteInput}s. See {@link Builder#build}.
          *
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 11b40c2..6a301c9 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -627,7 +627,7 @@
     public boolean canNotifyAsPackage(@NonNull String pkg) {
         INotificationManager service = getService();
         try {
-            return service.canNotifyAsPackage(mContext.getPackageName(), pkg);
+            return service.canNotifyAsPackage(mContext.getPackageName(), pkg, mContext.getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 9a4e215..9436145 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -112,6 +112,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.CompletableFuture;
@@ -5171,7 +5172,8 @@
      * </ul>
      * The call will fail if called with the package name of an unsupported VPN app.
      * <p> Enabling lockdown via {@code lockdownEnabled} argument carries the risk that any failure
-     * of the VPN provider could break networking for all apps.
+     * of the VPN provider could break networking for all apps. This method clears any lockdown
+     * whitelist set by {@link #setAlwaysOnVpnPackage(ComponentName, String, boolean, Set)}.
      *
      * @param vpnPackage The package name for an installed VPN app on the device, or {@code null} to
      *        remove an existing always-on VPN configuration.
@@ -5181,11 +5183,11 @@
      * @throws NameNotFoundException if {@code vpnPackage} is not installed.
      * @throws UnsupportedOperationException if {@code vpnPackage} exists but does not support being
      *         set as always-on, or if always-on VPN is not available.
-     * @see #setAlwaysOnVpnPackage(ComponentName, String, boolean, List)
+     * @see #setAlwaysOnVpnPackage(ComponentName, String, boolean, Set)
      */
     public void setAlwaysOnVpnPackage(@NonNull ComponentName admin, @Nullable String vpnPackage,
             boolean lockdownEnabled) throws NameNotFoundException {
-        setAlwaysOnVpnPackage(admin, vpnPackage, lockdownEnabled, Collections.emptyList());
+        setAlwaysOnVpnPackage(admin, vpnPackage, lockdownEnabled, Collections.emptySet());
     }
 
     /**
@@ -5195,6 +5197,11 @@
      * System apps can always bypass VPN.
      * <p> Note that the system doesn't update the whitelist when packages are installed or
      * uninstalled, the admin app must call this method to keep the list up to date.
+     * <p> When {@code lockdownEnabled} is false {@code lockdownWhitelist} is ignored . When
+     * {@code lockdownEnabled} is {@code true} and {@code lockdownWhitelist} is {@code null} or
+     * empty, only system apps can bypass VPN.
+     * <p> Setting always-on VPN package to {@code null} or using
+     * {@link #setAlwaysOnVpnPackage(ComponentName, String, boolean)} clears lockdown whitelist.
      *
      * @param vpnPackage package name for an installed VPN app on the device, or {@code null}
      *         to remove an existing always-on VPN configuration
@@ -5211,13 +5218,13 @@
      *         available.
      */
     public void setAlwaysOnVpnPackage(@NonNull ComponentName admin, @Nullable String vpnPackage,
-            boolean lockdownEnabled, @Nullable List<String> lockdownWhitelist)
+            boolean lockdownEnabled, @Nullable Set<String> lockdownWhitelist)
             throws NameNotFoundException {
         throwIfParentInstance("setAlwaysOnVpnPackage");
         if (mService != null) {
             try {
-                mService.setAlwaysOnVpnPackage(
-                        admin, vpnPackage, lockdownEnabled, lockdownWhitelist);
+                mService.setAlwaysOnVpnPackage(admin, vpnPackage, lockdownEnabled,
+                        lockdownWhitelist == null ? null : new ArrayList<>(lockdownWhitelist));
             } catch (ServiceSpecificException e) {
                 switch (e.errorCode) {
                     case ERROR_VPN_PACKAGE_NOT_FOUND:
@@ -5255,7 +5262,7 @@
     }
 
     /**
-     * Called by device or profile owner to query the list of packages that are allowed to access
+     * Called by device or profile owner to query the set of packages that are allowed to access
      * the network directly when always-on VPN is in lockdown mode but not connected. Returns
      * {@code null} when always-on VPN is not active or not in lockdown mode.
      *
@@ -5263,13 +5270,15 @@
      *
      * @throws SecurityException if {@code admin} is not a device or a profile owner.
      *
-     * @see #setAlwaysOnVpnPackage(ComponentName, String, boolean, List)
+     * @see #setAlwaysOnVpnPackage(ComponentName, String, boolean, Set)
      */
-    public @Nullable List<String> getAlwaysOnVpnLockdownWhitelist(@NonNull ComponentName admin) {
+    public @Nullable Set<String> getAlwaysOnVpnLockdownWhitelist(@NonNull ComponentName admin) {
         throwIfParentInstance("getAlwaysOnVpnLockdownWhitelist");
         if (mService != null) {
             try {
-                return mService.getAlwaysOnVpnLockdownWhitelist(admin);
+                final List<String> whitelist =
+                        mService.getAlwaysOnVpnLockdownWhitelist(admin);
+                return whitelist == null ? null : new HashSet<>(whitelist);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
diff --git a/core/java/android/app/backup/IRestoreSession.aidl b/core/java/android/app/backup/IRestoreSession.aidl
index b9e9485..c3a298b 100644
--- a/core/java/android/app/backup/IRestoreSession.aidl
+++ b/core/java/android/app/backup/IRestoreSession.aidl
@@ -71,8 +71,8 @@
      *   applications mentioned in this list will have their data restored.
      * @param monitor If non null the binder will send important events to this monitor.
      */
-    int restoreSome(long token, IRestoreObserver observer, IBackupManagerMonitor monitor,
-            in String[] packages);
+    int restorePackages(long token, IRestoreObserver observer, in String[] packages,
+            IBackupManagerMonitor monitor);
 
     /**
      * Restore a single application from backup.  The data will be restored from the
diff --git a/core/java/android/app/backup/RestoreSession.java b/core/java/android/app/backup/RestoreSession.java
index 79925ec..084b13b 100644
--- a/core/java/android/app/backup/RestoreSession.java
+++ b/core/java/android/app/backup/RestoreSession.java
@@ -16,6 +16,8 @@
 
 package android.app.backup;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.content.Context;
 import android.os.Bundle;
@@ -24,6 +26,10 @@
 import android.os.RemoteException;
 import android.util.Log;
 
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
 /**
  * Interface for managing a restore session.
  * @hide
@@ -138,14 +144,15 @@
      *   the restore set that should be used.
      * @param observer If non-null, this binder points to an object that will receive
      *   progress callbacks during the restore operation.
-     * @param monitor If non-null, this binder points to an object that will receive
-     *   progress callbacks during the restore operation.
      * @param packages The set of packages for which to attempt a restore.  Regardless of
      *   the contents of the actual back-end dataset named by {@code token}, only
      *   applications mentioned in this list will have their data restored.
+     * @param monitor If non-null, this binder points to an object that will receive
+     *   progress callbacks during the restore operation containing detailed information on any
+     *   failures or important decisions made by {@link BackupManager}.
      */
-    public int restoreSome(long token, RestoreObserver observer, BackupManagerMonitor monitor,
-            String[] packages) {
+    public int restorePackages(long token, @Nullable RestoreObserver observer,
+            @NonNull Set<String> packages, @Nullable BackupManagerMonitor monitor) {
         int err = -1;
         if (mObserver != null) {
             Log.d(TAG, "restoreAll() called during active restore");
@@ -156,7 +163,8 @@
                 ? null
                 : new BackupManagerMonitorWrapper(monitor);
         try {
-            err = mBinder.restoreSome(token, mObserver, monitorWrapper, packages);
+            err = mBinder.restorePackages(token, mObserver, packages.toArray(new String[] {}),
+                    monitorWrapper);
         } catch (RemoteException e) {
             Log.d(TAG, "Can't contact server to restore packages");
         }
@@ -180,6 +188,60 @@
      *   the contents of the actual back-end dataset named by {@code token}, only
      *   applications mentioned in this list will have their data restored.
      */
+    public int restorePackages(long token, @Nullable RestoreObserver observer,
+            @NonNull Set<String> packages) {
+        return restorePackages(token, observer, packages, null);
+    }
+
+    /**
+     * Restore select packages from the given set onto the device, replacing the
+     * current data of any app contained in the set with the data previously
+     * backed up.
+     *
+     * <p>Callers must hold the android.permission.BACKUP permission to use this method.
+     *
+     * @return Zero on success, nonzero on error. The observer will only receive
+     *   progress callbacks if this method returned zero.
+     * @param token The token from {@link getAvailableRestoreSets()} corresponding to
+     *   the restore set that should be used.
+     * @param observer If non-null, this binder points to an object that will receive
+     *   progress callbacks during the restore operation.
+     * @param monitor If non-null, this binder points to an object that will receive
+     *   progress callbacks during the restore operation.
+     * @param packages The set of packages for which to attempt a restore.  Regardless of
+     *   the contents of the actual back-end dataset named by {@code token}, only
+     *   applications mentioned in this list will have their data restored.
+     *
+     * @deprecated use {@link RestoreSession#restorePackages(long, RestoreObserver,
+     *   BackupManagerMonitor, Set)} instead.
+     */
+    @Deprecated
+    public int restoreSome(long token, RestoreObserver observer, BackupManagerMonitor monitor,
+            String[] packages) {
+        return restorePackages(token, observer, new HashSet<>(Arrays.asList(packages)), monitor);
+    }
+
+    /**
+     * Restore select packages from the given set onto the device, replacing the
+     * current data of any app contained in the set with the data previously
+     * backed up.
+     *
+     * <p>Callers must hold the android.permission.BACKUP permission to use this method.
+     *
+     * @return Zero on success, nonzero on error. The observer will only receive
+     *   progress callbacks if this method returned zero.
+     * @param token The token from {@link getAvailableRestoreSets()} corresponding to
+     *   the restore set that should be used.
+     * @param observer If non-null, this binder points to an object that will receive
+     *   progress callbacks during the restore operation.
+     * @param packages The set of packages for which to attempt a restore.  Regardless of
+     *   the contents of the actual back-end dataset named by {@code token}, only
+     *   applications mentioned in this list will have their data restored.
+     *
+     * @deprecated use {@link RestoreSession#restorePackages(long, RestoreObserver, Set)}
+     *   instead.
+     */
+    @Deprecated
     public int restoreSome(long token, RestoreObserver observer, String[] packages) {
         return restoreSome(token, observer, null, packages);
     }
diff --git a/core/java/android/bluetooth/BluetoothHearingAid.java b/core/java/android/bluetooth/BluetoothHearingAid.java
index b4eaab2..d6edb90 100644
--- a/core/java/android/bluetooth/BluetoothHearingAid.java
+++ b/core/java/android/bluetooth/BluetoothHearingAid.java
@@ -22,7 +22,6 @@
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -92,7 +91,6 @@
      * @hide
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    @UnsupportedAppUsage
     public static final String ACTION_ACTIVE_DEVICE_CHANGED =
             "android.bluetooth.hearingaid.profile.action.ACTIVE_DEVICE_CHANGED";
 
@@ -324,7 +322,8 @@
     /**
      * {@inheritDoc}
      */
-    @Override public @NonNull List<BluetoothDevice> getDevicesMatchingConnectionStates(
+    @Override
+    public @NonNull List<BluetoothDevice> getDevicesMatchingConnectionStates(
     @NonNull int[] states) {
         if (VDBG) log("getDevicesMatchingStates()");
         try {
@@ -346,7 +345,8 @@
      * {@inheritDoc}
      */
     @Override
-    public int getConnectionState(@NonNull BluetoothDevice device) {
+    public @BluetoothProfile.BtProfileState int getConnectionState(
+    @NonNull BluetoothDevice device) {
         if (VDBG) log("getState(" + device + ")");
         try {
             mServiceLock.readLock().lock();
@@ -386,7 +386,6 @@
      * @return false on immediate error, true otherwise
      * @hide
      */
-    @UnsupportedAppUsage
     public boolean setActiveDevice(@Nullable BluetoothDevice device) {
         if (DBG) log("setActiveDevice(" + device + ")");
         try {
@@ -418,7 +417,6 @@
      * @hide
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH)
-    @UnsupportedAppUsage
     public List<BluetoothDevice> getActiveDevices() {
         if (VDBG) log("getActiveDevices()");
         try {
diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java
index ef77596..dabe0fd 100644
--- a/core/java/android/bluetooth/BluetoothProfile.java
+++ b/core/java/android/bluetooth/BluetoothProfile.java
@@ -276,7 +276,7 @@
      * #STATE_CONNECTING}, {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING}
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH)
-    public int getConnectionState(BluetoothDevice device);
+    @BtProfileState int getConnectionState(BluetoothDevice device);
 
     /**
      * An interface for notifying BluetoothProfile IPC clients when they have
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index efb3bfc1..bb1501f 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -338,6 +338,16 @@
     public static final int BIND_ADJUST_BELOW_PERCEPTIBLE = 0x0100;
 
     /**
+     * Flag for {@link #bindService}: This flag is intended to be used only by the system to adjust
+     * the scheduling policy for IMEs (and any other out-of-process user-visible components that
+     * work closely with the top app) so that UI hosted in such services can have the same
+     * scheduling policy (e.g. SCHED_FIFO when it is enabled and TOP_APP_PRIORITY_BOOST otherwise)
+     * as the actual top-app.
+     * @hide
+     */
+    public static final int BIND_SCHEDULE_LIKE_TOP_APP = 0x00080000;
+
+    /**
      * Flag for {@link #bindService}: allow background activity starts from the bound service's
      * process.
      * This flag is only respected if the caller is holding
@@ -4006,6 +4016,16 @@
 
     /**
      * Use with {@link #getSystemService(String)} to retrieve a
+     * {@link com.android.server.attention.AttentionManagerService} for attention services.
+     *
+     * @see #getSystemService(String)
+     * @see android.server.attention.AttentionManagerService
+     * @hide
+     */
+    public static final String ATTENTION_SERVICE = "attention";
+
+    /**
+     * Use with {@link #getSystemService(String)} to retrieve a
      * {@link android.view.inputmethod.InputMethodManager} for accessing input
      * methods.
      *
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 2a19763..954deac 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -142,17 +142,6 @@
     public static final String EXTRA_PIN_ITEM_REQUEST =
             "android.content.pm.extra.PIN_ITEM_REQUEST";
 
-    /**
-     * Metadata key that specifies vouched certs, so any apps signed by a cert in vouched certs
-     * will not show hidden icon in launcher even it does not have a launcher visible activity.
-     *
-     * If an app has this metadata in manifest, it won't be eligible to hide its icon even if its
-     * cert is in vouched certs list.
-     *
-     * @hide
-     */
-    public static final String VOUCHED_CERTS_KEY = "vouched_certs";
-
     private final Context mContext;
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     private final ILauncherApps mService;
diff --git a/core/java/android/hardware/biometrics/BiometricFaceConstants.java b/core/java/android/hardware/biometrics/BiometricFaceConstants.java
index 6ea35f0..bae0fd3 100644
--- a/core/java/android/hardware/biometrics/BiometricFaceConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricFaceConstants.java
@@ -315,7 +315,7 @@
     /**
      * The sensor is dirty. The user should be informed to clean the sensor.
      */
-    public static final int SENSOR_DIRTY = 21;
+    public static final int FACE_ACQUIRED_SENSOR_DIRTY = 21;
 
     /**
      * Hardware vendors may extend this list if there are conditions that do not fall under one of
diff --git a/core/java/android/hardware/biometrics/BiometricPrompt.java b/core/java/android/hardware/biometrics/BiometricPrompt.java
index e751b2c..08035972 100644
--- a/core/java/android/hardware/biometrics/BiometricPrompt.java
+++ b/core/java/android/hardware/biometrics/BiometricPrompt.java
@@ -523,6 +523,11 @@
      * cancelled notification through {@link AuthenticationCallback#onAuthenticationError(int,
      * CharSequence)}.
      *
+     * Note: Applications generally should not cancel and start authentication in quick succession.
+     * For example, to properly handle authentication across configuration changes, it's recommended
+     * to use BiometricPrompt in a fragment with setRetainInstance(true). By doing so, the
+     * application will not need to cancel/restart authentication during the configuration change.
+     *
      * @throws IllegalArgumentException If any of the arguments are null
      *
      * @param crypto Object associated with the call
@@ -568,6 +573,11 @@
      * authentication. The interrupted client will receive a cancelled notification through {@link
      * AuthenticationCallback#onAuthenticationError(int, CharSequence)}.
      *
+     * Note: Applications generally should not cancel and start authentication in quick succession.
+     * For example, to properly handle authentication across configuration changes, it's recommended
+     * to use BiometricPrompt in a fragment with setRetainInstance(true). By doing so, the
+     * application will not need to cancel/restart authentication during the configuration change.
+     *
      * @throws IllegalArgumentException If any of the arguments are null
      *
      * @param cancel An object that can be used to cancel authentication
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 7ae673c..c39796b 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -336,6 +336,7 @@
      * <li>{@link RecommendedStreamConfigurationMap#USECASE_SNAPSHOT}</li>
      * <li>{@link RecommendedStreamConfigurationMap#USECASE_RAW}</li>
      * <li>{@link RecommendedStreamConfigurationMap#USECASE_ZSL}</li>
+     * <li>{@link RecommendedStreamConfigurationMap#USECASE_LOW_LATENCY_SNAPSHOT}</li>
      * </ul>
      * </p>
      *
@@ -400,7 +401,7 @@
     public @Nullable RecommendedStreamConfigurationMap getRecommendedStreamConfigurationMap(
             @RecommendedStreamConfigurationMap.RecommendedUsecase int usecase) {
         if (((usecase >= RecommendedStreamConfigurationMap.USECASE_PREVIEW) &&
-                (usecase <= RecommendedStreamConfigurationMap.USECASE_RAW)) ||
+                (usecase <= RecommendedStreamConfigurationMap.USECASE_LOW_LATENCY_SNAPSHOT)) ||
                 ((usecase >= RecommendedStreamConfigurationMap.USECASE_VENDOR_START) &&
                 (usecase < RecommendedStreamConfigurationMap.MAX_USECASE_COUNT))) {
             if (mRecommendedConfigurations == null) {
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index 1cdf235..e909c00 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -1113,8 +1113,10 @@
                         depthStreamDurationList.get(i), depthStreamStallList.get(i), depthScData);
             }
 
-            if ((scData.streamConfigurationArray == null) &&
-                    (depthScData.streamConfigurationArray == null)) {
+            if ((scData.streamConfigurationArray == null ||
+                    scData.streamConfigurationArray.length == 0) &&
+                    (depthScData.streamConfigurationArray == null ||
+                     depthScData.streamConfigurationArray.length == 0)) {
                 recommendedConfigurations.add(null);
                 continue;
             }
@@ -1125,6 +1127,7 @@
             switch (i) {
                 case RecommendedStreamConfigurationMap.USECASE_PREVIEW:
                 case RecommendedStreamConfigurationMap.USECASE_RAW:
+                case RecommendedStreamConfigurationMap.USECASE_LOW_LATENCY_SNAPSHOT:
                 case RecommendedStreamConfigurationMap.USECASE_VIDEO_SNAPSHOT:
                     map = new StreamConfigurationMap(scData.streamConfigurationArray,
                             scData.minDurationArray, scData.stallDurationArray,
diff --git a/core/java/android/hardware/camera2/params/RecommendedStreamConfigurationMap.java b/core/java/android/hardware/camera2/params/RecommendedStreamConfigurationMap.java
index 068c0ce..2d72598 100644
--- a/core/java/android/hardware/camera2/params/RecommendedStreamConfigurationMap.java
+++ b/core/java/android/hardware/camera2/params/RecommendedStreamConfigurationMap.java
@@ -21,6 +21,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.graphics.ImageFormat;
+import android.graphics.ImageFormat.Format;
 import android.graphics.PixelFormat;
 import android.hardware.camera2.CameraCharacteristics;
 import android.hardware.camera2.CameraDevice;
@@ -137,6 +138,17 @@
     public static final int USECASE_RAW = 0x5;
 
     /**
+     * The recommended stream configuration map for use case low latency snapshot must contain
+     * subset of configurations with end-to-end latency that does not exceed 200 ms. under standard
+     * operating conditions (reasonable light levels, not loaded system). The expected output format
+     * will be primarily {@link android.graphics.ImageFormat#JPEG} however other image formats can
+     * be present as well.  Even if available for the camera device, high speed and input
+     * configurations will be absent. This suggested configuration map may be absent on some devices
+     * that can not support any low latency requests.
+     */
+    public static final int USECASE_LOW_LATENCY_SNAPSHOT = 0x6;
+
+    /**
      * Device specific use cases.
      * @hide
      */
@@ -150,7 +162,8 @@
         USECASE_VIDEO_SNAPSHOT,
         USECASE_SNAPSHOT,
         USECASE_ZSL,
-        USECASE_RAW })
+        USECASE_RAW,
+        USECASE_LOW_LATENCY_SNAPSHOT})
      public @interface RecommendedUsecase {};
 
     /**
@@ -214,7 +227,7 @@
      *
      * @return a non-modifiable set of Integer formats
      */
-    public @Nullable Set<Integer> getValidOutputFormatsForInput(int inputFormat) {
+    public @Nullable Set<Integer> getValidOutputFormatsForInput(@Format int inputFormat) {
         return getUnmodifiableIntegerSet(mRecommendedMap.getValidOutputFormatsForInput(
                     inputFormat));
     }
@@ -250,7 +263,7 @@
      * @param format a format from {@link #getInputFormats}
      * @return a non-modifiable set of sizes, or {@code null} if the format was not available.
      */
-    public @Nullable Set<Size> getInputSizes(int format) {
+    public @Nullable Set<Size> getInputSizes(@Format int format) {
         return getUnmodifiableSizeSet(mRecommendedMap.getInputSizes(format));
     }
 
@@ -272,7 +285,7 @@
      *          if the image format was not a defined named constant
      *          from either {@link ImageFormat} or {@link PixelFormat}
      */
-    public boolean isOutputSupportedFor(int format) {
+    public boolean isOutputSupportedFor(@Format int format) {
         return mRecommendedMap.isOutputSupportedFor(format);
     }
 
@@ -288,7 +301,7 @@
      * @return  a non-modifiable set of supported sizes,
      *          or {@code null} if the {@code format} is not a supported output
      */
-    public @Nullable Set<Size> getOutputSizes(int format) {
+    public @Nullable Set<Size> getOutputSizes(@Format int format) {
         return getUnmodifiableSizeSet(mRecommendedMap.getOutputSizes(format));
     }
 
@@ -372,7 +385,7 @@
      * @return a non-modifiable set of supported slower high-resolution sizes, or {@code null} if
      *         the BURST_CAPTURE capability is not supported
      */
-    public @Nullable Set<Size> getHighResolutionOutputSizes(int format) {
+    public @Nullable Set<Size> getHighResolutionOutputSizes(@Format int format) {
         return getUnmodifiableSizeSet(mRecommendedMap.getHighResolutionOutputSizes(format));
     }
 
@@ -392,7 +405,8 @@
      *
      * @throws IllegalArgumentException if {@code format} or {@code size} was not supported
      */
-    public @IntRange(from = 0) long getOutputMinFrameDuration(int format, @NonNull Size size) {
+    public @IntRange(from = 0) long getOutputMinFrameDuration(@Format int format,
+            @NonNull Size size) {
         return mRecommendedMap.getOutputMinFrameDuration(format, size);
     }
 
@@ -409,7 +423,7 @@
      *
      * @throws IllegalArgumentException if {@code format} or {@code size} was not supported
      */
-    public @IntRange(from = 0) long getOutputStallDuration(int format, @NonNull Size size) {
+    public @IntRange(from = 0) long getOutputStallDuration(@Format int format, @NonNull Size size) {
         return mRecommendedMap.getOutputStallDuration(format, size);
     }
 
@@ -425,7 +439,7 @@
      *          a non-modifiable set of supported sizes for {@link ImageFormat#PRIVATE} format,
      *          or {@code null} if the {@code klass} is not a supported output.
      */
-    public <T> @Nullable Set<Size> getOutputSizes(@NonNull Class<T> klass) {
+    public @Nullable <T> Set<Size> getOutputSizes(@NonNull Class<T> klass) {
         if (mSupportsPrivate) {
             return getUnmodifiableSizeSet(mRecommendedMap.getOutputSizes(klass));
         }
@@ -448,7 +462,7 @@
      *
      * @throws IllegalArgumentException if {@code klass} or {@code size} was not supported
      */
-    public <T> @IntRange(from = 0) long getOutputMinFrameDuration(@NonNull final Class<T> klass,
+    public @IntRange(from = 0) <T> long getOutputMinFrameDuration(@NonNull final Class<T> klass,
             @NonNull final Size size) {
         if (mSupportsPrivate) {
             return mRecommendedMap.getOutputMinFrameDuration(klass, size);
@@ -471,7 +485,7 @@
      *
      * @throws IllegalArgumentException if {@code klass} or {@code size} was not supported
      */
-    public <T> @IntRange(from = 0) long getOutputStallDuration(@NonNull final Class<T> klass,
+    public @IntRange(from = 0) <T> long getOutputStallDuration(@NonNull final Class<T> klass,
             @NonNull final Size size) {
         if (mSupportsPrivate) {
             return mRecommendedMap.getOutputStallDuration(klass, size);
diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index 139a5ee..3e8c334 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -634,6 +634,8 @@
                 return context.getString(R.string.face_acquired_obscured);
             case FACE_ACQUIRED_START:
                 return null;
+            case FACE_ACQUIRED_SENSOR_DIRTY:
+                return context.getString(R.string.face_acquired_sensor_dirty);
             case FACE_ACQUIRED_VENDOR: {
                 String[] msgArray = context.getResources().getStringArray(
                         R.array.face_acquired_vendor);
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index d08379fa..e5802c2 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -2816,23 +2816,6 @@
     }
 
     /**
-     * @removed
-     * @deprecated This API would be removed when all of caller has been updated.
-     * */
-    @Deprecated
-    public abstract static class TetheringEntitlementValueListener  {
-        /**
-         * Called to notify entitlement result.
-         *
-         * @param resultCode a int value of entitlement result. It may be one of
-         *         {@link #TETHER_ERROR_NO_ERROR},
-         *         {@link #TETHER_ERROR_PROVISION_FAILED}, or
-         *         {@link #TETHER_ERROR_ENTITLEMENT_UNKONWN}.
-         */
-        public void onEntitlementResult(int resultCode) {}
-    }
-
-    /**
      * Get the last value of the entitlement check on this downstream. If the cached value is
      * {@link #TETHER_ERROR_NO_ERROR} or showEntitlementUi argument is false, it just return the
      * cached value. Otherwise, a UI-based entitlement check would be performed. It is not
@@ -2878,31 +2861,6 @@
     }
 
     /**
-     * @removed
-     * @deprecated This API would be removed when all of caller has been updated.
-     * */
-    @Deprecated
-    public void getLatestTetheringEntitlementValue(int type, boolean showEntitlementUi,
-            @NonNull final TetheringEntitlementValueListener listener, @Nullable Handler handler) {
-        Preconditions.checkNotNull(listener, "TetheringEntitlementValueListener cannot be null.");
-        ResultReceiver wrappedListener = new ResultReceiver(handler) {
-            @Override
-            protected void onReceiveResult(int resultCode, Bundle resultData) {
-                listener.onEntitlementResult(resultCode);
-            }
-        };
-
-        try {
-            String pkgName = mContext.getOpPackageName();
-            Log.i(TAG, "getLatestTetheringEntitlementValue:" + pkgName);
-            mService.getLatestTetheringEntitlementResult(type, wrappedListener,
-                    showEntitlementUi, pkgName);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
      * Report network connectivity status.  This is currently used only
      * to alter status bar UI.
      * <p>This method requires the caller to hold the permission
diff --git a/core/java/android/net/INetworkStackConnector.aidl b/core/java/android/net/INetworkStackConnector.aidl
index e052488..edb9df61 100644
--- a/core/java/android/net/INetworkStackConnector.aidl
+++ b/core/java/android/net/INetworkStackConnector.aidl
@@ -16,7 +16,7 @@
 package android.net;
 
 import android.net.INetworkMonitorCallbacks;
-import android.net.NetworkParcelable;
+import android.net.Network;
 import android.net.dhcp.DhcpServingParamsParcel;
 import android.net.dhcp.IDhcpServerCallbacks;
 import android.net.ip.IIpClientCallbacks;
@@ -25,7 +25,6 @@
 oneway interface INetworkStackConnector {
     void makeDhcpServer(in String ifName, in DhcpServingParamsParcel params,
         in IDhcpServerCallbacks cb);
-    void makeNetworkMonitor(in NetworkParcelable network, String name,
-        in INetworkMonitorCallbacks cb);
+    void makeNetworkMonitor(in Network network, String name, in INetworkMonitorCallbacks cb);
     void makeIpClient(in String ifName, in IIpClientCallbacks callbacks);
 }
\ No newline at end of file
diff --git a/core/java/android/net/InitialConfigurationParcelable.aidl b/core/java/android/net/InitialConfigurationParcelable.aidl
index bdda3559..3fa88c3 100644
--- a/core/java/android/net/InitialConfigurationParcelable.aidl
+++ b/core/java/android/net/InitialConfigurationParcelable.aidl
@@ -16,12 +16,12 @@
 
 package android.net;
 
-import android.net.IpPrefixParcelable;
-import android.net.LinkAddressParcelable;
+import android.net.IpPrefix;
+import android.net.LinkAddress;
 
 parcelable InitialConfigurationParcelable {
-    LinkAddressParcelable[] ipAddresses;
-    IpPrefixParcelable[] directlyConnectedRoutes;
+    LinkAddress[] ipAddresses;
+    IpPrefix[] directlyConnectedRoutes;
     String[] dnsServers;
     String gateway;
 }
\ No newline at end of file
diff --git a/core/java/android/net/IpPrefix.aidl b/core/java/android/net/IpPrefix.aidl
index 837db5f..0d70f2a 100644
--- a/core/java/android/net/IpPrefix.aidl
+++ b/core/java/android/net/IpPrefix.aidl
@@ -17,4 +17,6 @@
 
 package android.net;
 
-parcelable IpPrefix cpp_header "binder/IpPrefix.h";
+// @JavaOnlyStableParcelable only affects the parcelable when built as stable aidl (aidl_interface
+// build rule). IpPrefix is also used in cpp but only as non-stable aidl.
+@JavaOnlyStableParcelable parcelable IpPrefix cpp_header "binder/IpPrefix.h";
diff --git a/core/java/android/net/IpPrefixParcelable.aidl b/core/java/android/net/IpPrefixParcelable.aidl
deleted file mode 100644
index 93a8d41..0000000
--- a/core/java/android/net/IpPrefixParcelable.aidl
+++ /dev/null
@@ -1,22 +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.
-*/
-
-package android.net;
-
-parcelable IpPrefixParcelable {
-    String address;
-    int prefixLength;
-}
\ No newline at end of file
diff --git a/core/java/android/net/LinkAddress.aidl b/core/java/android/net/LinkAddress.aidl
index e7d8646..9c804db 100644
--- a/core/java/android/net/LinkAddress.aidl
+++ b/core/java/android/net/LinkAddress.aidl
@@ -17,5 +17,5 @@
 
 package android.net;
 
-parcelable LinkAddress;
+@JavaOnlyStableParcelable parcelable LinkAddress;
 
diff --git a/core/java/android/net/LinkAddressParcelable.aidl b/core/java/android/net/LinkAddressParcelable.aidl
deleted file mode 100644
index af8e79b..0000000
--- a/core/java/android/net/LinkAddressParcelable.aidl
+++ /dev/null
@@ -1,24 +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.
-*/
-
-package android.net;
-
-parcelable LinkAddressParcelable {
-    String address;
-    int prefixLength;
-    int flags;
-    int scope;
-}
\ No newline at end of file
diff --git a/core/java/android/net/LinkProperties.aidl b/core/java/android/net/LinkProperties.aidl
index 3cb9525..a8b3c7b 100644
--- a/core/java/android/net/LinkProperties.aidl
+++ b/core/java/android/net/LinkProperties.aidl
@@ -17,4 +17,4 @@
 
 package android.net;
 
-parcelable LinkProperties;
+@JavaOnlyStableParcelable parcelable LinkProperties;
diff --git a/core/java/android/net/LinkPropertiesParcelable.aidl b/core/java/android/net/LinkPropertiesParcelable.aidl
deleted file mode 100644
index 6b52239..0000000
--- a/core/java/android/net/LinkPropertiesParcelable.aidl
+++ /dev/null
@@ -1,38 +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.
-*/
-
-package android.net;
-
-import android.net.IpPrefixParcelable;
-import android.net.LinkAddressParcelable;
-import android.net.ProxyInfoParcelable;
-import android.net.RouteInfoParcelable;
-
-parcelable LinkPropertiesParcelable {
-    String ifaceName;
-    LinkAddressParcelable[] linkAddresses;
-    String[] dnses;
-    String[] pcscfs;
-    String[] validatedPrivateDnses;
-    boolean usePrivateDns;
-    String privateDnsServerName;
-    String domains;
-    RouteInfoParcelable[] routes;
-    ProxyInfoParcelable httpProxy;
-    int mtu;
-    String tcpBufferSizes;
-    IpPrefixParcelable nat64Prefix;
-}
\ No newline at end of file
diff --git a/core/java/android/net/Network.aidl b/core/java/android/net/Network.aidl
index 73ba1af..05622025b 100644
--- a/core/java/android/net/Network.aidl
+++ b/core/java/android/net/Network.aidl
@@ -17,4 +17,4 @@
 
 package android.net;
 
-parcelable Network;
+@JavaOnlyStableParcelable parcelable Network;
diff --git a/core/java/android/net/NetworkParcelable.aidl b/core/java/android/net/NetworkParcelable.aidl
deleted file mode 100644
index c26352e..0000000
--- a/core/java/android/net/NetworkParcelable.aidl
+++ /dev/null
@@ -1,22 +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.
-*/
-
-package android.net;
-
-parcelable NetworkParcelable {
-    long networkHandle;
-}
diff --git a/core/java/android/net/ProvisioningConfigurationParcelable.aidl b/core/java/android/net/ProvisioningConfigurationParcelable.aidl
index 2a144f2..5b46d7f 100644
--- a/core/java/android/net/ProvisioningConfigurationParcelable.aidl
+++ b/core/java/android/net/ProvisioningConfigurationParcelable.aidl
@@ -19,7 +19,7 @@
 
 import android.net.ApfCapabilitiesParcelable;
 import android.net.InitialConfigurationParcelable;
-import android.net.NetworkParcelable;
+import android.net.Network;
 import android.net.StaticIpConfigurationParcelable;
 
 parcelable ProvisioningConfigurationParcelable {
@@ -33,6 +33,6 @@
     ApfCapabilitiesParcelable apfCapabilities;
     int provisioningTimeoutMs;
     int ipv6AddrGenMode;
-    NetworkParcelable network;
+    Network network;
     String displayName;
 }
diff --git a/core/java/android/net/ProxyInfo.aidl b/core/java/android/net/ProxyInfo.aidl
index 2c91960..a5d0c12 100644
--- a/core/java/android/net/ProxyInfo.aidl
+++ b/core/java/android/net/ProxyInfo.aidl
@@ -17,5 +17,5 @@
 
 package android.net;
 
-parcelable ProxyInfo;
+@JavaOnlyStableParcelable parcelable ProxyInfo;
 
diff --git a/core/java/android/net/ProxyInfoParcelable.aidl b/core/java/android/net/ProxyInfoParcelable.aidl
deleted file mode 100644
index 59fd846..0000000
--- a/core/java/android/net/ProxyInfoParcelable.aidl
+++ /dev/null
@@ -1,24 +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.
-*/
-
-package android.net;
-
-parcelable ProxyInfoParcelable {
-    String host;
-    int port;
-    String[] exclusionList;
-    String pacFileUrl;
-}
diff --git a/core/java/android/net/RouteInfo.aidl b/core/java/android/net/RouteInfo.aidl
index 2296a57..7af9fda 100644
--- a/core/java/android/net/RouteInfo.aidl
+++ b/core/java/android/net/RouteInfo.aidl
@@ -16,4 +16,4 @@
 
 package android.net;
 
-parcelable RouteInfo;
+@JavaOnlyStableParcelable parcelable RouteInfo;
diff --git a/core/java/android/net/RouteInfoParcelable.aidl b/core/java/android/net/RouteInfoParcelable.aidl
deleted file mode 100644
index 15bcdcf..0000000
--- a/core/java/android/net/RouteInfoParcelable.aidl
+++ /dev/null
@@ -1,26 +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.
-*/
-
-package android.net;
-
-import android.net.IpPrefixParcelable;
-
-parcelable RouteInfoParcelable {
-    IpPrefixParcelable destination;
-    String gatewayAddr;
-    String ifaceName;
-    int type;
-}
diff --git a/core/java/android/net/StaticIpConfigurationParcelable.aidl b/core/java/android/net/StaticIpConfigurationParcelable.aidl
index 45dc021..6fffb42 100644
--- a/core/java/android/net/StaticIpConfigurationParcelable.aidl
+++ b/core/java/android/net/StaticIpConfigurationParcelable.aidl
@@ -17,10 +17,10 @@
 
 package android.net;
 
-import android.net.LinkAddressParcelable;
+import android.net.LinkAddress;
 
 parcelable StaticIpConfigurationParcelable {
-    LinkAddressParcelable ipAddress;
+    LinkAddress ipAddress;
     String gateway;
     String[] dnsServers;
     String domains;
diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java
index 870d8b1..ea245a4 100644
--- a/core/java/android/net/VpnService.java
+++ b/core/java/android/net/VpnService.java
@@ -27,6 +27,8 @@
 import android.app.Activity;
 import android.app.PendingIntent;
 import android.app.Service;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.IPackageManager;
@@ -48,6 +50,7 @@
 import java.net.Socket;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
 
 /**
  * VpnService is a base class for applications to extend and build their
@@ -138,7 +141,7 @@
      * provides users with the ability to set it as always-on, so that VPN connection is
      * persisted after device reboot and app upgrade. Always-on VPN can also be enabled by device
      * owner and profile owner apps through
-     * {@link android.app.admin.DevicePolicyManager#setAlwaysOnVpnPackage}.
+     * {@link DevicePolicyManager#setAlwaysOnVpnPackage}.
      *
      * <p>VPN apps not supporting this feature should opt out by adding this meta-data field to the
      * {@code VpnService} component of {@code AndroidManifest.xml}. In case there is more than one
@@ -370,7 +373,10 @@
     }
 
     /**
-     * Returns whether the service is running in always-on VPN mode.
+     * Returns whether the service is running in always-on VPN mode. In this mode the system ensures
+     * that the service is always running by restarting it when necessary, e.g. after reboot.
+     *
+     * @see DevicePolicyManager#setAlwaysOnVpnPackage(ComponentName, String, boolean, Set)
      */
     public final boolean isAlwaysOn() {
         try {
@@ -381,8 +387,11 @@
     }
 
     /**
-     * Returns whether the service is running in always-on VPN mode blocking connections without
-     * VPN.
+     * Returns whether the service is running in always-on VPN lockdown mode. In this mode the
+     * system ensures that the service is always running and that the apps aren't allowed to bypass
+     * the VPN.
+     *
+     * @see DevicePolicyManager#setAlwaysOnVpnPackage(ComponentName, String, boolean, Set)
      */
     public final boolean isLockdownEnabled() {
         try {
diff --git a/core/java/android/net/ip/IIpClient.aidl b/core/java/android/net/ip/IIpClient.aidl
index a4a80e1..b834e45 100644
--- a/core/java/android/net/ip/IIpClient.aidl
+++ b/core/java/android/net/ip/IIpClient.aidl
@@ -15,7 +15,7 @@
  */
 package android.net.ip;
 
-import android.net.ProxyInfoParcelable;
+import android.net.ProxyInfo;
 import android.net.ProvisioningConfigurationParcelable;
 import android.net.TcpKeepalivePacketDataParcelable;
 
@@ -28,7 +28,7 @@
     void startProvisioning(in ProvisioningConfigurationParcelable req);
     void stop();
     void setTcpBufferSizes(in String tcpBufferSizes);
-    void setHttpProxy(in ProxyInfoParcelable proxyInfo);
+    void setHttpProxy(in ProxyInfo proxyInfo);
     void setMulticastFilter(boolean enabled);
     void addKeepalivePacketFilter(int slot, in TcpKeepalivePacketDataParcelable pkt);
     void removeKeepalivePacketFilter(int slot);
diff --git a/core/java/android/net/ip/IIpClientCallbacks.aidl b/core/java/android/net/ip/IIpClientCallbacks.aidl
index f077e3b..3681416 100644
--- a/core/java/android/net/ip/IIpClientCallbacks.aidl
+++ b/core/java/android/net/ip/IIpClientCallbacks.aidl
@@ -15,7 +15,7 @@
  */
 package android.net.ip;
 
-import android.net.LinkPropertiesParcelable;
+import android.net.LinkProperties;
 import android.net.ip.IIpClient;
 import android.net.DhcpResultsParcelable;
 
@@ -34,11 +34,11 @@
     // null or not.
     void onNewDhcpResults(in DhcpResultsParcelable dhcpResults);
 
-    void onProvisioningSuccess(in LinkPropertiesParcelable newLp);
-    void onProvisioningFailure(in LinkPropertiesParcelable newLp);
+    void onProvisioningSuccess(in LinkProperties newLp);
+    void onProvisioningFailure(in LinkProperties newLp);
 
     // Invoked on LinkProperties changes.
-    void onLinkPropertiesChange(in LinkPropertiesParcelable newLp);
+    void onLinkPropertiesChange(in LinkProperties newLp);
 
     // Called when the internal IpReachabilityMonitor (if enabled) has
     // detected the loss of a critical number of required neighbors.
diff --git a/core/java/android/os/AsyncResult.java b/core/java/android/os/AsyncResult.java
index 5bad09d..58a2701 100644
--- a/core/java/android/os/AsyncResult.java
+++ b/core/java/android/os/AsyncResult.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.Message;
 
 /** @hide */
@@ -25,13 +26,17 @@
     /*************************** Instance Variables **************************/
 
     // Expect either exception or result to be null
+    @UnsupportedAppUsage
     public Object userObj;
+    @UnsupportedAppUsage
     public Throwable exception;
+    @UnsupportedAppUsage
     public Object result;
 
     /***************************** Class Methods *****************************/
 
     /** Saves and sets m.obj */
+    @UnsupportedAppUsage
     public static AsyncResult 
     forMessage(Message m, Object r, Throwable ex)
     {
@@ -45,6 +50,7 @@
     }
 
     /** Saves and sets m.obj */
+    @UnsupportedAppUsage
     public static AsyncResult 
     forMessage(Message m)
     {
@@ -58,6 +64,7 @@
     }
 
     /** please note, this sets m.obj to be this */
+    @UnsupportedAppUsage
     public 
     AsyncResult (Object uo, Object r, Throwable ex)
     {
diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java
index a851e04..d259f38 100644
--- a/core/java/android/os/AsyncTask.java
+++ b/core/java/android/os/AsyncTask.java
@@ -18,6 +18,7 @@
 
 import android.annotation.MainThread;
 import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
 import android.annotation.WorkerThread;
 
 import java.util.ArrayDeque;
@@ -259,15 +260,20 @@
     private static final int MESSAGE_POST_RESULT = 0x1;
     private static final int MESSAGE_POST_PROGRESS = 0x2;
 
+    @UnsupportedAppUsage
     private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
     private static InternalHandler sHandler;
 
+    @UnsupportedAppUsage
     private final WorkerRunnable<Params, Result> mWorker;
+    @UnsupportedAppUsage
     private final FutureTask<Result> mFuture;
 
+    @UnsupportedAppUsage
     private volatile Status mStatus = Status.PENDING;
     
     private final AtomicBoolean mCancelled = new AtomicBoolean();
+    @UnsupportedAppUsage
     private final AtomicBoolean mTaskInvoked = new AtomicBoolean();
 
     private final Handler mHandler;
@@ -331,6 +337,7 @@
     }
 
     /** @hide */
+    @UnsupportedAppUsage
     public static void setDefaultExecutor(Executor exec) {
         sDefaultExecutor = exec;
     }
diff --git a/core/java/android/os/BaseBundle.java b/core/java/android/os/BaseBundle.java
index 3d4c00c..7f63f8f 100644
--- a/core/java/android/os/BaseBundle.java
+++ b/core/java/android/os/BaseBundle.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.MathUtils;
@@ -82,6 +83,7 @@
     // Invariant - exactly one of mMap / mParcelledData will be null
     // (except inside a call to unparcel)
 
+    @UnsupportedAppUsage
     ArrayMap<String, Object> mMap = null;
 
     /*
@@ -89,6 +91,7 @@
      * data are stored as a Parcel containing a Bundle.  When the data
      * are unparcelled, mParcelledData willbe set to null.
      */
+    @UnsupportedAppUsage
     Parcel mParcelledData = null;
 
     /**
@@ -225,6 +228,7 @@
      * If the underlying data are stored as a Parcel, unparcel them
      * using the currently assigned class loader.
      */
+    @UnsupportedAppUsage
     /* package */ void unparcel() {
         synchronized (this) {
             final Parcel source = mParcelledData;
@@ -311,6 +315,7 @@
     /**
      * @hide
      */
+    @UnsupportedAppUsage
     public boolean isParcelled() {
         return mParcelledData != null;
     }
diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java
index 6639f0f..5ced86c 100644
--- a/core/java/android/os/BatteryManager.java
+++ b/core/java/android/os/BatteryManager.java
@@ -21,6 +21,7 @@
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.Intent;
 import android.hardware.health.V1_0.Constants;
@@ -112,6 +113,7 @@
      * to the device.
      * {@hide}
      */
+    @UnsupportedAppUsage
     public static final String EXTRA_INVALID_CHARGER = "invalid_charger";
 
     /**
@@ -119,6 +121,7 @@
      * Int value set to the maximum charging current supported by the charger in micro amperes.
      * {@hide}
      */
+    @UnsupportedAppUsage
     public static final String EXTRA_MAX_CHARGING_CURRENT = "max_charging_current";
 
     /**
@@ -126,6 +129,7 @@
      * Int value set to the maximum charging voltage supported by the charger in micro volts.
      * {@hide}
      */
+    @UnsupportedAppUsage
     public static final String EXTRA_MAX_CHARGING_VOLTAGE = "max_charging_voltage";
 
     /**
@@ -133,6 +137,7 @@
      * integer containing the charge counter present in the battery.
      * {@hide}
      */
+     @UnsupportedAppUsage
      public static final String EXTRA_CHARGE_COUNTER = "charge_counter";
 
     /**
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index e4277e4..4fae3a8 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -18,6 +18,7 @@
 
 import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION;
 
+import android.annotation.UnsupportedAppUsage;
 import android.app.ActivityManager;
 import android.app.job.JobParameters;
 import android.content.Context;
@@ -74,6 +75,7 @@
     /**
      * A constant indicating a partial wake lock timer.
      */
+    @UnsupportedAppUsage
     public static final int WAKE_TYPE_PARTIAL = 0;
 
     /**
@@ -199,6 +201,7 @@
     /**
      * Include only the current run in the stats.
      */
+    @UnsupportedAppUsage
     public static final int STATS_CURRENT = 1;
 
     /**
@@ -396,6 +399,7 @@
          *
          * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
          */
+        @UnsupportedAppUsage
         public abstract int getCountLocked(int which);
 
         /**
@@ -504,6 +508,7 @@
          *
          * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
          */
+        @UnsupportedAppUsage
         public abstract int getCountLocked(int which);
 
         /**
@@ -514,6 +519,7 @@
          * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
          * @return a time in microseconds
          */
+        @UnsupportedAppUsage
         public abstract long getTotalTimeLocked(long elapsedRealtimeUs, int which);
 
         /**
@@ -616,6 +622,7 @@
          *
          * @return a Map from Strings to Uid.Wakelock objects.
          */
+        @UnsupportedAppUsage
         public abstract ArrayMap<String, ? extends Wakelock> getWakelockStats();
 
         /**
@@ -650,6 +657,7 @@
          * The statistics associated with a particular wake lock.
          */
         public static abstract class Wakelock {
+            @UnsupportedAppUsage
             public abstract Timer getWakeTime(int type);
         }
 
@@ -665,6 +673,7 @@
          *
          * @return a Map from Integer sensor ids to Uid.Sensor objects.
          */
+        @UnsupportedAppUsage
         public abstract SparseArray<? extends Sensor> getSensorStats();
 
         /**
@@ -677,6 +686,7 @@
          *
          * @return a Map from Strings to Uid.Proc objects.
          */
+        @UnsupportedAppUsage
         public abstract ArrayMap<String, ? extends Proc> getProcessStats();
 
         /**
@@ -684,6 +694,7 @@
          *
          * @return a Map from Strings to Uid.Pkg objects.
          */
+        @UnsupportedAppUsage
         public abstract ArrayMap<String, ? extends Pkg> getPackageStats();
 
         public abstract ControllerActivityCounter getWifiControllerActivity();
@@ -693,6 +704,7 @@
         /**
          * {@hide}
          */
+        @UnsupportedAppUsage
         public abstract int getUid();
 
         public abstract void noteWifiRunningLocked(long elapsedRealtime);
@@ -707,8 +719,11 @@
         public abstract void noteWifiMulticastDisabledLocked(long elapsedRealtime);
         public abstract void noteActivityResumedLocked(long elapsedRealtime);
         public abstract void noteActivityPausedLocked(long elapsedRealtime);
+        @UnsupportedAppUsage
         public abstract long getWifiRunningTime(long elapsedRealtimeUs, int which);
+        @UnsupportedAppUsage
         public abstract long getFullWifiLockTime(long elapsedRealtimeUs, int which);
+        @UnsupportedAppUsage
         public abstract long getWifiScanTime(long elapsedRealtimeUs, int which);
         public abstract int getWifiScanCount(int which);
         /**
@@ -722,10 +737,14 @@
          * Returns the timer keeping track of background wifi scans.
          */
         public abstract Timer getWifiScanBackgroundTimer();
+        @UnsupportedAppUsage
         public abstract long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which);
         public abstract int getWifiBatchedScanCount(int csphBin, int which);
+        @UnsupportedAppUsage
         public abstract long getWifiMulticastTime(long elapsedRealtimeUs, int which);
+        @UnsupportedAppUsage
         public abstract Timer getAudioTurnedOnTimer();
+        @UnsupportedAppUsage
         public abstract Timer getVideoTurnedOnTimer();
         public abstract Timer getFlashlightTurnedOnTimer();
         public abstract Timer getCameraTurnedOnTimer();
@@ -857,8 +876,10 @@
         public abstract int getUserActivityCount(int type, int which);
 
         public abstract boolean hasNetworkActivity();
+        @UnsupportedAppUsage
         public abstract long getNetworkActivityBytes(int type, int which);
         public abstract long getNetworkActivityPackets(int type, int which);
+        @UnsupportedAppUsage
         public abstract long getMobileRadioActiveTime(int which);
         public abstract int getMobileRadioActiveCount(int which);
 
@@ -918,10 +939,13 @@
              * the sensor HAL, and therefore out of our control
              */
             // Magic sensor number for the GPS.
+            @UnsupportedAppUsage
             public static final int GPS = -10000;
 
+            @UnsupportedAppUsage
             public abstract int getHandle();
 
+            @UnsupportedAppUsage
             public abstract Timer getSensorTime();
 
             /** Returns a Timer for sensor usage when app is in the background. */
@@ -943,8 +967,11 @@
                 public static final int TYPE_WAKE = 1;
                 public static final int TYPE_CPU = 2;
 
+                @UnsupportedAppUsage
                 public int type;
+                @UnsupportedAppUsage
                 public long overTime;
+                @UnsupportedAppUsage
                 public long usedTime;
             }
 
@@ -958,6 +985,7 @@
              *
              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
              */
+            @UnsupportedAppUsage
             public abstract long getUserTime(int which);
 
             /**
@@ -965,6 +993,7 @@
              *
              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
              */
+            @UnsupportedAppUsage
             public abstract long getSystemTime(int which);
 
             /**
@@ -972,6 +1001,7 @@
              *
              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
              */
+            @UnsupportedAppUsage
             public abstract int getStarts(int which);
 
             /**
@@ -993,10 +1023,13 @@
              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
              * @return foreground cpu time in microseconds
              */
+            @UnsupportedAppUsage
             public abstract long getForegroundTime(int which);
 
+            @UnsupportedAppUsage
             public abstract int countExcessivePowers();
 
+            @UnsupportedAppUsage
             public abstract ExcessivePower getExcessivePower(int i);
         }
 
@@ -1010,11 +1043,13 @@
              * package.  The mapping keys are tag names for the alarms, the counter contains
              * the number of times the alarm was triggered while on battery.
              */
+            @UnsupportedAppUsage
             public abstract ArrayMap<String, ? extends Counter> getWakeupAlarmStats();
 
             /**
              * Returns a mapping containing service statistics.
              */
+            @UnsupportedAppUsage
             public abstract ArrayMap<String, ? extends Serv> getServiceStats();
 
             /**
@@ -1029,6 +1064,7 @@
                  * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
                  * @return
                  */
+                @UnsupportedAppUsage
                 public abstract long getStartTime(long batteryUptime, int which);
 
                 /**
@@ -1036,6 +1072,7 @@
                  *
                  * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
                  */
+                @UnsupportedAppUsage
                 public abstract int getStarts(int which);
 
                 /**
@@ -1043,6 +1080,7 @@
                  *
                  * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
                  */
+                @UnsupportedAppUsage
                 public abstract int getLaunches(int which);
             }
         }
@@ -1505,8 +1543,10 @@
         public HistoryItem next;
 
         // The time of this event in milliseconds, as per SystemClock.elapsedRealtime().
+        @UnsupportedAppUsage
         public long time;
 
+        @UnsupportedAppUsage
         public static final byte CMD_UPDATE = 0;        // These can be written as deltas
         public static final byte CMD_NULL = -1;
         public static final byte CMD_START = 4;
@@ -1515,6 +1555,7 @@
         public static final byte CMD_RESET = 7;
         public static final byte CMD_SHUTDOWN = 8;
 
+        @UnsupportedAppUsage
         public byte cmd = CMD_NULL;
 
         /**
@@ -1524,12 +1565,17 @@
             return cmd == CMD_UPDATE;
         }
 
+        @UnsupportedAppUsage
         public byte batteryLevel;
+        @UnsupportedAppUsage
         public byte batteryStatus;
+        @UnsupportedAppUsage
         public byte batteryHealth;
+        @UnsupportedAppUsage
         public byte batteryPlugType;
 
         public short batteryTemperature;
+        @UnsupportedAppUsage
         public char batteryVoltage;
 
         // The charge of the battery in micro-Ampere-hours.
@@ -1579,6 +1625,7 @@
 
         public static final int SETTLE_TO_ZERO_STATES = 0xffff0000 & ~MOST_INTERESTING_STATES;
 
+        @UnsupportedAppUsage
         public int states;
 
         // Constants from WIFI_SUPPL_STATE_*
@@ -1614,6 +1661,7 @@
 
         public static final int SETTLE_TO_ZERO_STATES2 = 0xffff0000 & ~MOST_INTERESTING_STATES2;
 
+        @UnsupportedAppUsage
         public int states2;
 
         // The wake lock that was acquired at this point.
@@ -1722,6 +1770,7 @@
         public final HistoryTag localWakeReasonTag = new HistoryTag();
         public final HistoryTag localEventTag = new HistoryTag();
 
+        @UnsupportedAppUsage
         public HistoryItem() {
         }
 
@@ -2023,6 +2072,7 @@
 
     public abstract int getHistoryUsedSize();
 
+    @UnsupportedAppUsage
     public abstract boolean startIteratingHistoryLocked();
 
     public abstract int getHistoryStringPoolSize();
@@ -2033,6 +2083,7 @@
 
     public abstract int getHistoryTagPoolUid(int index);
 
+    @UnsupportedAppUsage
     public abstract boolean getNextHistoryLocked(HistoryItem out);
 
     public abstract void finishIteratingHistoryLocked();
@@ -2059,6 +2110,7 @@
      *
      * {@hide}
      */
+    @UnsupportedAppUsage
     public abstract long getScreenOnTime(long elapsedRealtimeUs, int which);
 
     /**
@@ -2099,6 +2151,7 @@
         "0", "1", "2", "3", "4"
     };
 
+    @UnsupportedAppUsage
     public static final int NUM_SCREEN_BRIGHTNESS_BINS = 5;
 
     /**
@@ -2107,6 +2160,7 @@
      *
      * {@hide}
      */
+    @UnsupportedAppUsage
     public abstract long getScreenBrightnessTime(int brightnessBin,
             long elapsedRealtimeUs, int which);
 
@@ -2215,6 +2269,7 @@
      *
      * {@hide}
      */
+    @UnsupportedAppUsage
     public abstract long getPhoneOnTime(long elapsedRealtimeUs, int which);
 
     /**
@@ -2230,6 +2285,7 @@
      *
      * {@hide}
      */
+    @UnsupportedAppUsage
     public abstract long getPhoneSignalStrengthTime(int strengthBin,
             long elapsedRealtimeUs, int which);
 
@@ -2313,6 +2369,7 @@
         "other"
     };
 
+    @UnsupportedAppUsage
     public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER+1;
 
     /**
@@ -2475,6 +2532,7 @@
      *
      * {@hide}
      */
+    @UnsupportedAppUsage
     public abstract long getWifiOnTime(long elapsedRealtimeUs, int which);
 
     /**
@@ -2491,6 +2549,7 @@
      *
      * {@hide}
      */
+    @UnsupportedAppUsage
     public abstract long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which);
 
     public static final int WIFI_STATE_OFF = 0;
@@ -2696,6 +2755,7 @@
     /**
      * Returns a SparseArray containing the statistics for each uid.
      */
+    @UnsupportedAppUsage
     public abstract SparseArray<? extends Uid> getUidStats();
 
     /**
@@ -2703,6 +2763,7 @@
      *
      * @param curTime the amount of elapsed realtime in microseconds.
      */
+    @UnsupportedAppUsage
     public abstract long getBatteryUptime(long curTime);
 
     /**
@@ -2783,6 +2844,7 @@
      * @param curTime the elapsed realtime in microseconds.
      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
      */
+    @UnsupportedAppUsage
     public abstract long computeBatteryUptime(long curTime, int which);
 
     /**
@@ -2791,6 +2853,7 @@
      * @param curTime the current elapsed realtime in microseconds.
      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
      */
+    @UnsupportedAppUsage
     public abstract long computeBatteryRealtime(long curTime, int which);
 
     /**
@@ -2833,6 +2896,7 @@
      *
      * @param curTime The current elepsed realtime in microseconds.
      */
+    @UnsupportedAppUsage
     public abstract long computeBatteryTimeRemaining(long curTime);
 
     // The part of a step duration that is the actual time.
@@ -2967,6 +3031,7 @@
      *
      * @param curTime The current elepsed realtime in microseconds.
      */
+    @UnsupportedAppUsage
     public abstract long computeChargeTimeRemaining(long curTime);
 
     /**
@@ -3251,6 +3316,7 @@
      * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" ,  "process", "network")
      * @param args type-dependent data arguments
      */
+    @UnsupportedAppUsage
     private static final void dumpLine(PrintWriter pw, int uid, String category, String type,
            Object... args ) {
         dumpLineHeader(pw, uid, category, type);
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index d5ef249..eb91860 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.annotation.UnsupportedAppUsage;
 import android.util.ExceptionUtils;
 import android.util.Log;
 import android.util.Slog;
@@ -247,6 +248,7 @@
     /**
      * Raw native pointer to JavaBBinderHolder object. Owned by this Java object. Not null.
      */
+    @UnsupportedAppUsage
     private final long mObject;
 
     private IInterface mOwner;
@@ -990,6 +992,7 @@
     }
 
     // Entry point from android_util_Binder.cpp's onTransact
+    @UnsupportedAppUsage
     private boolean execTransact(int code, long dataObj, long replyObj,
             int flags) {
         // At that point, the parcel request headers haven't been parsed so we do not know what
diff --git a/core/java/android/os/Broadcaster.java b/core/java/android/os/Broadcaster.java
index 70dcdd8..6ac7f1a 100644
--- a/core/java/android/os/Broadcaster.java
+++ b/core/java/android/os/Broadcaster.java
@@ -16,9 +16,12 @@
 
 package android.os;
 
+import android.annotation.UnsupportedAppUsage;
+
 /** @hide */
 public class Broadcaster
 {
+    @UnsupportedAppUsage
     public Broadcaster()
     {
     }
@@ -29,6 +32,7 @@
      *  When this broadcaster pushes a message with senderWhat in the what field,
      *  target will be sent a copy of that message with targetWhat in the what field.
      */
+    @UnsupportedAppUsage
     public void request(int senderWhat, Handler target, int targetWhat)
     {
         synchronized (this) {
@@ -96,6 +100,7 @@
     /**
      * Unregister for notifications for this senderWhat/target/targetWhat tuple.
      */
+    @UnsupportedAppUsage
     public void cancelRequest(int senderWhat, Handler target, int targetWhat)
     {
         synchronized (this) {
@@ -168,6 +173,7 @@
      * Send out msg.  Anyone who has registered via the request() method will be
      * sent the message.
      */
+    @UnsupportedAppUsage
     public void broadcast(Message msg)
     {
         synchronized (this) {
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 0de4ddc..94c8b91 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -22,6 +22,7 @@
 import android.annotation.SuppressAutoDoc;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
 import android.app.ActivityThread;
 import android.app.Application;
 import android.content.Context;
@@ -321,6 +322,7 @@
         /**
          * @hide
          */
+        @UnsupportedAppUsage
         public static final String[] ACTIVE_CODENAMES = "REL".equals(ALL_CODENAMES[0])
                 ? new String[0] : ALL_CODENAMES;
 
@@ -1202,6 +1204,7 @@
      * Returns true if we are running a debug build such as "user-debug" or "eng".
      * @hide
      */
+    @UnsupportedAppUsage
     public static final boolean IS_DEBUGGABLE =
             SystemProperties.getInt("ro.debuggable", 0) == 1;
 
@@ -1249,6 +1252,7 @@
         return TextUtils.isEmpty(propVal) ? null : propVal;
     }
 
+    @UnsupportedAppUsage
     private static String getString(String property) {
         return SystemProperties.get(property, UNKNOWN);
     }
@@ -1262,6 +1266,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private static long getLong(String property) {
         try {
             return Long.parseLong(SystemProperties.get(property));
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index 8e6a554..6432c24 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -17,6 +17,7 @@
 package android.os;
 
 import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
 import android.util.ArrayMap;
 import android.util.Size;
 import android.util.SizeF;
@@ -173,6 +174,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public static Bundle forPair(String key, String value) {
         Bundle b = new Bundle(1);
         b.putString(key, value);
@@ -229,6 +231,7 @@
     }
 
     /** {@hide} */
+    @UnsupportedAppUsage
     public static Bundle setDefusable(Bundle bundle, boolean defusable) {
         if (bundle != null) {
             bundle.setDefusable(defusable);
@@ -303,6 +306,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public int getSize() {
         if (mParcelledData != null) {
             return mParcelledData.dataSize();
@@ -385,6 +389,7 @@
      * Filter values in Bundle to only basic types.
      * @hide
      */
+    @UnsupportedAppUsage
     public Bundle filterValues() {
         unparcel();
         Bundle bundle = this;
@@ -557,6 +562,7 @@
     }
 
     /** {@hide} */
+    @UnsupportedAppUsage
     public void putParcelableList(String key, List<? extends Parcelable> value) {
         unparcel();
         mMap.put(key, value);
@@ -728,6 +734,7 @@
      * @deprecated
      * @hide This is the old name of the function.
      */
+    @UnsupportedAppUsage
     @Deprecated
     public void putIBinder(@Nullable String key, @Nullable IBinder value) {
         unparcel();
@@ -1180,6 +1187,7 @@
      * @deprecated
      * @hide This is the old name of the function.
      */
+    @UnsupportedAppUsage
     @Deprecated
     @Nullable
     public IBinder getIBinder(@Nullable String key) {
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index a395ed4..1213eea 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
 import android.app.AppGlobals;
 import android.content.Context;
 import android.util.Log;
@@ -87,6 +88,7 @@
     // set/cleared by waitForDebugger()
     private static volatile boolean mWaiting = false;
 
+    @UnsupportedAppUsage
     private Debug() {}
 
     /*
@@ -115,8 +117,10 @@
         public int dalvikPss;
         /** The proportional set size that is swappable for dalvik heap. */
         /** @hide We may want to expose this, eventually. */
+        @UnsupportedAppUsage
         public int dalvikSwappablePss;
         /** @hide The resident set size for dalvik heap.  (Without other Dalvik overhead.) */
+        @UnsupportedAppUsage
         public int dalvikRss;
         /** The private dirty pages used by dalvik heap. */
         public int dalvikPrivateDirty;
@@ -124,23 +128,29 @@
         public int dalvikSharedDirty;
         /** The private clean pages used by dalvik heap. */
         /** @hide We may want to expose this, eventually. */
+        @UnsupportedAppUsage
         public int dalvikPrivateClean;
         /** The shared clean pages used by dalvik heap. */
         /** @hide We may want to expose this, eventually. */
+        @UnsupportedAppUsage
         public int dalvikSharedClean;
         /** The dirty dalvik pages that have been swapped out. */
         /** @hide We may want to expose this, eventually. */
+        @UnsupportedAppUsage
         public int dalvikSwappedOut;
         /** The dirty dalvik pages that have been swapped out, proportional. */
         /** @hide We may want to expose this, eventually. */
+        @UnsupportedAppUsage
         public int dalvikSwappedOutPss;
 
         /** The proportional set size for the native heap. */
         public int nativePss;
         /** The proportional set size that is swappable for the native heap. */
         /** @hide We may want to expose this, eventually. */
+        @UnsupportedAppUsage
         public int nativeSwappablePss;
         /** @hide The resident set size for the native heap. */
+        @UnsupportedAppUsage
         public int nativeRss;
         /** The private dirty pages used by the native heap. */
         public int nativePrivateDirty;
@@ -148,23 +158,29 @@
         public int nativeSharedDirty;
         /** The private clean pages used by the native heap. */
         /** @hide We may want to expose this, eventually. */
+        @UnsupportedAppUsage
         public int nativePrivateClean;
         /** The shared clean pages used by the native heap. */
         /** @hide We may want to expose this, eventually. */
+        @UnsupportedAppUsage
         public int nativeSharedClean;
         /** The dirty native pages that have been swapped out. */
         /** @hide We may want to expose this, eventually. */
+        @UnsupportedAppUsage
         public int nativeSwappedOut;
         /** The dirty native pages that have been swapped out, proportional. */
         /** @hide We may want to expose this, eventually. */
+        @UnsupportedAppUsage
         public int nativeSwappedOutPss;
 
         /** The proportional set size for everything else. */
         public int otherPss;
         /** The proportional set size that is swappable for everything else. */
         /** @hide We may want to expose this, eventually. */
+        @UnsupportedAppUsage
         public int otherSwappablePss;
         /** @hide The resident set size for everything else. */
+        @UnsupportedAppUsage
         public int otherRss;
         /** The private dirty pages used by everything else. */
         public int otherPrivateDirty;
@@ -172,19 +188,24 @@
         public int otherSharedDirty;
         /** The private clean pages used by everything else. */
         /** @hide We may want to expose this, eventually. */
+        @UnsupportedAppUsage
         public int otherPrivateClean;
         /** The shared clean pages used by everything else. */
         /** @hide We may want to expose this, eventually. */
+        @UnsupportedAppUsage
         public int otherSharedClean;
         /** The dirty pages used by anyting else that have been swapped out. */
         /** @hide We may want to expose this, eventually. */
+        @UnsupportedAppUsage
         public int otherSwappedOut;
         /** The dirty pages used by anyting else that have been swapped out, proportional. */
         /** @hide We may want to expose this, eventually. */
+        @UnsupportedAppUsage
         public int otherSwappedOutPss;
 
         /** Whether the kernel reports proportional swap usage */
         /** @hide */
+        @UnsupportedAppUsage
         public boolean hasSwappedOutPss;
 
         /** @hide */
@@ -231,6 +252,7 @@
 
         // Needs to be declared here for the DVK_STAT ranges below.
         /** @hide */
+        @UnsupportedAppUsage
         public static final int NUM_OTHER_STATS = 17;
 
         // Dalvik subsections.
@@ -291,6 +313,7 @@
         public static final int OTHER_DVK_STAT_ART_END = OTHER_ART_BOOT - NUM_OTHER_STATS;
 
         /** @hide */
+        @UnsupportedAppUsage
         public static final int NUM_DVK_STATS = 14;
 
         /** @hide */
@@ -315,6 +338,7 @@
         /** @hide */
         public static final int OFFSET_SWAPPED_OUT_PSS = 8;
 
+        @UnsupportedAppUsage
         private int[] otherStats = new int[(NUM_OTHER_STATS+NUM_DVK_STATS)*NUM_CATEGORIES];
 
         public MemoryInfo() {
@@ -369,6 +393,7 @@
         /**
          * @hide Return total PSS memory usage in kB.
          */
+        @UnsupportedAppUsage
         public int getTotalUss() {
             return dalvikPrivateClean + dalvikPrivateDirty
                     + nativePrivateClean + nativePrivateDirty
@@ -435,6 +460,7 @@
         }
 
         /** @hide */
+        @UnsupportedAppUsage
         public int getOtherPss(int which) {
             return otherStats[which * NUM_CATEGORIES + OFFSET_PSS];
         }
@@ -450,11 +476,13 @@
         }
 
         /** @hide */
+        @UnsupportedAppUsage
         public int getOtherPrivateDirty(int which) {
             return otherStats[which * NUM_CATEGORIES + OFFSET_PRIVATE_DIRTY];
         }
 
         /** @hide */
+        @UnsupportedAppUsage
         public int getOtherSharedDirty(int which) {
             return otherStats[which * NUM_CATEGORIES + OFFSET_SHARED_DIRTY];
         }
@@ -465,6 +493,7 @@
         }
 
         /** @hide */
+        @UnsupportedAppUsage
         public int getOtherPrivate(int which) {
           return getOtherPrivateClean(which) + getOtherPrivateDirty(which);
         }
@@ -485,6 +514,7 @@
         }
 
         /** @hide */
+        @UnsupportedAppUsage
         public static String getOtherLabel(int which) {
             switch (which) {
                 case OTHER_DALVIK_OTHER: return "Dalvik Other";
@@ -662,6 +692,7 @@
          *    such thing as private clean for the Java Heap.
          * @hide
          */
+        @UnsupportedAppUsage
         public int getSummaryJavaHeap() {
             return dalvikPrivateDirty + getOtherPrivate(OTHER_ART);
         }
@@ -674,6 +705,7 @@
          *    such thing as private clean for the Native Heap.
          * @hide
          */
+        @UnsupportedAppUsage
         public int getSummaryNativeHeap() {
             return nativePrivateDirty;
         }
@@ -683,6 +715,7 @@
          * the application.
          * @hide
          */
+        @UnsupportedAppUsage
         public int getSummaryCode() {
             return getOtherPrivate(OTHER_SO)
               + getOtherPrivate(OTHER_JAR)
@@ -701,6 +734,7 @@
          *    such thing as private clean for the stack.
          * @hide
          */
+        @UnsupportedAppUsage
         public int getSummaryStack() {
             return getOtherPrivateDirty(OTHER_STACK);
         }
@@ -716,6 +750,7 @@
          *    memory into the System category.
          * @hide
          */
+        @UnsupportedAppUsage
         public int getSummaryGraphics() {
             return getOtherPrivate(OTHER_GL_DEV)
               + getOtherPrivate(OTHER_GRAPHICS)
@@ -727,6 +762,7 @@
          * accounted for.
          * @hide
          */
+        @UnsupportedAppUsage
         public int getSummaryPrivateOther() {
             return getTotalPrivateClean()
               + getTotalPrivateDirty()
@@ -743,6 +779,7 @@
          *  * Includes all shared memory.
          * @hide
          */
+        @UnsupportedAppUsage
         public int getSummarySystem() {
             return getTotalPss()
               - getTotalPrivateClean()
@@ -1782,6 +1819,7 @@
      * as the caller.
      * @hide
      */
+    @UnsupportedAppUsage
     public static native void getMemoryInfo(int pid, MemoryInfo memoryInfo);
 
     /**
@@ -1837,6 +1875,7 @@
      * as defined by MEMINFO_* offsets.
      * @hide
      */
+    @UnsupportedAppUsage
     public static native void getMemInfo(long[] outSizes);
 
     /**
@@ -1925,6 +1964,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public static native void dumpNativeHeap(FileDescriptor fd);
 
     /**
@@ -1939,6 +1979,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public static long countInstancesOfClass(Class cls) {
         return VMDebug.countInstancesOfClass(cls, true);
     }
@@ -1998,6 +2039,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public static final void dumpReferenceTables() {
         VMDebug.dumpReferenceTables();
     }
@@ -2364,6 +2406,7 @@
      * @return a string describing the call stack.
      * {@hide}
      */
+    @UnsupportedAppUsage
     public static String getCallers(final int depth) {
         final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
         StringBuffer sb = new StringBuffer();
@@ -2410,6 +2453,7 @@
      * @return a String describing the immediate caller of the calling method.
      * {@hide}
      */
+    @UnsupportedAppUsage
     public static String getCaller() {
         return getCaller(Thread.currentThread().getStackTrace(), 0);
     }
diff --git a/core/java/android/os/DropBoxManager.java b/core/java/android/os/DropBoxManager.java
index 1be7b6b..320f471 100644
--- a/core/java/android/os/DropBoxManager.java
+++ b/core/java/android/os/DropBoxManager.java
@@ -24,6 +24,7 @@
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemService;
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.util.Log;
 
@@ -50,6 +51,7 @@
     private static final String TAG = "DropBoxManager";
 
     private final Context mContext;
+    @UnsupportedAppUsage
     private final IDropBoxManagerService mService;
 
     /** Flag value: Entry's content was deleted to save space. */
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index fea69c0..cceb6ed 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.os.storage.StorageManager;
@@ -74,6 +75,7 @@
     private static final File DIR_PRODUCT_SERVICES_ROOT = getDirectory(ENV_PRODUCT_SERVICES_ROOT,
                                                            "/product_services");
 
+    @UnsupportedAppUsage
     private static UserEnvironment sCurrentUser;
     private static boolean sUserRequired;
 
@@ -82,6 +84,7 @@
     }
 
     /** {@hide} */
+    @UnsupportedAppUsage
     public static void initForCurrentUser() {
         final int userId = UserHandle.myUserId();
         sCurrentUser = new UserEnvironment(userId);
@@ -91,10 +94,12 @@
     public static class UserEnvironment {
         private final int mUserId;
 
+        @UnsupportedAppUsage
         public UserEnvironment(int userId) {
             mUserId = userId;
         }
 
+        @UnsupportedAppUsage
         public File[] getExternalDirs() {
             final StorageVolume[] volumes = StorageManager.getVolumeList(mUserId,
                     StorageManager.FLAG_FOR_WRITE);
@@ -105,11 +110,13 @@
             return files;
         }
 
+        @UnsupportedAppUsage
         @Deprecated
         public File getExternalStorageDirectory() {
             return getExternalDirs()[0];
         }
 
+        @UnsupportedAppUsage
         @Deprecated
         public File getExternalStoragePublicDirectory(String type) {
             return buildExternalStoragePublicDirs(type)[0];
@@ -278,6 +285,7 @@
     }
 
     /** {@hide} */
+    @UnsupportedAppUsage
     public static File getDataSystemDirectory() {
         return new File(getDataDirectory(), "system");
     }
@@ -553,11 +561,13 @@
     }
 
     /** {@hide} */
+    @UnsupportedAppUsage
     public static File getLegacyExternalStorageDirectory() {
         return new File(System.getenv(ENV_EXTERNAL_STORAGE));
     }
 
     /** {@hide} */
+    @UnsupportedAppUsage
     public static File getLegacyExternalStorageObbDirectory() {
         return buildPath(getLegacyExternalStorageDirectory(), DIR_ANDROID, DIR_OBB);
     }
@@ -839,6 +849,7 @@
      * Returns the path for android-specific data on the SD card.
      * @hide
      */
+    @UnsupportedAppUsage
     public static File[] buildExternalStorageAndroidDataDirs() {
         throwIfUserRequired();
         return sCurrentUser.buildExternalStorageAndroidDataDirs();
@@ -848,6 +859,7 @@
      * Generates the raw path to an application's data
      * @hide
      */
+    @UnsupportedAppUsage
     public static File[] buildExternalStorageAppDataDirs(String packageName) {
         throwIfUserRequired();
         return sCurrentUser.buildExternalStorageAppDataDirs(packageName);
@@ -857,6 +869,7 @@
      * Generates the raw path to an application's media
      * @hide
      */
+    @UnsupportedAppUsage
     public static File[] buildExternalStorageAppMediaDirs(String packageName) {
         throwIfUserRequired();
         return sCurrentUser.buildExternalStorageAppMediaDirs(packageName);
@@ -866,6 +879,7 @@
      * Generates the raw path to an application's OBB files
      * @hide
      */
+    @UnsupportedAppUsage
     public static File[] buildExternalStorageAppObbDirs(String packageName) {
         throwIfUserRequired();
         return sCurrentUser.buildExternalStorageAppObbDirs(packageName);
@@ -875,6 +889,7 @@
      * Generates the path to an application's files.
      * @hide
      */
+    @UnsupportedAppUsage
     public static File[] buildExternalStorageAppFilesDirs(String packageName) {
         throwIfUserRequired();
         return sCurrentUser.buildExternalStorageAppFilesDirs(packageName);
@@ -884,6 +899,7 @@
      * Generates the path to an application's cache.
      * @hide
      */
+    @UnsupportedAppUsage
     public static File[] buildExternalStorageAppCacheDirs(String packageName) {
         throwIfUserRequired();
         return sCurrentUser.buildExternalStorageAppCacheDirs(packageName);
@@ -1118,6 +1134,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public static File[] buildPaths(File[] base, String... segments) {
         File[] result = new File[base.length];
         for (int i = 0; i < base.length; i++) {
@@ -1157,6 +1174,7 @@
      * @deprecated disabled now that FUSE has been replaced by sdcardfs
      * @hide
      */
+    @UnsupportedAppUsage
     @Deprecated
     public static File maybeTranslateEmulatedPathToInternal(File path) {
         return StorageManager.maybeTranslateEmulatedPathToInternal(path);
diff --git a/core/java/android/os/FileObserver.java b/core/java/android/os/FileObserver.java
index 330bde5..4d9ebc2 100644
--- a/core/java/android/os/FileObserver.java
+++ b/core/java/android/os/FileObserver.java
@@ -19,6 +19,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
 import android.util.Log;
 
 import java.io.File;
@@ -141,6 +142,7 @@
             stopWatching(m_fd, descriptors);
         }
 
+        @UnsupportedAppUsage
         public void onEvent(int wfd, @NotifyEventType int mask, String path) {
             // look up our observer, fixing up the map if necessary...
             FileObserver observer = null;
@@ -172,6 +174,7 @@
         private native void stopWatching(int fd, int[] wfds);
     }
 
+    @UnsupportedAppUsage
     private static ObserverThread s_observerThread;
 
     static {
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 316572c..f789b72 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -40,6 +40,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
 import android.content.ContentResolver;
 import android.provider.DocumentsContract.Document;
 import android.system.ErrnoException;
@@ -103,6 +104,7 @@
     /** {@hide} */ public static final int S_IWOTH = 00002;
     /** {@hide} */ public static final int S_IXOTH = 00001;
 
+    @UnsupportedAppUsage
     private FileUtils() {
     }
 
@@ -135,6 +137,7 @@
      * @return 0 on success, otherwise errno.
      * @hide
      */
+    @UnsupportedAppUsage
     public static int setPermissions(File path, int mode, int uid, int gid) {
         return setPermissions(path.getAbsolutePath(), mode, uid, gid);
     }
@@ -148,6 +151,7 @@
      * @return 0 on success, otherwise errno.
      * @hide
      */
+    @UnsupportedAppUsage
     public static int setPermissions(String path, int mode, int uid, int gid) {
         try {
             Os.chmod(path, mode);
@@ -177,6 +181,7 @@
      * @return 0 on success, otherwise errno.
      * @hide
      */
+    @UnsupportedAppUsage
     public static int setPermissions(FileDescriptor fd, int mode, int uid, int gid) {
         try {
             Os.fchmod(fd, mode);
@@ -233,6 +238,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public static boolean sync(FileOutputStream stream) {
         try {
             if (stream != null) {
@@ -248,6 +254,7 @@
      * @deprecated use {@link #copy(File, File)} instead.
      * @hide
      */
+    @UnsupportedAppUsage
     @Deprecated
     public static boolean copyFile(File srcFile, File destFile) {
         try {
@@ -273,6 +280,7 @@
      * @deprecated use {@link #copy(InputStream, OutputStream)} instead.
      * @hide
      */
+    @UnsupportedAppUsage
     @Deprecated
     public static boolean copyToFile(InputStream inputStream, File destFile) {
         try {
@@ -584,6 +592,7 @@
      * @param file  The file to check
      * @hide
      */
+    @UnsupportedAppUsage
     public static boolean isFilenameSafe(File file) {
         // Note, we check whether it matches what's known to be safe,
         // rather than what's known to be unsafe.  Non-ASCII, control
@@ -600,6 +609,7 @@
      * @throws IOException if something goes wrong reading the file
      * @hide
      */
+    @UnsupportedAppUsage
     public static String readTextFile(File file, int max, String ellipsis) throws IOException {
         InputStream input = new FileInputStream(file);
         // wrapping a BufferedInputStream around it because when reading /proc with unbuffered
@@ -654,6 +664,7 @@
     }
 
     /** {@hide} */
+    @UnsupportedAppUsage
     public static void stringToFile(File file, String string) throws IOException {
         stringToFile(file.getAbsolutePath(), string);
     }
@@ -687,6 +698,7 @@
      * @throws IOException
      * @hide
      */
+    @UnsupportedAppUsage
     public static void stringToFile(String filename, String string) throws IOException {
         bytesToFile(filename, string.getBytes(StandardCharsets.UTF_8));
     }
@@ -701,6 +713,7 @@
      *             to its potential for collision.
      * @hide
      */
+    @UnsupportedAppUsage
     @Deprecated
     public static long checksumCrc32(File file) throws FileNotFoundException, IOException {
         CRC32 checkSummer = new CRC32();
@@ -783,6 +796,7 @@
      * @return if any files were deleted.
      * @hide
      */
+    @UnsupportedAppUsage
     public static boolean deleteOlderFiles(File dir, int minCount, long minAgeMs) {
         if (minCount < 0 || minAgeMs < 0) {
             throw new IllegalArgumentException("Constraints must be positive or 0");
@@ -891,6 +905,7 @@
     }
 
     /** {@hide} */
+    @UnsupportedAppUsage
     public static boolean deleteContents(File dir) {
         File[] files = dir.listFiles();
         boolean success = true;
diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java
index a039742..9af9eda 100644
--- a/core/java/android/os/Handler.java
+++ b/core/java/android/os/Handler.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
 import android.util.Log;
 import android.util.Printer;
 
@@ -168,6 +169,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public Handler(boolean async) {
         this(null, async);
     }
@@ -229,6 +231,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async) {
         mLooper = looper;
         mQueue = looper.mQueue;
@@ -274,6 +277,7 @@
     }
 
     /** @hide */
+    @UnsupportedAppUsage
     @NonNull
     public static Handler getMain() {
         if (MAIN_THREAD_HANDLER == null) {
@@ -843,6 +847,7 @@
         + "}";
     }
 
+    @UnsupportedAppUsage
     final IMessenger getIMessenger() {
         synchronized (mQueue) {
             if (mMessenger != null) {
@@ -866,6 +871,7 @@
         return m;
     }
 
+    @UnsupportedAppUsage
     private static Message getPostMessage(Runnable r, Object token) {
         Message m = Message.obtain();
         m.obj = token;
@@ -877,10 +883,13 @@
         message.callback.run();
     }
 
+    @UnsupportedAppUsage
     final Looper mLooper;
     final MessageQueue mQueue;
+    @UnsupportedAppUsage
     final Callback mCallback;
     final boolean mAsynchronous;
+    @UnsupportedAppUsage
     IMessenger mMessenger;
 
     private static final class BlockingRunnable implements Runnable {
diff --git a/core/java/android/os/HwBinder.java b/core/java/android/os/HwBinder.java
index 9e3e83e..09afdc7 100644
--- a/core/java/android/os/HwBinder.java
+++ b/core/java/android/os/HwBinder.java
@@ -18,6 +18,7 @@
 
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
 
 import libcore.util.NativeAllocationRegistry;
 
@@ -151,6 +152,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public static void reportSyspropChanged() {
         native_report_sysprop_change();
     }
diff --git a/core/java/android/os/HwParcel.java b/core/java/android/os/HwParcel.java
index dc640c9..cfb582e 100644
--- a/core/java/android/os/HwParcel.java
+++ b/core/java/android/os/HwParcel.java
@@ -21,6 +21,7 @@
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
 
 import libcore.util.NativeAllocationRegistry;
 
@@ -49,6 +50,7 @@
 
     private static final NativeAllocationRegistry sNativeRegistry;
 
+    @UnsupportedAppUsage
     private HwParcel(boolean allocate) {
         native_setup(allocate);
 
diff --git a/core/java/android/os/HwRemoteBinder.java b/core/java/android/os/HwRemoteBinder.java
index a07e42c..72ec958 100644
--- a/core/java/android/os/HwRemoteBinder.java
+++ b/core/java/android/os/HwRemoteBinder.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.annotation.UnsupportedAppUsage;
 import libcore.util.NativeAllocationRegistry;
 
 /** @hide */
@@ -24,6 +25,7 @@
 
     private static final NativeAllocationRegistry sNativeRegistry;
 
+    @UnsupportedAppUsage
     public HwRemoteBinder() {
         native_setup_empty();
 
diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java
index e74b0bb..83f88ad 100644
--- a/core/java/android/os/IBinder.java
+++ b/core/java/android/os/IBinder.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
 
 import java.io.FileDescriptor;
 
@@ -149,6 +150,7 @@
     int LIKE_TRANSACTION   = ('_'<<24)|('L'<<16)|('I'<<8)|'K';
 
     /** @hide */
+    @UnsupportedAppUsage
     int SYSPROPS_TRANSACTION = ('_'<<24)|('S'<<16)|('P'<<8)|'R';
 
     /**
diff --git a/core/java/android/os/IDeviceIdleController.aidl b/core/java/android/os/IDeviceIdleController.aidl
index fe17c6b..aa255bf 100644
--- a/core/java/android/os/IDeviceIdleController.aidl
+++ b/core/java/android/os/IDeviceIdleController.aidl
@@ -39,6 +39,7 @@
     int[] getAppIdTempWhitelist();
     boolean isPowerSaveWhitelistExceptIdleApp(String name);
     boolean isPowerSaveWhitelistApp(String name);
+    @UnsupportedAppUsage
     void addPowerSaveTempWhitelistApp(String name, long duration, int userId, String reason);
     long addPowerSaveTempWhitelistAppForMms(String name, int userId, String reason);
     long addPowerSaveTempWhitelistAppForSms(String name, int userId, String reason);
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 8ced722..f62a999 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -38,11 +38,13 @@
     /**
      * Register an observer to receive events.
      */
+    @UnsupportedAppUsage
     void registerObserver(INetworkManagementEventObserver obs);
 
     /**
      * Unregister an observer from receiving events.
      */
+    @UnsupportedAppUsage
     void unregisterObserver(INetworkManagementEventObserver obs);
 
     /**
@@ -54,16 +56,19 @@
      * Retrieves the specified interface config
      *
      */
+    @UnsupportedAppUsage
     InterfaceConfiguration getInterfaceConfig(String iface);
 
     /**
      * Sets the configuration of the specified interface
      */
+    @UnsupportedAppUsage
     void setInterfaceConfig(String iface, in InterfaceConfiguration cfg);
 
     /**
      * Clear all IP addresses on the specified interface
      */
+    @UnsupportedAppUsage
     void clearInterfaceAddresses(String iface);
 
     /**
@@ -79,22 +84,26 @@
     /**
      * Set interface IPv6 privacy extensions
      */
+    @UnsupportedAppUsage
     void setInterfaceIpv6PrivacyExtensions(String iface, boolean enable);
 
     /**
      * Disable IPv6 on an interface
      */
+    @UnsupportedAppUsage
     void disableIpv6(String iface);
 
     /**
      * Enable IPv6 on an interface
      */
+    @UnsupportedAppUsage
     void enableIpv6(String iface);
 
     /**
      * Set IPv6 autoconf address generation mode.
      * This is a no-op if an unsupported mode is requested.
      */
+    @UnsupportedAppUsage
     void setIPv6AddrGenMode(String iface, int mode);
 
     /**
@@ -124,37 +133,44 @@
     /**
      * Returns true if IP forwarding is enabled
      */
+    @UnsupportedAppUsage
     boolean getIpForwardingEnabled();
 
     /**
      * Enables/Disables IP Forwarding
      */
+    @UnsupportedAppUsage
     void setIpForwardingEnabled(boolean enabled);
 
     /**
      * Start tethering services with the specified dhcp server range
      * arg is a set of start end pairs defining the ranges.
      */
+    @UnsupportedAppUsage
     void startTethering(in String[] dhcpRanges);
 
     /**
      * Stop currently running tethering services
      */
+    @UnsupportedAppUsage
     void stopTethering();
 
     /**
      * Returns true if tethering services are started
      */
+    @UnsupportedAppUsage
     boolean isTetheringStarted();
 
     /**
      * Tethers the specified interface
      */
+    @UnsupportedAppUsage
     void tetherInterface(String iface);
 
     /**
      * Untethers the specified interface
      */
+    @UnsupportedAppUsage
     void untetherInterface(String iface);
 
     /**
@@ -189,11 +205,13 @@
      *  The address and netmask of the external interface is used for
      *  the NAT'ed network.
      */
+    @UnsupportedAppUsage
     void enableNat(String internalInterface, String externalInterface);
 
     /**
      *  Disables Network Address Translation between two interfaces.
      */
+    @UnsupportedAppUsage
     void disableNat(String internalInterface, String externalInterface);
 
     /**
@@ -311,6 +329,7 @@
     /**
      * Return status of bandwidth control module.
      */
+    @UnsupportedAppUsage
     boolean isBandwidthControlEnabled();
 
     /**
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index a0d88ee..4233340 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -41,10 +41,13 @@
     void updateWakeLockWorkSource(IBinder lock, in WorkSource ws, String historyTag);
     boolean isWakeLockLevelSupported(int level);
 
+    @UnsupportedAppUsage
     void userActivity(long time, int event, int flags);
     void wakeUp(long time, int reason, String details, String opPackageName);
+    @UnsupportedAppUsage
     void goToSleep(long time, int reason, int flags);
     void nap(long time);
+    @UnsupportedAppUsage
     boolean isInteractive();
     boolean isPowerSaveMode();
     PowerSaveState getPowerSaveState(int serviceType);
@@ -56,6 +59,7 @@
     boolean isDeviceIdleMode();
     boolean isLightDeviceIdleMode();
 
+    @UnsupportedAppUsage
     void reboot(boolean confirm, String reason, boolean wait);
     void rebootSafeMode(boolean confirm, boolean wait);
     void shutdown(boolean confirm, String reason, boolean wait);
diff --git a/core/java/android/os/IRemoteCallback.aidl b/core/java/android/os/IRemoteCallback.aidl
index f0c6c73..71f3b06 100644
--- a/core/java/android/os/IRemoteCallback.aidl
+++ b/core/java/android/os/IRemoteCallback.aidl
@@ -21,5 +21,6 @@
 
 /** @hide */
 oneway interface IRemoteCallback {
+    @UnsupportedAppUsage
     void sendResult(in Bundle data);
 }
diff --git a/core/java/android/os/IServiceManager.java b/core/java/android/os/IServiceManager.java
index 89bf7b9..bc0690d 100644
--- a/core/java/android/os/IServiceManager.java
+++ b/core/java/android/os/IServiceManager.java
@@ -16,6 +16,8 @@
 
 package android.os;
 
+import android.annotation.UnsupportedAppUsage;
+
 /**
  * Basic interface for finding and publishing system services.
  *
@@ -33,12 +35,14 @@
      * service manager.  Blocks for a few seconds waiting for it to be
      * published if it does not already exist.
      */
+    @UnsupportedAppUsage
     IBinder getService(String name) throws RemoteException;
 
     /**
      * Retrieve an existing service called @a name from the
      * service manager.  Non-blocking.
      */
+    @UnsupportedAppUsage
     IBinder checkService(String name) throws RemoteException;
 
     /**
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index 3017f25..63641e5 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -59,6 +59,7 @@
     boolean canAddMoreManagedProfiles(int userHandle, boolean allowedToRemoveOne);
     UserInfo getProfileParent(int userHandle);
     boolean isSameProfileGroup(int userHandle, int otherUserHandle);
+    @UnsupportedAppUsage
     UserInfo getUserInfo(int userHandle);
     String getUserAccount(int userHandle);
     void setUserAccount(int userHandle, String accountName);
@@ -100,6 +101,7 @@
     boolean isUserNameSet(int userHandle);
     boolean hasRestrictedProfiles();
     boolean requestQuietModeEnabled(String callingPackage, boolean enableQuietMode, int userHandle, in IntentSender target);
+    String getUserName();
     long getUserStartRealtime();
     long getUserUnlockRealtime();
 }
diff --git a/core/java/android/os/LocaleList.java b/core/java/android/os/LocaleList.java
index a9da080..351df1b 100644
--- a/core/java/android/os/LocaleList.java
+++ b/core/java/android/os/LocaleList.java
@@ -21,6 +21,7 @@
 import android.annotation.Nullable;
 import android.annotation.Size;
 import android.annotation.SystemApi;
+import android.annotation.UnsupportedAppUsage;
 import android.content.LocaleProto;
 import android.icu.util.ULocale;
 import android.util.proto.ProtoOutputStream;
@@ -568,6 +569,7 @@
      *
      * {@hide}
      */
+    @UnsupportedAppUsage
     public static void setDefault(@NonNull @Size(min=1) LocaleList locales, int localeIndex) {
         if (locales == null) {
             throw new NullPointerException("locales is null");
diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java
index a8d1215..3222fc4 100644
--- a/core/java/android/os/Looper.java
+++ b/core/java/android/os/Looper.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
 import android.util.Log;
 import android.util.Printer;
 import android.util.Slog;
@@ -67,13 +68,17 @@
     private static final String TAG = "Looper";
 
     // sThreadLocal.get() will return null unless you've called prepare().
+    @UnsupportedAppUsage
     static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
+    @UnsupportedAppUsage
     private static Looper sMainLooper;  // guarded by Looper.class
     private static Observer sObserver;
 
+    @UnsupportedAppUsage
     final MessageQueue mQueue;
     final Thread mThread;
 
+    @UnsupportedAppUsage
     private Printer mLogging;
     private long mTraceTag;
 
@@ -315,6 +320,7 @@
     }
 
     /** {@hide} */
+    @UnsupportedAppUsage
     public void setTraceTag(long traceTag) {
         mTraceTag = traceTag;
     }
diff --git a/core/java/android/os/MemoryFile.java b/core/java/android/os/MemoryFile.java
index ff3258f..5a1e3d4 100644
--- a/core/java/android/os/MemoryFile.java
+++ b/core/java/android/os/MemoryFile.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.annotation.UnsupportedAppUsage;
 import android.system.ErrnoException;
 
 import java.io.FileDescriptor;
@@ -40,7 +41,9 @@
     private static String TAG = "MemoryFile";
 
     // Returns 'true' if purged, 'false' otherwise
+    @UnsupportedAppUsage
     private static native boolean native_pin(FileDescriptor fd, boolean pin) throws IOException;
+    @UnsupportedAppUsage
     private static native int native_get_size(FileDescriptor fd) throws IOException;
 
     private SharedMemory mSharedMemory;
@@ -79,6 +82,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     void deactivate() {
         if (mMapping != null) {
             SharedMemory.unmap(mMapping);
@@ -222,6 +226,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public FileDescriptor getFileDescriptor() throws IOException {
         return mSharedMemory.getFileDescriptor();
     }
@@ -234,6 +239,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public static int getSize(FileDescriptor fd) throws IOException {
         return native_get_size(fd);
     }
diff --git a/core/java/android/os/Message.java b/core/java/android/os/Message.java
index 317579e..6055bef 100644
--- a/core/java/android/os/Message.java
+++ b/core/java/android/os/Message.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.annotation.UnsupportedAppUsage;
 import android.util.TimeUtils;
 import android.util.proto.ProtoOutputStream;
 
@@ -111,6 +112,7 @@
     /** Flags to clear in the copyFrom method */
     /*package*/ static final int FLAGS_TO_CLEAR_ON_COPY_FROM = FLAG_IN_USE;
 
+    @UnsupportedAppUsage
     /*package*/ int flags;
 
     /**
@@ -118,16 +120,20 @@
      * {@link SystemClock#uptimeMillis}.
      * @hide Only for use within the tests.
      */
+    @UnsupportedAppUsage
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
     public long when;
 
     /*package*/ Bundle data;
 
+    @UnsupportedAppUsage
     /*package*/ Handler target;
 
+    @UnsupportedAppUsage
     /*package*/ Runnable callback;
 
     // sometimes we store linked lists of these things
+    @UnsupportedAppUsage
     /*package*/ Message next;
 
 
@@ -314,6 +320,7 @@
      * Recycles a Message that may be in-use.
      * Used internally by the MessageQueue and Looper when disposing of queued Messages.
      */
+    @UnsupportedAppUsage
     void recycleUnchecked() {
         // Mark the message as in use while it remains in the recycled object pool.
         // Clear out all other details.
@@ -397,6 +404,7 @@
     }
 
     /** @hide */
+    @UnsupportedAppUsage
     public Message setCallback(Runnable r) {
         callback = r;
         return this;
@@ -510,6 +518,7 @@
         return ((flags & FLAG_IN_USE) == FLAG_IN_USE);
     }
 
+    @UnsupportedAppUsage
     /*package*/ void markInUse() {
         flags |= FLAG_IN_USE;
     }
@@ -524,6 +533,7 @@
         return toString(SystemClock.uptimeMillis());
     }
 
+    @UnsupportedAppUsage
     String toString(long now) {
         StringBuilder b = new StringBuilder();
         b.append("{ when=");
diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java
index 7c2ecc5..c5f1698 100644
--- a/core/java/android/os/MessageQueue.java
+++ b/core/java/android/os/MessageQueue.java
@@ -19,6 +19,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
 import android.os.MessageQueueProto;
 import android.util.Log;
 import android.util.Printer;
@@ -43,12 +44,16 @@
     private static final boolean DEBUG = false;
 
     // True if the message queue can be quit.
+    @UnsupportedAppUsage
     private final boolean mQuitAllowed;
 
+    @UnsupportedAppUsage
     @SuppressWarnings("unused")
     private long mPtr; // used by native code
 
+    @UnsupportedAppUsage
     Message mMessages;
+    @UnsupportedAppUsage
     private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>();
     private SparseArray<FileDescriptorRecord> mFileDescriptorRecords;
     private IdleHandler[] mPendingIdleHandlers;
@@ -59,10 +64,12 @@
 
     // The next barrier token.
     // Barriers are indicated by messages with a null target whose arg1 field carries the token.
+    @UnsupportedAppUsage
     private int mNextBarrierToken;
 
     private native static long nativeInit();
     private native static void nativeDestroy(long ptr);
+    @UnsupportedAppUsage
     private native void nativePollOnce(long ptr, int timeoutMillis); /*non-static for callbacks*/
     private native static void nativeWake(long ptr);
     private native static boolean nativeIsPolling(long ptr);
@@ -260,6 +267,7 @@
     }
 
     // Called from native code.
+    @UnsupportedAppUsage
     private int dispatchEvents(int fd, int events) {
         // Get the file descriptor record and any state that might change.
         final FileDescriptorRecord record;
@@ -308,6 +316,7 @@
         return newWatchedEvents;
     }
 
+    @UnsupportedAppUsage
     Message next() {
         // Return here if the message loop has already quit and been disposed.
         // This can happen if the application tries to restart a looper after quit
@@ -607,6 +616,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     boolean hasMessages(Handler h, Runnable r, Object object) {
         if (h == null) {
             return false;
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 79e9ba5..de963c9 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -197,6 +198,7 @@
     private static final boolean DEBUG_ARRAY_MAP = false;
     private static final String TAG = "Parcel";
 
+    @UnsupportedAppUsage
     @SuppressWarnings({"UnusedDeclaration"})
     private long mNativePtr; // used by native code
 
@@ -453,9 +455,11 @@
     }
 
     /** @hide */
+    @UnsupportedAppUsage
     public static native long getGlobalAllocSize();
 
     /** @hide */
+    @UnsupportedAppUsage
     public static native long getGlobalAllocCount();
 
     /**
@@ -679,6 +683,7 @@
      * {@hide}
      * {@SystemApi}
      */
+    @UnsupportedAppUsage
     public final void writeBlob(@Nullable byte[] b) {
         writeBlob(b, 0, (b != null) ? b.length : 0);
     }
@@ -768,6 +773,7 @@
      * growing dataCapacity() if needed.
      * @hide
      */
+    @UnsupportedAppUsage
     public final void writeCharSequence(@Nullable CharSequence val) {
         TextUtils.writeToParcel(val, this, 0);
     }
@@ -929,6 +935,7 @@
     /**
      * @hide For testing only.
      */
+    @UnsupportedAppUsage
     public void writeArrayMap(@Nullable ArrayMap<String, Object> val) {
         writeArrayMapInternal(val);
     }
@@ -967,6 +974,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public void writeArraySet(@Nullable ArraySet<? extends Object> val) {
         final int size = (val != null) ? val.size() : -1;
         writeInt(size);
@@ -1793,6 +1801,7 @@
     }
 
     /** @hide */
+    @UnsupportedAppUsage
     public final void writeParcelableCreator(@NonNull Parcelable p) {
         String name = p.getClass().getName();
         writeString(name);
@@ -1991,6 +2000,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public final int readExceptionCode() {
         int code = readInt();
         if (code == EX_HAS_REPLY_HEADER) {
@@ -2137,6 +2147,7 @@
      * Read a CharSequence value from the parcel at the current dataPosition().
      * @hide
      */
+    @UnsupportedAppUsage
     @Nullable
     public final CharSequence readCharSequence() {
         return TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(this);
@@ -2158,6 +2169,7 @@
     }
 
     /** {@hide} */
+    @UnsupportedAppUsage
     public final FileDescriptor readRawFileDescriptor() {
         return nativeReadFileDescriptor(mNativePtr);
     }
@@ -2349,6 +2361,7 @@
      * {@hide}
      * {@SystemApi}
      */
+    @UnsupportedAppUsage
     @Nullable
     public final byte[] readBlob() {
         return nativeReadBlob(mNativePtr);
@@ -2358,6 +2371,7 @@
      * Read and return a String[] object from the parcel.
      * {@hide}
      */
+    @UnsupportedAppUsage
     @Nullable
     public final String[] readStringArray() {
         String[] array = null;
@@ -2958,6 +2972,7 @@
     }
 
     /** @hide */
+    @UnsupportedAppUsage
     @SuppressWarnings("unchecked")
     @Nullable
     public final <T extends Parcelable> T readCreator(@NonNull Parcelable.Creator<?> creator,
@@ -2971,6 +2986,7 @@
     }
 
     /** @hide */
+    @UnsupportedAppUsage
     @Nullable
     public final Parcelable.Creator<?> readParcelableCreator(@Nullable ClassLoader loader) {
         String name = readString();
@@ -3253,6 +3269,7 @@
     /**
      * @hide For testing only.
      */
+    @UnsupportedAppUsage
     public void readArrayMap(@NonNull ArrayMap outVal, @Nullable ClassLoader loader) {
         final int N = readInt();
         if (N < 0) {
@@ -3268,6 +3285,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public @Nullable ArraySet<? extends Object> readArraySet(@Nullable ClassLoader loader) {
         final int size = readInt();
         if (size < 0) {
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index ed1d8a5..8355e08 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -32,6 +32,7 @@
 import static android.system.OsConstants.S_IWOTH;
 
 import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.ContentProvider;
 import android.os.MessageQueue.OnFileDescriptorEventListener;
@@ -178,6 +179,7 @@
     }
 
     /** {@hide} */
+    @UnsupportedAppUsage
     public ParcelFileDescriptor(FileDescriptor fd) {
         this(fd, null);
     }
@@ -574,6 +576,7 @@
      * @return A ParcelFileDescriptor.
      * @throws IOException if there is an error while creating the shared memory area.
      */
+    @UnsupportedAppUsage
     @Deprecated
     public static ParcelFileDescriptor fromData(byte[] data, String name) throws IOException {
         if (data == null) return null;
@@ -659,6 +662,7 @@
      * and I really don't think we want it to be public.
      * @hide
      */
+    @UnsupportedAppUsage
     public long seekTo(long pos) throws IOException {
         if (mWrapped != null) {
             return mWrapped.seekTo(pos);
diff --git a/core/java/android/os/ParcelableParcel.java b/core/java/android/os/ParcelableParcel.java
index 5bbe6488..61f3968 100644
--- a/core/java/android/os/ParcelableParcel.java
+++ b/core/java/android/os/ParcelableParcel.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.annotation.UnsupportedAppUsage;
 import android.util.MathUtils;
 
 /**
@@ -26,6 +27,7 @@
     final Parcel mParcel;
     final ClassLoader mClassLoader;
 
+    @UnsupportedAppUsage
     public ParcelableParcel(ClassLoader loader) {
         mParcel = Parcel.obtain();
         mClassLoader = loader;
@@ -44,11 +46,13 @@
         mParcel.appendFrom(src, pos, size);
     }
 
+    @UnsupportedAppUsage
     public Parcel getParcel() {
         mParcel.setDataPosition(0);
         return mParcel;
     }
 
+    @UnsupportedAppUsage
     public ClassLoader getClassLoader() {
         return mClassLoader;
     }
@@ -64,6 +68,7 @@
         dest.appendFrom(mParcel, 0, mParcel.dataSize());
     }
 
+    @UnsupportedAppUsage
     public static final Parcelable.ClassLoaderCreator<ParcelableParcel> CREATOR
             = new Parcelable.ClassLoaderCreator<ParcelableParcel>() {
         public ParcelableParcel createFromParcel(Parcel in) {
diff --git a/core/java/android/os/PerformanceCollector.java b/core/java/android/os/PerformanceCollector.java
index be1cf6d..33c86b8 100644
--- a/core/java/android/os/PerformanceCollector.java
+++ b/core/java/android/os/PerformanceCollector.java
@@ -17,6 +17,7 @@
 package android.os;
 
 
+import android.annotation.UnsupportedAppUsage;
 import java.util.ArrayList;
 
 /**
@@ -285,6 +286,7 @@
     private long mCpuTime;
     private long mExecTime;
 
+    @UnsupportedAppUsage
     public PerformanceCollector() {
     }
 
@@ -302,6 +304,7 @@
      * @param label description of code block between beginSnapshot and
      *              endSnapshot, used to label output
      */
+    @UnsupportedAppUsage
     public void beginSnapshot(String label) {
         if (mPerfWriter != null)
             mPerfWriter.writeBeginSnapshot(label);
@@ -346,6 +349,7 @@
      *         <li>{@link #METRIC_KEY_OTHER_SHARED_DIRTY other_shared_dirty}
      *         </ul>
      */
+    @UnsupportedAppUsage
     public Bundle endSnapshot() {
         endPerformanceSnapshot();
         if (mPerfWriter != null)
@@ -359,6 +363,7 @@
      * @param label description of code block between startTiming and
      *        stopTiming, used to label output
      */
+    @UnsupportedAppUsage
     public void startTiming(String label) {
         if (mPerfWriter != null)
             mPerfWriter.writeStartTiming(label);
@@ -408,6 +413,7 @@
      *         between calls to startTiming and stopTiming. List of iterations
      *         is keyed by {@link #METRIC_KEY_ITERATIONS iterations}.
      */
+    @UnsupportedAppUsage
     public Bundle stopTiming(String label) {
         addIteration(label);
         if (mPerfWriter != null)
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index fdc5157..36bae2d 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -25,6 +25,7 @@
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.service.dreams.Sandman;
 import android.util.ArrayMap;
@@ -290,6 +291,7 @@
      * Brightness value for fully on.
      * @hide
      */
+    @UnsupportedAppUsage
     public static final int BRIGHTNESS_ON = 255;
 
     /**
@@ -384,6 +386,7 @@
      * Go to sleep reason code: Going to sleep due to a screen timeout.
      * @hide
      */
+    @UnsupportedAppUsage
     public static final int GO_TO_SLEEP_REASON_TIMEOUT = 2;
 
     /**
@@ -805,6 +808,7 @@
     }
 
     final Context mContext;
+    @UnsupportedAppUsage
     final IPowerManager mService;
     final Handler mHandler;
 
@@ -829,6 +833,7 @@
      * this is the minimum value that can be set by the user.
      * @hide
      */
+    @UnsupportedAppUsage
     public int getMinimumScreenBrightnessSetting() {
         return mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_screenBrightnessSettingMinimum);
@@ -840,6 +845,7 @@
      * this is the maximum value that can be set by the user.
      * @hide
      */
+    @UnsupportedAppUsage
     public int getMaximumScreenBrightnessSetting() {
         return mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_screenBrightnessSettingMaximum);
@@ -849,6 +855,7 @@
      * Gets the default screen brightness setting.
      * @hide
      */
+    @UnsupportedAppUsage
     public int getDefaultScreenBrightnessSetting() {
         return mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_screenBrightnessSettingDefault);
@@ -963,6 +970,7 @@
     }
 
     /** @hide */
+    @UnsupportedAppUsage
     public static void validateWakeLockParameters(int levelAndFlags, String tag) {
         switch (levelAndFlags & WAKE_LOCK_LEVEL_MASK) {
             case PARTIAL_WAKE_LOCK:
@@ -1095,6 +1103,7 @@
      *
      * @hide Requires signature permission.
      */
+    @UnsupportedAppUsage
     public void goToSleep(long time, int reason, int flags) {
         try {
             mService.goToSleep(time, reason, flags);
@@ -1151,6 +1160,7 @@
      * @deprecated Use {@link #wakeUp(long, int, String)} instead.
      * @hide
      */
+    @UnsupportedAppUsage
     @Deprecated
     public void wakeUp(long time, String details) {
         wakeUp(time, WAKE_REASON_UNKNOWN, details);
@@ -1635,6 +1645,7 @@
      * restrictions have been lifted.
      * @hide
      */
+    @UnsupportedAppUsage
     public boolean isLightDeviceIdleMode() {
         try {
             return mService.isLightDeviceIdleMode();
@@ -1970,6 +1981,7 @@
      * This broadcast is only sent to registered receivers.
      * @hide
      */
+    @UnsupportedAppUsage
     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED
             = "android.os.action.LIGHT_DEVICE_IDLE_MODE_CHANGED";
@@ -1996,11 +2008,13 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_POWER_SAVE_MODE_CHANGING
             = "android.os.action.POWER_SAVE_MODE_CHANGING";
 
     /** @hide */
+    @UnsupportedAppUsage
     public static final String EXTRA_POWER_SAVE_MODE = "mode";
 
     /**
@@ -2051,7 +2065,9 @@
      * </p>
      */
     public final class WakeLock {
+        @UnsupportedAppUsage
         private int mFlags;
+        @UnsupportedAppUsage
         private String mTag;
         private final String mPackageName;
         private final IBinder mToken;
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 03fc2a9..a7ac7a1 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
 import android.system.Os;
 import android.system.OsConstants;
 import android.webkit.WebViewZygote;
@@ -60,30 +61,35 @@
      * Defines the UID/GID for the log group.
      * @hide
      */
+    @UnsupportedAppUsage
     public static final int LOG_UID = 1007;
 
     /**
      * Defines the UID/GID for the WIFI supplicant process.
      * @hide
      */
+    @UnsupportedAppUsage
     public static final int WIFI_UID = 1010;
 
     /**
      * Defines the UID/GID for the mediaserver process.
      * @hide
      */
+    @UnsupportedAppUsage
     public static final int MEDIA_UID = 1013;
 
     /**
      * Defines the UID/GID for the DRM process.
      * @hide
      */
+    @UnsupportedAppUsage
     public static final int DRM_UID = 1019;
 
     /**
      * Defines the UID/GID for the group that controls VPN services.
      * @hide
      */
+    @UnsupportedAppUsage
     public static final int VPN_UID = 1016;
 
     /**
@@ -96,6 +102,7 @@
      * Defines the UID/GID for the NFC service process.
      * @hide
      */
+    @UnsupportedAppUsage
     public static final int NFC_UID = 1027;
 
     /**
@@ -600,6 +607,7 @@
      * Returns the identifier of this process' parent.
      * @hide
      */
+    @UnsupportedAppUsage
     public static final int myPpid() {
         return Os.getppid();
     }
@@ -658,6 +666,7 @@
     }
 
     /** {@hide} */
+    @UnsupportedAppUsage
     public static final boolean isIsolated(int uid) {
         uid = UserHandle.getAppId(uid);
         return (uid >= FIRST_ISOLATED_UID && uid <= LAST_ISOLATED_UID)
@@ -684,6 +693,7 @@
      * @return the uid of the process, or -1 if the process is not running.
      * @hide pending API council review
      */
+    @UnsupportedAppUsage
     public static final int getUidForPid(int pid) {
         String[] procStatusLabels = { "Uid:" };
         long[] procStatusValues = new long[1];
@@ -698,6 +708,7 @@
      * @return the parent process id of the process, or -1 if the process is not running.
      * @hide
      */
+    @UnsupportedAppUsage
     public static final int getParentPid(int pid) {
         String[] procStatusLabels = { "PPid:" };
         long[] procStatusValues = new long[1];
@@ -801,6 +812,7 @@
      *
      * Always sets cpusets.
      */
+    @UnsupportedAppUsage
     public static final native void setProcessGroup(int pid, int group)
             throws IllegalArgumentException, SecurityException;
 
@@ -942,6 +954,7 @@
      * 
      * {@hide}
      */
+    @UnsupportedAppUsage
     public static final native void setArgV0(String text);
 
     /**
@@ -992,41 +1005,55 @@
     public static final native void sendSignalQuiet(int pid, int signal);
     
     /** @hide */
+    @UnsupportedAppUsage
     public static final native long getFreeMemory();
     
     /** @hide */
+    @UnsupportedAppUsage
     public static final native long getTotalMemory();
     
     /** @hide */
+    @UnsupportedAppUsage
     public static final native void readProcLines(String path,
             String[] reqFields, long[] outSizes);
     
     /** @hide */
+    @UnsupportedAppUsage
     public static final native int[] getPids(String path, int[] lastArray);
     
     /** @hide */
+    @UnsupportedAppUsage
     public static final int PROC_TERM_MASK = 0xff;
     /** @hide */
+    @UnsupportedAppUsage
     public static final int PROC_ZERO_TERM = 0;
     /** @hide */
+    @UnsupportedAppUsage
     public static final int PROC_SPACE_TERM = (int)' ';
     /** @hide */
+    @UnsupportedAppUsage
     public static final int PROC_TAB_TERM = (int)'\t';
     /** @hide */
     public static final int PROC_NEWLINE_TERM = (int) '\n';
     /** @hide */
+    @UnsupportedAppUsage
     public static final int PROC_COMBINE = 0x100;
     /** @hide */
+    @UnsupportedAppUsage
     public static final int PROC_PARENS = 0x200;
     /** @hide */
+    @UnsupportedAppUsage
     public static final int PROC_QUOTES = 0x400;
     /** @hide */
     public static final int PROC_CHAR = 0x800;
     /** @hide */
+    @UnsupportedAppUsage
     public static final int PROC_OUT_STRING = 0x1000;
     /** @hide */
+    @UnsupportedAppUsage
     public static final int PROC_OUT_LONG = 0x2000;
     /** @hide */
+    @UnsupportedAppUsage
     public static final int PROC_OUT_FLOAT = 0x4000;
 
     /**
@@ -1058,14 +1085,17 @@
      * @param outFloats the parsed {@code float}s from the file
      * @hide
      */
+    @UnsupportedAppUsage
     public static final native boolean readProcFile(String file, int[] format,
             String[] outStrings, long[] outLongs, float[] outFloats);
 
     /** @hide */
+    @UnsupportedAppUsage
     public static final native boolean parseProcLine(byte[] buffer, int startIndex, 
             int endIndex, int[] format, String[] outStrings, long[] outLongs, float[] outFloats);
 
     /** @hide */
+    @UnsupportedAppUsage
     public static final native int[] getPidsForCommands(String[] cmds);
 
     /**
@@ -1076,6 +1106,7 @@
      *  or -1 if the value cannot be determined 
      * @hide
      */
+    @UnsupportedAppUsage
     public static final native long getPss(int pid);
 
     /** @hide */
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 3ee54ce..6a01e56 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -22,6 +22,7 @@
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
+import android.annotation.UnsupportedAppUsage;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
@@ -355,6 +356,7 @@
      *
      * @return the verification result.
      */
+    @UnsupportedAppUsage
     private static boolean verifyPackageCompatibility(InputStream inputStream) throws IOException {
         ArrayList<String> list = new ArrayList<>();
         ZipInputStream zis = new ZipInputStream(inputStream);
diff --git a/core/java/android/os/Registrant.java b/core/java/android/os/Registrant.java
index 705cc5d..8fb123a 100644
--- a/core/java/android/os/Registrant.java
+++ b/core/java/android/os/Registrant.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.Handler;
 import android.os.Message;
 
@@ -24,6 +25,7 @@
 /** @hide */
 public class Registrant
 {
+    @UnsupportedAppUsage
     public
     Registrant(Handler h, int what, Object obj)
     {
@@ -32,6 +34,7 @@
         userObj = obj;
     }
 
+    @UnsupportedAppUsage
     public void
     clear()
     {
@@ -39,12 +42,14 @@
         userObj = null;
     }
 
+    @UnsupportedAppUsage
     public void
     notifyRegistrant()
     {
         internalNotifyRegistrant (null, null);
     }
     
+    @UnsupportedAppUsage
     public void
     notifyResult(Object result)
     {
@@ -60,6 +65,7 @@
     /**
      * This makes a copy of @param ar
      */
+    @UnsupportedAppUsage
     public void
     notifyRegistrant(AsyncResult ar)
     {
@@ -88,6 +94,7 @@
      * NOTE: May return null if weak reference has been collected
      */
 
+    @UnsupportedAppUsage
     public Message
     messageForRegistrant()
     {
diff --git a/core/java/android/os/RegistrantList.java b/core/java/android/os/RegistrantList.java
index 9ab61f5..6e562ff 100644
--- a/core/java/android/os/RegistrantList.java
+++ b/core/java/android/os/RegistrantList.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.Handler;         
 
 import java.util.ArrayList;
@@ -25,12 +26,14 @@
 {
     ArrayList   registrants = new ArrayList();      // of Registrant
 
+    @UnsupportedAppUsage
     public synchronized void
     add(Handler h, int what, Object obj)
     {
         add(new Registrant(h, what, obj));
     }
 
+    @UnsupportedAppUsage
     public synchronized void
     addUnique(Handler h, int what, Object obj)
     {
@@ -39,6 +42,7 @@
         add(new Registrant(h, what, obj));        
     }
     
+    @UnsupportedAppUsage
     public synchronized void
     add(Registrant r)
     {
@@ -46,6 +50,7 @@
         registrants.add(r);
     }
 
+    @UnsupportedAppUsage
     public synchronized void
     removeCleared()
     {
@@ -58,6 +63,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     public synchronized int
     size()
     {
@@ -79,6 +85,7 @@
        }
     }
     
+    @UnsupportedAppUsage
     public /*synchronized*/ void
     notifyRegistrants()
     {
@@ -91,6 +98,7 @@
         internalNotifyRegistrants (null, exception);
     }
 
+    @UnsupportedAppUsage
     public /*synchronized*/ void
     notifyResult(Object result)
     {
@@ -98,12 +106,14 @@
     }
 
     
+    @UnsupportedAppUsage
     public /*synchronized*/ void
     notifyRegistrants(AsyncResult ar)
     {
         internalNotifyRegistrants(ar.result, ar.exception);
     }
     
+    @UnsupportedAppUsage
     public synchronized void
     remove(Handler h)
     {
diff --git a/core/java/android/os/RemoteCallbackList.java b/core/java/android/os/RemoteCallbackList.java
index be8f784..b377e8d 100644
--- a/core/java/android/os/RemoteCallbackList.java
+++ b/core/java/android/os/RemoteCallbackList.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.annotation.UnsupportedAppUsage;
 import android.util.ArrayMap;
 import android.util.Slog;
 
@@ -53,6 +54,7 @@
 public class RemoteCallbackList<E extends IInterface> {
     private static final String TAG = "RemoteCallbackList";
 
+    @UnsupportedAppUsage
     /*package*/ ArrayMap<IBinder, Callback> mCallbacks
             = new ArrayMap<IBinder, Callback>();
     private Object[] mActiveBroadcast;
diff --git a/core/java/android/os/RemoteException.java b/core/java/android/os/RemoteException.java
index 4e8b971..2e673a8 100644
--- a/core/java/android/os/RemoteException.java
+++ b/core/java/android/os/RemoteException.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.annotation.UnsupportedAppUsage;
 import android.util.AndroidException;
 
 /**
@@ -54,6 +55,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public RuntimeException rethrowFromSystemServer() {
         if (this instanceof DeadObjectException) {
             throw new RuntimeException(new DeadSystemException());
diff --git a/core/java/android/os/SELinux.java b/core/java/android/os/SELinux.java
index a96618a..8ffafe4 100644
--- a/core/java/android/os/SELinux.java
+++ b/core/java/android/os/SELinux.java
@@ -42,12 +42,14 @@
      * Determine whether SELinux is disabled or enabled.
      * @return a boolean indicating whether SELinux is enabled.
      */
+    @UnsupportedAppUsage
     public static final native boolean isSELinuxEnabled();
 
     /**
      * Determine whether SELinux is permissive or enforcing.
      * @return a boolean indicating whether SELinux is enforcing.
      */
+    @UnsupportedAppUsage
     public static final native boolean isSELinuxEnforced();
 
     /**
@@ -91,6 +93,7 @@
      * Gets the security context of the current process.
      * @return a String representing the security context of the current process.
      */
+    @UnsupportedAppUsage
     public static final native String getContext();
 
     /**
@@ -98,6 +101,7 @@
      * @param pid an int representing the process id to check.
      * @return a String representing the security context of the given pid.
      */
+    @UnsupportedAppUsage
     public static final native String getPidContext(int pid);
 
     /**
@@ -108,6 +112,7 @@
      * @param perm The permission name.
      * @return a boolean indicating whether permission was granted.
      */
+    @UnsupportedAppUsage
     public static final native boolean checkSELinuxAccess(String scon, String tcon, String tclass, String perm);
 
     /**
@@ -167,6 +172,7 @@
      *
      * @return a boolean indicating whether the relabeling succeeded.
      */
+    @UnsupportedAppUsage
     public static boolean restoreconRecursive(File file) {
         try {
             return native_restorecon(file.getCanonicalPath(), SELINUX_ANDROID_RESTORECON_RECURSE);
diff --git a/core/java/android/os/ServiceManager.java b/core/java/android/os/ServiceManager.java
index 2966bff..9a9b030 100644
--- a/core/java/android/os/ServiceManager.java
+++ b/core/java/android/os/ServiceManager.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.annotation.UnsupportedAppUsage;
 import android.util.ArrayMap;
 import android.util.Log;
 
@@ -30,11 +31,13 @@
     private static final String TAG = "ServiceManager";
     private static final Object sLock = new Object();
 
+    @UnsupportedAppUsage
     private static IServiceManager sServiceManager;
 
     /**
      * Cache for the "well known" services, such as WM and AM.
      */
+    @UnsupportedAppUsage
     private static Map<String, IBinder> sCache = new ArrayMap<String, IBinder>();
 
     /**
@@ -98,6 +101,7 @@
             "getService()",
     });
 
+    @UnsupportedAppUsage
     private static IServiceManager getIServiceManager() {
         if (sServiceManager != null) {
             return sServiceManager;
@@ -115,6 +119,7 @@
      * @param name the name of the service to get
      * @return a reference to the service, or <code>null</code> if the service doesn't exist
      */
+    @UnsupportedAppUsage
     public static IBinder getService(String name) {
         try {
             IBinder service = sCache.get(name);
@@ -151,6 +156,7 @@
      * @param name the name of the new service
      * @param service the service object
      */
+    @UnsupportedAppUsage
     public static void addService(String name, IBinder service) {
         addService(name, service, false, IServiceManager.DUMP_FLAG_PRIORITY_DEFAULT);
     }
@@ -164,6 +170,7 @@
      * @param allowIsolated set to true to allow isolated sandboxed processes
      * to access this service
      */
+    @UnsupportedAppUsage
     public static void addService(String name, IBinder service, boolean allowIsolated) {
         addService(name, service, allowIsolated, IServiceManager.DUMP_FLAG_PRIORITY_DEFAULT);
     }
@@ -178,6 +185,7 @@
      * @param dumpPriority supported dump priority levels as a bitmask
      * to access this service
      */
+    @UnsupportedAppUsage
     public static void addService(String name, IBinder service, boolean allowIsolated,
             int dumpPriority) {
         try {
@@ -191,6 +199,7 @@
      * Retrieve an existing service called @a name from the
      * service manager.  Non-blocking.
      */
+    @UnsupportedAppUsage
     public static IBinder checkService(String name) {
         try {
             IBinder service = sCache.get(name);
@@ -210,6 +219,7 @@
      * @return an array of all currently running services, or <code>null</code> in
      * case of an exception
      */
+    @UnsupportedAppUsage
     public static String[] listServices() {
         try {
             return getIServiceManager().listServices(IServiceManager.DUMP_FLAG_PRIORITY_ALL);
diff --git a/core/java/android/os/ServiceManagerNative.java b/core/java/android/os/ServiceManagerNative.java
index 589b8c4..b7c026c 100644
--- a/core/java/android/os/ServiceManagerNative.java
+++ b/core/java/android/os/ServiceManagerNative.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.annotation.UnsupportedAppUsage;
 import java.util.ArrayList;
 
 
@@ -30,6 +31,7 @@
      * Cast a Binder object into a service manager interface, generating
      * a proxy if needed.
      */
+    @UnsupportedAppUsage
     static public IServiceManager asInterface(IBinder obj)
     {
         if (obj == null) {
@@ -117,6 +119,7 @@
         return mRemote;
     }
 
+    @UnsupportedAppUsage
     public IBinder getService(String name) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
@@ -196,5 +199,6 @@
         data.recycle();
     }
 
+    @UnsupportedAppUsage
     private IBinder mRemote;
 }
diff --git a/core/java/android/os/SharedMemory.java b/core/java/android/os/SharedMemory.java
index 395485b..57a8801 100644
--- a/core/java/android/os/SharedMemory.java
+++ b/core/java/android/os/SharedMemory.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
@@ -156,6 +157,7 @@
      *
      * @hide Exposed for native ASharedMemory_dupFromJava()
      */
+    @UnsupportedAppUsage
     public int getFd() {
         return mFileDescriptor.getInt$();
     }
diff --git a/core/java/android/os/ShellCommand.java b/core/java/android/os/ShellCommand.java
index 5228d6d..2fe8726 100644
--- a/core/java/android/os/ShellCommand.java
+++ b/core/java/android/os/ShellCommand.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.annotation.UnsupportedAppUsage;
 import android.util.Slog;
 
 import com.android.internal.util.FastPrintWriter;
@@ -304,6 +305,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     public String peekNextArg() {
         if (mCurArgData != null) {
             return mCurArgData;
diff --git a/core/java/android/os/StatFs.java b/core/java/android/os/StatFs.java
index 4e0b238..881d0b4 100644
--- a/core/java/android/os/StatFs.java
+++ b/core/java/android/os/StatFs.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.annotation.UnsupportedAppUsage;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.StructStatVfs;
@@ -25,6 +26,7 @@
  * wrapper for Unix statvfs().
  */
 public class StatFs {
+    @UnsupportedAppUsage
     private StructStatVfs mStat;
 
     /**
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index f0b83d8..94cca30 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -20,6 +20,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
 import android.app.ActivityManager;
 import android.app.ActivityThread;
 import android.app.IActivityManager;
@@ -421,6 +422,7 @@
         /** The default, lax policy which doesn't catch anything. */
         public static final ThreadPolicy LAX = new ThreadPolicy(0, null, null);
 
+        @UnsupportedAppUsage
         final @ThreadPolicyMask int mask;
         final OnThreadViolationListener mListener;
         final Executor mCallbackExecutor;
@@ -713,6 +715,7 @@
         /** The default, lax policy which doesn't catch anything. */
         public static final VmPolicy LAX = new VmPolicy(0, EMPTY_CLASS_LIMIT_MAP, null, null);
 
+        @UnsupportedAppUsage
         final @VmPolicyMask int mask;
         final OnVmViolationListener mListener;
         final Executor mCallbackExecutor;
@@ -758,6 +761,7 @@
          * </pre>
          */
         public static final class Builder {
+            @UnsupportedAppUsage
             private @VmPolicyMask int mMask;
             private OnVmViolationListener mListener;
             private Executor mExecutor;
@@ -1208,6 +1212,7 @@
      * @return the bitmask of all the DETECT_* and PENALTY_* bits currently enabled
      * @hide
      */
+    @UnsupportedAppUsage
     public static @ThreadPolicyMask int getThreadPolicyMask() {
         final BlockGuard.Policy policy = BlockGuard.getThreadPolicy();
         if (policy instanceof AndroidBlockGuardPolicy) {
@@ -1412,6 +1417,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public static void enableDeathOnFileUriExposure() {
         sVmPolicy =
                 new VmPolicy(
@@ -1429,6 +1435,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public static void disableDeathOnFileUriExposure() {
         sVmPolicy =
                 new VmPolicy(
@@ -1440,6 +1447,7 @@
                         sVmPolicy.mCallbackExecutor);
     }
 
+    @UnsupportedAppUsage
     private static final ThreadLocal<ArrayList<ViolationInfo>> violationsBeingTimed =
             new ThreadLocal<ArrayList<ViolationInfo>>() {
                 @Override
@@ -2051,6 +2059,7 @@
     }
 
     /** @hide */
+    @UnsupportedAppUsage
     public static void onWebViewMethodCalledOnWrongThread(Throwable originStack) {
         onVmPolicyViolation(new WebViewMethodCalledOnWrongThreadViolation(originStack));
     }
@@ -2155,6 +2164,7 @@
     }
 
     // Map from VM violation fingerprint to uptime millis.
+    @UnsupportedAppUsage
     private static final HashMap<Integer, Long> sLastVmViolationTime = new HashMap<>();
 
     /** @hide */
@@ -2280,6 +2290,7 @@
      * Binder for its current (native) thread-local policy value and synchronize it to libcore's
      * (Java) thread-local policy value.
      */
+    @UnsupportedAppUsage
     private static void onBinderStrictModePolicyChange(@ThreadPolicyMask int newPolicy) {
         setBlockGuardPolicy(newPolicy);
     }
@@ -2316,6 +2327,7 @@
          *
          * @hide
          */
+        @UnsupportedAppUsage
         public void finish() {
             ThreadSpanState state = mContainerState;
             synchronized (state) {
@@ -2387,6 +2399,7 @@
                 }
             };
 
+    @UnsupportedAppUsage
     private static Singleton<IWindowManager> sWindowManager =
             new Singleton<IWindowManager>() {
                 protected IWindowManager create() {
@@ -2407,6 +2420,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public static Span enterCriticalSpan(String name) {
         if (Build.IS_USER) {
             return NO_OP_SPAN;
@@ -2516,6 +2530,7 @@
     }
 
     /** @hide */
+    @UnsupportedAppUsage
     public static void incrementExpectedActivityCount(Class klass) {
         if (klass == null) {
             return;
diff --git a/core/java/android/os/SystemClock.java b/core/java/android/os/SystemClock.java
index b2541663..e695a1b 100644
--- a/core/java/android/os/SystemClock.java
+++ b/core/java/android/os/SystemClock.java
@@ -17,6 +17,7 @@
 package android.os;
 
 import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
 import android.app.IAlarmManager;
 import android.content.Context;
 import android.util.Slog;
@@ -104,6 +105,7 @@
     /**
      * This class is uninstantiable.
      */
+    @UnsupportedAppUsage
     private SystemClock() {
         // This space intentionally left blank.
     }
@@ -241,6 +243,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     @CriticalNative
     public static native long currentThreadTimeMicro();
 
@@ -251,6 +254,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     @CriticalNative
     public static native long currentTimeMicro();
 
diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java
index cbcf600..edfdda8bb 100644
--- a/core/java/android/os/SystemProperties.java
+++ b/core/java/android/os/SystemProperties.java
@@ -20,6 +20,7 @@
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
 import android.util.Log;
 import android.util.MutableInt;
 
@@ -51,11 +52,13 @@
      * uses reflection to read this whenever text is selected (http://b/36095274).
      * @hide
      */
+    @UnsupportedAppUsage
     public static final int PROP_NAME_MAX = Integer.MAX_VALUE;
 
     /** @hide */
     public static final int PROP_VALUE_MAX = 91;
 
+    @UnsupportedAppUsage
     @GuardedBy("sChangeCallbacks")
     private static final ArrayList<Runnable> sChangeCallbacks = new ArrayList<Runnable>();
 
@@ -83,9 +86,11 @@
         }
     }
 
+    @UnsupportedAppUsage
     private static native String native_get(String key);
     private static native String native_get(String key, String def);
     private static native int native_get_int(String key, int def);
+    @UnsupportedAppUsage
     private static native long native_get_long(String key, long def);
     private static native boolean native_get_boolean(String key, boolean def);
     private static native void native_set(String key, String def);
@@ -180,6 +185,7 @@
      * @throws IllegalArgumentException if the {@code val} exceeds 91 characters
      * @hide
      */
+    @UnsupportedAppUsage
     public static void set(@NonNull String key, @Nullable String val) {
         if (val != null && !val.startsWith("ro.") && val.length() > PROP_VALUE_MAX) {
             throw new IllegalArgumentException("value of system property '" + key
@@ -196,6 +202,7 @@
      * changes.
      * @hide
      */
+    @UnsupportedAppUsage
     public static void addChangeCallback(@NonNull Runnable callback) {
         synchronized (sChangeCallbacks) {
             if (sChangeCallbacks.size() == 0) {
@@ -233,6 +240,7 @@
      * Notifies listeners that a system property has changed
      * @hide
      */
+    @UnsupportedAppUsage
     public static void reportSyspropChanged() {
         native_report_sysprop_change();
     }
@@ -258,6 +266,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private SystemProperties() {
     }
 }
diff --git a/core/java/android/os/SystemService.java b/core/java/android/os/SystemService.java
index 41e7546..968c761 100644
--- a/core/java/android/os/SystemService.java
+++ b/core/java/android/os/SystemService.java
@@ -18,6 +18,7 @@
 
 import com.google.android.collect.Maps;
 
+import android.annotation.UnsupportedAppUsage;
 import java.util.HashMap;
 import java.util.concurrent.TimeoutException;
 
@@ -58,11 +59,13 @@
     }
 
     /** Request that the init daemon start a named service. */
+    @UnsupportedAppUsage
     public static void start(String name) {
         SystemProperties.set("ctl.start", name);
     }
 
     /** Request that the init daemon stop a named service. */
+    @UnsupportedAppUsage
     public static void stop(String name) {
         SystemProperties.set("ctl.stop", name);
     }
diff --git a/core/java/android/os/SystemVibrator.java b/core/java/android/os/SystemVibrator.java
index c989197..4af514a 100644
--- a/core/java/android/os/SystemVibrator.java
+++ b/core/java/android/os/SystemVibrator.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.media.AudioAttributes;
 import android.util.Log;
@@ -31,10 +32,12 @@
     private final IVibratorService mService;
     private final Binder mToken = new Binder();
 
+    @UnsupportedAppUsage
     public SystemVibrator() {
         mService = IVibratorService.Stub.asInterface(ServiceManager.getService("vibrator"));
     }
 
+    @UnsupportedAppUsage
     public SystemVibrator(Context context) {
         super(context);
         mService = IVibratorService.Stub.asInterface(ServiceManager.getService("vibrator"));
diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java
index 68d6d85..1456a73 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -17,6 +17,7 @@
 package android.os;
 
 import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
 
 import com.android.internal.os.Zygote;
 
@@ -52,6 +53,7 @@
     /** @hide */
     public static final long TRACE_TAG_INPUT = 1L << 2;
     /** @hide */
+    @UnsupportedAppUsage
     public static final long TRACE_TAG_VIEW = 1L << 3;
     /** @hide */
     public static final long TRACE_TAG_WEBVIEW = 1L << 4;
@@ -70,6 +72,7 @@
     /** @hide */
     public static final long TRACE_TAG_HAL = 1L << 11;
     /** @hide */
+    @UnsupportedAppUsage
     public static final long TRACE_TAG_APP = 1L << 12;
     /** @hide */
     public static final long TRACE_TAG_RESOURCES = 1L << 13;
@@ -104,10 +107,12 @@
     private static final int MAX_SECTION_NAME_LEN = 127;
 
     // Must be volatile to avoid word tearing.
+    @UnsupportedAppUsage
     private static volatile long sEnabledTags = TRACE_TAG_NOT_READY;
 
     private static int sZygoteDebugFlags = 0;
 
+    @UnsupportedAppUsage
     private static native long nativeGetEnabledTags();
     private static native void nativeSetAppTracingAllowed(boolean allowed);
     private static native void nativeSetTracingEnabled(boolean allowed);
@@ -171,6 +176,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public static boolean isTagEnabled(long traceTag) {
         long tags = sEnabledTags;
         if (tags == TRACE_TAG_NOT_READY) {
@@ -188,6 +194,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public static void traceCounter(long traceTag, String counterName, int counterValue) {
         if (isTagEnabled(traceTag)) {
             nativeTraceCounter(traceTag, counterName, counterValue);
@@ -200,6 +207,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public static void setAppTracingAllowed(boolean allowed) {
         nativeSetAppTracingAllowed(allowed);
 
@@ -235,6 +243,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public static void traceBegin(long traceTag, String methodName) {
         if (isTagEnabled(traceTag)) {
             nativeTraceBegin(traceTag, methodName);
@@ -249,6 +258,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public static void traceEnd(long traceTag) {
         if (isTagEnabled(traceTag)) {
             nativeTraceEnd(traceTag);
@@ -268,6 +278,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public static void asyncTraceBegin(long traceTag, String methodName, int cookie) {
         if (isTagEnabled(traceTag)) {
             nativeAsyncTraceBegin(traceTag, methodName, cookie);
@@ -285,6 +296,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public static void asyncTraceEnd(long traceTag, String methodName, int cookie) {
         if (isTagEnabled(traceTag)) {
             nativeAsyncTraceEnd(traceTag, methodName, cookie);
diff --git a/core/java/android/os/UEventObserver.java b/core/java/android/os/UEventObserver.java
index 69a3922..dc98c42 100644
--- a/core/java/android/os/UEventObserver.java
+++ b/core/java/android/os/UEventObserver.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.annotation.UnsupportedAppUsage;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -49,6 +50,7 @@
     private static native void nativeAddMatch(String match);
     private static native void nativeRemoveMatch(String match);
 
+    @UnsupportedAppUsage
     public UEventObserver() {
     }
 
@@ -93,6 +95,7 @@
      * are expensive to parse.  For example, some devices may send one netlink message
      * for each vsync period.
      */
+    @UnsupportedAppUsage
     public final void startObserving(String match) {
         if (match == null || match.isEmpty()) {
             throw new IllegalArgumentException("match substring must be non-empty");
@@ -107,6 +110,7 @@
      * This process's UEvent thread will never call onUEvent() on this
      * UEventObserver after this call. Repeated calls have no effect.
      */
+    @UnsupportedAppUsage
     public final void stopObserving() {
         final UEventThread t = peekThread();
         if (t != null) {
@@ -118,6 +122,7 @@
      * Subclasses of UEventObserver should override this method to handle
      * UEvents.
      */
+    @UnsupportedAppUsage
     public abstract void onUEvent(UEvent event);
 
     /**
@@ -146,10 +151,12 @@
             }
         }
 
+        @UnsupportedAppUsage
         public String get(String key) {
             return mMap.get(key);
         }
 
+        @UnsupportedAppUsage
         public String get(String key, String defaultValue) {
             String result = mMap.get(key);
             return (result == null ? defaultValue : result);
diff --git a/core/java/android/os/UpdateLock.java b/core/java/android/os/UpdateLock.java
index 4060326..ea273ce 100644
--- a/core/java/android/os/UpdateLock.java
+++ b/core/java/android/os/UpdateLock.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.util.Log;
 
@@ -50,6 +51,7 @@
      * locker releases theirs.  The broadcast is sticky but is sent only to
      * registered receivers.
      */
+    @UnsupportedAppUsage
     public static final String UPDATE_LOCK_CHANGED = "android.os.UpdateLock.UPDATE_LOCK_CHANGED";
 
     /**
@@ -58,6 +60,7 @@
      * update operation.  True means that updates are okay right now; false indicates
      * that perhaps later would be a better time.
      */
+    @UnsupportedAppUsage
     public static final String NOW_IS_CONVENIENT = "nowisconvenient";
 
     /**
@@ -66,6 +69,7 @@
      * in the System.currentTimeMillis() time base, which may be non-monotonic especially
      * around reboots.
      */
+    @UnsupportedAppUsage
     public static final String TIMESTAMP = "timestamp";
 
     /**
@@ -90,6 +94,7 @@
     /**
      * Is this lock currently held?
      */
+    @UnsupportedAppUsage
     public boolean isHeld() {
         synchronized (mToken) {
             return mHeld;
@@ -99,6 +104,7 @@
     /**
      * Acquire an update lock.
      */
+    @UnsupportedAppUsage
     public void acquire() {
         if (DEBUG) {
             Log.v(TAG, "acquire() : " + this, new RuntimeException("here"));
@@ -125,6 +131,7 @@
     /**
      * Release this update lock.
      */
+    @UnsupportedAppUsage
     public void release() {
         if (DEBUG) Log.v(TAG, "release() : " + this, new RuntimeException("here"));
         checkService();
diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java
index 286185b..b121234 100644
--- a/core/java/android/os/UserHandle.java
+++ b/core/java/android/os/UserHandle.java
@@ -20,6 +20,7 @@
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
 import android.annotation.UserIdInt;
 
 import java.io.PrintWriter;
@@ -33,9 +34,11 @@
     /**
      * @hide Range of uids allocated for a user.
      */
+    @UnsupportedAppUsage
     public static final int PER_USER_RANGE = 100000;
 
     /** @hide A user id to indicate all users on the device */
+    @UnsupportedAppUsage
     public static final @UserIdInt int USER_ALL = -1;
 
     /** @hide A user handle to indicate all users on the device */
@@ -44,6 +47,7 @@
     public static final @NonNull UserHandle ALL = new UserHandle(USER_ALL);
 
     /** @hide A user id to indicate the currently active user */
+    @UnsupportedAppUsage
     public static final @UserIdInt int USER_CURRENT = -2;
 
     /** @hide A user handle to indicate the current user of the device */
@@ -54,11 +58,13 @@
     /** @hide A user id to indicate that we would like to send to the current
      *  user, but if this is calling from a user process then we will send it
      *  to the caller's user instead of failing with a security exception */
+    @UnsupportedAppUsage
     public static final @UserIdInt int USER_CURRENT_OR_SELF = -3;
 
     /** @hide A user handle to indicate that we would like to send to the current
      *  user, but if this is calling from a user process then we will send it
      *  to the caller's user instead of failing with a security exception */
+    @UnsupportedAppUsage
     public static final @NonNull UserHandle CURRENT_OR_SELF = new UserHandle(USER_CURRENT_OR_SELF);
 
     /** @hide An undefined user id */
@@ -69,6 +75,7 @@
      * @deprecated Consider using either {@link UserHandle#USER_SYSTEM} constant or
      * check the target user's flag {@link android.content.pm.UserInfo#isAdmin}.
      */
+    @UnsupportedAppUsage
     @Deprecated
     public static final @UserIdInt int USER_OWNER = 0;
 
@@ -77,13 +84,16 @@
      * @deprecated Consider using either {@link UserHandle#SYSTEM} constant or
      * check the target user's flag {@link android.content.pm.UserInfo#isAdmin}.
      */
+    @UnsupportedAppUsage
     @Deprecated
     public static final @NonNull UserHandle OWNER = new UserHandle(USER_OWNER);
 
     /** @hide A user id constant to indicate the "system" user of the device */
+    @UnsupportedAppUsage
     public static final @UserIdInt int USER_SYSTEM = 0;
 
     /** @hide A user serial constant to indicate the "system" user of the device */
+    @UnsupportedAppUsage
     public static final int USER_SERIAL_SYSTEM = 0;
 
     /** @hide A user handle to indicate the "system" user of the device */
@@ -95,21 +105,29 @@
      * @hide Enable multi-user related side effects. Set this to false if
      * there are problems with single user use-cases.
      */
+    @UnsupportedAppUsage
     public static final boolean MU_ENABLED = true;
 
     /** @hide */
+    @UnsupportedAppUsage
     public static final int ERR_GID = -1;
     /** @hide */
+    @UnsupportedAppUsage
     public static final int AID_ROOT = android.os.Process.ROOT_UID;
     /** @hide */
+    @UnsupportedAppUsage
     public static final int AID_APP_START = android.os.Process.FIRST_APPLICATION_UID;
     /** @hide */
+    @UnsupportedAppUsage
     public static final int AID_APP_END = android.os.Process.LAST_APPLICATION_UID;
     /** @hide */
+    @UnsupportedAppUsage
     public static final int AID_SHARED_GID_START = android.os.Process.FIRST_SHARED_APPLICATION_GID;
     /** @hide */
+    @UnsupportedAppUsage
     public static final int AID_CACHE_GID_START = android.os.Process.FIRST_APPLICATION_CACHE_GID;
 
+    @UnsupportedAppUsage
     final int mHandle;
 
     /**
@@ -129,6 +147,7 @@
      * @return whether the appId is the same for both uids
      * @hide
      */
+    @UnsupportedAppUsage
     public static boolean isSameApp(int uid1, int uid2) {
         return getAppId(uid1) == getAppId(uid2);
     }
@@ -137,6 +156,7 @@
      * Whether a UID is an "isolated" UID.
      * @hide
      */
+    @UnsupportedAppUsage
     public static boolean isIsolated(int uid) {
         if (uid > 0) {
             return Process.isIsolated(uid);
@@ -186,6 +206,7 @@
      * Returns the user id for a given uid.
      * @hide
      */
+    @UnsupportedAppUsage
     public static @UserIdInt int getUserId(int uid) {
         if (MU_ENABLED) {
             return uid / PER_USER_RANGE;
@@ -195,6 +216,7 @@
     }
 
     /** @hide */
+    @UnsupportedAppUsage
     public static @UserIdInt int getCallingUserId() {
         return getUserId(Binder.getCallingUid());
     }
@@ -214,6 +236,7 @@
      * Returns the uid that is composed from the userId and the appId.
      * @hide
      */
+    @UnsupportedAppUsage
     public static int getUid(@UserIdInt int userId, @AppIdInt int appId) {
         if (MU_ENABLED) {
             return userId * PER_USER_RANGE + (appId % PER_USER_RANGE);
@@ -260,6 +283,7 @@
      * Returns the app id for a given shared app gid. Returns -1 if the ID is invalid.
      * @hide
      */
+    @UnsupportedAppUsage
     public static @AppIdInt int getAppIdFromSharedAppGid(int gid) {
         final int appId = getAppId(gid) + Process.FIRST_APPLICATION_UID
                 - Process.FIRST_SHARED_APPLICATION_GID;
@@ -405,6 +429,7 @@
     }
 
     /** @hide */
+    @UnsupportedAppUsage
     public UserHandle(int h) {
         mHandle = h;
     }
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 185df5e..790bb27 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -70,6 +70,7 @@
 public class UserManager {
 
     private static final String TAG = "UserManager";
+    @UnsupportedAppUsage
     private final IUserManager mService;
     private final Context mContext;
 
@@ -810,6 +811,7 @@
      * @see #getUserRestrictions()
      * @hide
      */
+    @UnsupportedAppUsage
     public static final String DISALLOW_RECORD_AUDIO = "no_record_audio";
 
     /**
@@ -1238,6 +1240,7 @@
     }
 
     /** @hide */
+    @UnsupportedAppUsage
     public static UserManager get(Context context) {
         return (UserManager) context.getSystemService(Context.USER_SERVICE);
     }
@@ -1341,6 +1344,7 @@
      * @return the user handle of this process.
      * @hide
      */
+    @UnsupportedAppUsage
     public @UserIdInt int getUserHandle() {
         return UserHandle.myUserId();
     }
@@ -1348,12 +1352,16 @@
     /**
      * Returns the user name of the user making this call.  This call is only
      * available to applications on the system image; it requires the
-     * MANAGE_USERS permission.
+     * {@code android.permission.MANAGE_USERS} or {@code android.permission.GET_ACCOUNTS_PRIVILEGED}
+     * permissions.
      * @return the user name
      */
     public String getUserName() {
-        UserInfo user = getUserInfo(getUserHandle());
-        return user == null ? "" : user.name;
+        try {
+            return mService.getUserName();
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
     }
 
     /**
@@ -1428,6 +1436,7 @@
      * Returns whether the provided user is an admin user. There can be more than one admin
      * user.
      */
+    @UnsupportedAppUsage
     public boolean isUserAdmin(@UserIdInt int userId) {
         UserInfo user = getUserInfo(userId);
         return user != null && user.isAdmin();
@@ -1437,6 +1446,7 @@
      * @hide
      * @deprecated Use {@link #isRestrictedProfile()}
      */
+    @UnsupportedAppUsage
     @Deprecated
     public boolean isLinkedUser() {
         return isRestrictedProfile();
@@ -1490,6 +1500,7 @@
      * @return whether user is a guest user.
      * @hide
      */
+    @UnsupportedAppUsage
     public boolean isGuestUser(int id) {
         UserInfo user = getUserInfo(id);
         return user != null && user.isGuest();
@@ -1699,6 +1710,7 @@
     }
 
     /** {@hide} */
+    @UnsupportedAppUsage
     public boolean isUserUnlocked(@UserIdInt int userId) {
         try {
             return mService.isUserUnlocked(userId);
@@ -1727,6 +1739,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public long getUserStartRealtime() {
         try {
             return mService.getUserStartRealtime();
@@ -1741,6 +1754,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public long getUserUnlockRealtime() {
         try {
             return mService.getUserUnlockRealtime();
@@ -1756,6 +1770,7 @@
      * @return the UserInfo object for a specific user.
      * @hide
      */
+    @UnsupportedAppUsage
     public UserInfo getUserInfo(@UserIdInt int userHandle) {
         try {
             return mService.getUserInfo(userHandle);
@@ -1836,6 +1851,7 @@
      * @param restrictionKey the string key representing the restriction
      * @param userHandle the UserHandle of the user for whom to retrieve the restrictions.
      */
+    @UnsupportedAppUsage
     public boolean hasBaseUserRestriction(String restrictionKey, UserHandle userHandle) {
         try {
             return mService.hasBaseUserRestriction(restrictionKey, userHandle.getIdentifier());
@@ -1918,6 +1934,7 @@
      * @param restrictionKey the string key representing the restriction
      * @param userHandle the UserHandle of the user for whom to retrieve the restrictions.
      */
+    @UnsupportedAppUsage
     public boolean hasUserRestriction(String restrictionKey, UserHandle userHandle) {
         try {
             return mService.hasUserRestriction(restrictionKey,
@@ -1978,6 +1995,7 @@
      * @return the UserInfo object for the created user, or null if the user could not be created.
      * @hide
      */
+    @UnsupportedAppUsage
     public UserInfo createUser(String name, int flags) {
         UserInfo user = null;
         try {
@@ -2026,6 +2044,7 @@
      *         could not be created.
      * @hide
      */
+    @UnsupportedAppUsage
     public UserInfo createProfileForUser(String name, int flags, @UserIdInt int userHandle) {
         return createProfileForUser(name, flags, userHandle, null);
     }
@@ -2314,6 +2333,7 @@
      * @return the list of users that exist on the device.
      * @hide
      */
+    @UnsupportedAppUsage
     public List<UserInfo> getUsers() {
         try {
             return mService.getUsers(false);
@@ -2439,6 +2459,7 @@
      * @return the list of profiles.
      * @hide
      */
+    @UnsupportedAppUsage
     public List<UserInfo> getProfiles(@UserIdInt int userHandle) {
         try {
             return mService.getProfiles(userHandle, false /* enabledOnly */);
@@ -2472,6 +2493,7 @@
      * @return the list of profiles.
      * @hide
      */
+    @UnsupportedAppUsage
     public List<UserInfo> getEnabledProfiles(@UserIdInt int userHandle) {
         try {
             return mService.getProfiles(userHandle, true /* enabledOnly */);
@@ -2519,6 +2541,7 @@
      * @see #getProfileIds(int, boolean)
      * @hide
      */
+    @UnsupportedAppUsage
     public int[] getProfileIdsWithDisabled(@UserIdInt int userId) {
         return getProfileIds(userId, false /* enabledOnly */);
     }
@@ -2552,6 +2575,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     public UserInfo getProfileParent(@UserIdInt int userHandle) {
         try {
             return mService.getProfileParent(userHandle);
@@ -2721,6 +2745,7 @@
      * @return the list of users that were created.
      * @hide
      */
+    @UnsupportedAppUsage
     public @NonNull List<UserInfo> getUsers(boolean excludeDying) {
         try {
             return mService.getUsers(excludeDying);
@@ -2735,6 +2760,7 @@
      * @param userHandle the integer handle of the user, where 0 is the primary user.
      * @hide
      */
+    @UnsupportedAppUsage
     public boolean removeUser(@UserIdInt int userHandle) {
         try {
             return mService.removeUser(userHandle);
@@ -2840,6 +2866,7 @@
      * @see com.android.internal.util.UserIcons#getDefaultUserIcon for a default.
      * @hide
      */
+    @UnsupportedAppUsage
     public Bitmap getUserIcon(@UserIdInt int userHandle) {
         try {
             ParcelFileDescriptor fd = mService.getUserIcon(userHandle);
@@ -2861,14 +2888,16 @@
 
     /**
      * Returns a Bitmap for the calling user's photo.
-     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
+     * Requires {@link android.Manifest.permission#MANAGE_USERS}
+     * or {@link android.Manifest.permission#GET_ACCOUNTS_PRIVILEGED} permissions.
      *
      * @return a {@link Bitmap} of the user's photo, or null if there's no photo.
      * @see com.android.internal.util.UserIcons#getDefaultUserIcon for a default.
      * @hide
      */
     @SystemApi
-    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
+    @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS,
+            android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED})
     public @Nullable Bitmap getUserIcon() {
         return getUserIcon(getUserHandle());
     }
@@ -2879,6 +2908,7 @@
      * @hide
      * @return a value greater than or equal to 1
      */
+    @UnsupportedAppUsage
     public static int getMaxSupportedUsers() {
         // Don't allow multiple users on certain builds
         if (android.os.Build.ID.startsWith("JVP")) return 1;
@@ -2934,6 +2964,7 @@
     /**
      * @hide
      */
+    @UnsupportedAppUsage
     public static boolean isDeviceInDemoMode(Context context) {
         return Settings.Global.getInt(context.getContentResolver(),
                 Settings.Global.DEVICE_DEMO_MODE, 0) > 0;
@@ -2946,6 +2977,7 @@
      * @return a serial number associated with that user, or -1 if the userHandle is not valid.
      * @hide
      */
+    @UnsupportedAppUsage
     public int getUserSerialNumber(@UserIdInt int userHandle) {
         try {
             return mService.getUserSerialNumber(userHandle);
@@ -2963,6 +2995,7 @@
      * is not valid.
      * @hide
      */
+    @UnsupportedAppUsage
     public @UserIdInt int getUserHandle(int userSerialNumber) {
         try {
             return mService.getUserHandle(userSerialNumber);
diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java
index 226d1d0..28909c8 100644
--- a/core/java/android/os/Vibrator.java
+++ b/core/java/android/os/Vibrator.java
@@ -19,6 +19,7 @@
 import android.annotation.IntDef;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemService;
+import android.annotation.UnsupportedAppUsage;
 import android.app.ActivityThread;
 import android.content.Context;
 import android.media.AudioAttributes;
@@ -85,6 +86,7 @@
     /**
      * @hide to prevent subclassing from outside of the framework
      */
+    @UnsupportedAppUsage
     public Vibrator() {
         mPackageName = ActivityThread.currentPackageName();
         final Context ctx = ActivityThread.currentActivityThread().getSystemContext();
diff --git a/core/java/android/os/WorkSource.java b/core/java/android/os/WorkSource.java
index 9980ade..0b4a561 100644
--- a/core/java/android/os/WorkSource.java
+++ b/core/java/android/os/WorkSource.java
@@ -3,6 +3,7 @@
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.WorkSourceProto;
 import android.provider.Settings;
@@ -24,8 +25,11 @@
     static final String TAG = "WorkSource";
     static final boolean DEBUG = false;
 
+    @UnsupportedAppUsage
     int mNum;
+    @UnsupportedAppUsage
     int[] mUids;
+    @UnsupportedAppUsage
     String[] mNames;
 
     private ArrayList<WorkChain> mChains;
@@ -103,6 +107,7 @@
         mChains = null;
     }
 
+    @UnsupportedAppUsage
     WorkSource(Parcel in) {
         mNum = in.readInt();
         mUids = in.createIntArray();
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index 6f0a1f2..40238d2 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
 import android.content.pm.ApplicationInfo;
 import android.net.LocalSocket;
 import android.net.LocalSocketAddress;
@@ -41,10 +42,12 @@
 import java.util.UUID;
 
 /*package*/ class ZygoteStartFailedEx extends Exception {
+    @UnsupportedAppUsage
     ZygoteStartFailedEx(String s) {
         super(s);
     }
 
+    @UnsupportedAppUsage
     ZygoteStartFailedEx(Throwable cause) {
         super(cause);
     }
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 27e3914..3e60d51 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -16,6 +16,8 @@
 
 package android.os.storage;
 
+import static android.content.ContentResolver.DEPRECATE_DATA_PREFIX;
+
 import android.annotation.BytesLong;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -30,6 +32,7 @@
 import android.annotation.WorkerThread;
 import android.app.Activity;
 import android.app.ActivityThread;
+import android.app.AppGlobals;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
@@ -1139,6 +1142,12 @@
         if (file == null) {
             return null;
         }
+        final String path = file.getAbsolutePath();
+        if (path.startsWith(DEPRECATE_DATA_PREFIX)) {
+            final Uri uri = ContentResolver.translateDeprecatedDataPath(path);
+            return AppGlobals.getInitialApplication().getSystemService(StorageManager.class)
+                    .getStorageVolume(uri);
+        }
         try {
             file = file.getCanonicalFile();
         } catch (IOException ignored) {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index df5da6c..313384d 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -9053,7 +9053,6 @@
          * @return true if the provider is enabled
          *
          * @deprecated use {@link LocationManager#isProviderEnabled(String)}
-         * @removed no longer supported
          */
         @Deprecated
         public static boolean isLocationProviderEnabled(ContentResolver cr, String provider) {
@@ -9063,12 +9062,12 @@
         }
 
         /**
-         * Thread-safe method for enabling or disabling a single location provider.
+         * Thread-safe method for enabling or disabling a single location provider. This will have
+         * no effect on Android Q and above.
          * @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
-         * @removed no longer supported
          */
         @Deprecated
         public static void setLocationProviderEnabled(ContentResolver cr,
diff --git a/core/java/android/view/GestureDetector.java b/core/java/android/view/GestureDetector.java
index c794a69..c1d122a 100644
--- a/core/java/android/view/GestureDetector.java
+++ b/core/java/android/view/GestureDetector.java
@@ -16,11 +16,20 @@
 
 package android.view;
 
+import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DEEP_PRESS;
+import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DOUBLE_TAP;
+import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS;
+import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SCROLL;
+import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SINGLE_TAP;
+import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__UNKNOWN_CLASSIFICATION;
+
 import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.Build;
 import android.os.Handler;
 import android.os.Message;
+import android.os.SystemClock;
+import android.util.StatsLog;
 
 /**
  * Detects various gestures and events using the supplied {@link MotionEvent}s.
@@ -251,8 +260,12 @@
     private boolean mAlwaysInTapRegion;
     private boolean mAlwaysInBiggerTapRegion;
     private boolean mIgnoreNextUpEvent;
+    // Whether a classification has been recorded by statsd for the current event stream. Reset on
+    // ACTION_DOWN.
+    private boolean mHasRecordedClassification;
 
     private MotionEvent mCurrentDownEvent;
+    private MotionEvent mCurrentMotionEvent;
     private MotionEvent mPreviousUpEvent;
 
     /**
@@ -297,6 +310,7 @@
                     break;
 
                 case LONG_PRESS:
+                    recordGestureClassification(msg.arg1);
                     dispatchLongPress();
                     break;
 
@@ -304,6 +318,8 @@
                     // If the user's finger is still down, do not count it as a tap
                     if (mDoubleTapListener != null) {
                         if (!mStillDown) {
+                            recordGestureClassification(
+                                    TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SINGLE_TAP);
                             mDoubleTapListener.onSingleTapConfirmed(mCurrentDownEvent);
                         } else {
                             mDeferConfirmSingleTap = true;
@@ -501,6 +517,11 @@
 
         final int action = ev.getAction();
 
+        if (mCurrentMotionEvent != null) {
+            mCurrentMotionEvent.recycle();
+        }
+        mCurrentMotionEvent = MotionEvent.obtain(ev);
+
         if (mVelocityTracker == null) {
             mVelocityTracker = VelocityTracker.obtain();
         }
@@ -569,6 +590,8 @@
                             && isConsideredDoubleTap(mCurrentDownEvent, mPreviousUpEvent, ev)) {
                         // This is a second tap
                         mIsDoubleTapping = true;
+                        recordGestureClassification(
+                                TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DOUBLE_TAP);
                         // Give a callback with the first tap of the double-tap
                         handled |= mDoubleTapListener.onDoubleTap(mCurrentDownEvent);
                         // Give a callback with down event of the double-tap
@@ -590,11 +613,17 @@
                 mStillDown = true;
                 mInLongPress = false;
                 mDeferConfirmSingleTap = false;
+                mHasRecordedClassification = false;
 
                 if (mIsLongpressEnabled) {
                     mHandler.removeMessages(LONG_PRESS);
-                    mHandler.sendEmptyMessageAtTime(LONG_PRESS, mCurrentDownEvent.getDownTime()
-                            + ViewConfiguration.getLongPressTimeout());
+                    mHandler.sendMessageAtTime(
+                            mHandler.obtainMessage(
+                                    LONG_PRESS,
+                                    TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS,
+                                    0 /* arg2 */),
+                            mCurrentDownEvent.getDownTime()
+                                    + ViewConfiguration.getLongPressTimeout());
                 }
                 mHandler.sendEmptyMessageAtTime(SHOW_PRESS,
                         mCurrentDownEvent.getDownTime() + TAP_TIMEOUT);
@@ -613,6 +642,8 @@
                 final float scrollY = mLastFocusY - focusY;
                 if (mIsDoubleTapping) {
                     // Give the move events of the double-tap
+                    recordGestureClassification(
+                            TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DOUBLE_TAP);
                     handled |= mDoubleTapListener.onDoubleTapEvent(ev);
                 } else if (mAlwaysInTapRegion) {
                     final int deltaX = (int) (focusX - mDownFocusX);
@@ -635,8 +666,12 @@
                             // reschedule long press with a modified timeout.
                             mHandler.removeMessages(LONG_PRESS);
                             final long longPressTimeout = ViewConfiguration.getLongPressTimeout();
-                            mHandler.sendEmptyMessageAtTime(LONG_PRESS, ev.getDownTime()
-                                    + (long) (longPressTimeout * multiplier));
+                            mHandler.sendMessageAtTime(
+                                    mHandler.obtainMessage(
+                                            LONG_PRESS,
+                                            TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS,
+                                            0 /* arg2 */),
+                                    ev.getDownTime() + (long) (longPressTimeout * multiplier));
                         }
                         // Inhibit default scroll. If a gesture is ambiguous, we prevent scroll
                         // until the gesture is resolved.
@@ -646,6 +681,8 @@
                     }
 
                     if (distance > slopSquare) {
+                        recordGestureClassification(
+                                TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SCROLL);
                         handled = mListener.onScroll(mCurrentDownEvent, ev, scrollX, scrollY);
                         mLastFocusX = focusX;
                         mLastFocusY = focusY;
@@ -659,6 +696,7 @@
                         mAlwaysInBiggerTapRegion = false;
                     }
                 } else if ((Math.abs(scrollX) >= 1) || (Math.abs(scrollY) >= 1)) {
+                    recordGestureClassification(TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SCROLL);
                     handled = mListener.onScroll(mCurrentDownEvent, ev, scrollX, scrollY);
                     mLastFocusX = focusX;
                     mLastFocusY = focusY;
@@ -667,7 +705,11 @@
                         motionClassification == MotionEvent.CLASSIFICATION_DEEP_PRESS;
                 if (deepPress && hasPendingLongPress) {
                     mHandler.removeMessages(LONG_PRESS);
-                    mHandler.sendEmptyMessage(LONG_PRESS);
+                    mHandler.sendMessage(
+                            mHandler.obtainMessage(
+                                  LONG_PRESS,
+                                  TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DEEP_PRESS,
+                                  0 /* arg2 */));
                 }
                 break;
 
@@ -676,11 +718,15 @@
                 MotionEvent currentUpEvent = MotionEvent.obtain(ev);
                 if (mIsDoubleTapping) {
                     // Finally, give the up event of the double-tap
+                    recordGestureClassification(
+                            TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DOUBLE_TAP);
                     handled |= mDoubleTapListener.onDoubleTapEvent(ev);
                 } else if (mInLongPress) {
                     mHandler.removeMessages(TAP);
                     mInLongPress = false;
                 } else if (mAlwaysInTapRegion && !mIgnoreNextUpEvent) {
+                    recordGestureClassification(
+                            TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SINGLE_TAP);
                     handled = mListener.onSingleTapUp(ev);
                     if (mDeferConfirmSingleTap && mDoubleTapListener != null) {
                         mDoubleTapListener.onSingleTapConfirmed(ev);
@@ -821,4 +867,21 @@
         mInLongPress = true;
         mListener.onLongPress(mCurrentDownEvent);
     }
+
+    private void recordGestureClassification(int classification) {
+        if (mHasRecordedClassification
+                || classification
+                    == TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__UNKNOWN_CLASSIFICATION) {
+            // Only record the first classification for an event stream.
+            return;
+        }
+        StatsLog.write(
+                StatsLog.TOUCH_GESTURE_CLASSIFIED,
+                getClass().getName(),
+                classification,
+                (int) (SystemClock.uptimeMillis() - mCurrentMotionEvent.getDownTime()),
+                (float) Math.hypot(mCurrentMotionEvent.getRawX() - mCurrentDownEvent.getRawX(),
+                                   mCurrentMotionEvent.getRawY() - mCurrentDownEvent.getRawY()));
+        mHasRecordedClassification = true;
+    }
 }
diff --git a/core/java/android/view/InputWindowHandle.java b/core/java/android/view/InputWindowHandle.java
index ec79eea..16a6412 100644
--- a/core/java/android/view/InputWindowHandle.java
+++ b/core/java/android/view/InputWindowHandle.java
@@ -18,9 +18,12 @@
 
 import static android.view.Display.INVALID_DISPLAY;
 
+import android.annotation.Nullable;
 import android.graphics.Region;
 import android.os.IBinder;
 
+import java.lang.ref.WeakReference;
+
 /**
  * Functions as a handle for a window that can receive input.
  * Enables the native input dispatcher to refer indirectly to the window manager's window state.
@@ -38,7 +41,7 @@
     // The client window.
     public final IWindow clientWindow;
 
-    // The token assosciated with the window.
+    // The token associated with the window.
     public IBinder token;
 
     // The window name.
@@ -98,6 +101,23 @@
     // transports the touch of this window to the display indicated by portalToDisplayId.
     public int portalToDisplayId = INVALID_DISPLAY;
 
+    /**
+     * Crops the touchable region to the bounds of the surface provided.
+     *
+     * This can be used in cases where the window is not
+     * {@link android.view.WindowManager#FLAG_NOT_TOUCH_MODAL} but should be constrained to the
+     * bounds of a parent window. That is the window should receive touch events outside its
+     * window but be limited to its stack bounds, such as in the case of split screen.
+     */
+    public WeakReference<IBinder> touchableRegionCropHandle = new WeakReference<>(null);
+
+    /**
+     * Replace {@link touchableRegion} with the bounds of {@link touchableRegionCropHandle}. If
+     * the handle is {@code null}, the bounds of the surface associated with this window is used
+     * as the touchable region.
+     */
+    public boolean replaceTouchableRegionWithCrop;
+
     private native void nativeDispose();
 
     public InputWindowHandle(InputApplicationHandle inputApplicationHandle,
@@ -127,4 +147,25 @@
             super.finalize();
         }
     }
+
+    /**
+     * Set the window touchable region to the bounds of {@link touchableRegionBounds} ignoring any
+     * touchable region provided.
+     *
+     * @param bounds surface to set the touchable region to. Set to {@code null} to set the bounds
+     * to the current surface.
+     */
+    public void replaceTouchableRegionWithCrop(@Nullable SurfaceControl bounds) {
+        setTouchableRegionCrop(bounds);
+        replaceTouchableRegionWithCrop = true;
+    }
+
+    /**
+     * Crop the window touchable region to the bounds of the surface provided.
+     */
+    public void setTouchableRegionCrop(@Nullable SurfaceControl bounds) {
+        if (bounds != null) {
+            touchableRegionCropHandle = new WeakReference<>(bounds.getHandle());
+        }
+    }
 }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index b857f1e..49eb78d 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -17,6 +17,10 @@
 package android.view;
 
 import static android.content.res.Resources.ID_NULL;
+import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DEEP_PRESS;
+import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS;
+import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SINGLE_TAP;
+import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__UNKNOWN_CLASSIFICATION;
 import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
 import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED;
 
@@ -96,6 +100,7 @@
 import android.util.SparseArray;
 import android.util.SparseIntArray;
 import android.util.StateSet;
+import android.util.StatsLog;
 import android.util.SuperNotCalledException;
 import android.util.TypedValue;
 import android.view.AccessibilityIterators.CharacterTextSegmentIterator;
@@ -14542,7 +14547,12 @@
                     if (clickable) {
                         setPressed(true, x, y);
                     }
-                    checkForLongClick(ViewConfiguration.getLongPressTimeout(), x, y);
+                    checkForLongClick(
+                            ViewConfiguration.getLongPressTimeout(),
+                            x,
+                            y,
+                            // This is not a touch gesture -- do not classify it as one.
+                            TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__UNKNOWN_CLASSIFICATION);
                     return true;
                 }
             }
@@ -15283,7 +15293,11 @@
                     mHasPerformedLongPress = false;
 
                     if (!clickable) {
-                        checkForLongClick(ViewConfiguration.getLongPressTimeout(), x, y);
+                        checkForLongClick(
+                                ViewConfiguration.getLongPressTimeout(),
+                                x,
+                                y,
+                                TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS);
                         break;
                     }
 
@@ -15307,7 +15321,11 @@
                     } else {
                         // Not inside a scrolling container, so show the feedback right away
                         setPressed(true, x, y);
-                        checkForLongClick(ViewConfiguration.getLongPressTimeout(), x, y);
+                        checkForLongClick(
+                                ViewConfiguration.getLongPressTimeout(),
+                                x,
+                                y,
+                                TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS);
                     }
                     break;
 
@@ -15344,7 +15362,11 @@
                                     * ambiguousMultiplier);
                             // Subtract the time already spent
                             delay -= event.getEventTime() - event.getDownTime();
-                            checkForLongClick(delay, x, y);
+                            checkForLongClick(
+                                    delay,
+                                    x,
+                                    y,
+                                    TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS);
                         }
                         touchSlop *= ambiguousMultiplier;
                     }
@@ -15366,7 +15388,11 @@
                     if (deepPress && hasPendingLongPressCallback()) {
                         // process the long click action immediately
                         removeLongPressCallback();
-                        checkForLongClick(0 /* send immediately */, x, y);
+                        checkForLongClick(
+                                0 /* send immediately */,
+                                x,
+                                y,
+                                TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DEEP_PRESS);
                     }
 
                     break;
@@ -26031,7 +26057,7 @@
         }
     }
 
-    private void checkForLongClick(long delay, float x, float y) {
+    private void checkForLongClick(long delay, float x, float y, int classification) {
         if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE || (mViewFlags & TOOLTIP) == TOOLTIP) {
             mHasPerformedLongPress = false;
 
@@ -26041,6 +26067,7 @@
             mPendingCheckForLongPress.setAnchor(x, y);
             mPendingCheckForLongPress.rememberWindowAttachCount();
             mPendingCheckForLongPress.rememberPressedState();
+            mPendingCheckForLongPress.setClassification(classification);
             postDelayed(mPendingCheckForLongPress, delay);
         }
     }
@@ -27598,11 +27625,17 @@
         private float mX;
         private float mY;
         private boolean mOriginalPressedState;
+        /**
+         * The classification of the long click being checked: one of the
+         * StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__* constants.
+         */
+        private int mClassification;
 
         @Override
         public void run() {
             if ((mOriginalPressedState == isPressed()) && (mParent != null)
                     && mOriginalWindowAttachCount == mWindowAttachCount) {
+                recordGestureClassification(mClassification);
                 if (performLongClick(mX, mY)) {
                     mHasPerformedLongPress = true;
                 }
@@ -27621,6 +27654,10 @@
         public void rememberPressedState() {
             mOriginalPressedState = isPressed();
         }
+
+        public void setClassification(int classification) {
+            mClassification = classification;
+        }
     }
 
     private final class CheckForTap implements Runnable {
@@ -27633,17 +27670,28 @@
             setPressed(true, x, y);
             final long delay =
                     ViewConfiguration.getLongPressTimeout() - ViewConfiguration.getTapTimeout();
-            checkForLongClick(delay, x, y);
+            checkForLongClick(delay, x, y, TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS);
         }
     }
 
     private final class PerformClick implements Runnable {
         @Override
         public void run() {
+            recordGestureClassification(TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SINGLE_TAP);
             performClickInternal();
         }
     }
 
+    /** Records a classification for the current event stream. */
+    private void recordGestureClassification(int classification) {
+        if (classification == TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__UNKNOWN_CLASSIFICATION) {
+            return;
+        }
+        // To avoid negatively impacting View performance, the latency and displacement metrics
+        // are omitted.
+        StatsLog.write(StatsLog.TOUCH_GESTURE_CLASSIFIED, getClass().getName(), classification);
+    }
+
     /**
      * This method returns a ViewPropertyAnimator object, which can be used to animate
      * specific properties on this View.
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 5f23719..07b82d0 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -122,6 +122,12 @@
 
     private static boolean sPreloadComplete;
 
+    /**
+     * Cached classloader to use for the system server. Will only be populated in the system
+     * server process.
+     */
+    private static ClassLoader sCachedSystemServerClassLoader = null;
+
     static void preload(TimingsTraceLog bootTimingsTraceLog) {
         Log.d(TAG, "begin preload");
         bootTimingsTraceLog.traceBegin("BeginPreload");
@@ -443,7 +449,13 @@
 
         final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
         if (systemServerClasspath != null) {
-            performSystemServerDexOpt(systemServerClasspath);
+            if (performSystemServerDexOpt(systemServerClasspath)) {
+                // Throw away the cached classloader. If we compiled here, the classloader would
+                // not have had AoT-ed artifacts.
+                // Note: This only works in a very special environment where selinux enforcement is
+                // disabled, e.g., Mac builds.
+                sCachedSystemServerClassLoader = null;
+            }
             // Capturing profiles is only supported for debug or eng builds since selinux normally
             // prevents it.
             boolean profileSystemServer = SystemProperties.getBoolean(
@@ -476,10 +488,9 @@
 
             throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
         } else {
-            ClassLoader cl = null;
-            if (systemServerClasspath != null) {
-                cl = createPathClassLoader(systemServerClasspath, parsedArgs.mTargetSdkVersion);
-
+            createSystemServerClassLoader();
+            ClassLoader cl = sCachedSystemServerClassLoader;
+            if (cl != null) {
                 Thread.currentThread().setContextClassLoader(cl);
             }
 
@@ -494,6 +505,24 @@
     }
 
     /**
+     * Create the classloader for the system server and store it in
+     * {@link sCachedSystemServerClassLoader}. This function may be called through JNI in
+     * system server startup, when the runtime is in a critically low state. Do not do
+     * extended computation etc here.
+     */
+    private static void createSystemServerClassLoader() {
+        if (sCachedSystemServerClassLoader != null) {
+            return;
+        }
+        final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
+        // TODO: Should we run optimization here?
+        if (systemServerClasspath != null) {
+            sCachedSystemServerClassLoader = createPathClassLoader(systemServerClasspath,
+                    VMRuntime.SDK_VERSION_CUR_DEVELOPMENT);
+        }
+    }
+
+    /**
      * Note that preparing the profiles for system server does not require special selinux
      * permissions. From the installer perspective the system server is a regular package which can
      * capture profile information.
@@ -557,15 +586,16 @@
 
     /**
      * Performs dex-opt on the elements of {@code classPath}, if needed. We choose the instruction
-     * set of the current runtime.
+     * set of the current runtime. If something was compiled, return true.
      */
-    private static void performSystemServerDexOpt(String classPath) {
+    private static boolean performSystemServerDexOpt(String classPath) {
         final String[] classPathElements = classPath.split(":");
         final IInstalld installd = IInstalld.Stub
                 .asInterface(ServiceManager.getService("installd"));
         final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();
 
         String classPathForElement = "";
+        boolean compiledSomething = false;
         for (String classPathElement : classPathElements) {
             // System server is fully AOTed and never profiled
             // for profile guided compilation.
@@ -607,6 +637,7 @@
                             uuid, classLoaderContext, seInfo, false /* downgrade */,
                             targetSdkVersion, /*profileName*/ null, /*dexMetadataPath*/ null,
                             "server-dexopt");
+                    compiledSomething = true;
                 } catch (RemoteException | ServiceSpecificException e) {
                     // Ignore (but log), we need this on the classpath for fallback mode.
                     Log.w(TAG, "Failed compiling classpath element for system server: "
@@ -617,6 +648,8 @@
             classPathForElement = encodeSystemServerClassPath(
                     classPathForElement, classPathElement);
         }
+
+        return compiledSomething;
     }
 
     /**
diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl
index 3be7c3e..41e2fc84 100644
--- a/core/java/com/android/internal/widget/ILockSettings.aidl
+++ b/core/java/com/android/internal/widget/ILockSettings.aidl
@@ -62,6 +62,7 @@
     void systemReady();
     void userPresent(int userId);
     int getStrongAuthForUser(int userId);
+    boolean hasPendingEscrowToken(int userId);
 
     // Keystore RecoveryController methods.
     // {@code ServiceSpecificException} may be thrown to signal an error, which caller can
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index c095376..1965609 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -1638,7 +1638,7 @@
     }
 
     /**
-     * @see StrongAuthTracker#isFingerprintAllowedForUser
+     * @see StrongAuthTracker#isBiometricAllowedForUser(int)
      */
     public boolean isBiometricAllowedForUser(int userId) {
         return (getStrongAuthForUser(userId) & ~StrongAuthTracker.ALLOWING_BIOMETRIC) == 0;
@@ -1980,6 +1980,18 @@
     }
 
     /**
+     * Returns whether the given user has pending escrow tokens
+     */
+    public boolean hasPendingEscrowToken(int userId) {
+        try {
+            return getLockSettings().hasPendingEscrowToken(userId);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+        return false;
+    }
+
+    /**
      * Return true if the device supports the lock screen feature, false otherwise.
      */
     public boolean hasSecureLockScreen() {
diff --git a/core/jni/android/graphics/HarfBuzzNGFaceSkia.h b/core/jni/android/graphics/HarfBuzzNGFaceSkia.h
deleted file mode 100644
index 3308d5d..0000000
--- a/core/jni/android/graphics/HarfBuzzNGFaceSkia.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2011, The Android Open Source Project
- * Copyright 2011, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _ANDROID_GRAPHICS_HARF_BUZZ_NG_FACE_SKIA_H_
-#define _ANDROID_GRAPHICS_HARF_BUZZ_NG_FACE_SKIA_H_
-
-#include <SkScalar.h>
-#include <SkPaint.h>
-
-#include <hb.h>
-
-namespace android {
-
-static inline float
-HBFixedToFloat (hb_position_t v)
-{
-    return scalbnf (v, -8);
-}
-
-static inline hb_position_t
-HBFloatToFixed (float v)
-{
-    return scalbnf (v, +8);
-}
-
-static inline hb_position_t SkScalarToHBFixed(SkScalar value) {
-    return HBFloatToFixed(SkScalarToFloat(value));
-}
-
-hb_blob_t* harfbuzzSkiaReferenceTable(hb_face_t* face, hb_tag_t tag, void* userData);
-
-hb_font_t* createFont(hb_face_t* face, SkPaint* paint, float sizeX, float sizeY);
-
-}  // namespace android
-
-#endif  // _ANDROID_GRAPHICS_HARF_BUZZ_NG_FACE_SKIA_H_
diff --git a/core/jni/android_hardware_input_InputWindowHandle.cpp b/core/jni/android_hardware_input_InputWindowHandle.cpp
index eb71052..a1d1d4f 100644
--- a/core/jni/android_hardware_input_InputWindowHandle.cpp
+++ b/core/jni/android_hardware_input_InputWindowHandle.cpp
@@ -31,6 +31,11 @@
 
 namespace android {
 
+struct WeakRefHandleField {
+    jfieldID handle;
+    jmethodID get;
+};
+
 static struct {
     jfieldID ptr;
     jfieldID inputApplicationHandle;
@@ -57,6 +62,8 @@
     jfieldID inputFeatures;
     jfieldID displayId;
     jfieldID portalToDisplayId;
+    jfieldID replaceTouchableRegionWithCrop;
+    WeakRefHandleField touchableRegionCropHandle;
 } gInputWindowHandleClassInfo;
 
 static Mutex gHandleMutex;
@@ -90,6 +97,7 @@
     jobject tokenObj = env->GetObjectField(obj, gInputWindowHandleClassInfo.token);
     if (tokenObj) {
         mInfo.token = ibinderForJavaObject(env, tokenObj);
+        env->DeleteLocalRef(tokenObj);
     } else {
         mInfo.token.clear();
     }
@@ -161,6 +169,24 @@
         env->DeleteLocalRef(inputApplicationHandleObj);
     }
 
+    mInfo.replaceTouchableRegionWithCrop = env->GetBooleanField(obj,
+            gInputWindowHandleClassInfo.replaceTouchableRegionWithCrop);
+
+    jobject handleObj = env->GetObjectField(obj,
+            gInputWindowHandleClassInfo.touchableRegionCropHandle.handle);
+    if (handleObj) {
+        // Promote java weak reference.
+        jobject strongHandleObj = env->CallObjectMethod(handleObj,
+                gInputWindowHandleClassInfo.touchableRegionCropHandle.get);
+        if (strongHandleObj) {
+            mInfo.touchableRegionCropHandle = ibinderForJavaObject(env, strongHandleObj);
+            env->DeleteLocalRef(strongHandleObj);
+        } else {
+            mInfo.touchableRegionCropHandle.clear();
+        }
+        env->DeleteLocalRef(handleObj);
+    }
+
     env->DeleteLocalRef(obj);
     return true;
 }
@@ -220,6 +246,10 @@
         var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
         LOG_FATAL_IF(! (var), "Unable to find field " fieldName);
 
+#define GET_METHOD_ID(var, clazz, methodName, methodSignature) \
+        var = env->GetMethodID(clazz, methodName, methodSignature); \
+        LOG_FATAL_IF(! (var), "Unable to find method " methodName);
+
 int register_android_view_InputWindowHandle(JNIEnv* env) {
     int res = jniRegisterNativeMethods(env, "android/view/InputWindowHandle",
             gInputWindowHandleMethods, NELEM(gInputWindowHandleMethods));
@@ -303,6 +333,18 @@
 
     GET_FIELD_ID(gInputWindowHandleClassInfo.portalToDisplayId, clazz,
             "portalToDisplayId", "I");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.replaceTouchableRegionWithCrop, clazz,
+            "replaceTouchableRegionWithCrop", "Z");
+
+    jclass weakRefClazz;
+    FIND_CLASS(weakRefClazz, "java/lang/ref/Reference");
+
+    GET_METHOD_ID(gInputWindowHandleClassInfo.touchableRegionCropHandle.get, weakRefClazz,
+             "get", "()Ljava/lang/Object;")
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.touchableRegionCropHandle.handle, clazz,
+            "touchableRegionCropHandle", "Ljava/lang/ref/WeakReference;");
     return 0;
 }
 
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
index 9f9fbf9..c4c16ee 100644
--- a/core/jni/android_view_RenderNode.cpp
+++ b/core/jni/android_view_RenderNode.cpp
@@ -31,6 +31,7 @@
 #include <renderthread/CanvasContext.h>
 #include <TreeInfo.h>
 #include <hwui/Paint.h>
+#include <utils/TraceUtils.h>
 
 #include "core_jni_helpers.h"
 
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 009a6ca..cde1884 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -24,6 +24,7 @@
 #endif
 
 #define LOG_TAG "Zygote"
+#define ATRACE_TAG ATRACE_TAG_DALVIK
 
 #include <async_safe/log.h>
 
@@ -73,6 +74,7 @@
 #include <cutils/multiuser.h>
 #include <private/android_filesystem_config.h>
 #include <utils/String8.h>
+#include <utils/Trace.h>
 #include <selinux/android.h>
 #include <seccomp_policy.h>
 #include <stats_event_list.h>
@@ -111,11 +113,16 @@
 
 static const char kIsolatedStorage[] = "persist.sys.isolated_storage";
 static const char kIsolatedStorageSnapshot[] = "sys.isolated_storage_snapshot";
-static const char kZygoteClassName[] = "com/android/internal/os/Zygote";
+
+static constexpr const char* kZygoteClassName = "com/android/internal/os/Zygote";
 static jclass gZygoteClass;
 static jmethodID gCallPostForkSystemServerHooks;
 static jmethodID gCallPostForkChildHooks;
 
+static constexpr const char* kZygoteInitClassName = "com/android/internal/os/ZygoteInit";
+static jclass gZygoteInitClass;
+static jmethodID gCreateSystemServerClassLoader;
+
 static bool g_is_security_enforced = true;
 
 /**
@@ -585,6 +592,8 @@
 }
 
 static int UnmountTree(const char* path) {
+  ATRACE_CALL();
+
   size_t path_len = strlen(path);
 
   FILE* fp = setmntent("/proc/mounts", "r");
@@ -627,6 +636,8 @@
 }
 
 static void CreatePkgSandboxTarget(userid_t user_id, fail_fn_t fail_fn) {
+  ATRACE_CALL();
+
   // Create /mnt/user/0/package
   std::string pkg_sandbox_dir = StringPrintf("/mnt/user/%d", user_id);
   CreateDir(pkg_sandbox_dir, 0751, AID_ROOT, AID_ROOT, fail_fn);
@@ -650,6 +661,8 @@
                                 uid_t uid,
                                 const char* dir_name,
                                 fail_fn_t fail_fn) {
+  ATRACE_CALL();
+
   std::string mnt_source_dir = StringPrintf("%s/Android/%s/%s",
       mnt_source_root.c_str(), dir_name, package_name.c_str());
 
@@ -662,6 +675,8 @@
 static void CreateSubDirs(int parent_fd, const std::string& parent_path,
                           const std::vector<std::string>& sub_dirs,
                           fail_fn_t fail_fn) {
+  ATRACE_CALL();
+
   for (auto& dir_name : sub_dirs) {
     struct stat sb;
     if (TEMP_FAILURE_RETRY(fstatat(parent_fd, dir_name.c_str(), &sb, 0)) == 0) {
@@ -686,6 +701,8 @@
                                   const std::vector<std::string>& package_names,
                                   bool create_sandbox_dir,
                                   fail_fn_t fail_fn) {
+  ATRACE_CALL();
+
   std::string android_dir = StringPrintf("%s/Android", path.c_str());
   android::base::unique_fd android_fd(open(android_dir.c_str(),
                                            O_RDONLY | O_DIRECTORY | O_CLOEXEC));
@@ -729,6 +746,7 @@
 }
 
 static void CreatePkgSandboxSource(const std::string& sandbox_source, fail_fn_t fail_fn) {
+  ATRACE_CALL();
 
   struct stat sb;
   if (TEMP_FAILURE_RETRY(stat(sandbox_source.c_str(), &sb)) == 0) {
@@ -751,6 +769,8 @@
 static void PreparePkgSpecificDirs(const std::vector<std::string>& package_names,
                                    bool mount_all_obbs, const std::string& sandbox_id,
                                    userid_t user_id, uid_t uid, fail_fn_t fail_fn) {
+  ATRACE_CALL();
+
   std::unique_ptr<DIR, decltype(&closedir)> dirp(opendir("/storage"), closedir);
   if (!dirp) {
     fail_fn(CREATE_ERROR("Failed to opendir /storage: %s", strerror(errno)));
@@ -807,6 +827,8 @@
                                      userid_t user_id,
                                      const std::string& sandbox_id,
                                      fail_fn_t fail_fn) {
+  ATRACE_CALL();
+
   std::string obb_mount_dir = StringPrintf("/mnt/user/%d/obb_mount", user_id);
   std::string obb_mount_file = StringPrintf("%s/%s", obb_mount_dir.c_str(), sandbox_id.c_str());
   if (mount_mode == MOUNT_EXTERNAL_INSTALLER) {
@@ -844,6 +866,7 @@
         const std::string& sandbox_id,
         fail_fn_t fail_fn) {
   // See storage config details at http://source.android.com/tech/storage/
+  ATRACE_CALL();
 
   String8 storage_source;
   if (mount_mode == MOUNT_EXTERNAL_DEFAULT) {
@@ -1420,6 +1443,15 @@
       fail_fn("Error calling post fork system server hooks.");
     }
 
+    // Prefetch the classloader for the system server. This is done early to
+    // allow a tie-down of the proper system server selinux domain.
+    env->CallStaticVoidMethod(gZygoteInitClass, gCreateSystemServerClassLoader);
+    if (env->ExceptionCheck()) {
+      // Be robust here. The Java code will attempt to create the classloader
+      // at a later point (but may not have rights to use AoT artifacts).
+      env->ExceptionClear();
+    }
+
     // TODO(oth): Remove hardcoded label here (b/117874058).
     static const char* kSystemServerLabel = "u:r:system_server:s0";
     if (selinux_android_setcon(kSystemServerLabel) != 0) {
@@ -1986,6 +2018,13 @@
   gCallPostForkChildHooks = GetStaticMethodIDOrDie(env, gZygoteClass, "callPostForkChildHooks",
                                                    "(IZZLjava/lang/String;)V");
 
-  return RegisterMethodsOrDie(env, "com/android/internal/os/Zygote", gMethods, NELEM(gMethods));
+  gZygoteInitClass = MakeGlobalRefOrDie(env, FindClassOrDie(env, kZygoteInitClassName));
+  gCreateSystemServerClassLoader = GetStaticMethodIDOrDie(env, gZygoteInitClass,
+                                                          "createSystemServerClassLoader",
+                                                          "()V");
+
+  RegisterMethodsOrDie(env, "com/android/internal/os/Zygote", gMethods, NELEM(gMethods));
+
+  return JNI_OK;
 }
 }  // namespace android
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index 927c85f2..7ad9223 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -2302,4 +2302,7 @@
 
     // Panel for Wifi
     PANEL_WIFI = 1687;
+
+    // Open: Settings > Special App Access > Do not disturb control for app
+    ZEN_ACCESS_DETAIL = 1692;
 }
diff --git a/core/proto/android/server/powermanagerservice.proto b/core/proto/android/server/powermanagerservice.proto
index 8fce94e..9bf1825 100644
--- a/core/proto/android/server/powermanagerservice.proto
+++ b/core/proto/android/server/powermanagerservice.proto
@@ -318,6 +318,16 @@
     // Whether battery saver is enabled.
     optional bool enabled = 1;
 
+    enum StateEnum {
+        STATE_UNKNOWN = 0;
+        STATE_OFF = 1;
+        STATE_MANUAL_ON = 2;
+        STATE_AUTOMATIC_ON = 3;
+        STATE_OFF_AUTOMATIC_SNOOZED = 4;
+        STATE_PENDING_STICKY_ON = 5;
+    }
+    optional StateEnum state = 18;
+
     // Whether full battery saver is enabled.
     optional bool is_full_enabled = 14;
 
@@ -337,8 +347,7 @@
     // Whether battery status has been set at least once.
     optional bool battery_status_set = 4;
 
-    // Whether automatic battery saver has been canceled by the user.
-    optional bool battery_saver_snoozing = 5;
+    reserved 5; // battery_saver_snoozing
 
     // Whether the device is connected to any power source.
     optional bool is_powered = 6;
@@ -373,5 +382,5 @@
     // using elapsed realtime as the timebase.
     optional int64 last_adaptive_battery_saver_changed_externally_elapsed = 17;
 
-    // Next tag: 18
+    // Next tag: 19
 }
diff --git a/media/java/android/media/session/ControllerLink.aidl b/core/proto/android/stats/storage/storage_enums.proto
similarity index 74%
rename from media/java/android/media/session/ControllerLink.aidl
rename to core/proto/android/stats/storage/storage_enums.proto
index 532df59..6892e287 100644
--- a/media/java/android/media/session/ControllerLink.aidl
+++ b/core/proto/android/stats/storage/storage_enums.proto
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019 The Android Open Source Project
+ * 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.
@@ -14,6 +14,13 @@
  * limitations under the License.
  */
 
-package android.media.session;
+syntax = "proto2";
 
-parcelable ControllerLink;
+package android.stats.storage;
+
+enum ExternalStorageType {
+  UNKNOWN = 0;
+  SD_CARD = 1;
+  USB = 2;
+  OTHER = 3;
+}
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 2b13c4e..74970e8 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1538,43 +1538,45 @@
     <string name="permdesc_useFaceAuthentication">Allows the app to use face authentication hardware for authentication</string>
 
     <!-- Message shown during face acquisition when the face cannot be recognized [CHAR LIMIT=50] -->
-    <string name="face_acquired_insufficient">Couldn\u2019t process face. Please try again.</string>
+    <string name="face_acquired_insufficient">Couldn\u2019t capture accurate face data. Try again.</string>
     <!-- Message shown during face acquisition when the image is too bright [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_bright">Face is too bright. Please try in lower light.</string>
+    <string name="face_acquired_too_bright">Too bright. Try gentler lighting.</string>
     <!-- Message shown during face acquisition when the image is too dark [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_dark">Face is too dark. Please uncover light source.</string>
+    <string name="face_acquired_too_dark">Too dark. Try brighter lighting.</string>
     <!-- Message shown during face acquisition when the user is too close to sensor [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_close">Please move sensor farther from face.</string>
+    <string name="face_acquired_too_close">Move phone farther away.</string>
     <!-- Message shown during face acquisition when the user is too far from sensor [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_far">Please bring sensor closer to face.</string>
+    <string name="face_acquired_too_far">Move phone closer.</string>
     <!-- Message shown during face acquisition when the user is too high relatively to sensor [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_high">Please move sensor higher.</string>
+    <string name="face_acquired_too_high">Move phone higher.</string>
     <!-- Message shown during face acquisition when the user is too low relatively to sensor [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_low">Please move sensor lower.</string>
+    <string name="face_acquired_too_low">Move phone lower.</string>
     <!-- Message shown during face acquisition when the user is too right relatively to sensor [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_right">Please move sensor to the right.</string>
+    <string name="face_acquired_too_right">Move phone to the right.</string>
     <!-- Message shown during face acquisition when the user is too left relatively to sensor [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_left">Please move sensor to the left.</string>
+    <string name="face_acquired_too_left">Move phone to the left.</string>
     <!-- Message shown during face acquisition when the user is not front facing the sensor [CHAR LIMIT=50] -->
-    <string name="face_acquired_poor_gaze">Please look at the sensor.</string>
+    <string name="face_acquired_poor_gaze">Look at the screen with your eyes open.</string>
     <!-- Message shown during face acquisition when the user is not detected [CHAR LIMIT=50] -->
-    <string name="face_acquired_not_detected">No face detected.</string>
+    <string name="face_acquired_not_detected">Can\u2019t see your face. Look at the phone.</string>
     <!-- Message shown during face acquisition when the device is not steady [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_much_motion">Too much motion.</string>
+    <string name="face_acquired_too_much_motion">Too much motion. Hold phone steady.</string>
     <!-- Message shown during face acquisition when the sensor needs to be recalibrated [CHAR LIMIT=50] -->
     <string name="face_acquired_recalibrate">Please re-enroll your face.</string>
     <!-- Message shown during face enrollment when a different person's face is detected [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_different">Different face detected.</string>
+    <string name="face_acquired_too_different">No longer able to recognize face. Try again.</string>
     <!-- Message shown during face enrollment when the face is too similar to a previous acquisition [CHAR LIMIT=50] -->
     <string name="face_acquired_too_similar">Too similar, please change your pose.</string>
     <!-- Message shown during acqusition when the user's face is turned too far left or right [CHAR LIMIT=50] -->
-    <string name="face_acquired_pan_too_extreme">Please look more directly at the camera.</string>
+    <string name="face_acquired_pan_too_extreme">Please look more directly at the screen.</string>
     <!-- Message shown during acqusition when the user's face is tilted too high or too low [CHAR LIMIT=50] -->
-    <string name="face_acquired_tilt_too_extreme">Please look more directly at the camera.</string>
+    <string name="face_acquired_tilt_too_extreme">Please look more directly at the screen.</string>
     <!-- Message shown during acquisiton when the user's face is tilted too far left or right [CHAR LIMIT=50] -->
     <string name="face_acquired_roll_too_extreme">Please straighten your head vertically.</string>
     <!-- Message shown during acquisition when the user's face is obscured [CHAR LIMIT=50] -->
-    <string name="face_acquired_obscured">Please uncover your face.</string>
+    <string name="face_acquired_obscured">Clear the space between your head and the phone.</string>
+    <!-- Message shown during acquisition when the sensor is dirty [CHAR LIMIT=50] -->
+    <string name="face_acquired_sensor_dirty">Please clean the camera.</string>
     <!-- Array containing custom messages shown during face acquisition from vendor.  Vendor is expected to add and translate these strings -->
     <string-array name="face_acquired_vendor">
     </string-array>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index e5fc104..17ccc31 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2546,6 +2546,7 @@
   <java-symbol type="string" name="face_acquired_tilt_too_extreme" />
   <java-symbol type="string" name="face_acquired_roll_too_extreme" />
   <java-symbol type="string" name="face_acquired_obscured" />
+  <java-symbol type="string" name="face_acquired_sensor_dirty" />
   <java-symbol type="array" name="face_acquired_vendor" />
   <java-symbol type="string" name="face_name_template" />
   <java-symbol type="string" name="face_authenticated_no_confirmation_required" />
diff --git a/graphics/java/android/graphics/text/MeasuredText.java b/graphics/java/android/graphics/text/MeasuredText.java
index 66bcd865..9db7533 100644
--- a/graphics/java/android/graphics/text/MeasuredText.java
+++ b/graphics/java/android/graphics/text/MeasuredText.java
@@ -65,6 +65,7 @@
 
     /**
      * Returns the characters in the paragraph used to compute this MeasuredText instance.
+     * @hide
      */
     public @NonNull char[] getChars() {
         return mChars;
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
index 105af6e8..51c4252 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
@@ -16,7 +16,6 @@
 
 package android.security.keystore;
 
-import libcore.util.EmptyArray;
 import android.security.Credentials;
 import android.security.GateKeeper;
 import android.security.KeyStore;
@@ -31,6 +30,8 @@
 import android.security.keystore.WrappedKeyEntry;
 import android.util.Log;
 
+import libcore.util.EmptyArray;
+
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -123,7 +124,14 @@
 
         final Certificate[] caList;
 
-        final byte[] caBytes = mKeyStore.get(Credentials.CA_CERTIFICATE + alias, mUid);
+        // Suppress the key not found warning for this call. It seems that this error is exclusively
+        // being thrown when there is a self signed certificate chain, so when the keystore service
+        // attempts to query for the CA details, it obviously fails to find them and returns a
+        // key not found exception. This is WAI, and throwing a stack trace here can be very
+        // misleading since the trace is not clear.
+        final byte[] caBytes = mKeyStore.get(Credentials.CA_CERTIFICATE + alias,
+                                             mUid,
+                                             true /* suppressKeyNotFoundWarning */);
         if (caBytes != null) {
             final Collection<X509Certificate> caChain = toCertificates(caBytes);
 
diff --git a/libs/androidfw/Asset.cpp b/libs/androidfw/Asset.cpp
index c512a6b..9a95fdf8 100644
--- a/libs/androidfw/Asset.cpp
+++ b/libs/androidfw/Asset.cpp
@@ -292,8 +292,10 @@
 
     pAsset = new _FileAsset;
     result = pAsset->openChunk(dataMap);
-    if (result != NO_ERROR)
+    if (result != NO_ERROR) {
+        delete pAsset;
         return NULL;
+    }
 
     pAsset->mAccessMode = mode;
     return pAsset;
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 4f1b2a4..ebba4cb 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -191,7 +191,7 @@
         "surfacetexture/EGLConsumer.cpp",
         "surfacetexture/ImageConsumer.cpp",
         "surfacetexture/SurfaceTexture.cpp",
-        "thread/TaskManager.cpp",
+        "thread/CommonPool.cpp",
         "utils/Blur.cpp",
         "utils/Color.cpp",
         "utils/GLUtils.cpp",
@@ -308,6 +308,7 @@
         "tests/unit/main.cpp",
         "tests/unit/CacheManagerTests.cpp",
         "tests/unit/CanvasContextTests.cpp",
+        "tests/unit/CommonPoolTests.cpp",
         "tests/unit/DamageAccumulatorTests.cpp",
         "tests/unit/DeferredLayerUpdaterTests.cpp",
         "tests/unit/FatVectorTests.cpp",
@@ -381,7 +382,6 @@
         "tests/microbench/LinearAllocatorBench.cpp",
         "tests/microbench/PathParserBench.cpp",
         "tests/microbench/RenderNodeBench.cpp",
-        "tests/microbench/TaskManagerBench.cpp",
     ],
 }
 
diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp
index fe633e9..fb60a96 100644
--- a/libs/hwui/Readback.cpp
+++ b/libs/hwui/Readback.cpp
@@ -28,6 +28,7 @@
 #include "hwui/Bitmap.h"
 #include "utils/Color.h"
 #include "utils/MathUtils.h"
+#include "utils/TraceUtils.h"
 
 using namespace android::uirenderer::renderthread;
 
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index a00a36f..721a115 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -25,6 +25,7 @@
 #include <SkPictureRecorder.h>
 #include "TreeInfo.h"
 #include "VectorDrawable.h"
+#include "thread/CommonPool.h"
 #include "utils/TraceUtils.h"
 
 #include <unistd.h>
@@ -49,10 +50,6 @@
     unpinImages();
 }
 
-TaskManager* SkiaPipeline::getTaskManager() {
-    return mRenderThread.cacheManager().getTaskManager();
-}
-
 void SkiaPipeline::onDestroyHardwareResources() {
     unpinImages();
     mRenderThread.cacheManager().trimStaleResources();
@@ -225,42 +222,21 @@
     }
 }
 
-class SkiaPipeline::SavePictureProcessor : public TaskProcessor<bool> {
-public:
-    explicit SavePictureProcessor(TaskManager* taskManager) : TaskProcessor<bool>(taskManager) {}
-
-    struct SavePictureTask : public Task<bool> {
-        sk_sp<SkData> data;
-        std::string filename;
-    };
-
-    void savePicture(const sk_sp<SkData>& data, const std::string& filename) {
-        sp<SavePictureTask> task(new SavePictureTask());
-        task->data = data;
-        task->filename = filename;
-        TaskProcessor<bool>::add(task);
-    }
-
-    virtual void onProcess(const sp<Task<bool>>& task) override {
-        ATRACE_NAME("SavePictureTask");
-        SavePictureTask* t = static_cast<SavePictureTask*>(task.get());
-
-        if (0 == access(t->filename.c_str(), F_OK)) {
-            task->setResult(false);
+static void savePictureAsync(const sk_sp<SkData>& data, const std::string& filename) {
+    CommonPool::post([data, filename] {
+        if (0 == access(filename.c_str(), F_OK)) {
             return;
         }
 
-        SkFILEWStream stream(t->filename.c_str());
+        SkFILEWStream stream(filename.c_str());
         if (stream.isValid()) {
-            stream.write(t->data->data(), t->data->size());
+            stream.write(data->data(), data->size());
             stream.flush();
             SkDebugf("SKP Captured Drawing Output (%d bytes) for frame. %s", stream.bytesWritten(),
-                     t->filename.c_str());
+                     filename.c_str());
         }
-
-        task->setResult(true);
-    }
-};
+    });
+}
 
 SkCanvas* SkiaPipeline::tryCapture(SkSurface* surface) {
     if (CC_UNLIKELY(Properties::skpCaptureEnabled)) {
@@ -297,16 +273,10 @@
                 ATRACE_END();
 
                 // offload saving to file in a different thread
-                if (!mSavePictureProcessor.get()) {
-                    TaskManager* taskManager = getTaskManager();
-                    mSavePictureProcessor = new SavePictureProcessor(
-                            taskManager->canRunTasks() ? taskManager : nullptr);
-                }
                 if (1 == mCaptureSequence) {
-                    mSavePictureProcessor->savePicture(data, mCapturedFile);
+                    savePictureAsync(data, mCapturedFile);
                 } else {
-                    mSavePictureProcessor->savePicture(
-                            data,
+                    savePictureAsync(data,
                             mCapturedFile + "_" + std::to_string(mCaptureSequence));
                 }
                 mCaptureSequence--;
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.h b/libs/hwui/pipeline/skia/SkiaPipeline.h
index 7381e04..41d8646 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.h
@@ -33,8 +33,6 @@
     explicit SkiaPipeline(renderthread::RenderThread& thread);
     virtual ~SkiaPipeline();
 
-    TaskManager* getTaskManager() override;
-
     void onDestroyHardwareResources() override;
 
     bool pinImages(std::vector<SkImage*>& mutableImages) override;
@@ -157,11 +155,7 @@
      *  mCaptureSequence counts how many frames are left to take in the sequence.
      */
     int mCaptureSequence = 0;
-    /**
-     *  mSavePictureProcessor is used to run the file saving code in a separate thread.
-     */
-    class SavePictureProcessor;
-    sp<SavePictureProcessor> mSavePictureProcessor;
+
     /**
      *  mRecorder holds the current picture recorder. We could store it on the stack to support
      *  parallel tryCapture calls (not really needed).
diff --git a/libs/hwui/renderthread/CacheManager.cpp b/libs/hwui/renderthread/CacheManager.cpp
index 6c04232..8b02c11 100644
--- a/libs/hwui/renderthread/CacheManager.cpp
+++ b/libs/hwui/renderthread/CacheManager.cpp
@@ -23,6 +23,7 @@
 #include "pipeline/skia/SkiaMemoryTracer.h"
 #include "Properties.h"
 #include "renderstate/RenderState.h"
+#include "thread/CommonPool.h"
 
 #include <GrContextOptions.h>
 #include <SkExecutor.h>
@@ -76,29 +77,15 @@
     mGrContext->setResourceCacheLimits(mMaxResources, mMaxResourceBytes);
 }
 
-class CacheManager::SkiaTaskProcessor : public TaskProcessor<bool>, public SkExecutor {
+class CommonPoolExecutor : public SkExecutor {
 public:
-    explicit SkiaTaskProcessor(TaskManager* taskManager) : TaskProcessor<bool>(taskManager) {}
-
-    // This is really a Task<void> but that doesn't really work when Future<>
-    // expects to be able to get/set a value
-    struct SkiaTask : public Task<bool> {
-        std::function<void()> func;
-    };
-
     virtual void add(std::function<void(void)> func) override {
-        sp<SkiaTask> task(new SkiaTask());
-        task->func = func;
-        TaskProcessor<bool>::add(task);
-    }
-
-    virtual void onProcess(const sp<Task<bool> >& task) override {
-        SkiaTask* t = static_cast<SkiaTask*>(task.get());
-        t->func();
-        task->setResult(true);
+        CommonPool::post(std::move(func));
     }
 };
 
+static CommonPoolExecutor sDefaultExecutor;
+
 void CacheManager::configureContext(GrContextOptions* contextOptions, const void* identity, ssize_t size) {
     contextOptions->fAllowPathMaskCaching = true;
 
@@ -107,12 +94,7 @@
     // provided to Skia.
     contextOptions->fGlyphCacheTextureMaximumBytes = GrNextSizePow2(mMaxSurfaceArea);
 
-    if (mTaskManager.canRunTasks()) {
-        if (!mTaskProcessor.get()) {
-            mTaskProcessor = new SkiaTaskProcessor(&mTaskManager);
-        }
-        contextOptions->fExecutor = mTaskProcessor.get();
-    }
+    contextOptions->fExecutor = &sDefaultExecutor;
 
     auto& cache = skiapipeline::ShaderCache::get();
     cache.initShaderDiskCache(identity, size);
diff --git a/libs/hwui/renderthread/CacheManager.h b/libs/hwui/renderthread/CacheManager.h
index 66f04f1..b0286e8 100644
--- a/libs/hwui/renderthread/CacheManager.h
+++ b/libs/hwui/renderthread/CacheManager.h
@@ -24,8 +24,6 @@
 #include <vector>
 
 #include "pipeline/skia/VectorDrawableAtlas.h"
-#include "thread/TaskManager.h"
-#include "thread/TaskProcessor.h"
 
 namespace android {
 
@@ -54,8 +52,6 @@
     size_t getCacheSize() const { return mMaxResourceBytes; }
     size_t getBackgroundCacheSize() const { return mBackgroundResourceBytes; }
 
-    TaskManager* getTaskManager() { return &mTaskManager; }
-
 private:
     friend class RenderThread;
 
@@ -78,10 +74,6 @@
     };
 
     sp<skiapipeline::VectorDrawableAtlas> mVectorDrawableAtlas;
-
-    class SkiaTaskProcessor;
-    sp<SkiaTaskProcessor> mTaskProcessor;
-    TaskManager mTaskManager;
 };
 
 } /* namespace renderthread */
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index f5b4d93..baa41c1 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -27,8 +27,10 @@
 #include "pipeline/skia/SkiaOpenGLPipeline.h"
 #include "pipeline/skia/SkiaPipeline.h"
 #include "pipeline/skia/SkiaVulkanPipeline.h"
+#include "thread/CommonPool.h"
 #include "utils/GLUtils.h"
 #include "utils/TimeUtils.h"
+#include "utils/TraceUtils.h"
 #include "../Properties.h"
 
 #include <cutils/properties.h>
@@ -603,31 +605,14 @@
     if (mFrameFences.size()) {
         ATRACE_CALL();
         for (auto& fence : mFrameFences) {
-            fence->getResult();
+            fence.get();
         }
         mFrameFences.clear();
     }
 }
 
-class CanvasContext::FuncTaskProcessor : public TaskProcessor<bool> {
-public:
-    explicit FuncTaskProcessor(TaskManager* taskManager) : TaskProcessor<bool>(taskManager) {}
-
-    virtual void onProcess(const sp<Task<bool> >& task) override {
-        FuncTask* t = static_cast<FuncTask*>(task.get());
-        t->func();
-        task->setResult(true);
-    }
-};
-
 void CanvasContext::enqueueFrameWork(std::function<void()>&& func) {
-    if (!mFrameWorkProcessor.get()) {
-        mFrameWorkProcessor = new FuncTaskProcessor(mRenderPipeline->getTaskManager());
-    }
-    sp<FuncTask> task(new FuncTask());
-    task->func = func;
-    mFrameFences.push_back(task);
-    mFrameWorkProcessor->add(task);
+    mFrameFences.push_back(CommonPool::async(std::move(func)));
 }
 
 int64_t CanvasContext::getFrameNumber() {
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 4da0eac..abca342 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -28,8 +28,6 @@
 #include "ReliableSurface.h"
 #include "renderthread/RenderTask.h"
 #include "renderthread/RenderThread.h"
-#include "thread/Task.h"
-#include "thread/TaskProcessor.h"
 
 #include <EGL/egl.h>
 #include <SkBitmap.h>
@@ -42,6 +40,7 @@
 #include <set>
 #include <string>
 #include <vector>
+#include <future>
 
 namespace android {
 namespace uirenderer {
@@ -274,15 +273,7 @@
     // Stores the bounds of the main content.
     Rect mContentDrawBounds;
 
-    // TODO: This is really a Task<void> but that doesn't really work
-    // when Future<> expects to be able to get/set a value
-    struct FuncTask : public Task<bool> {
-        std::function<void()> func;
-    };
-    class FuncTaskProcessor;
-
-    std::vector<sp<FuncTask>> mFrameFences;
-    sp<TaskProcessor<bool>> mFrameWorkProcessor;
+    std::vector<std::future<void>> mFrameFences;
     std::unique_ptr<IRenderPipeline> mRenderPipeline;
 
     std::vector<std::function<void(int64_t)>> mFrameCompleteCallbacks;
diff --git a/libs/hwui/renderthread/IRenderPipeline.h b/libs/hwui/renderthread/IRenderPipeline.h
index 2cfc8df3..0502eb8 100644
--- a/libs/hwui/renderthread/IRenderPipeline.h
+++ b/libs/hwui/renderthread/IRenderPipeline.h
@@ -75,7 +75,6 @@
     virtual void renderLayers(const LightGeometry& lightGeometry,
                               LayerUpdateQueue* layerUpdateQueue, bool opaque,
                               const LightInfo& lightInfo) = 0;
-    virtual TaskManager* getTaskManager() = 0;
     virtual bool createOrUpdateLayer(RenderNode* node, const DamageAccumulator& damageAccumulator,
                                      ErrorHandler* errorHandler) = 0;
     virtual bool pinImages(std::vector<SkImage*>& mutableImages) = 0;
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 34f76d9..1bcb819 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -31,6 +31,7 @@
 #include "renderthread/RenderThread.h"
 #include "utils/Macros.h"
 #include "utils/TimeUtils.h"
+#include "utils/TraceUtils.h"
 
 #include <ui/GraphicBuffer.h>
 
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index c784d64..def805a 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -28,6 +28,7 @@
 #include "renderstate/RenderState.h"
 #include "utils/FatVector.h"
 #include "utils/TimeUtils.h"
+#include "utils/TraceUtils.h"
 
 #ifdef HWUI_GLES_WRAP_ENABLED
 #include "debug/GlesDriver.h"
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index 6dacc7a..9916da5 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -23,6 +23,7 @@
 #include "RenderThread.h"
 #include "renderstate/RenderState.h"
 #include "utils/FatVector.h"
+#include "utils/TraceUtils.h"
 
 #include <GrBackendSemaphore.h>
 #include <GrBackendSurface.h>
diff --git a/libs/hwui/tests/macrobench/TestSceneRunner.cpp b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
index 0e61899e..b45dbc8 100644
--- a/libs/hwui/tests/macrobench/TestSceneRunner.cpp
+++ b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
@@ -21,6 +21,7 @@
 #include "tests/common/TestContext.h"
 #include "tests/common/TestScene.h"
 #include "tests/common/scenes/TestSceneBase.h"
+#include "utils/TraceUtils.h"
 
 #include <benchmark/benchmark.h>
 #include <gui/Surface.h>
diff --git a/libs/hwui/tests/microbench/TaskManagerBench.cpp b/libs/hwui/tests/microbench/TaskManagerBench.cpp
deleted file mode 100644
index 4153bae..0000000
--- a/libs/hwui/tests/microbench/TaskManagerBench.cpp
+++ /dev/null
@@ -1,134 +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.
- */
-
-#include <benchmark/benchmark.h>
-
-#include "thread/Task.h"
-#include "thread/TaskManager.h"
-#include "thread/TaskProcessor.h"
-#include "thread/ThreadBase.h"
-
-#include <atomic>
-#include <vector>
-
-using namespace android;
-using namespace android::uirenderer;
-
-class TrivialTask : public Task<char> {};
-
-class TrivialProcessor : public TaskProcessor<char> {
-public:
-    explicit TrivialProcessor(TaskManager* manager) : TaskProcessor(manager) {}
-    virtual ~TrivialProcessor() {}
-    virtual void onProcess(const sp<Task<char>>& task) override {
-        TrivialTask* t = static_cast<TrivialTask*>(task.get());
-        t->setResult(reinterpret_cast<intptr_t>(t) % 16 == 0 ? 'a' : 'b');
-    }
-};
-
-class TestThread : public ThreadBase, public virtual RefBase {};
-
-void BM_TaskManager_allocateTask(benchmark::State& state) {
-    std::vector<sp<TrivialTask>> tasks;
-    tasks.reserve(state.max_iterations);
-
-    while (state.KeepRunning()) {
-        tasks.emplace_back(new TrivialTask);
-        benchmark::DoNotOptimize(tasks.back());
-    }
-}
-BENCHMARK(BM_TaskManager_allocateTask);
-
-void BM_TaskManager_enqueueTask(benchmark::State& state) {
-    TaskManager taskManager;
-    sp<TrivialProcessor> processor(new TrivialProcessor(&taskManager));
-    std::vector<sp<TrivialTask>> tasks;
-    tasks.reserve(state.max_iterations);
-
-    while (state.KeepRunning()) {
-        tasks.emplace_back(new TrivialTask);
-        benchmark::DoNotOptimize(tasks.back());
-        processor->add(tasks.back());
-    }
-
-    for (sp<TrivialTask>& task : tasks) {
-        task->getResult();
-    }
-}
-BENCHMARK(BM_TaskManager_enqueueTask);
-
-void BM_TaskManager_enqueueRunDeleteTask(benchmark::State& state) {
-    TaskManager taskManager;
-    sp<TrivialProcessor> processor(new TrivialProcessor(&taskManager));
-    std::vector<sp<TrivialTask>> tasks;
-    tasks.reserve(state.max_iterations);
-
-    while (state.KeepRunning()) {
-        tasks.emplace_back(new TrivialTask);
-        benchmark::DoNotOptimize(tasks.back());
-        processor->add(tasks.back());
-    }
-    state.ResumeTiming();
-    for (sp<TrivialTask>& task : tasks) {
-        benchmark::DoNotOptimize(task->getResult());
-    }
-    tasks.clear();
-    state.PauseTiming();
-}
-BENCHMARK(BM_TaskManager_enqueueRunDeleteTask);
-
-void BM_Thread_enqueueTask(benchmark::State& state) {
-    sp<TestThread> thread{new TestThread};
-    thread->start();
-
-    atomic_int counter(0);
-    int expected = 0;
-    while (state.KeepRunning()) {
-        expected++;
-        thread->queue().post([&counter]() { counter++; });
-    }
-    thread->queue().runSync([]() {});
-
-    thread->requestExit();
-    thread->join();
-    if (counter != expected) {
-        printf("Ran %d lambads, should have been %d\n", counter.load(), expected);
-    }
-}
-BENCHMARK(BM_Thread_enqueueTask);
-
-void BM_Thread_enqueueRunDeleteTask(benchmark::State& state) {
-    sp<TestThread> thread{new TestThread};
-    thread->start();
-    std::vector<std::future<int>> tasks;
-    tasks.reserve(state.max_iterations);
-
-    int expected = 0;
-    while (state.KeepRunning()) {
-        tasks.emplace_back(thread->queue().async([expected]() -> int { return expected + 1; }));
-        expected++;
-    }
-    state.ResumeTiming();
-    expected = 0;
-    for (auto& future : tasks) {
-        if (future.get() != ++expected) {
-            printf("Mismatch expected %d vs. observed %d\n", expected, future.get());
-        }
-    }
-    tasks.clear();
-    state.PauseTiming();
-}
-BENCHMARK(BM_Thread_enqueueRunDeleteTask);
\ No newline at end of file
diff --git a/libs/hwui/tests/unit/CommonPoolTests.cpp b/libs/hwui/tests/unit/CommonPoolTests.cpp
new file mode 100644
index 0000000..c564ed6
--- /dev/null
+++ b/libs/hwui/tests/unit/CommonPoolTests.cpp
@@ -0,0 +1,138 @@
+/*
+ * 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.
+ */
+
+#include <gtest/gtest.h>
+
+#include "thread/CommonPool.h"
+
+#include <array>
+#include <condition_variable>
+#include <set>
+#include <thread>
+#include "unistd.h"
+
+using namespace android;
+using namespace android::uirenderer;
+
+TEST(CommonPool, post) {
+    std::atomic_bool ran(false);
+    CommonPool::post([&ran] { ran = true; });
+    for (int i = 0; !ran && i < 1000; i++) {
+        usleep(1);
+    }
+    EXPECT_TRUE(ran) << "Failed to flip atomic after 1 second";
+}
+
+TEST(CommonPool, threadCount) {
+    std::set<pid_t> threads;
+    std::array<std::future<pid_t>, 64> futures;
+    for (int i = 0; i < futures.size(); i++) {
+        futures[i] = CommonPool::async([] {
+            usleep(10);
+            return gettid();
+        });
+    }
+    for (auto& f : futures) {
+        threads.insert(f.get());
+    }
+    EXPECT_EQ(threads.size(), CommonPool::THREAD_COUNT);
+    EXPECT_EQ(0, threads.count(gettid()));
+}
+
+TEST(CommonPool, singleThread) {
+    std::mutex mutex;
+    std::condition_variable fence;
+    bool isProcessing = false;
+    bool queuedSecond = false;
+
+    auto f1 = CommonPool::async([&] {
+        {
+            std::unique_lock lock{mutex};
+            isProcessing = true;
+            fence.notify_all();
+            while (!queuedSecond) {
+                fence.wait(lock);
+            }
+        }
+        return gettid();
+    });
+
+    {
+        std::unique_lock lock{mutex};
+        while (!isProcessing) {
+            fence.wait(lock);
+        }
+    }
+
+    auto f2 = CommonPool::async([] {
+        return gettid();
+    });
+
+    {
+        std::unique_lock lock{mutex};
+        queuedSecond = true;
+        fence.notify_all();
+    }
+
+    auto tid1 = f1.get();
+    auto tid2 = f2.get();
+    EXPECT_EQ(tid1, tid2);
+    EXPECT_NE(gettid(), tid1);
+}
+
+TEST(CommonPool, fullQueue) {
+    std::mutex lock;
+    std::condition_variable fence;
+    bool signaled = false;
+    static constexpr auto QUEUE_COUNT = CommonPool::THREAD_COUNT + CommonPool::QUEUE_SIZE + 10;
+    std::atomic_int queuedCount{0};
+    std::array<std::future<void>, QUEUE_COUNT> futures;
+
+    std::thread queueThread{[&] {
+        for (int i = 0; i < QUEUE_COUNT; i++) {
+            futures[i] = CommonPool::async([&] {
+                std::unique_lock _lock{lock};
+                while (!signaled) {
+                    fence.wait(_lock);
+                }
+            });
+            queuedCount++;
+        }
+    }};
+
+    int previous;
+    do {
+        previous = queuedCount.load();
+        usleep(10000);
+    } while (previous != queuedCount.load());
+
+    EXPECT_GT(queuedCount.load(), CommonPool::QUEUE_SIZE);
+    EXPECT_LT(queuedCount.load(), QUEUE_COUNT);
+
+    {
+        std::unique_lock _lock{lock};
+        signaled = true;
+        fence.notify_all();
+    }
+
+    queueThread.join();
+    EXPECT_EQ(queuedCount.load(), QUEUE_COUNT);
+
+    // Ensure all our tasks are finished before return as they have references to the stack
+    for (auto& f : futures) {
+        f.get();
+    }
+}
\ No newline at end of file
diff --git a/libs/hwui/tests/unit/main.cpp b/libs/hwui/tests/unit/main.cpp
index 63d1540..83d888c 100644
--- a/libs/hwui/tests/unit/main.cpp
+++ b/libs/hwui/tests/unit/main.cpp
@@ -22,9 +22,6 @@
 #include "debug/NullGlesDriver.h"
 #include "hwui/Typeface.h"
 #include "tests/common/LeakChecker.h"
-#include "thread/Task.h"
-#include "thread/TaskManager.h"
-#include "thread/TaskProcessor.h"
 
 #include <signal.h>
 
diff --git a/libs/hwui/thread/Barrier.h b/libs/hwui/thread/Barrier.h
deleted file mode 100644
index bb750ca..0000000
--- a/libs/hwui/thread/Barrier.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-#ifndef ANDROID_HWUI_BARRIER_H
-#define ANDROID_HWUI_BARRIER_H
-
-#include <utils/Condition.h>
-
-namespace android {
-namespace uirenderer {
-
-class Barrier {
-public:
-    explicit Barrier(Condition::WakeUpType type = Condition::WAKE_UP_ALL)
-            : mType(type), mOpened(false) {}
-    ~Barrier() {}
-
-    void open() {
-        Mutex::Autolock l(mLock);
-        mOpened = true;
-        mCondition.signal(mType);
-    }
-
-    void wait() const {
-        Mutex::Autolock l(mLock);
-        while (!mOpened) {
-            mCondition.wait(mLock);
-        }
-    }
-
-private:
-    Condition::WakeUpType mType;
-    volatile bool mOpened;
-    mutable Mutex mLock;
-    mutable Condition mCondition;
-};
-
-}  // namespace uirenderer
-}  // namespace android
-
-#endif  // ANDROID_HWUI_BARRIER_H
diff --git a/libs/hwui/thread/CommonPool.cpp b/libs/hwui/thread/CommonPool.cpp
new file mode 100644
index 0000000..7f94a15
--- /dev/null
+++ b/libs/hwui/thread/CommonPool.cpp
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+#include "CommonPool.h"
+
+#include <sys/resource.h>
+#include <utils/Trace.h>
+#include "renderthread/RenderThread.h"
+
+#include <array>
+
+namespace android {
+namespace uirenderer {
+
+CommonPool::CommonPool() {
+    ATRACE_CALL();
+
+    CommonPool* pool = this;
+    // Create 2 workers
+    for (int i = 0; i < THREAD_COUNT; i++) {
+        std::thread worker([pool, i] {
+            {
+                std::array<char, 20> name{"hwuiTask"};
+                snprintf(name.data(), name.size(), "hwuiTask%d", i);
+                auto self = pthread_self();
+                pthread_setname_np(self, name.data());
+                setpriority(PRIO_PROCESS, 0, PRIORITY_FOREGROUND);
+                auto startHook = renderthread::RenderThread::getOnStartHook();
+                if (startHook) {
+                    startHook(name.data());
+                }
+            }
+            pool->workerLoop();
+        });
+        worker.detach();
+    }
+}
+
+void CommonPool::post(Task&& task) {
+    static CommonPool pool;
+    pool.enqueue(std::move(task));
+}
+
+void CommonPool::enqueue(Task&& task) {
+    std::unique_lock lock(mLock);
+    while (!mWorkQueue.hasSpace()) {
+        lock.unlock();
+        usleep(100);
+        lock.lock();
+    }
+    mWorkQueue.push(std::move(task));
+    if (mWaitingThreads == THREAD_COUNT || (mWaitingThreads > 0 && mWorkQueue.size() > 1)) {
+        mCondition.notify_one();
+    }
+}
+
+void CommonPool::workerLoop() {
+    std::unique_lock lock(mLock);
+    while (true) {
+        if (!mWorkQueue.hasWork()) {
+            mWaitingThreads++;
+            mCondition.wait(lock);
+            mWaitingThreads--;
+        }
+        // Need to double-check that work is still available now that we have the lock
+        // It may have already been grabbed by a different thread
+        while (mWorkQueue.hasWork()) {
+            auto work = mWorkQueue.pop();
+            lock.unlock();
+            work();
+            lock.lock();
+        }
+    }
+}
+
+}  // namespace uirenderer
+}  // namespace android
\ No newline at end of file
diff --git a/libs/hwui/thread/CommonPool.h b/libs/hwui/thread/CommonPool.h
new file mode 100644
index 0000000..aef2990
--- /dev/null
+++ b/libs/hwui/thread/CommonPool.h
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+
+#ifndef FRAMEWORKS_BASE_COMMONPOOL_H
+#define FRAMEWORKS_BASE_COMMONPOOL_H
+
+#include "utils/Macros.h"
+
+#include <log/log.h>
+
+#include <condition_variable>
+#include <functional>
+#include <future>
+#include <mutex>
+
+namespace android {
+namespace uirenderer {
+
+template <class T, int SIZE>
+class ArrayQueue {
+    PREVENT_COPY_AND_ASSIGN(ArrayQueue);
+    static_assert(SIZE > 0, "Size must be positive");
+
+public:
+    ArrayQueue() = default;
+    ~ArrayQueue() = default;
+
+    constexpr size_t capacity() const { return SIZE; }
+    constexpr bool hasWork() const { return mHead != mTail; }
+    constexpr bool hasSpace() const { return ((mHead + 1) % SIZE) != mTail; }
+    constexpr int size() const {
+        if (mHead > mTail) {
+            return mHead - mTail;
+        } else {
+            return mTail - mHead + SIZE;
+        }
+    }
+
+    constexpr void push(T&& t) {
+        int newHead = (mHead + 1) % SIZE;
+        LOG_ALWAYS_FATAL_IF(newHead == mTail, "no space");
+
+        mBuffer[mHead] = std::move(t);
+        mHead = newHead;
+    }
+
+    constexpr T&& pop() {
+        LOG_ALWAYS_FATAL_IF(mTail == mHead, "empty");
+        int index = mTail;
+        mTail = (mTail + 1) % SIZE;
+        return std::move(mBuffer[index]);
+    }
+
+private:
+    T mBuffer[SIZE];
+    int mHead = 0;
+    int mTail = 0;
+};
+
+class CommonPool {
+    PREVENT_COPY_AND_ASSIGN(CommonPool);
+
+public:
+    using Task = std::function<void()>;
+    static constexpr auto THREAD_COUNT = 2;
+    static constexpr auto QUEUE_SIZE = 128;
+
+    static void post(Task&& func);
+
+    template <class F>
+    static auto async(F&& func) -> std::future<decltype(func())> {
+        typedef std::packaged_task<decltype(func())()> task_t;
+        auto task = std::make_shared<task_t>(std::forward<F>(func));
+        post([task]() { std::invoke(*task); });
+        return task->get_future();
+    }
+
+    template <class F>
+    static auto runSync(F&& func) -> decltype(func()) {
+        std::packaged_task<decltype(func())()> task{std::forward<F>(func)};
+        post([&task]() { std::invoke(task); });
+        return task.get_future().get();
+    };
+
+private:
+    CommonPool();
+    ~CommonPool() {}
+
+    void enqueue(Task&&);
+
+    void workerLoop();
+
+    std::mutex mLock;
+    std::condition_variable mCondition;
+    int mWaitingThreads = 0;
+    ArrayQueue<Task, QUEUE_SIZE> mWorkQueue;
+};
+
+}  // namespace uirenderer
+}  // namespace android
+
+#endif  // FRAMEWORKS_BASE_COMMONPOOL_H
diff --git a/libs/hwui/thread/Future.h b/libs/hwui/thread/Future.h
deleted file mode 100644
index df53348e..0000000
--- a/libs/hwui/thread/Future.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-#ifndef ANDROID_HWUI_FUTURE_H
-#define ANDROID_HWUI_FUTURE_H
-
-#include <utils/RefBase.h>
-
-#include "Barrier.h"
-
-namespace android {
-namespace uirenderer {
-
-template <typename T>
-class Future : public LightRefBase<Future<T> > {
-public:
-    explicit Future(Condition::WakeUpType type = Condition::WAKE_UP_ONE)
-            : mBarrier(type), mResult() {}
-    ~Future() {}
-
-    /**
-     * Returns the result of this future, blocking if
-     * the result is not available yet.
-     */
-    T get() const {
-        mBarrier.wait();
-        return mResult;
-    }
-
-    /**
-     * This method must be called only once.
-     */
-    void produce(T result) {
-        mResult = result;
-        mBarrier.open();
-    }
-
-private:
-    Barrier mBarrier;
-    T mResult;
-};
-
-}  // namespace uirenderer
-}  // namespace android
-
-#endif  // ANDROID_HWUI_FUTURE_H
diff --git a/libs/hwui/thread/Signal.h b/libs/hwui/thread/Signal.h
deleted file mode 100644
index 6d33ac4..0000000
--- a/libs/hwui/thread/Signal.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-#ifndef ANDROID_HWUI_SIGNAL_H
-#define ANDROID_HWUI_SIGNAL_H
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <utils/threads.h>
-
-namespace android {
-namespace uirenderer {
-
-class Signal {
-public:
-    explicit Signal(Condition::WakeUpType type = Condition::WAKE_UP_ALL)
-            : mType(type), mSignaled(false) {}
-    ~Signal() {}
-
-    void signal() {
-        {
-            Mutex::Autolock l(mLock);
-            mSignaled = true;
-        }
-        mCondition.signal(mType);
-    }
-
-    void wait() {
-        Mutex::Autolock l(mLock);
-        while (!mSignaled) {
-            mCondition.wait(mLock);
-        }
-        mSignaled = false;
-    }
-
-private:
-    Condition::WakeUpType mType;
-    volatile bool mSignaled;
-    mutable Mutex mLock;
-    mutable Condition mCondition;
-};
-
-}  // namespace uirenderer
-}  // namespace android
-
-#endif  // ANDROID_HWUI_SIGNAL_H
diff --git a/libs/hwui/thread/Task.h b/libs/hwui/thread/Task.h
deleted file mode 100644
index 228ce19..0000000
--- a/libs/hwui/thread/Task.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-#ifndef ANDROID_HWUI_TASK_H
-#define ANDROID_HWUI_TASK_H
-
-#include <utils/RefBase.h>
-#include <utils/Trace.h>
-
-#include "Future.h"
-
-namespace android {
-namespace uirenderer {
-
-class TaskBase : public RefBase {
-public:
-    TaskBase() {}
-    virtual ~TaskBase() {}
-};
-
-template <typename T>
-class Task : public TaskBase {
-public:
-    Task() : mFuture(new Future<T>()) {}
-    virtual ~Task() {}
-
-    T getResult() const { return mFuture->get(); }
-
-    void setResult(T result) { mFuture->produce(result); }
-
-protected:
-    const sp<Future<T> >& future() const { return mFuture; }
-
-private:
-    sp<Future<T> > mFuture;
-};
-
-}  // namespace uirenderer
-}  // namespace android
-
-#endif  // ANDROID_HWUI_TASK_H
diff --git a/libs/hwui/thread/TaskManager.cpp b/libs/hwui/thread/TaskManager.cpp
deleted file mode 100644
index de10ff1..0000000
--- a/libs/hwui/thread/TaskManager.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2013 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 <sys/resource.h>
-#include <sys/sysinfo.h>
-
-#include "Task.h"
-#include "TaskManager.h"
-#include "TaskProcessor.h"
-#include "utils/MathUtils.h"
-#include "renderthread/RenderThread.h"
-
-namespace android {
-namespace uirenderer {
-
-///////////////////////////////////////////////////////////////////////////////
-// Manager
-///////////////////////////////////////////////////////////////////////////////
-
-TaskManager::TaskManager() {
-    // Get the number of available CPUs. This value does not change over time.
-    int cpuCount = sysconf(_SC_NPROCESSORS_CONF);
-
-    // Really no point in making more than 2 of these worker threads, but
-    // we do want to limit ourselves to 1 worker thread on dual-core devices.
-    int workerCount = cpuCount > 2 ? 2 : 1;
-    for (int i = 0; i < workerCount; i++) {
-        String8 name;
-        name.appendFormat("hwuiTask%d", i + 1);
-        mThreads.push_back(new WorkerThread(name));
-    }
-}
-
-TaskManager::~TaskManager() {
-    for (size_t i = 0; i < mThreads.size(); i++) {
-        mThreads[i]->exit();
-    }
-}
-
-bool TaskManager::canRunTasks() const {
-    return mThreads.size() > 0;
-}
-
-void TaskManager::stop() {
-    for (size_t i = 0; i < mThreads.size(); i++) {
-        mThreads[i]->exit();
-    }
-}
-
-bool TaskManager::addTaskBase(const sp<TaskBase>& task, const sp<TaskProcessorBase>& processor) {
-    if (mThreads.size() > 0) {
-        TaskWrapper wrapper(task, processor);
-
-        size_t minQueueSize = INT_MAX;
-        sp<WorkerThread> thread;
-
-        for (size_t i = 0; i < mThreads.size(); i++) {
-            if (mThreads[i]->getTaskCount() < minQueueSize) {
-                thread = mThreads[i];
-                minQueueSize = mThreads[i]->getTaskCount();
-            }
-        }
-
-        return thread->addTask(wrapper);
-    }
-    return false;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Thread
-///////////////////////////////////////////////////////////////////////////////
-
-status_t TaskManager::WorkerThread::readyToRun() {
-    setpriority(PRIO_PROCESS, 0, PRIORITY_FOREGROUND);
-    auto onStartHook = renderthread::RenderThread::getOnStartHook();
-    if (onStartHook) {
-        onStartHook(mName.c_str());
-    }
-
-    return NO_ERROR;
-}
-
-bool TaskManager::WorkerThread::threadLoop() {
-    mSignal.wait();
-    std::vector<TaskWrapper> tasks;
-    {
-        Mutex::Autolock l(mLock);
-        tasks.swap(mTasks);
-    }
-
-    for (size_t i = 0; i < tasks.size(); i++) {
-        const TaskWrapper& task = tasks[i];
-        task.mProcessor->process(task.mTask);
-    }
-
-    return true;
-}
-
-bool TaskManager::WorkerThread::addTask(const TaskWrapper& task) {
-    if (!isRunning()) {
-        run(mName.string(), PRIORITY_DEFAULT);
-    } else if (exitPending()) {
-        return false;
-    }
-
-    {
-        Mutex::Autolock l(mLock);
-        mTasks.push_back(task);
-    }
-    mSignal.signal();
-
-    return true;
-}
-
-size_t TaskManager::WorkerThread::getTaskCount() const {
-    Mutex::Autolock l(mLock);
-    return mTasks.size();
-}
-
-void TaskManager::WorkerThread::exit() {
-    requestExit();
-    mSignal.signal();
-}
-
-}  // namespace uirenderer
-}  // namespace android
diff --git a/libs/hwui/thread/TaskManager.h b/libs/hwui/thread/TaskManager.h
deleted file mode 100644
index 6c67222..0000000
--- a/libs/hwui/thread/TaskManager.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-#ifndef ANDROID_HWUI_TASK_MANAGER_H
-#define ANDROID_HWUI_TASK_MANAGER_H
-
-#include <utils/Mutex.h>
-#include <utils/String8.h>
-#include <utils/Thread.h>
-
-#include "Signal.h"
-
-#include <vector>
-
-namespace android {
-namespace uirenderer {
-
-template <typename T>
-class Task;
-class TaskBase;
-
-template <typename T>
-class TaskProcessor;
-class TaskProcessorBase;
-
-class TaskManager {
-public:
-    TaskManager();
-    ~TaskManager();
-
-    /**
-     * Returns true if this task  manager can run tasks,
-     * false otherwise. This method will typically return
-     * false on a single CPU core device.
-     */
-    bool canRunTasks() const;
-
-    /**
-     * Stops all allocated threads. Adding tasks will start
-     * the threads again as necessary.
-     */
-    void stop();
-
-private:
-    template <typename T>
-    friend class TaskProcessor;
-
-    template <typename T>
-    bool addTask(const sp<Task<T> >& task, const sp<TaskProcessor<T> >& processor) {
-        return addTaskBase(sp<TaskBase>(task), sp<TaskProcessorBase>(processor));
-    }
-
-    bool addTaskBase(const sp<TaskBase>& task, const sp<TaskProcessorBase>& processor);
-
-    struct TaskWrapper {
-        TaskWrapper() : mTask(), mProcessor() {}
-
-        TaskWrapper(const sp<TaskBase>& task, const sp<TaskProcessorBase>& processor)
-                : mTask(task), mProcessor(processor) {}
-
-        sp<TaskBase> mTask;
-        sp<TaskProcessorBase> mProcessor;
-    };
-
-    class WorkerThread : public Thread {
-    public:
-        explicit WorkerThread(const String8& name)
-                : Thread(false), mSignal(Condition::WAKE_UP_ONE), mName(name) {}
-
-        bool addTask(const TaskWrapper& task);
-        size_t getTaskCount() const;
-        void exit();
-
-    private:
-        virtual status_t readyToRun() override;
-        virtual bool threadLoop() override;
-
-        // Lock for the list of tasks
-        mutable Mutex mLock;
-        std::vector<TaskWrapper> mTasks;
-
-        // Signal used to wake up the thread when a new
-        // task is available in the list
-        mutable Signal mSignal;
-
-        const String8 mName;
-    };
-
-    std::vector<sp<WorkerThread> > mThreads;
-};
-
-}  // namespace uirenderer
-}  // namespace android
-
-#endif  // ANDROID_HWUI_TASK_MANAGER_H
diff --git a/libs/hwui/thread/TaskProcessor.h b/libs/hwui/thread/TaskProcessor.h
deleted file mode 100644
index 8117ae6..0000000
--- a/libs/hwui/thread/TaskProcessor.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-#ifndef ANDROID_HWUI_TASK_PROCESSOR_H
-#define ANDROID_HWUI_TASK_PROCESSOR_H
-
-#include <utils/RefBase.h>
-
-#include "Task.h"
-#include "TaskManager.h"
-
-namespace android {
-namespace uirenderer {
-
-class TaskProcessorBase : public RefBase {
-public:
-    TaskProcessorBase() {}
-    virtual ~TaskProcessorBase(){};
-
-    virtual void process(const sp<TaskBase>& task) = 0;
-};
-
-template <typename T>
-class TaskProcessor : public TaskProcessorBase {
-public:
-    explicit TaskProcessor(TaskManager* manager) : mManager(manager) {}
-    virtual ~TaskProcessor() {}
-
-    void add(const sp<Task<T> >& task) {
-        if (!addImpl(task)) {
-            // fall back to immediate execution
-            process(task);
-        }
-    }
-
-    virtual void onProcess(const sp<Task<T> >& task) = 0;
-
-private:
-    bool addImpl(const sp<Task<T> >& task);
-
-    virtual void process(const sp<TaskBase>& task) override {
-        sp<Task<T> > realTask = static_cast<Task<T>*>(task.get());
-        // This is the right way to do it but sp<> doesn't play nice
-        // sp<Task<T> > realTask = static_cast<sp<Task<T> > >(task);
-        onProcess(realTask);
-    }
-
-    TaskManager* mManager;
-};
-
-template <typename T>
-bool TaskProcessor<T>::addImpl(const sp<Task<T> >& task) {
-    if (mManager) {
-        sp<TaskProcessor<T> > self(this);
-        return mManager->addTask(task, self);
-    }
-    return false;
-}
-
-};  // namespace uirenderer
-};  // namespace android
-
-#endif  // ANDROID_HWUI_TASK_PROCESSOR_H
diff --git a/libs/hwui/thread/WorkQueue.h b/libs/hwui/thread/WorkQueue.h
index 7a6e638..42f8503 100644
--- a/libs/hwui/thread/WorkQueue.h
+++ b/libs/hwui/thread/WorkQueue.h
@@ -26,7 +26,6 @@
 #include <functional>
 #include <future>
 #include <mutex>
-#include <variant>
 #include <vector>
 
 namespace android::uirenderer {
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index dd179f3..050b2ec 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -167,11 +167,21 @@
 
     /**
      * Broadcast intent action when the set of enabled location providers changes. To check the
-     * status of a provider, use {@link #isProviderEnabled(String)}.
+     * status of a provider, use {@link #isProviderEnabled(String)}. Depending on API level, may
+     * include a string intent extra, {@link #EXTRA_PROVIDER_NAME}, with the name of the provider
+     * whose state has changed. See {@link #EXTRA_PROVIDER_NAME} for the supported API level.
+     *
+     * @see #EXTRA_PROVIDER_NAME
      */
     public static final String PROVIDERS_CHANGED_ACTION = "android.location.PROVIDERS_CHANGED";
 
     /**
+     * Intent extra included with {@link #PROVIDERS_CHANGED_ACTION} broadcasts, containing the name
+     * of the location provider that has changed, to be used with location provider APIs.
+     */
+    public static final String EXTRA_PROVIDER_NAME = "android.location.extra.PROVIDER_NAME";
+
+    /**
      * Broadcast intent action when the device location mode changes. To check the location mode,
      * use {@link #isLocationEnabled()}.
      */
diff --git a/media/OWNERS b/media/OWNERS
index eb26367..72c8952 100644
--- a/media/OWNERS
+++ b/media/OWNERS
@@ -3,7 +3,9 @@
 elaurent@google.com
 etalvala@google.com
 gkasten@google.com
+hdmoon@google.com
 hunga@google.com
+insun@google.com
 jaewan@google.com
 jmtrivi@google.com
 jsharkey@android.com
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 09cfa95..41e059b 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -1014,9 +1014,9 @@
      * frame indicates the number of samples per channel, e.g. 100 frames for a stereo compressed
      * stream corresponds to 200 decoded interleaved PCM samples.
      * @param delayInFrames number of frames to be ignored at the beginning of the stream. A value
-     *     of 0 indicates no padding is to be applied.
-     * @param paddingInFrames number of frames to be ignored at the end of the stream. A value of 0
      *     of 0 indicates no delay is to be applied.
+     * @param paddingInFrames number of frames to be ignored at the end of the stream. A value of 0
+     *     of 0 indicates no padding is to be applied.
      */
     public void setOffloadDelayPadding(@IntRange(from = 0) int delayInFrames,
             @IntRange(from = 0) int paddingInFrames) {
diff --git a/media/java/android/media/ExternalRingtonesCursorWrapper.java b/media/java/android/media/ExternalRingtonesCursorWrapper.java
index dd4c77a..ea63a3a 100644
--- a/media/java/android/media/ExternalRingtonesCursorWrapper.java
+++ b/media/java/android/media/ExternalRingtonesCursorWrapper.java
@@ -16,7 +16,6 @@
 
 package android.media;
 
-import android.content.ContentProvider;
 import android.database.Cursor;
 import android.database.CursorWrapper;
 import android.net.Uri;
@@ -28,19 +27,18 @@
  * @hide
  */
 public class ExternalRingtonesCursorWrapper extends CursorWrapper {
+    private Uri mUri;
 
-    private int mUserId;
-
-    public ExternalRingtonesCursorWrapper(Cursor cursor, int userId) {
+    public ExternalRingtonesCursorWrapper(Cursor cursor, Uri uri) {
         super(cursor);
-        mUserId = userId;
+        mUri = uri;
     }
 
     public String getString(int index) {
-        String result = super.getString(index);
         if (index == RingtoneManager.URI_COLUMN_INDEX) {
-            result = ContentProvider.maybeAddUserId(Uri.parse(result), mUserId).toString();
+            return mUri.toString();
+        } else {
+            return super.getString(index);
         }
-        return result;
     }
 }
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 4bc3897..2ec9355 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -3223,14 +3223,83 @@
         // These constants were originally in-line with OMX values, but this
         // correspondence is no longer maintained.
 
+        // Profiles and levels for AVC Codec, corresponding to the definitions in
+        // "SERIES H: AUDIOVISUAL AND MULTIMEDIA SYSTEMS,
+        // Infrastructure of audiovisual services – Coding of moving video
+        // Advanced video coding for generic audiovisual services"
+        // found at
+        // https://www.itu.int/rec/T-REC-H.264-201704-I
+
+        /**
+         * AVC Baseline profile.
+         * See definition in
+         * <a href="https://www.itu.int/rec/T-REC-H.264-201704-I">H.264 recommendation</a>,
+         * Annex A.
+         */
         public static final int AVCProfileBaseline = 0x01;
+
+        /**
+         * AVC Main profile.
+         * See definition in
+         * <a href="https://www.itu.int/rec/T-REC-H.264-201704-I">H.264 recommendation</a>,
+         * Annex A.
+         */
         public static final int AVCProfileMain     = 0x02;
+
+        /**
+         * AVC Extended profile.
+         * See definition in
+         * <a href="https://www.itu.int/rec/T-REC-H.264-201704-I">H.264 recommendation</a>,
+         * Annex A.
+         */
         public static final int AVCProfileExtended = 0x04;
+
+        /**
+         * AVC High profile.
+         * See definition in
+         * <a href="https://www.itu.int/rec/T-REC-H.264-201704-I">H.264 recommendation</a>,
+         * Annex A.
+         */
         public static final int AVCProfileHigh     = 0x08;
+
+        /**
+         * AVC High 10 profile.
+         * See definition in
+         * <a href="https://www.itu.int/rec/T-REC-H.264-201704-I">H.264 recommendation</a>,
+         * Annex A.
+         */
         public static final int AVCProfileHigh10   = 0x10;
+
+        /**
+         * AVC High 4:2:2 profile.
+         * See definition in
+         * <a href="https://www.itu.int/rec/T-REC-H.264-201704-I">H.264 recommendation</a>,
+         * Annex A.
+         */
         public static final int AVCProfileHigh422  = 0x20;
+
+        /**
+         * AVC High 4:4:4 profile.
+         * See definition in
+         * <a href="https://www.itu.int/rec/T-REC-H.264-201704-I">H.264 recommendation</a>,
+         * Annex A.
+         */
         public static final int AVCProfileHigh444  = 0x40;
+
+        /**
+         * AVC Constrained Baseline profile.
+         * See definition in
+         * <a href="https://www.itu.int/rec/T-REC-H.264-201704-I">H.264 recommendation</a>,
+         * Annex A.
+         */
         public static final int AVCProfileConstrainedBaseline = 0x10000;
+
+        /**
+         * AVC Constrained High profile.
+         * See definition in
+         * <a href="https://www.itu.int/rec/T-REC-H.264-201704-I">H.264 recommendation</a>,
+         * Annex A.
+         */
         public static final int AVCProfileConstrainedHigh     = 0x80000;
 
         public static final int AVCLevel1       = 0x01;
@@ -3420,8 +3489,34 @@
         public static final int DolbyVisionLevelUhd48   = 0x80;
         public static final int DolbyVisionLevelUhd60   = 0x100;
 
+        // Profiles and levels for AV1 Codec, corresponding to the
+        // definitions in
+        // "AV1 Bitstream & Decoding Process Specification", Annex A
+        // found at
+        // https://aomedia.org/av1-bitstream-and-decoding-process-specification/
+
+        /**
+         * AV1 Main profile.
+         * See definition in
+         * <a href="https://aomedia.org/av1-bitstream-and-decoding-process-specification/"> AV1 Bitstream and Decoding Process Specification</a>
+         * Annex A.
+         */
         public static final int AV1Profile0     = 0x1;
+
+        /**
+         * AV1 High profile.
+         * See definition in
+         * <a href="https://aomedia.org/av1-bitstream-and-decoding-process-specification/"> AV1 Bitstream and Decoding Process Specification</a>
+         * Annex A.
+         */
         public static final int AV1Profile1     = 0x2;
+
+        /**
+         * AV1 Professional profile.
+         * See definition in
+         * <a href="https://aomedia.org/av1-bitstream-and-decoding-process-specification/"> AV1 Bitstream and Decoding Process Specification</a>
+         * Annex A.
+         */
         public static final int AV1Profile2     = 0x4;
 
         public static final int AV1Level2       = 0x1;
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index 579ee8d..aeb77cf 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -1588,13 +1588,13 @@
      * {@link #PROPERTY_DESCRIPTION}, {@link #PROPERTY_ALGORITHMS}
      */
     @NonNull
-    public native String getPropertyString(@NonNull @StringProperty String propertyName);
+    public native String getPropertyString(@NonNull String propertyName);
 
     /**
      * Set a MediaDrm String property value, given the property name string
      * and new value for the property.
      */
-    public native void setPropertyString(@NonNull @StringProperty String propertyName,
+    public native void setPropertyString(@NonNull String propertyName,
             @NonNull String value);
 
     /**
@@ -1616,14 +1616,14 @@
      * Standard fields names are {@link #PROPERTY_DEVICE_UNIQUE_ID}
      */
     @NonNull
-    public native byte[] getPropertyByteArray(@ArrayProperty String propertyName);
+    public native byte[] getPropertyByteArray(String propertyName);
 
     /**
     * Set a MediaDrm byte array property value, given the property name string
     * and new value for the property.
     */
-    public native void setPropertyByteArray(@NonNull @ArrayProperty
-            String propertyName, @NonNull byte[] value);
+    public native void setPropertyByteArray(
+            @NonNull String propertyName, @NonNull byte[] value);
 
     private static final native void setCipherAlgorithmNative(
             @NonNull MediaDrm drm, @NonNull byte[] sessionId, @NonNull String algorithm);
diff --git a/media/java/android/media/MediaHTTPConnection.java b/media/java/android/media/MediaHTTPConnection.java
index d724762..3838a999 100644
--- a/media/java/android/media/MediaHTTPConnection.java
+++ b/media/java/android/media/MediaHTTPConnection.java
@@ -37,6 +37,7 @@
 import java.net.UnknownServiceException;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
 
 /** @hide */
 public class MediaHTTPConnection extends IMediaHTTPConnection.Stub {
@@ -46,27 +47,23 @@
     // connection timeout - 30 sec
     private static final int CONNECT_TIMEOUT_MS = 30 * 1000;
 
-    @UnsupportedAppUsage
-    private long mCurrentOffset = -1;
-    @UnsupportedAppUsage
-    private URL mURL = null;
-    @UnsupportedAppUsage
-    private Map<String, String> mHeaders = null;
-    @UnsupportedAppUsage
-    private HttpURLConnection mConnection = null;
-    @UnsupportedAppUsage
-    private long mTotalSize = -1;
-    private InputStream mInputStream = null;
-
-    @UnsupportedAppUsage
-    private boolean mAllowCrossDomainRedirect = true;
-    @UnsupportedAppUsage
-    private boolean mAllowCrossProtocolRedirect = true;
-
     // from com.squareup.okhttp.internal.http
     private final static int HTTP_TEMP_REDIRECT = 307;
     private final static int MAX_REDIRECTS = 20;
 
+    class ConnectionState {
+        public HttpURLConnection mConnection = null;
+        public InputStream mInputStream = null;
+        public long mCurrentOffset = -1;
+        public Map<String, String> mHeaders = null;
+        public URL mURL = null;
+        public long mTotalSize = -1;
+        public boolean mAllowCrossDomainRedirect = true;
+        public boolean mAllowCrossProtocolRedirect = true;
+    }
+    private final AtomicReference<ConnectionState> mConnectionStateHolder =
+            new AtomicReference<ConnectionState>();
+
     @UnsupportedAppUsage
     public MediaHTTPConnection() {
         CookieHandler cookieHandler = CookieHandler.getDefault();
@@ -84,13 +81,23 @@
             Log.d(TAG, "connect: uri=" + uri + ", headers=" + headers);
         }
 
+        ConnectionState connectionState = mConnectionStateHolder.get();
+        synchronized (this) {
+            if (connectionState == null) {
+                connectionState = new ConnectionState();
+                mConnectionStateHolder.set(connectionState);
+            }
+        }
+
         try {
             disconnect();
-            mAllowCrossDomainRedirect = true;
-            mURL = new URL(uri);
-            mHeaders = convertHeaderStringToMap(headers);
+            connectionState.mAllowCrossDomainRedirect = true;
+            connectionState.mURL = new URL(uri);
+            connectionState.mHeaders = convertHeaderStringToMap(headers, connectionState);
         } catch (MalformedURLException e) {
             return null;
+        } finally {
+            mConnectionStateHolder.set(connectionState);
         }
 
         return native_getIMemory();
@@ -106,18 +113,21 @@
     }
 
     /* returns true iff header is internal */
-    private boolean filterOutInternalHeaders(String key, String val) {
+    private boolean filterOutInternalHeaders(
+            String key, String val, ConnectionState connectionState) {
         if ("android-allow-cross-domain-redirect".equalsIgnoreCase(key)) {
-            mAllowCrossDomainRedirect = parseBoolean(val);
+            connectionState.mAllowCrossDomainRedirect = parseBoolean(val);
             // cross-protocol redirects are also controlled by this flag
-            mAllowCrossProtocolRedirect = mAllowCrossDomainRedirect;
+            connectionState.mAllowCrossProtocolRedirect =
+                    connectionState.mAllowCrossDomainRedirect;
         } else {
             return false;
         }
         return true;
     }
 
-    private Map<String, String> convertHeaderStringToMap(String headers) {
+    private Map<String, String> convertHeaderStringToMap(String headers,
+            ConnectionState connectionState) {
         HashMap<String, String> map = new HashMap<String, String>();
 
         String[] pairs = headers.split("\r\n");
@@ -127,7 +137,7 @@
                 String key = pair.substring(0, colonPos);
                 String val = pair.substring(colonPos + 1);
 
-                if (!filterOutInternalHeaders(key, val)) {
+                if (!filterOutInternalHeaders(key, val, connectionState)) {
                     map.put(key, val);
                 }
             }
@@ -139,25 +149,28 @@
     @Override
     @UnsupportedAppUsage
     public void disconnect() {
-        teardownConnection();
-        mHeaders = null;
-        mURL = null;
+        ConnectionState connectionState = mConnectionStateHolder.getAndSet(null);
+        if (connectionState != null) {
+            teardownConnection(connectionState);
+            connectionState.mHeaders = null;
+            connectionState.mURL = null;
+        }
     }
 
-    private void teardownConnection() {
-        if (mConnection != null) {
-            if (mInputStream != null) {
+    private void teardownConnection(ConnectionState connectionState) {
+        if (connectionState.mConnection != null) {
+            if (connectionState.mInputStream != null) {
                 try {
-                    mInputStream.close();
+                    connectionState.mInputStream.close();
                 } catch (IOException e) {
                 }
-                mInputStream = null;
+                connectionState.mInputStream = null;
             }
 
-            mConnection.disconnect();
-            mConnection = null;
+            connectionState.mConnection.disconnect();
+            connectionState.mConnection = null;
 
-            mCurrentOffset = -1;
+            connectionState.mCurrentOffset = -1;
         }
     }
 
@@ -184,42 +197,44 @@
         return false;
     }
 
-    private void seekTo(long offset) throws IOException {
-        teardownConnection();
+    private void seekTo(long offset, ConnectionState connectionState) throws IOException {
+        teardownConnection(connectionState);
 
         try {
             int response;
             int redirectCount = 0;
 
-            URL url = mURL;
+            URL url = connectionState.mURL;
 
             // do not use any proxy for localhost (127.0.0.1)
             boolean noProxy = isLocalHost(url);
 
             while (true) {
                 if (noProxy) {
-                    mConnection = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
+                    connectionState.mConnection =
+                            (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);
                 } else {
-                    mConnection = (HttpURLConnection)url.openConnection();
+                    connectionState.mConnection = (HttpURLConnection) url.openConnection();
                 }
-                mConnection.setConnectTimeout(CONNECT_TIMEOUT_MS);
+                connectionState.mConnection.setConnectTimeout(CONNECT_TIMEOUT_MS);
 
                 // handle redirects ourselves if we do not allow cross-domain redirect
-                mConnection.setInstanceFollowRedirects(mAllowCrossDomainRedirect);
+                connectionState.mConnection.setInstanceFollowRedirects(
+                        connectionState.mAllowCrossDomainRedirect);
 
-                if (mHeaders != null) {
-                    for (Map.Entry<String, String> entry : mHeaders.entrySet()) {
-                        mConnection.setRequestProperty(
+                if (connectionState.mHeaders != null) {
+                    for (Map.Entry<String, String> entry : connectionState.mHeaders.entrySet()) {
+                        connectionState.mConnection.setRequestProperty(
                                 entry.getKey(), entry.getValue());
                     }
                 }
 
                 if (offset > 0) {
-                    mConnection.setRequestProperty(
+                    connectionState.mConnection.setRequestProperty(
                             "Range", "bytes=" + offset + "-");
                 }
 
-                response = mConnection.getResponseCode();
+                response = connectionState.mConnection.getResponseCode();
                 if (response != HttpURLConnection.HTTP_MULT_CHOICE &&
                         response != HttpURLConnection.HTTP_MOVED_PERM &&
                         response != HttpURLConnection.HTTP_MOVED_TEMP &&
@@ -233,7 +248,7 @@
                     throw new NoRouteToHostException("Too many redirects: " + redirectCount);
                 }
 
-                String method = mConnection.getRequestMethod();
+                String method = connectionState.mConnection.getRequestMethod();
                 if (response == HTTP_TEMP_REDIRECT &&
                         !method.equals("GET") && !method.equals("HEAD")) {
                     // "If the 307 status code is received in response to a
@@ -241,34 +256,35 @@
                     // automatically redirect the request"
                     throw new NoRouteToHostException("Invalid redirect");
                 }
-                String location = mConnection.getHeaderField("Location");
+                String location = connectionState.mConnection.getHeaderField("Location");
                 if (location == null) {
                     throw new NoRouteToHostException("Invalid redirect");
                 }
-                url = new URL(mURL /* TRICKY: don't use url! */, location);
+                url = new URL(connectionState.mURL /* TRICKY: don't use url! */, location);
                 if (!url.getProtocol().equals("https") &&
                         !url.getProtocol().equals("http")) {
                     throw new NoRouteToHostException("Unsupported protocol redirect");
                 }
-                boolean sameProtocol = mURL.getProtocol().equals(url.getProtocol());
-                if (!mAllowCrossProtocolRedirect && !sameProtocol) {
+                boolean sameProtocol =
+                        connectionState.mURL.getProtocol().equals(url.getProtocol());
+                if (!connectionState.mAllowCrossProtocolRedirect && !sameProtocol) {
                     throw new NoRouteToHostException("Cross-protocol redirects are disallowed");
                 }
-                boolean sameHost = mURL.getHost().equals(url.getHost());
-                if (!mAllowCrossDomainRedirect && !sameHost) {
+                boolean sameHost = connectionState.mURL.getHost().equals(url.getHost());
+                if (!connectionState.mAllowCrossDomainRedirect && !sameHost) {
                     throw new NoRouteToHostException("Cross-domain redirects are disallowed");
                 }
 
                 if (response != HTTP_TEMP_REDIRECT) {
                     // update effective URL, unless it is a Temporary Redirect
-                    mURL = url;
+                    connectionState.mURL = url;
                 }
             }
 
-            if (mAllowCrossDomainRedirect) {
+            if (connectionState.mAllowCrossDomainRedirect) {
                 // remember the current, potentially redirected URL if redirects
                 // were handled by HttpURLConnection
-                mURL = mConnection.getURL();
+                connectionState.mURL = connectionState.mConnection.getURL();
             }
 
             if (response == HttpURLConnection.HTTP_PARTIAL) {
@@ -276,10 +292,9 @@
                 // because what we want is not just the length of the range
                 // returned but the size of the full content if available.
 
-                String contentRange =
-                    mConnection.getHeaderField("Content-Range");
+                String contentRange = connectionState.mConnection.getHeaderField("Content-Range");
 
-                mTotalSize = -1;
+                connectionState.mTotalSize = -1;
                 if (contentRange != null) {
                     // format is "bytes xxx-yyy/zzz
                     // where "zzz" is the total number of bytes of the
@@ -291,7 +306,7 @@
                             contentRange.substring(lastSlashPos + 1);
 
                         try {
-                            mTotalSize = Long.parseLong(total);
+                            connectionState.mTotalSize = Long.parseLong(total);
                         } catch (NumberFormatException e) {
                         }
                     }
@@ -299,7 +314,7 @@
             } else if (response != HttpURLConnection.HTTP_OK) {
                 throw new IOException();
             } else {
-                mTotalSize = mConnection.getContentLength();
+                connectionState.mTotalSize = connectionState.mConnection.getContentLength();
             }
 
             if (offset > 0 && response != HttpURLConnection.HTTP_PARTIAL) {
@@ -308,14 +323,14 @@
                 throw new ProtocolException();
             }
 
-            mInputStream =
-                new BufferedInputStream(mConnection.getInputStream());
+            connectionState.mInputStream =
+                new BufferedInputStream(connectionState.mConnection.getInputStream());
 
-            mCurrentOffset = offset;
+            connectionState.mCurrentOffset = offset;
         } catch (IOException e) {
-            mTotalSize = -1;
-            teardownConnection();
-            mCurrentOffset = -1;
+            connectionState.mTotalSize = -1;
+            teardownConnection(connectionState);
+            connectionState.mCurrentOffset = -1;
 
             throw e;
         }
@@ -324,10 +339,14 @@
     @Override
     @UnsupportedAppUsage
     public int readAt(long offset, int size) {
-        return native_readAt(offset, size);
+        ConnectionState connectionState = mConnectionStateHolder.get();
+        if (connectionState != null) {
+            return native_readAt(offset, size, connectionState);
+        }
+        return -1;
     }
 
-    private int readAt(long offset, byte[] data, int size) {
+    private int readAt(long offset, byte[] data, int size, ConnectionState connectionState) {
         StrictMode.ThreadPolicy policy =
             new StrictMode.ThreadPolicy.Builder().permitAll().build();
 
@@ -335,12 +354,12 @@
 
         try {
             synchronized(this) {
-                if (offset != mCurrentOffset) {
-                    seekTo(offset);
+                if (offset != connectionState.mCurrentOffset) {
+                    seekTo(offset, connectionState);
                 }
             }
 
-            int n = mInputStream.read(data, 0, size);
+            int n = connectionState.mInputStream.read(data, 0, size);
 
             if (n == -1) {
                 // InputStream signals EOS using a -1 result, our semantics
@@ -348,7 +367,7 @@
                 n = 0;
             }
 
-            mCurrentOffset += n;
+            connectionState.mCurrentOffset += n;
 
             if (VERBOSE) {
                 Log.d(TAG, "readAt " + offset + " / " + size + " => " + n);
@@ -380,35 +399,47 @@
 
     @Override
     public synchronized long getSize() {
-        if (mConnection == null) {
-            try {
-                seekTo(0);
-            } catch (IOException e) {
-                return -1;
+        ConnectionState connectionState = mConnectionStateHolder.get();
+        if (connectionState != null) {
+            if (connectionState.mConnection == null) {
+                try {
+                    seekTo(0, connectionState);
+                } catch (IOException e) {
+                    return -1;
+                }
             }
+            return connectionState.mTotalSize;
         }
 
-        return mTotalSize;
+        return -1;
     }
 
     @Override
     @UnsupportedAppUsage
     public synchronized String getMIMEType() {
-        if (mConnection == null) {
-            try {
-                seekTo(0);
-            } catch (IOException e) {
-                return "application/octet-stream";
+        ConnectionState connectionState = mConnectionStateHolder.get();
+        if (connectionState != null) {
+            if (connectionState.mConnection == null) {
+                try {
+                    seekTo(0, connectionState);
+                } catch (IOException e) {
+                    return "application/octet-stream";
+                }
             }
+            return connectionState.mConnection.getContentType();
         }
 
-        return mConnection.getContentType();
+        return null;
     }
 
     @Override
     @UnsupportedAppUsage
     public String getUri() {
-        return mURL.toString();
+        ConnectionState connectionState = mConnectionStateHolder.get();
+        if (connectionState != null) {
+            return connectionState.mURL.toString();
+        }
+        return null;
     }
 
     @Override
@@ -421,7 +452,7 @@
     private native final void native_finalize();
 
     private native final IBinder native_getIMemory();
-    private native final int native_readAt(long offset, int size);
+    private native int native_readAt(long offset, int size, ConnectionState connectionState);
 
     static {
         System.loadLibrary("media_jni");
diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java
index 0679e8e9..9a60923 100644
--- a/media/java/android/media/RingtoneManager.java
+++ b/media/java/android/media/RingtoneManager.java
@@ -215,17 +215,19 @@
     // Make sure the column ordering and then ..._COLUMN_INDEX are in sync
     
     private static final String[] INTERNAL_COLUMNS = new String[] {
-        MediaStore.Audio.Media._ID, MediaStore.Audio.Media.TITLE,
-        "\"" + MediaStore.Audio.Media.INTERNAL_CONTENT_URI + "\"",
-        MediaStore.Audio.Media.TITLE_KEY
+        MediaStore.Audio.Media._ID,
+        MediaStore.Audio.Media.TITLE,
+        MediaStore.Audio.Media.TITLE,
+        MediaStore.Audio.Media.TITLE_KEY,
     };
 
     private static final String[] MEDIA_COLUMNS = new String[] {
-        MediaStore.Audio.Media._ID, MediaStore.Audio.Media.TITLE,
-        "\"" + MediaStore.Audio.Media.EXTERNAL_CONTENT_URI + "\"",
-        MediaStore.Audio.Media.TITLE_KEY
+        MediaStore.Audio.Media._ID,
+        MediaStore.Audio.Media.TITLE,
+        MediaStore.Audio.Media.TITLE,
+        MediaStore.Audio.Media.TITLE_KEY,
     };
-    
+
     /**
      * The column index (in the cursor returned by {@link #getCursor()} for the
      * row ID.
@@ -459,8 +461,9 @@
                 // We don't need to re-add the internal ringtones for the work profile since
                 // they are the same as the personal profile. We just need the external
                 // ringtones.
-                return new ExternalRingtonesCursorWrapper(getMediaRingtones(parentContext),
-                        parentInfo.id);
+                final Cursor res = getMediaRingtones(parentContext);
+                return new ExternalRingtonesCursorWrapper(res, ContentProvider.maybeAddUserId(
+                        MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, parentInfo.id));
             }
         }
         return null;
@@ -580,14 +583,16 @@
 
     @UnsupportedAppUsage
     private Cursor getInternalRingtones() {
-        return query(
+        final Cursor res = query(
                 MediaStore.Audio.Media.INTERNAL_CONTENT_URI, INTERNAL_COLUMNS,
                 constructBooleanTrueWhereClause(mFilterColumns),
                 null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
+        return new ExternalRingtonesCursorWrapper(res, MediaStore.Audio.Media.INTERNAL_CONTENT_URI);
     }
 
     private Cursor getMediaRingtones() {
-        return getMediaRingtones(mContext);
+        final Cursor res = getMediaRingtones(mContext);
+        return new ExternalRingtonesCursorWrapper(res, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
     }
 
     @UnsupportedAppUsage
diff --git a/media/java/android/media/session/ControllerLink.java b/media/java/android/media/session/ControllerLink.java
deleted file mode 100644
index d4ea2a3..0000000
--- a/media/java/android/media/session/ControllerLink.java
+++ /dev/null
@@ -1,1042 +0,0 @@
-/*
- * 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.
- */
-
-package android.media.session;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.PendingIntent;
-import android.media.MediaMetadata;
-import android.media.MediaParceledListSlice;
-import android.media.Rating;
-import android.media.session.MediaController.PlaybackInfo;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.RemoteException;
-import android.os.ResultReceiver;
-import android.view.KeyEvent;
-
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Handles incoming commands from {@link MediaController}.
- * @hide
- */
-public final class ControllerLink implements Parcelable {
-    public static final @android.annotation.NonNull Parcelable.Creator<ControllerLink> CREATOR =
-            new Parcelable.Creator<ControllerLink>() {
-                @Override
-                public ControllerLink createFromParcel(Parcel in) {
-                    return new ControllerLink(in.readStrongBinder());
-                }
-
-                @Override
-                public ControllerLink[] newArray(int size) {
-                    return new ControllerLink[size];
-                }
-            };
-
-    final ControllerStub mControllerStub;
-    final ISessionController mISessionController;
-
-    /**
-     * Constructor for stub (Callee)
-     */
-    public ControllerLink(@NonNull ControllerStub controllerStub) {
-        mControllerStub = controllerStub;
-        mISessionController = new StubProxy();
-    }
-
-    /**
-     * Constructor for interface (Caller)
-     */
-    public ControllerLink(IBinder binder) {
-        mControllerStub = null;
-        mISessionController = ISessionController.Stub.asInterface(binder);
-    }
-
-    /**
-     * Tell system that a controller sends a command.
-     *
-     * @param packageName the package name of the controller
-     * @param caller the {@link ControllerCallbackLink} of the controller
-     * @param command the name of the command
-     * @param args the arguments included with the command
-     * @param cb the result receiver for getting the result of the command
-     */
-    void sendCommand(@NonNull String packageName, @NonNull ControllerCallbackLink caller,
-            @NonNull String command, @Nullable Bundle args, @Nullable ResultReceiver cb) {
-        try {
-            mISessionController.sendCommand(packageName, caller, command, args, cb);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that a controller sends a media button event.
-     *
-     * @param packageName the package name of the controller
-     * @param caller the {@link ControllerCallbackLink} of the controller
-     * @param mediaButton the media button key event
-     */
-    boolean sendMediaButton(@NonNull String packageName,
-            @NonNull ControllerCallbackLink caller, @NonNull KeyEvent mediaButton) {
-        try {
-            return mISessionController.sendMediaButton(packageName, caller, mediaButton);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Registers a controller callback link to the system.
-     *
-     * @param packageName the package name of the controller
-     * @param cb the controller callback link to register
-     */
-    void registerCallback(@NonNull String packageName, @NonNull ControllerCallbackLink cb) {
-        try {
-            mISessionController.registerCallback(packageName, cb);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Unregisters a controller callback link from the system.
-     *
-     * @param cb the controller callback link to register
-     */
-    void unregisterCallback(@NonNull ControllerCallbackLink cb) {
-        try {
-            mISessionController.unregisterCallback(cb);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Gets the package name of the connected session.
-     */
-    @NonNull
-    String getPackageName() {
-        try {
-            return mISessionController.getPackageName();
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Gets the tag of the connected session.
-     */
-    @NonNull
-    String getTag() {
-        try {
-            return mISessionController.getTag();
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Gets the session info of the connected session.
-     */
-    @Nullable
-    Bundle getSessionInfo() {
-        try {
-            return mISessionController.getSessionInfo();
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Gets the {@link PendingIntent} for launching UI of the connected session.
-     */
-    @Nullable
-    PendingIntent getLaunchPendingIntent() {
-        try {
-            return mISessionController.getLaunchPendingIntent();
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Gets the flags of the connected session.
-     */
-    long getFlags() {
-        try {
-            return mISessionController.getFlags();
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Gets the volume attributes of the connected session.
-     */
-    @NonNull
-    PlaybackInfo getVolumeAttributes() {
-        try {
-            return mISessionController.getVolumeAttributes();
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that a controller requests adjusting the volume.
-     *
-     * @param packageName the package name of the controller
-     * @param opPackageName the op package name of this request
-     * @param caller the {@link ControllerCallbackLink} of the controller
-     * @param direction the direction to adjust the volume in
-     * @param flags the flags with this volume change request
-     */
-    void adjustVolume(@NonNull String packageName, @NonNull String opPackageName,
-            @NonNull ControllerCallbackLink caller, int direction,
-            int flags) {
-        try {
-            mISessionController.adjustVolume(packageName, opPackageName, caller, direction, flags);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that a controller requests setting the volume.
-     *
-     * @param packageName the package name of the controller
-     * @param opPackageName the op package name of this request
-     * @param caller the {@link ControllerCallbackLink} of the controller
-     * @param flags the flags with this volume change request
-     */
-    void setVolumeTo(@NonNull String packageName, @NonNull String opPackageName,
-            @NonNull ControllerCallbackLink caller, int value, int flags) {
-        try {
-            mISessionController.setVolumeTo(packageName, opPackageName, caller, value, flags);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that a controller requests preparing media.
-     *
-     * @param packageName the package name of the controller
-     * @param caller the {@link ControllerCallbackLink} of the controller
-     */
-    void prepare(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
-        try {
-            mISessionController.prepare(packageName, caller);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that a controller requests preparing media from given media ID.
-     *
-     * @param packageName the package name of the controller
-     * @param caller the {@link ControllerCallbackLink} of the controller
-     * @param mediaId the ID of the media
-     * @param extras the extras included with this request.
-     */
-    void prepareFromMediaId(@NonNull String packageName,
-            @NonNull ControllerCallbackLink caller, @NonNull String mediaId,
-            @Nullable Bundle extras) {
-        try {
-            mISessionController.prepareFromMediaId(packageName, caller, mediaId, extras);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that a controller requests preparing media from given search query.
-     *
-     * @param packageName the package name of the controller
-     * @param caller the {@link ControllerCallbackLink} of the controller
-     * @param query the search query
-     * @param extras the extras included with this request.
-     */
-    void prepareFromSearch(@NonNull String packageName,
-            @NonNull ControllerCallbackLink caller, @NonNull String query,
-            @Nullable Bundle extras) {
-        try {
-            mISessionController.prepareFromSearch(packageName, caller, query, extras);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that a controller requests preparing media from given uri.
-     *
-     * @param packageName the package name of the controller
-     * @param caller the {@link ControllerCallbackLink} of the controller
-     * @param uri the uri of the media
-     * @param extras the extras included with this request.
-     */
-    void prepareFromUri(@NonNull String packageName, @NonNull ControllerCallbackLink caller,
-            @NonNull Uri uri, @Nullable Bundle extras) {
-        try {
-            mISessionController.prepareFromUri(packageName, caller, uri, extras);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that a controller requests playing media.
-     *
-     * @param packageName the package name of the controller
-     * @param caller the {@link ControllerCallbackLink} of the controller
-     */
-    void play(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
-        try {
-            mISessionController.play(packageName, caller);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that a controller requests playing media from given media ID.
-     *
-     * @param packageName the package name of the controller
-     * @param caller the {@link ControllerCallbackLink} of the controller
-     * @param mediaId the ID of the media
-     * @param extras the extras included with this request.
-     */
-    void playFromMediaId(@NonNull String packageName, @NonNull ControllerCallbackLink caller,
-            @NonNull String mediaId, @Nullable Bundle extras) {
-        try {
-            mISessionController.playFromMediaId(packageName, caller, mediaId, extras);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that a controller requests playing media from given search query.
-     *
-     * @param packageName the package name of the controller
-     * @param caller the {@link ControllerCallbackLink} of the controller
-     * @param query the search query
-     * @param extras the extras included with this request.
-     */
-    void playFromSearch(@NonNull String packageName, @NonNull ControllerCallbackLink caller,
-            @NonNull String query, @Nullable Bundle extras) {
-        try {
-            mISessionController.playFromSearch(packageName, caller, query, extras);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that a controller requests playing media from given uri.
-     *
-     * @param packageName the package name of the controller
-     * @param caller the {@link ControllerCallbackLink} of the controller
-     * @param uri the uri of the media
-     * @param extras the extras included with this request.
-     */
-    void playFromUri(@NonNull String packageName, @NonNull ControllerCallbackLink caller,
-            @NonNull Uri uri, @Nullable Bundle extras) {
-        try {
-            mISessionController.playFromUri(packageName, caller, uri, extras);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that a controller requests skipping to the queue item with given ID.
-     *
-     * @param packageName the package name of the controller
-     * @param caller the {@link ControllerCallbackLink} of the controller
-     * @param id the queue id of the item
-     */
-    void skipToQueueItem(@NonNull String packageName, @NonNull ControllerCallbackLink caller,
-            long id) {
-        try {
-            mISessionController.skipToQueueItem(packageName, caller, id);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that a controller requests pausing media.
-     *
-     * @param packageName the package name of the controller
-     * @param caller the {@link ControllerCallbackLink} of the controller
-     */
-    void pause(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
-        try {
-            mISessionController.pause(packageName, caller);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that a controller requests stopping media.
-     *
-     * @param packageName the package name of the controller
-     * @param caller the {@link ControllerCallbackLink} of the controller
-     */
-    void stop(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
-        try {
-            mISessionController.stop(packageName, caller);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that a controller requests skipping to the next queue item.
-     *
-     * @param packageName the package name of the controller
-     * @param caller the {@link ControllerCallbackLink} of the controller
-     */
-    void next(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
-        try {
-            mISessionController.next(packageName, caller);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that a controller requests skipping to the previous queue item.
-     *
-     * @param packageName the package name of the controller
-     * @param caller the {@link ControllerCallbackLink} of the controller
-     */
-    void previous(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
-        try {
-            mISessionController.previous(packageName, caller);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that a controller requests fast-forwarding.
-     *
-     * @param packageName the package name of the controller
-     * @param caller the {@link ControllerCallbackLink} of the controller
-     */
-    void fastForward(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
-        try {
-            mISessionController.fastForward(packageName, caller);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that a controller requests rewinding.
-     *
-     * @param packageName the package name of the controller
-     * @param caller the {@link ControllerCallbackLink} of the controller
-     */
-    void rewind(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
-        try {
-            mISessionController.rewind(packageName, caller);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that a controller requests seeking to the specific position.
-     *
-     * @param packageName the package name of the controller
-     * @param caller the {@link ControllerCallbackLink} of the controller
-     * @param pos the position to move to, in milliseconds
-     */
-    void seekTo(@NonNull String packageName, @NonNull ControllerCallbackLink caller,
-            long pos) {
-        try {
-            mISessionController.seekTo(packageName, caller, pos);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that a controller requests rating of the current media.
-     *
-     * @param packageName the package name of the controller
-     * @param caller the {@link ControllerCallbackLink} of the controller
-     * @param rating the rating of the current media
-     */
-    void rate(@NonNull String packageName, @NonNull ControllerCallbackLink caller,
-            @NonNull Rating rating) {
-        try {
-            mISessionController.rate(packageName, caller, rating);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that a controller requests changing the playback speed.
-     *
-     * @param packageName the package name of the controller
-     * @param caller the {@link ControllerCallbackLink} of the controller
-     * @param speed the playback speed
-     */
-    void setPlaybackSpeed(@NonNull String packageName, @NonNull ControllerCallbackLink caller,
-            float speed) {
-        try {
-            mISessionController.setPlaybackSpeed(packageName, caller, speed);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that a controller sends a custom action.
-     *
-     * @param packageName the package name of the controller
-     * @param caller the {@link ControllerCallbackLink} of the controller
-     * @param action the name of the action
-     * @param args the arguments included with this action
-     */
-    void sendCustomAction(@NonNull String packageName,
-            @NonNull ControllerCallbackLink caller, @NonNull String action, @Nullable Bundle args) {
-        try {
-            mISessionController.sendCustomAction(packageName, caller, action, args);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Gets the current metadata of the connected session.
-     */
-    @Nullable
-    public MediaMetadata getMetadata() {
-        try {
-            return mISessionController.getMetadata();
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Gets the current playback state of the connected session.
-     */
-    @Nullable
-    public PlaybackState getPlaybackState() {
-        try {
-            return mISessionController.getPlaybackState();
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Gets the current queue of the connected session.
-     */
-    @Nullable
-    public List<MediaSession.QueueItem> getQueue() {
-        try {
-            MediaParceledListSlice queue = mISessionController.getQueue();
-            return queue == null ? null : queue.getList();
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Gets the current queue title of the connected session.
-     */
-    @Nullable
-    public CharSequence getQueueTitle() {
-        try {
-            return mISessionController.getQueueTitle();
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Gets the current extras of the connected session.
-     */
-    @Nullable
-    public Bundle getExtras() {
-        try {
-            return mISessionController.getExtras();
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Gets the current rating type of the connected session.
-     */
-    public int getRatingType() {
-        try {
-            return mISessionController.getRatingType();
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /** Gets the binder */
-    @NonNull
-    public IBinder getBinder() {
-        return mISessionController.asBinder();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeStrongBinder(mISessionController.asBinder());
-    }
-
-    @Override
-    public int hashCode() {
-        return mISessionController.asBinder().hashCode();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (!(obj instanceof ControllerLink)) {
-            return false;
-        }
-        ControllerLink other = (ControllerLink) obj;
-        return Objects.equals(getBinder(), other.getBinder());
-    }
-
-    /**
-     * Class for Stub implementation
-     */
-    public abstract static class ControllerStub {
-        /** Stub method for ISessionController.sendCommand */
-        public void sendCommand(@NonNull String packageName, @NonNull ControllerCallbackLink caller,
-                @NonNull String command, @Nullable Bundle args, @Nullable ResultReceiver cb) {
-        }
-
-        /** Stub method for ISessionController.sendMediaButton */
-        public boolean sendMediaButton(@NonNull String packageName,
-                @NonNull ControllerCallbackLink caller, @NonNull KeyEvent mediaButton) {
-            return false;
-        }
-
-        /** Stub method for ISessionController.registerCallback */
-        public void registerCallback(@NonNull String packageName,
-                @NonNull ControllerCallbackLink cb) {
-        }
-
-        /** Stub method for ISessionController.unregisterCallback */
-        public void unregisterCallback(@NonNull ControllerCallbackLink cb) {
-        }
-
-        /** Stub method for ISessionController.getPackageName */
-        @NonNull
-        public String getPackageName() {
-            return null;
-        }
-
-        /** Stub method for ISessionController.getTag */
-        @NonNull
-        public String getTag() {
-            return null;
-        }
-
-        /** Stub method for ISessionController.getSessionInfo */
-        @Nullable
-        public Bundle getSessionInfo() {
-            return null;
-        }
-
-        /** Stub method for ISessionController.getLaunchPendingIntent */
-        @Nullable
-        public PendingIntent getLaunchPendingIntent() {
-            return null;
-        }
-
-        /** Stub method for ISessionController.getFlags */
-        public long getFlags() {
-            return 0;
-        }
-
-        /** Stub method for ISessionController.getVolumeAttributes */
-        @NonNull
-        public PlaybackInfo getVolumeAttributes() {
-            return null;
-        }
-
-        /** Stub method for ISessionController.adjustVolume */
-        public void adjustVolume(@NonNull String packageName, @NonNull String opPackageName,
-                @NonNull ControllerCallbackLink caller, int direction, int flags) {
-        }
-
-        /** Stub method for ISessionController.setVolumeTo */
-        public void setVolumeTo(@NonNull String packageName, @NonNull String opPackageName,
-                @NonNull ControllerCallbackLink caller, int value, int flags) {
-        }
-
-        /** Stub method for ISessionController.prepare */
-        public void prepare(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
-        }
-
-        /** Stub method for ISessionController.prepareFromMediaId */
-        public void prepareFromMediaId(@NonNull String packageName,
-                @NonNull ControllerCallbackLink caller, @NonNull String mediaId,
-                @Nullable Bundle extras) {
-        }
-
-        /** Stub method for ISessionController.prepareFromSearch */
-        public void prepareFromSearch(@NonNull String packageName,
-                @NonNull ControllerCallbackLink caller, @NonNull String query,
-                @Nullable Bundle extras) {
-        }
-
-        /** Stub method for ISessionController.prepareFromUri */
-        public void prepareFromUri(@NonNull String packageName,
-                @NonNull ControllerCallbackLink caller, @NonNull Uri uri, @Nullable Bundle extras) {
-        }
-
-        /** Stub method for ISessionController.play */
-        public void play(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
-        }
-
-        /** Stub method for ISessionController.playFromMediaId */
-        public void playFromMediaId(@NonNull String packageName,
-                @NonNull ControllerCallbackLink caller, @NonNull String mediaId,
-                @Nullable Bundle extras) {
-        }
-
-        /** Stub method for ISessionController.playFromSearch */
-        public void playFromSearch(@NonNull String packageName,
-                @NonNull ControllerCallbackLink caller, @NonNull String query,
-                @Nullable Bundle extras) {
-        }
-
-        /** Stub method for ISessionController.playFromUri */
-        public void playFromUri(@NonNull String packageName, @NonNull ControllerCallbackLink caller,
-                @NonNull Uri uri, @Nullable Bundle extras) {
-        }
-
-        /** Stub method for ISessionController.skipToQueueItem */
-        public void skipToQueueItem(@NonNull String packageName,
-                @NonNull ControllerCallbackLink caller, long id) {
-        }
-
-        /** Stub method for ISessionController.pause */
-        public void pause(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
-        }
-
-        /** Stub method for ISessionController.stop */
-        public void stop(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
-        }
-
-        /** Stub method for ISessionController.next */
-        public void next(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
-        }
-
-        /** Stub method for ISessionController.previous */
-        public void previous(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
-        }
-
-        /** Stub method for ISessionController.fastForward */
-        public void fastForward(@NonNull String packageName,
-                @NonNull ControllerCallbackLink caller) {
-        }
-
-        /** Stub method for ISessionController.rewind */
-        public void rewind(@NonNull String packageName, @NonNull ControllerCallbackLink caller) {
-        }
-
-        /** Stub method for ISessionController.seekTo */
-        public void seekTo(@NonNull String packageName, @NonNull ControllerCallbackLink caller,
-                long pos) {
-        }
-
-        /** Stub method for ISessionController.rate */
-        public void rate(@NonNull String packageName, @NonNull ControllerCallbackLink caller,
-                @NonNull Rating rating) {
-        }
-
-        /** Stub method for ISessionController.setPlaybackSpeed */
-        public void setPlaybackSpeed(@NonNull String packageName,
-                @NonNull ControllerCallbackLink caller, float speed) {
-        }
-
-        /** Stub method for ISessionController.sendCustomAction */
-        public void sendCustomAction(@NonNull String packageName,
-                @NonNull ControllerCallbackLink caller, @NonNull String action,
-                @Nullable Bundle args) {
-        }
-
-        /** Stub method for ISessionController.getMetadata */
-        @Nullable
-        public MediaMetadata getMetadata() {
-            return null;
-        }
-
-        /** Stub method for ISessionController.getPlaybackState */
-        @Nullable
-        public PlaybackState getPlaybackState() {
-            return null;
-        }
-
-        /** Stub method for ISessionController.getQueue */
-        @Nullable
-        public List<MediaSession.QueueItem> getQueue() {
-            return null;
-        }
-
-        /** Stub method for ISessionController.getQueueTitle */
-        @Nullable
-        public CharSequence getQueueTitle() {
-            return null;
-        }
-
-        /** Stub method for ISessionController.getExtras */
-        @Nullable
-        public Bundle getExtras() {
-            return null;
-        }
-
-        /** Stub method for ISessionController.getRatingType */
-        public int getRatingType() {
-            return Rating.RATING_NONE;
-        }
-    }
-
-    private class StubProxy extends ISessionController.Stub {
-        @Override
-        public void sendCommand(String packageName, ControllerCallbackLink caller,
-                String command, Bundle args, ResultReceiver cb) {
-            mControllerStub.sendCommand(packageName, caller, command, args, cb);
-        }
-
-        @Override
-        public boolean sendMediaButton(String packageName, ControllerCallbackLink caller,
-                KeyEvent mediaButton) {
-            return mControllerStub.sendMediaButton(packageName, caller, mediaButton);
-        }
-
-        @Override
-        public void registerCallback(String packageName, ControllerCallbackLink cb) {
-            mControllerStub.registerCallback(packageName, cb);
-        }
-
-        @Override
-        public void unregisterCallback(ControllerCallbackLink cb) {
-            mControllerStub.unregisterCallback(cb);
-        }
-
-        @Override
-        public String getPackageName() {
-            return mControllerStub.getPackageName();
-        }
-
-        @Override
-        public String getTag() {
-            return mControllerStub.getTag();
-        }
-
-        @Override
-        public Bundle getSessionInfo() {
-            return mControllerStub.getSessionInfo();
-        }
-
-        @Override
-        public PendingIntent getLaunchPendingIntent() {
-            return mControllerStub.getLaunchPendingIntent();
-        }
-
-        @Override
-        public long getFlags() {
-            return mControllerStub.getFlags();
-        }
-
-        @Override
-        public PlaybackInfo getVolumeAttributes() {
-            return mControllerStub.getVolumeAttributes();
-        }
-
-        @Override
-        public void adjustVolume(String packageName, String opPackageName,
-                ControllerCallbackLink caller, int direction, int flags) {
-            mControllerStub.adjustVolume(packageName, opPackageName, caller, direction, flags);
-        }
-
-        @Override
-        public void setVolumeTo(String packageName, String opPackageName,
-                ControllerCallbackLink caller, int value, int flags) {
-            mControllerStub.setVolumeTo(packageName, opPackageName, caller, value, flags);
-        }
-
-        @Override
-        public void prepare(String packageName, ControllerCallbackLink caller) {
-            mControllerStub.prepare(packageName, caller);
-        }
-
-        @Override
-        public void prepareFromMediaId(String packageName, ControllerCallbackLink caller,
-                String mediaId, Bundle extras) {
-            mControllerStub.prepareFromMediaId(packageName, caller, mediaId, extras);
-        }
-
-        @Override
-        public void prepareFromSearch(String packageName, ControllerCallbackLink caller,
-                String query, Bundle extras) {
-            mControllerStub.prepareFromSearch(packageName, caller, query, extras);
-        }
-
-        @Override
-        public void prepareFromUri(String packageName, ControllerCallbackLink caller,
-                Uri uri, Bundle extras) {
-            mControllerStub.prepareFromUri(packageName, caller, uri, extras);
-        }
-
-        @Override
-        public void play(String packageName, ControllerCallbackLink caller) {
-            mControllerStub.play(packageName, caller);
-        }
-
-        @Override
-        public void playFromMediaId(String packageName, ControllerCallbackLink caller,
-                String mediaId, Bundle extras) {
-            mControllerStub.playFromMediaId(packageName, caller, mediaId, extras);
-        }
-
-        @Override
-        public void playFromSearch(String packageName, ControllerCallbackLink caller,
-                String query, Bundle extras) {
-            mControllerStub.playFromSearch(packageName, caller, query, extras);
-        }
-
-        @Override
-        public void playFromUri(String packageName, ControllerCallbackLink caller,
-                Uri uri, Bundle extras) {
-            mControllerStub.playFromUri(packageName, caller, uri, extras);
-        }
-
-        @Override
-        public void skipToQueueItem(String packageName, ControllerCallbackLink caller, long id) {
-            mControllerStub.skipToQueueItem(packageName, caller, id);
-        }
-
-        @Override
-        public void pause(String packageName, ControllerCallbackLink caller) {
-            mControllerStub.pause(packageName, caller);
-        }
-
-        @Override
-        public void stop(String packageName, ControllerCallbackLink caller) {
-            mControllerStub.stop(packageName, caller);
-        }
-
-        @Override
-        public void next(String packageName, ControllerCallbackLink caller) {
-            mControllerStub.next(packageName, caller);
-        }
-
-        @Override
-        public void previous(String packageName, ControllerCallbackLink caller) {
-            mControllerStub.previous(packageName, caller);
-        }
-
-        @Override
-        public void fastForward(String packageName, ControllerCallbackLink caller) {
-            mControllerStub.fastForward(packageName, caller);
-        }
-
-        @Override
-        public void rewind(String packageName, ControllerCallbackLink caller) {
-            mControllerStub.rewind(packageName, caller);
-        }
-
-        @Override
-        public void seekTo(String packageName, ControllerCallbackLink caller, long pos) {
-            mControllerStub.seekTo(packageName, caller, pos);
-        }
-
-        @Override
-        public void rate(String packageName, ControllerCallbackLink caller, Rating rating) {
-            mControllerStub.rate(packageName, caller, rating);
-        }
-
-        @Override
-        public void setPlaybackSpeed(String packageName, ControllerCallbackLink caller,
-                float speed) {
-            mControllerStub.setPlaybackSpeed(packageName, caller, speed);
-        }
-
-        @Override
-        public void sendCustomAction(String packageName, ControllerCallbackLink caller,
-                String action, Bundle args) {
-            mControllerStub.sendCustomAction(packageName, caller, action, args);
-        }
-
-        @Override
-        public MediaMetadata getMetadata() {
-            return mControllerStub.getMetadata();
-        }
-
-        @Override
-        public PlaybackState getPlaybackState() {
-            return mControllerStub.getPlaybackState();
-        }
-
-        @Override
-        public MediaParceledListSlice getQueue() {
-            List<MediaSession.QueueItem> queue = mControllerStub.getQueue();
-            return queue == null ? null : new MediaParceledListSlice(queue);
-        }
-
-        @Override
-        public CharSequence getQueueTitle() {
-            return mControllerStub.getQueueTitle();
-        }
-
-        @Override
-        public Bundle getExtras() {
-            return mControllerStub.getExtras();
-        }
-
-        @Override
-        public int getRatingType() {
-            return mControllerStub.getRatingType();
-        }
-    }
-}
diff --git a/media/java/android/media/session/ISession.aidl b/media/java/android/media/session/ISession.aidl
index 9b1ad7b..fcde95a 100644
--- a/media/java/android/media/session/ISession.aidl
+++ b/media/java/android/media/session/ISession.aidl
@@ -19,7 +19,7 @@
 import android.media.AudioAttributes;
 import android.media.MediaMetadata;
 import android.media.MediaParceledListSlice;
-import android.media.session.ControllerLink;
+import android.media.session.ISessionController;
 import android.media.session.PlaybackState;
 import android.media.session.MediaSession;
 import android.os.Bundle;
@@ -31,7 +31,7 @@
  */
 interface ISession {
     void sendEvent(String event, in Bundle data);
-    ControllerLink getController();
+    ISessionController getController();
     void setFlags(int flags);
     void setActive(boolean active);
     void setMediaButtonReceiver(in PendingIntent mbr);
diff --git a/media/java/android/media/session/ISessionManager.aidl b/media/java/android/media/session/ISessionManager.aidl
index cfcc294..02348476 100644
--- a/media/java/android/media/session/ISessionManager.aidl
+++ b/media/java/android/media/session/ISessionManager.aidl
@@ -22,10 +22,10 @@
 import android.media.session.ICallback;
 import android.media.session.IOnMediaKeyListener;
 import android.media.session.IOnVolumeKeyLongPressListener;
+import android.media.session.ISession;
 import android.media.session.ISession2TokensListener;
 import android.media.session.MediaSession;
 import android.media.session.SessionCallbackLink;
-import android.media.session.SessionLink;
 import android.os.Bundle;
 import android.view.KeyEvent;
 
@@ -34,7 +34,7 @@
  * @hide
  */
 interface ISessionManager {
-    SessionLink createSession(String packageName, in SessionCallbackLink sessionCb, String tag,
+    ISession createSession(String packageName, in SessionCallbackLink sessionCb, String tag,
             in Bundle sessionInfo, int userId);
     void notifySession2Created(in Session2Token sessionToken);
     List<MediaSession.Token> getSessions(in ComponentName compName, int userId);
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index 7334044..036cd78 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -24,6 +24,7 @@
 import android.media.AudioAttributes;
 import android.media.AudioManager;
 import android.media.MediaMetadata;
+import android.media.MediaParceledListSlice;
 import android.media.Rating;
 import android.media.VolumeProvider;
 import android.media.session.MediaSession.QueueItem;
@@ -34,6 +35,7 @@
 import android.os.Message;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.text.TextUtils;
 import android.util.Log;
@@ -67,7 +69,7 @@
     private static final int MSG_UPDATE_EXTRAS = 7;
     private static final int MSG_DESTROYED = 8;
 
-    private final ControllerLink mSessionBinder;
+    private final ISessionController mSessionBinder;
 
     private final MediaSession.Token mToken;
     private final Context mContext;
@@ -95,10 +97,10 @@
         if (token == null) {
             throw new IllegalArgumentException("token shouldn't be null");
         }
-        if (token.getControllerLink() == null) {
-            throw new IllegalArgumentException("token.getControllerLink() shouldn't be null");
+        if (token.getBinder() == null) {
+            throw new IllegalArgumentException("token.getBinder() shouldn't be null");
         }
-        mSessionBinder = token.getControllerLink();
+        mSessionBinder = token.getBinder();
         mTransportControls = new TransportControls();
         mToken = token;
         mContext = context;
@@ -131,7 +133,7 @@
         }
         try {
             return mSessionBinder.sendMediaButton(mContext.getPackageName(), mCbStub, keyEvent);
-        } catch (RuntimeException e) {
+        } catch (RemoteException e) {
             // System is dead. =(
         }
         return false;
@@ -145,7 +147,7 @@
     public @Nullable PlaybackState getPlaybackState() {
         try {
             return mSessionBinder.getPlaybackState();
-        } catch (RuntimeException e) {
+        } catch (RemoteException e) {
             Log.wtf(TAG, "Error calling getPlaybackState.", e);
             return null;
         }
@@ -159,7 +161,7 @@
     public @Nullable MediaMetadata getMetadata() {
         try {
             return mSessionBinder.getMetadata();
-        } catch (RuntimeException e) {
+        } catch (RemoteException e) {
             Log.wtf(TAG, "Error calling getMetadata.", e);
             return null;
         }
@@ -173,8 +175,9 @@
      */
     public @Nullable List<MediaSession.QueueItem> getQueue() {
         try {
-            return mSessionBinder.getQueue();
-        } catch (RuntimeException e) {
+            MediaParceledListSlice list = mSessionBinder.getQueue();
+            return list == null ? null : list.getList();
+        } catch (RemoteException e) {
             Log.wtf(TAG, "Error calling getQueue.", e);
         }
         return null;
@@ -186,7 +189,7 @@
     public @Nullable CharSequence getQueueTitle() {
         try {
             return mSessionBinder.getQueueTitle();
-        } catch (RuntimeException e) {
+        } catch (RemoteException e) {
             Log.wtf(TAG, "Error calling getQueueTitle", e);
         }
         return null;
@@ -198,7 +201,7 @@
     public @Nullable Bundle getExtras() {
         try {
             return mSessionBinder.getExtras();
-        } catch (RuntimeException e) {
+        } catch (RemoteException e) {
             Log.wtf(TAG, "Error calling getExtras", e);
         }
         return null;
@@ -221,7 +224,7 @@
     public int getRatingType() {
         try {
             return mSessionBinder.getRatingType();
-        } catch (RuntimeException e) {
+        } catch (RemoteException e) {
             Log.wtf(TAG, "Error calling getRatingType.", e);
             return Rating.RATING_NONE;
         }
@@ -235,7 +238,7 @@
     public long getFlags() {
         try {
             return mSessionBinder.getFlags();
-        } catch (RuntimeException e) {
+        } catch (RemoteException e) {
             Log.wtf(TAG, "Error calling getFlags.", e);
         }
         return 0;
@@ -249,7 +252,7 @@
     public @Nullable PlaybackInfo getPlaybackInfo() {
         try {
             return mSessionBinder.getVolumeAttributes();
-        } catch (RuntimeException e) {
+        } catch (RemoteException e) {
             Log.wtf(TAG, "Error calling getAudioInfo.", e);
         }
         return null;
@@ -264,7 +267,7 @@
     public @Nullable PendingIntent getSessionActivity() {
         try {
             return mSessionBinder.getLaunchPendingIntent();
-        } catch (RuntimeException e) {
+        } catch (RemoteException e) {
             Log.wtf(TAG, "Error calling getPendingIntent.", e);
         }
         return null;
@@ -297,7 +300,7 @@
             //       AppOpsManager usages.
             mSessionBinder.setVolumeTo(mContext.getPackageName(), mContext.getOpPackageName(),
                     mCbStub, value, flags);
-        } catch (RuntimeException e) {
+        } catch (RemoteException e) {
             Log.wtf(TAG, "Error calling setVolumeTo.", e);
         }
     }
@@ -322,7 +325,7 @@
             //       AppOpsManager usages.
             mSessionBinder.adjustVolume(mContext.getPackageName(), mContext.getOpPackageName(),
                     mCbStub, direction, flags);
-        } catch (RuntimeException e) {
+        } catch (RemoteException e) {
             Log.wtf(TAG, "Error calling adjustVolumeBy.", e);
         }
     }
@@ -388,7 +391,7 @@
         }
         try {
             mSessionBinder.sendCommand(mContext.getPackageName(), mCbStub, command, args, cb);
-        } catch (RuntimeException e) {
+        } catch (RemoteException e) {
             Log.d(TAG, "Dead object in sendCommand.", e);
         }
     }
@@ -402,7 +405,7 @@
         if (mPackageName == null) {
             try {
                 mPackageName = mSessionBinder.getPackageName();
-            } catch (RuntimeException e) {
+            } catch (RemoteException e) {
                 Log.d(TAG, "Dead object in getPackageName.", e);
             }
         }
@@ -419,7 +422,7 @@
         if (mSessionInfo == null) {
             try {
                 mSessionInfo = mSessionBinder.getSessionInfo();
-            } catch (RuntimeException e) {
+            } catch (RemoteException e) {
                 Log.d(TAG, "Dead object in getSessionInfo.", e);
             }
         }
@@ -436,7 +439,7 @@
         if (mTag == null) {
             try {
                 mTag = mSessionBinder.getTag();
-            } catch (RuntimeException e) {
+            } catch (RemoteException e) {
                 Log.d(TAG, "Dead object in getTag.", e);
             }
         }
@@ -446,7 +449,7 @@
     /*
      * @hide
      */
-    ControllerLink getSessionBinder() {
+    ISessionController getSessionBinder() {
         return mSessionBinder;
     }
 
@@ -456,7 +459,7 @@
     @UnsupportedAppUsage
     public boolean controlsSameSession(MediaController other) {
         if (other == null) return false;
-        return mSessionBinder.getBinder() == other.getSessionBinder().getBinder();
+        return mSessionBinder.asBinder() == other.getSessionBinder().asBinder();
     }
 
     private void addCallbackLocked(Callback cb, Handler handler) {
@@ -472,7 +475,7 @@
             try {
                 mSessionBinder.registerCallback(mContext.getPackageName(), mCbStub);
                 mCbRegistered = true;
-            } catch (RuntimeException e) {
+            } catch (RemoteException e) {
                 Log.e(TAG, "Dead object in registerCallback", e);
             }
         }
@@ -491,7 +494,7 @@
         if (mCbRegistered && mCallbacks.size() == 0) {
             try {
                 mSessionBinder.unregisterCallback(mCbStub);
-            } catch (RuntimeException e) {
+            } catch (RemoteException e) {
                 Log.e(TAG, "Dead object in removeCallbackLocked");
             }
             mCbRegistered = false;
@@ -618,7 +621,7 @@
         public void prepare() {
             try {
                 mSessionBinder.prepare(mContext.getPackageName(), mCbStub);
-            } catch (RuntimeException e) {
+            } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling prepare.", e);
             }
         }
@@ -643,7 +646,7 @@
             try {
                 mSessionBinder.prepareFromMediaId(mContext.getPackageName(), mCbStub, mediaId,
                         extras);
-            } catch (RuntimeException e) {
+            } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling prepare(" + mediaId + ").", e);
             }
         }
@@ -670,7 +673,7 @@
             try {
                 mSessionBinder.prepareFromSearch(mContext.getPackageName(), mCbStub, query,
                         extras);
-            } catch (RuntimeException e) {
+            } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling prepare(" + query + ").", e);
             }
         }
@@ -694,7 +697,7 @@
             }
             try {
                 mSessionBinder.prepareFromUri(mContext.getPackageName(), mCbStub, uri, extras);
-            } catch (RuntimeException e) {
+            } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling prepare(" + uri + ").", e);
             }
         }
@@ -705,7 +708,7 @@
         public void play() {
             try {
                 mSessionBinder.play(mContext.getPackageName(), mCbStub);
-            } catch (RuntimeException e) {
+            } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling play.", e);
             }
         }
@@ -725,7 +728,7 @@
             try {
                 mSessionBinder.playFromMediaId(mContext.getPackageName(), mCbStub, mediaId,
                         extras);
-            } catch (RuntimeException e) {
+            } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling play(" + mediaId + ").", e);
             }
         }
@@ -747,7 +750,7 @@
             }
             try {
                 mSessionBinder.playFromSearch(mContext.getPackageName(), mCbStub, query, extras);
-            } catch (RuntimeException e) {
+            } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling play(" + query + ").", e);
             }
         }
@@ -766,7 +769,7 @@
             }
             try {
                 mSessionBinder.playFromUri(mContext.getPackageName(), mCbStub, uri, extras);
-            } catch (RuntimeException e) {
+            } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling play(" + uri + ").", e);
             }
         }
@@ -778,7 +781,7 @@
         public void skipToQueueItem(long id) {
             try {
                 mSessionBinder.skipToQueueItem(mContext.getPackageName(), mCbStub, id);
-            } catch (RuntimeException e) {
+            } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling skipToItem(" + id + ").", e);
             }
         }
@@ -790,7 +793,7 @@
         public void pause() {
             try {
                 mSessionBinder.pause(mContext.getPackageName(), mCbStub);
-            } catch (RuntimeException e) {
+            } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling pause.", e);
             }
         }
@@ -802,7 +805,7 @@
         public void stop() {
             try {
                 mSessionBinder.stop(mContext.getPackageName(), mCbStub);
-            } catch (RuntimeException e) {
+            } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling stop.", e);
             }
         }
@@ -815,7 +818,7 @@
         public void seekTo(long pos) {
             try {
                 mSessionBinder.seekTo(mContext.getPackageName(), mCbStub, pos);
-            } catch (RuntimeException e) {
+            } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling seekTo.", e);
             }
         }
@@ -827,7 +830,7 @@
         public void fastForward() {
             try {
                 mSessionBinder.fastForward(mContext.getPackageName(), mCbStub);
-            } catch (RuntimeException e) {
+            } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling fastForward.", e);
             }
         }
@@ -838,7 +841,7 @@
         public void skipToNext() {
             try {
                 mSessionBinder.next(mContext.getPackageName(), mCbStub);
-            } catch (RuntimeException e) {
+            } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling next.", e);
             }
         }
@@ -850,7 +853,7 @@
         public void rewind() {
             try {
                 mSessionBinder.rewind(mContext.getPackageName(), mCbStub);
-            } catch (RuntimeException e) {
+            } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling rewind.", e);
             }
         }
@@ -861,7 +864,7 @@
         public void skipToPrevious() {
             try {
                 mSessionBinder.previous(mContext.getPackageName(), mCbStub);
-            } catch (RuntimeException e) {
+            } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling previous.", e);
             }
         }
@@ -876,7 +879,7 @@
         public void setRating(Rating rating) {
             try {
                 mSessionBinder.rate(mContext.getPackageName(), mCbStub, rating);
-            } catch (RuntimeException e) {
+            } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling rate.", e);
             }
         }
@@ -889,7 +892,7 @@
         public void setPlaybackSpeed(float speed) {
             try {
                 mSessionBinder.setPlaybackSpeed(mContext.getPackageName(), mCbStub, speed);
-            } catch (RuntimeException e) {
+            } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling setPlaybackSpeed.", e);
             }
         }
@@ -924,7 +927,7 @@
             }
             try {
                 mSessionBinder.sendCustomAction(mContext.getPackageName(), mCbStub, action, args);
-            } catch (RuntimeException e) {
+            } catch (RemoteException e) {
                 Log.d(TAG, "Dead object in sendCustomAction.", e);
             }
         }
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index c4f8b79..cbc6c9d 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -36,6 +36,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.Process;
+import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.service.media.MediaBrowserService;
 import android.text.TextUtils;
@@ -163,11 +164,11 @@
                 .getSystemService(Context.MEDIA_SESSION_SERVICE);
         try {
             SessionCallbackLink cbLink = new SessionCallbackLink(context);
-            SessionLink sessionLink = manager.createSession(cbLink, tag, sessionInfo);
-            mImpl = new MediaSessionEngine(context, sessionLink, cbLink);
+            ISession binder = manager.createSession(cbLink, tag, sessionInfo);
+            mImpl = new MediaSessionEngine(context, binder, cbLink);
             mMaxBitmapSize = context.getResources().getDimensionPixelSize(
                     com.android.internal.R.dimen.config_mediaMetadataBitmapMaxSize);
-        } catch (RuntimeException e) {
+        } catch (RemoteException e) {
             throw new RuntimeException("Remote error creating session.", e);
         }
     }
@@ -445,19 +446,19 @@
     public static final class Token implements Parcelable {
 
         private final int mUid;
-        private final ControllerLink mControllerLink;
+        private final ISessionController mBinder;
 
         /**
          * @hide
          */
-        public Token(ControllerLink controllerLink) {
+        public Token(ISessionController binder) {
             mUid = Process.myUid();
-            mControllerLink = controllerLink;
+            mBinder = binder;
         }
 
         Token(Parcel in) {
             mUid = in.readInt();
-            mControllerLink = in.readParcelable(null);
+            mBinder = ISessionController.Stub.asInterface(in.readStrongBinder());
         }
 
         @Override
@@ -468,15 +469,14 @@
         @Override
         public void writeToParcel(Parcel dest, int flags) {
             dest.writeInt(mUid);
-            dest.writeParcelable(mControllerLink, flags);
+            dest.writeStrongBinder(mBinder.asBinder());
         }
 
         @Override
         public int hashCode() {
             final int prime = 31;
             int result = mUid;
-            result = prime * result + ((mControllerLink == null)
-                    ? 0 : mControllerLink.getBinder().hashCode());
+            result = prime * result + (mBinder == null ? 0 : mBinder.asBinder().hashCode());
             return result;
         }
 
@@ -492,7 +492,10 @@
             if (mUid != other.mUid) {
                 return false;
             }
-            return Objects.equals(mControllerLink, other.mControllerLink);
+            if (mBinder == null || other.mBinder == null) {
+                return mBinder == other.mBinder;
+            }
+            return Objects.equals(mBinder.asBinder(), other.mBinder.asBinder());
         }
 
         /**
@@ -504,11 +507,11 @@
         }
 
         /**
-         * Gets the controller link in this token.
+         * Gets the controller binder in this token.
          * @hide
          */
-        public ControllerLink getControllerLink() {
-            return mControllerLink;
+        public ISessionController getBinder() {
+            return mBinder;
         }
 
         public static final @android.annotation.NonNull Parcelable.Creator<Token> CREATOR =
diff --git a/media/java/android/media/session/MediaSessionEngine.java b/media/java/android/media/session/MediaSessionEngine.java
index 266bf32..7c5243a 100644
--- a/media/java/android/media/session/MediaSessionEngine.java
+++ b/media/java/android/media/session/MediaSessionEngine.java
@@ -25,6 +25,7 @@
 import android.media.AudioAttributes;
 import android.media.MediaDescription;
 import android.media.MediaMetadata;
+import android.media.MediaParceledListSlice;
 import android.media.Rating;
 import android.media.VolumeProvider;
 import android.media.session.MediaSessionManager.RemoteUserInfo;
@@ -34,6 +35,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.Parcel;
+import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.service.media.MediaBrowserService;
 import android.text.TextUtils;
@@ -55,7 +57,7 @@
 
     private final MediaSession.Token mSessionToken;
     private final MediaController mController;
-    private final SessionLink mSessionLink;
+    private final ISession mBinder;
 
     private CallbackMessageHandler mCallbackHandler;
     private VolumeProvider mVolumeProvider;
@@ -70,14 +72,14 @@
      * finished with the session.
      *
      * @param context The context to use to create the session.
-     * @param sessionLink A session link for the binder of MediaSessionRecord
+     * @param binder A session binder
      */
-    public MediaSessionEngine(@NonNull Context context, @NonNull SessionLink sessionLink,
-            @NonNull SessionCallbackLink cbLink) {
-        mSessionLink = sessionLink;
+    public MediaSessionEngine(@NonNull Context context, @NonNull ISession binder,
+            @NonNull SessionCallbackLink cbLink) throws RemoteException {
+        mBinder = binder;
 
         cbLink.setSessionEngine(this);
-        mSessionToken = new MediaSession.Token(mSessionLink.getController());
+        mSessionToken = new MediaSession.Token(mBinder.getController());
         mController = new MediaController(context, mSessionToken);
     }
 
@@ -134,8 +136,8 @@
      */
     public void setSessionActivity(@Nullable PendingIntent pi) {
         try {
-            mSessionLink.setLaunchPendingIntent(pi);
-        } catch (RuntimeException e) {
+            mBinder.setLaunchPendingIntent(pi);
+        } catch (RemoteException e) {
             Log.wtf(TAG, "Failure in setLaunchPendingIntent.", e);
         }
     }
@@ -150,8 +152,8 @@
      */
     public void setMediaButtonReceiver(@Nullable PendingIntent mbr) {
         try {
-            mSessionLink.setMediaButtonReceiver(mbr);
-        } catch (RuntimeException e) {
+            mBinder.setMediaButtonReceiver(mbr);
+        } catch (RemoteException e) {
             Log.wtf(TAG, "Failure in setMediaButtonReceiver.", e);
         }
     }
@@ -163,8 +165,8 @@
      */
     public void setFlags(int flags) {
         try {
-            mSessionLink.setFlags(flags);
-        } catch (RuntimeException e) {
+            mBinder.setFlags(flags);
+        } catch (RemoteException e) {
             Log.wtf(TAG, "Failure in setFlags.", e);
         }
     }
@@ -185,8 +187,8 @@
             throw new IllegalArgumentException("Attributes cannot be null for local playback.");
         }
         try {
-            mSessionLink.setPlaybackToLocal(attributes);
-        } catch (RuntimeException e) {
+            mBinder.setPlaybackToLocal(attributes);
+        } catch (RemoteException e) {
             Log.wtf(TAG, "Failure in setPlaybackToLocal.", e);
         }
     }
@@ -217,10 +219,10 @@
         });
 
         try {
-            mSessionLink.setPlaybackToRemote(volumeProvider.getVolumeControl(),
+            mBinder.setPlaybackToRemote(volumeProvider.getVolumeControl(),
                     volumeProvider.getMaxVolume());
-            mSessionLink.setCurrentVolume(volumeProvider.getCurrentVolume());
-        } catch (RuntimeException e) {
+            mBinder.setCurrentVolume(volumeProvider.getCurrentVolume());
+        } catch (RemoteException e) {
             Log.wtf(TAG, "Failure in setPlaybackToRemote.", e);
         }
     }
@@ -238,9 +240,9 @@
             return;
         }
         try {
-            mSessionLink.setActive(active);
+            mBinder.setActive(active);
             mActive = active;
-        } catch (RuntimeException e) {
+        } catch (RemoteException e) {
             Log.wtf(TAG, "Failure in setActive.", e);
         }
     }
@@ -267,8 +269,8 @@
             throw new IllegalArgumentException("event cannot be null or empty");
         }
         try {
-            mSessionLink.sendEvent(event, extras);
-        } catch (RuntimeException e) {
+            mBinder.sendEvent(event, extras);
+        } catch (RemoteException e) {
             Log.wtf(TAG, "Error sending event", e);
         }
     }
@@ -280,8 +282,8 @@
      */
     public void close() {
         try {
-            mSessionLink.destroySession();
-        } catch (RuntimeException e) {
+            mBinder.destroySession();
+        } catch (RemoteException e) {
             Log.wtf(TAG, "Error releasing session: ", e);
         }
     }
@@ -316,8 +318,8 @@
     public void setPlaybackState(@Nullable PlaybackState state) {
         mPlaybackState = state;
         try {
-            mSessionLink.setPlaybackState(state);
-        } catch (RuntimeException e) {
+            mBinder.setPlaybackState(state);
+        } catch (RemoteException e) {
             Log.wtf(TAG, "Dead object in setPlaybackState.", e);
         }
     }
@@ -344,8 +346,8 @@
         String metadataDescription = "size=" + fields + ", description=" + description;
 
         try {
-            mSessionLink.setMetadata(metadata, duration, metadataDescription);
-        } catch (RuntimeException e) {
+            mBinder.setMetadata(metadata, duration, metadataDescription);
+        } catch (RemoteException e) {
             Log.wtf(TAG, "Dead object in setPlaybackState.", e);
         }
     }
@@ -363,8 +365,8 @@
      */
     public void setQueue(@Nullable List<MediaSession.QueueItem> queue) {
         try {
-            mSessionLink.setQueue(queue);
-        } catch (RuntimeException e) {
+            mBinder.setQueue(queue == null ? null : new MediaParceledListSlice(queue));
+        } catch (RemoteException e) {
             Log.wtf("Dead object in setQueue.", e);
         }
     }
@@ -378,8 +380,8 @@
      */
     public void setQueueTitle(@Nullable CharSequence title) {
         try {
-            mSessionLink.setQueueTitle(title);
-        } catch (RuntimeException e) {
+            mBinder.setQueueTitle(title);
+        } catch (RemoteException e) {
             Log.wtf("Dead object in setQueueTitle.", e);
         }
     }
@@ -399,8 +401,8 @@
      */
     public void setRatingType(int type) {
         try {
-            mSessionLink.setRatingType(type);
-        } catch (RuntimeException e) {
+            mBinder.setRatingType(type);
+        } catch (RemoteException e) {
             Log.e(TAG, "Error in setRatingType.", e);
         }
     }
@@ -414,8 +416,8 @@
      */
     public void setExtras(@Nullable Bundle extras) {
         try {
-            mSessionLink.setExtras(extras);
-        } catch (RuntimeException e) {
+            mBinder.setExtras(extras);
+        } catch (RemoteException e) {
             Log.wtf("Dead object in setExtras.", e);
         }
     }
@@ -464,8 +466,8 @@
             }
         }
         try {
-            mSessionLink.setCurrentVolume(provider.getCurrentVolume());
-        } catch (RuntimeException e) {
+            mBinder.setCurrentVolume(provider.getCurrentVolume());
+        } catch (RemoteException e) {
             Log.e(TAG, "Error in notifyVolumeChanged", e);
         }
     }
diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java
index f530442..7ca5c93 100644
--- a/media/java/android/media/session/MediaSessionManager.java
+++ b/media/java/android/media/session/MediaSessionManager.java
@@ -107,7 +107,7 @@
      * @hide
      */
     @NonNull
-    public SessionLink createSession(@NonNull SessionCallbackLink cbStub, @NonNull String tag,
+    public ISession createSession(@NonNull SessionCallbackLink cbStub, @NonNull String tag,
             @Nullable Bundle sessionInfo) {
         try {
             return mService.createSession(mContext.getPackageName(), cbStub, tag, sessionInfo,
diff --git a/media/java/android/media/session/SessionLink.aidl b/media/java/android/media/session/SessionLink.aidl
deleted file mode 100644
index c3be23e..0000000
--- a/media/java/android/media/session/SessionLink.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * 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.
- */
-
-package android.media.session;
-
-parcelable SessionLink;
diff --git a/media/java/android/media/session/SessionLink.java b/media/java/android/media/session/SessionLink.java
deleted file mode 100644
index 2b42a2d6..0000000
--- a/media/java/android/media/session/SessionLink.java
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * 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.
- */
-
-package android.media.session;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.PendingIntent;
-import android.media.AudioAttributes;
-import android.media.MediaMetadata;
-import android.media.MediaParceledListSlice;
-import android.media.session.MediaSession.QueueItem;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.RemoteException;
-
-import java.util.List;
-
-/**
- * Handles incoming commands from {@link MediaSession}.
- * @hide
- */
-public final class SessionLink implements Parcelable {
-    public static final @android.annotation.NonNull Parcelable.Creator<SessionLink> CREATOR =
-            new Parcelable.Creator<SessionLink>() {
-                @Override
-                public SessionLink createFromParcel(Parcel in) {
-                    return new SessionLink(in.readStrongBinder());
-                }
-
-                @Override
-                public SessionLink[] newArray(int size) {
-                    return new SessionLink[size];
-                }
-            };
-
-    final SessionStub mSessionStub;
-    final ISession mISession;
-
-    /**
-     * Constructor for stub (Callee)
-     */
-    public SessionLink(@NonNull SessionStub sessionStub) {
-        mSessionStub = sessionStub;
-        mISession = new StubProxy();
-    }
-
-    /**
-     * Constructor for interface (Caller)
-     */
-    public SessionLink(IBinder binder) {
-        mSessionStub = null;
-        mISession = ISession.Stub.asInterface(binder);
-    }
-
-    /**
-     * Tell system that the session sends an event to all the connected controllers.
-     *
-     * @param event the name of the event
-     * @param extras the extras included with the event
-     */
-    void sendEvent(@NonNull String event, @Nullable Bundle extras) {
-        try {
-            mISession.sendEvent(event, extras);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Gets the controller link from the system.
-     */
-    @NonNull
-    ControllerLink getController() {
-        try {
-            return mISession.getController();
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that the session sets the flags.
-     *
-     * @param flags the new session flags
-     */
-    void setFlags(int flags) {
-        try {
-            mISession.setFlags(flags);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that the session is (in)active.
-     *
-     * @param active the new activeness state
-     */
-    void setActive(boolean active) {
-        try {
-            mISession.setActive(active);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that the session sets the media button receiver.
-     *
-     * @param mbr the pending intent for media button receiver
-     */
-    void setMediaButtonReceiver(@Nullable PendingIntent mbr) {
-        try {
-            mISession.setMediaButtonReceiver(mbr);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that the session sets the pending intent for launching UI.
-     *
-     * @param pi the pending intent for launching UI
-     */
-    void setLaunchPendingIntent(@Nullable PendingIntent pi) {
-        try {
-            mISession.setLaunchPendingIntent(pi);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that the session is destroyed.
-     */
-    void destroySession() {
-        try {
-            mISession.destroySession();
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that the session sets the new metadata.
-     *
-     * @param metadata the new metadata
-     * @param duration the duration of the media in milliseconds
-     * @param metadataDescription the description of the metadata
-     */
-    void setMetadata(@Nullable MediaMetadata metadata, long duration,
-            @Nullable String metadataDescription) {
-        try {
-            mISession.setMetadata(metadata, duration, metadataDescription);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that the session sets the new playback state.
-     *
-     * @param state the new playback state
-     */
-    void setPlaybackState(@Nullable PlaybackState state) {
-        try {
-            mISession.setPlaybackState(state);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that the session sets the new queue.
-     *
-     * @param queue the new queue
-     */
-    void setQueue(@Nullable List<QueueItem> queue) {
-        try {
-            mISession.setQueue(queue == null ? null : new MediaParceledListSlice(queue));
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that the session sets the new queue title.
-     *
-     * @param title the new queue title
-     */
-    void setQueueTitle(@Nullable CharSequence title) {
-        try {
-            mISession.setQueueTitle(title);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that the session sets the new extras.
-     *
-     * @param extras the new extras
-     */
-    void setExtras(@Nullable Bundle extras) {
-        try {
-            mISession.setExtras(extras);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that the session sets the new rating type of the current media.
-     *
-     * @param type the rating type.
-     */
-    void setRatingType(int type) {
-        try {
-            mISession.setRatingType(type);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that the session represents a local playback.
-     *
-     * @param attributes the audio attributes of the local playback.
-     */
-    void setPlaybackToLocal(@NonNull AudioAttributes attributes) {
-        try {
-            mISession.setPlaybackToLocal(attributes);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that the session represents a remote playback.
-     *
-     * @param control the volume control type
-     * @param max the max volume
-     */
-    void setPlaybackToRemote(int control, int max) {
-        try {
-            mISession.setPlaybackToRemote(control, max);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Tell system that the session sets the new current volume.
-     *
-     * @param currentVolume the new current volume
-     */
-    void setCurrentVolume(int currentVolume) {
-        try {
-            mISession.setCurrentVolume(currentVolume);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /** Gets the binder */
-    @NonNull
-    public IBinder getBinder() {
-        return mISession.asBinder();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeStrongBinder(mISession.asBinder());
-    }
-
-    /**
-     * Class for Stub implementation
-     */
-    public abstract static class SessionStub {
-        /** Stub method for ISession.sendEvent */
-        public void sendEvent(@NonNull String event, @Nullable Bundle data) {
-        }
-
-        /** Stub method for ISession.getController */
-        @NonNull
-        public ControllerLink getController() {
-            return null;
-        }
-
-        /** Stub method for ISession.setFlags */
-        public void setFlags(int flags) {
-        }
-
-        /** Stub method for ISession.setActive */
-        public void setActive(boolean active) {
-        }
-
-        /** Stub method for ISession.setMediaButtonReceiver */
-        public void setMediaButtonReceiver(@Nullable PendingIntent mbr) {
-        }
-
-        /** Stub method for ISession.setLaunchPendingIntent */
-        public void setLaunchPendingIntent(@Nullable PendingIntent pi) {
-        }
-
-        /** Stub method for ISession.destroySession */
-        public void destroySession() {
-        }
-
-        /** Stub method for ISession.setMetadata */
-        public void setMetadata(@Nullable MediaMetadata metadata, long duration,
-                @Nullable String metadataDescription) {
-        }
-
-        /** Stub method for ISession.setPlaybackState */
-        public void setPlaybackState(@Nullable PlaybackState state) {
-        }
-
-        /** Stub method for ISession.setQueue */
-        public void setQueue(@Nullable List<QueueItem> queue) {
-        }
-
-        /** Stub method for ISession.setQueueTitle */
-        public void setQueueTitle(@Nullable CharSequence title) {
-        }
-
-        /** Stub method for ISession.setExtras */
-        public void setExtras(@Nullable Bundle extras) {
-        }
-
-        /** Stub method for ISession.setRatingType */
-        public void setRatingType(int type) {
-        }
-
-        /** Stub method for ISession.setPlaybackToLocal */
-        public void setPlaybackToLocal(@NonNull AudioAttributes attributes) {
-        }
-
-        /** Stub method for ISession.setPlaybackToRemote */
-        public void setPlaybackToRemote(int control, int max) {
-        }
-
-        /** Stub method for ISession.setCurrentVolume */
-        public void setCurrentVolume(int currentVolume) {
-        }
-    }
-
-    private class StubProxy extends ISession.Stub {
-        @Override
-        public void sendEvent(String event, Bundle data) {
-            mSessionStub.sendEvent(event, data);
-        }
-
-        @Override
-        public ControllerLink getController() {
-            return mSessionStub.getController();
-        }
-
-        @Override
-        public void setFlags(int flags) {
-            mSessionStub.setFlags(flags);
-        }
-
-        @Override
-        public void setActive(boolean active) {
-            mSessionStub.setActive(active);
-        }
-
-        @Override
-        public void setMediaButtonReceiver(PendingIntent mbr) {
-            mSessionStub.setMediaButtonReceiver(mbr);
-        }
-
-        @Override
-        public void setLaunchPendingIntent(PendingIntent pi) {
-            mSessionStub.setLaunchPendingIntent(pi);
-        }
-
-        @Override
-        public void destroySession() {
-            mSessionStub.destroySession();
-        }
-
-        @Override
-        public void setMetadata(MediaMetadata metadata, long duration, String metadataDescription) {
-            mSessionStub.setMetadata(metadata, duration, metadataDescription);
-        }
-
-        @Override
-        public void setPlaybackState(PlaybackState state) {
-            mSessionStub.setPlaybackState(state);
-        }
-
-        @Override
-        public void setQueue(MediaParceledListSlice queue) {
-            mSessionStub.setQueue(queue == null ? null : queue.getList());
-        }
-
-        @Override
-        public void setQueueTitle(CharSequence title) {
-            mSessionStub.setQueueTitle(title);
-        }
-
-        @Override
-        public void setExtras(Bundle extras) {
-            mSessionStub.setExtras(extras);
-        }
-
-        @Override
-        public void setRatingType(int type) {
-            mSessionStub.setRatingType(type);
-        }
-
-        @Override
-        public void setPlaybackToLocal(AudioAttributes attributes) {
-            mSessionStub.setPlaybackToLocal(attributes);
-        }
-
-        @Override
-        public void setPlaybackToRemote(int control, int max) {
-            mSessionStub.setPlaybackToRemote(control, max);
-        }
-
-        @Override
-        public void setCurrentVolume(int currentVolume) {
-            mSessionStub.setCurrentVolume(currentVolume);
-        }
-    }
-}
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index 474b671..dc2d177 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -54,6 +54,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
+import java.util.Objects;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.stream.IntStream;
 
@@ -248,7 +249,7 @@
     public MtpDatabase(Context context, String volumeName,
             String[] subDirectories) {
         native_setup();
-        mContext = context;
+        mContext = Objects.requireNonNull(context);
         mMediaProvider = context.getContentResolver()
                 .acquireContentProviderClient(MediaStore.AUTHORITY);
         mVolumeName = volumeName;
@@ -294,6 +295,10 @@
         }
     }
 
+    public Context getContext() {
+        return mContext;
+    }
+
     @Override
     public void close() {
         mManager.close();
diff --git a/media/java/android/mtp/MtpServer.java b/media/java/android/mtp/MtpServer.java
index a555d37..f0ab9a3 100644
--- a/media/java/android/mtp/MtpServer.java
+++ b/media/java/android/mtp/MtpServer.java
@@ -18,7 +18,12 @@
 
 import com.android.internal.util.Preconditions;
 
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.util.ByteStringUtils;
+
 import java.io.FileDescriptor;
+import java.util.Random;
 
 /**
  * Java wrapper for MTP/PTP support as USB responder.
@@ -29,6 +34,12 @@
     private long mNativeContext; // accessed by native methods
     private final MtpDatabase mDatabase;
     private final Runnable mOnTerminate;
+    private final Context mContext;
+
+// It requires "exactly 32 characters, including any leading 0s" in MTP spec
+// (5.1.1.14 Serial Number)
+    private static final int sID_LEN_BYTES = 16;
+    private static final int sID_LEN_STR = (sID_LEN_BYTES * 2);
 
     static {
         System.loadLibrary("media_jni");
@@ -41,10 +52,41 @@
             Runnable onTerminate,
             String deviceInfoManufacturer,
             String deviceInfoModel,
-            String deviceInfoDeviceVersion,
-            String deviceInfoSerialNumber) {
+            String deviceInfoDeviceVersion) {
         mDatabase = Preconditions.checkNotNull(database);
         mOnTerminate = Preconditions.checkNotNull(onTerminate);
+        mContext = mDatabase.getContext();
+
+        final String strID_PREFS_NAME = "mtp-cfg";
+        final String strID_PREFS_KEY = "mtp-id";
+        String strRandomId = null;
+        String deviceInfoSerialNumber;
+
+        SharedPreferences sharedPref =
+                mContext.getSharedPreferences(strID_PREFS_NAME, Context.MODE_PRIVATE);
+        if (sharedPref.contains(strID_PREFS_KEY)) {
+            strRandomId = sharedPref.getString(strID_PREFS_KEY, null);
+
+            // Check for format consistence (regenerate upon corruption)
+            if (strRandomId.length() != sID_LEN_STR) {
+                strRandomId = null;
+            } else {
+                // Only accept hex digit
+                for (int ii = 0; ii < strRandomId.length(); ii++)
+                    if (Character.digit(strRandomId.charAt(ii), 16) == -1) {
+                        strRandomId = null;
+                        break;
+                    }
+            }
+        }
+
+        if (strRandomId == null) {
+            strRandomId = getRandId();
+            sharedPref.edit().putString(strID_PREFS_KEY, strRandomId).apply();
+        }
+
+        deviceInfoSerialNumber = strRandomId;
+
         native_setup(
                 database,
                 controlFd,
@@ -56,6 +98,14 @@
         database.setServer(this);
     }
 
+    private String getRandId() {
+        Random randomVal = new Random();
+        byte[] randomBytes = new byte[sID_LEN_BYTES];
+
+        randomVal.nextBytes(randomBytes);
+        return ByteStringUtils.toHexString(randomBytes);
+    }
+
     public void start() {
         Thread thread = new Thread(this, "MtpServer");
         thread.start();
diff --git a/media/jni/android_media_MediaHTTPConnection.cpp b/media/jni/android_media_MediaHTTPConnection.cpp
index 365e045..d28c15c 100644
--- a/media/jni/android_media_MediaHTTPConnection.cpp
+++ b/media/jni/android_media_MediaHTTPConnection.cpp
@@ -109,7 +109,8 @@
     gFields.context = env->GetFieldID(clazz.get(), "mNativeContext", "J");
     CHECK(gFields.context != NULL);
 
-    gFields.readAtMethodID = env->GetMethodID(clazz.get(), "readAt", "(J[BI)I");
+    gFields.readAtMethodID = env->GetMethodID(
+            clazz.get(), "readAt", "(J[BILandroid/media/MediaHTTPConnection$ConnectionState;)I");
 }
 
 static void android_media_MediaHTTPConnection_native_setup(
@@ -132,7 +133,7 @@
 }
 
 static jint android_media_MediaHTTPConnection_native_readAt(
-        JNIEnv *env, jobject thiz, jlong offset, jint size) {
+        JNIEnv *env, jobject thiz, jlong offset, jint size, jobject connectionState) {
     sp<JMediaHTTPConnection> conn = getObject(env, thiz);
     if (size > JMediaHTTPConnection::kBufferSize) {
         size = JMediaHTTPConnection::kBufferSize;
@@ -141,7 +142,7 @@
     jbyteArray byteArrayObj = conn->getByteArrayObj();
 
     jint n = env->CallIntMethod(
-            thiz, gFields.readAtMethodID, offset, byteArrayObj, size);
+            thiz, gFields.readAtMethodID, offset, byteArrayObj, size, connectionState);
 
     if (n > 0) {
         env->GetByteArrayRegion(
@@ -158,7 +159,7 @@
     { "native_getIMemory", "()Landroid/os/IBinder;",
       (void *)android_media_MediaHTTPConnection_native_getIMemory },
 
-    { "native_readAt", "(JI)I",
+    { "native_readAt", "(JILandroid/media/MediaHTTPConnection$ConnectionState;)I",
       (void *)android_media_MediaHTTPConnection_native_readAt },
 
     { "native_init", "()V",
diff --git a/packages/NetworkStack/src/android/net/ip/IpClient.java b/packages/NetworkStack/src/android/net/ip/IpClient.java
index b1f6d24..7c7cdbd 100644
--- a/packages/NetworkStack/src/android/net/ip/IpClient.java
+++ b/packages/NetworkStack/src/android/net/ip/IpClient.java
@@ -18,8 +18,6 @@
 
 import static android.net.RouteInfo.RTN_UNICAST;
 import static android.net.shared.IpConfigurationParcelableUtil.toStableParcelable;
-import static android.net.shared.LinkPropertiesParcelableUtil.fromStableParcelable;
-import static android.net.shared.LinkPropertiesParcelableUtil.toStableParcelable;
 
 import static com.android.server.util.PermissionUtil.checkNetworkStackCallingPermission;
 
@@ -33,7 +31,6 @@
 import android.net.LinkProperties;
 import android.net.ProvisioningConfigurationParcelable;
 import android.net.ProxyInfo;
-import android.net.ProxyInfoParcelable;
 import android.net.RouteInfo;
 import android.net.TcpKeepalivePacketDataParcelable;
 import android.net.apf.ApfCapabilities;
@@ -201,7 +198,7 @@
         public void onProvisioningSuccess(LinkProperties newLp) {
             log("onProvisioningSuccess({" + newLp + "})");
             try {
-                mCallback.onProvisioningSuccess(toStableParcelable(newLp));
+                mCallback.onProvisioningSuccess(newLp);
             } catch (RemoteException e) {
                 log("Failed to call onProvisioningSuccess", e);
             }
@@ -210,7 +207,7 @@
         public void onProvisioningFailure(LinkProperties newLp) {
             log("onProvisioningFailure({" + newLp + "})");
             try {
-                mCallback.onProvisioningFailure(toStableParcelable(newLp));
+                mCallback.onProvisioningFailure(newLp);
             } catch (RemoteException e) {
                 log("Failed to call onProvisioningFailure", e);
             }
@@ -219,7 +216,7 @@
         public void onLinkPropertiesChange(LinkProperties newLp) {
             log("onLinkPropertiesChange({" + newLp + "})");
             try {
-                mCallback.onLinkPropertiesChange(toStableParcelable(newLp));
+                mCallback.onLinkPropertiesChange(newLp);
             } catch (RemoteException e) {
                 log("Failed to call onLinkPropertiesChange", e);
             }
@@ -525,9 +522,9 @@
             IpClient.this.setTcpBufferSizes(tcpBufferSizes);
         }
         @Override
-        public void setHttpProxy(ProxyInfoParcelable proxyInfo) {
+        public void setHttpProxy(ProxyInfo proxyInfo) {
             checkNetworkStackCallingPermission();
-            IpClient.this.setHttpProxy(fromStableParcelable(proxyInfo));
+            IpClient.this.setHttpProxy(proxyInfo);
         }
         @Override
         public void setMulticastFilter(boolean enabled) {
diff --git a/packages/NetworkStack/src/com/android/server/NetworkStackService.java b/packages/NetworkStack/src/com/android/server/NetworkStackService.java
index 72955bb..e7c8e85 100644
--- a/packages/NetworkStack/src/com/android/server/NetworkStackService.java
+++ b/packages/NetworkStack/src/com/android/server/NetworkStackService.java
@@ -19,7 +19,6 @@
 import static android.net.dhcp.IDhcpServer.STATUS_INVALID_ARGUMENT;
 import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
 import static android.net.dhcp.IDhcpServer.STATUS_UNKNOWN_ERROR;
-import static android.net.shared.NetworkParcelableUtil.fromStableParcelable;
 
 import static com.android.server.util.PermissionUtil.checkDumpPermission;
 import static com.android.server.util.PermissionUtil.checkNetworkStackCallingPermission;
@@ -35,7 +34,6 @@
 import android.net.INetworkMonitorCallbacks;
 import android.net.INetworkStackConnector;
 import android.net.Network;
-import android.net.NetworkParcelable;
 import android.net.PrivateDnsConfigParcel;
 import android.net.dhcp.DhcpServer;
 import android.net.dhcp.DhcpServingParams;
@@ -152,12 +150,10 @@
         }
 
         @Override
-        public void makeNetworkMonitor(
-                NetworkParcelable network, String name, INetworkMonitorCallbacks cb)
+        public void makeNetworkMonitor(Network network, String name, INetworkMonitorCallbacks cb)
                 throws RemoteException {
-            final Network parsedNetwork = fromStableParcelable(network);
-            final SharedLog log = addValidationLogs(parsedNetwork, name);
-            final NetworkMonitor nm = new NetworkMonitor(mContext, cb, parsedNetwork, log);
+            final SharedLog log = addValidationLogs(network, name);
+            final NetworkMonitor nm = new NetworkMonitor(mContext, cb, network, log);
             cb.onNetworkMonitorCreated(new NetworkMonitorImpl(nm));
         }
 
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
index bcfc412..9d91487 100644
--- a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
+++ b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
@@ -72,7 +72,7 @@
 import android.provider.Settings;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.CellSignalStrength;
-import android.telephony.NetworkRegistrationState;
+import android.telephony.NetworkRegistrationInfo;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.telephony.TelephonyManager;
@@ -1615,12 +1615,12 @@
                 return;
             }
             // See if the data sub is registered for PS services on cell.
-            final NetworkRegistrationState nrs = dataSs.getNetworkRegistrationState(
-                    NetworkRegistrationState.DOMAIN_PS,
+            final NetworkRegistrationInfo nri = dataSs.getNetworkRegistrationInfo(
+                    NetworkRegistrationInfo.DOMAIN_PS,
                     AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
             latencyBroadcast.putExtra(
                     NetworkMonitorUtils.EXTRA_CELL_ID,
-                    nrs == null ? null : nrs.getCellIdentity());
+                    nri == null ? null : nri.getCellIdentity());
             latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_CONNECTIVITY_TYPE, TYPE_MOBILE);
         } else {
             return;
diff --git a/packages/NetworkStack/tests/src/android/net/ip/IpClientTest.java b/packages/NetworkStack/tests/src/android/net/ip/IpClientTest.java
index bd488ea..4536c47 100644
--- a/packages/NetworkStack/tests/src/android/net/ip/IpClientTest.java
+++ b/packages/NetworkStack/tests/src/android/net/ip/IpClientTest.java
@@ -16,13 +16,10 @@
 
 package android.net.ip;
 
-import static android.net.shared.LinkPropertiesParcelableUtil.fromStableParcelable;
-
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.argThat;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.eq;
@@ -207,8 +204,7 @@
         verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceSetEnableIPv6(iface, false);
         verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceClearAddrs(iface);
         verify(mCb, timeout(TEST_TIMEOUT_MS).times(1))
-                .onLinkPropertiesChange(argThat(
-                        lp -> fromStableParcelable(lp).equals(makeEmptyLinkProperties(iface))));
+                .onLinkPropertiesChange(makeEmptyLinkProperties(iface));
     }
 
     @Test
@@ -253,15 +249,13 @@
         mObserver.onInterfaceAddressUpdated(new LinkAddress(addresses[lastAddr]), iface);
         LinkProperties want = linkproperties(links(addresses), routes(prefixes));
         want.setInterfaceName(iface);
-        verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).onProvisioningSuccess(argThat(
-                lp -> fromStableParcelable(lp).equals(want)));
+        verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).onProvisioningSuccess(want);
 
         ipc.shutdown();
         verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceSetEnableIPv6(iface, false);
         verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceClearAddrs(iface);
         verify(mCb, timeout(TEST_TIMEOUT_MS).times(1))
-                .onLinkPropertiesChange(argThat(
-                        lp -> fromStableParcelable(lp).equals(makeEmptyLinkProperties(iface))));
+                .onLinkPropertiesChange(makeEmptyLinkProperties(iface));
     }
 
     @Test
diff --git a/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java b/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java
index 3e3c039..83ef4f9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java
+++ b/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java
@@ -107,20 +107,22 @@
     }
 
     /**
-     * Returns relative time for the given millis in the past, in a short format such as "2 days
-     * ago", "5 hr. ago", "40 min. ago", or "29 sec. ago".
+     * Returns relative time for the given millis in the past with different format style.
+     * In a short format such as "2 days ago", "5 hr. ago", "40 min. ago", or "29 sec. ago".
+     * In a long format such as "2 days ago", "5 hours ago",  "40 minutes ago" or "29 seconds ago".
      *
      * <p>The unit is chosen to have good information value while only using one unit. So 27 hours
      * and 50 minutes would be formatted as "28 hr. ago", while 50 hours would be formatted as
      * "2 days ago".
      *
-     * @param context the application context
-     * @param millis the elapsed time in milli seconds
+     * @param context     the application context
+     * @param millis      the elapsed time in milli seconds
      * @param withSeconds include seconds?
+     * @param formatStyle format style
      * @return the formatted elapsed time
      */
     public static CharSequence formatRelativeTime(Context context, double millis,
-            boolean withSeconds) {
+            boolean withSeconds, RelativeDateTimeFormatter.Style formatStyle) {
         final int seconds = (int) Math.floor(millis / 1000);
         final RelativeUnit unit;
         final int value;
@@ -144,9 +146,31 @@
         final RelativeDateTimeFormatter formatter = RelativeDateTimeFormatter.getInstance(
                 ULocale.forLocale(locale),
                 null /* default NumberFormat */,
-                RelativeDateTimeFormatter.Style.LONG,
+                formatStyle,
                 android.icu.text.DisplayContext.CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE);
 
         return formatter.format(value, RelativeDateTimeFormatter.Direction.LAST, unit);
     }
+
+    /**
+     * Returns relative time for the given millis in the past, in a long format such as "2 days
+     * ago", "5 hours ago",  "40 minutes ago" or "29 seconds ago".
+     *
+     * <p>The unit is chosen to have good information value while only using one unit. So 27 hours
+     * and 50 minutes would be formatted as "28 hr. ago", while 50 hours would be formatted as
+     * "2 days ago".
+     *
+     * @param context     the application context
+     * @param millis      the elapsed time in milli seconds
+     * @param withSeconds include seconds?
+     * @return the formatted elapsed time
+     * @deprecated use {@link #formatRelativeTime(Context, double, boolean,
+     * RelativeDateTimeFormatter.Style)} instead.
+     */
+    @Deprecated
+    public static CharSequence formatRelativeTime(Context context, double millis,
+            boolean withSeconds) {
+        return formatRelativeTime(context, millis, withSeconds,
+                RelativeDateTimeFormatter.Style.LONG);
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/StringUtilTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/StringUtilTest.java
index 8fbbfbb..b503972 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/StringUtilTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/StringUtilTest.java
@@ -21,6 +21,7 @@
 import static org.mockito.Mockito.spy;
 
 import android.content.Context;
+import android.icu.text.RelativeDateTimeFormatter;
 import android.text.SpannableStringBuilder;
 import android.text.format.DateUtils;
 import android.text.style.TtsSpan;
@@ -116,8 +117,8 @@
         final double testMillis = 40 * DateUtils.SECOND_IN_MILLIS;
         final String expectedTime = "Just now";
 
-        assertThat(StringUtil.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo(
-                expectedTime);
+        assertThat(StringUtil.formatRelativeTime(mContext, testMillis, true,
+                RelativeDateTimeFormatter.Style.LONG).toString()).isEqualTo(expectedTime);
     }
 
     @Test
@@ -125,8 +126,8 @@
         final double testMillis = 40 * DateUtils.SECOND_IN_MILLIS;
         final String expectedTime = "1 minute ago";
 
-        assertThat(StringUtil.formatRelativeTime(mContext, testMillis, false).toString()).isEqualTo(
-                expectedTime);
+        assertThat(StringUtil.formatRelativeTime(mContext, testMillis, false,
+                RelativeDateTimeFormatter.Style.LONG).toString()).isEqualTo(expectedTime);
     }
 
     @Test
@@ -134,8 +135,8 @@
         final double testMillis = 119 * DateUtils.SECOND_IN_MILLIS;
         final String expectedTime = "Just now";
 
-        assertThat(StringUtil.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo(
-                expectedTime);
+        assertThat(StringUtil.formatRelativeTime(mContext, testMillis, true,
+                RelativeDateTimeFormatter.Style.LONG).toString()).isEqualTo(expectedTime);
     }
 
     @Test
@@ -143,8 +144,8 @@
         final double testMillis = 119 * DateUtils.SECOND_IN_MILLIS;
         final String expectedTime = "2 minutes ago";
 
-        assertThat(StringUtil.formatRelativeTime(mContext, testMillis, false).toString()).isEqualTo(
-                expectedTime);
+        assertThat(StringUtil.formatRelativeTime(mContext, testMillis, false,
+                RelativeDateTimeFormatter.Style.LONG).toString()).isEqualTo(expectedTime);
     }
 
     @Test
@@ -152,8 +153,8 @@
         final double testMillis = 2 * DateUtils.MINUTE_IN_MILLIS;
         final String expectedTime = "2 minutes ago";
 
-        assertThat(StringUtil.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo(
-                expectedTime);
+        assertThat(StringUtil.formatRelativeTime(mContext, testMillis, true,
+                RelativeDateTimeFormatter.Style.LONG).toString()).isEqualTo(expectedTime);
     }
 
     @Test
@@ -161,8 +162,8 @@
         final double testMillis = 119 * DateUtils.MINUTE_IN_MILLIS;
         final String expectedTime = "119 minutes ago";
 
-        assertThat(StringUtil.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo(
-                expectedTime);
+        assertThat(StringUtil.formatRelativeTime(mContext, testMillis, true,
+                RelativeDateTimeFormatter.Style.LONG).toString()).isEqualTo(expectedTime);
     }
 
     @Test
@@ -170,8 +171,8 @@
         final double testMillis = 2 * DateUtils.HOUR_IN_MILLIS;
         final String expectedTime = "2 hours ago";
 
-        assertThat(StringUtil.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo(
-                expectedTime);
+        assertThat(StringUtil.formatRelativeTime(mContext, testMillis, true,
+                RelativeDateTimeFormatter.Style.LONG).toString()).isEqualTo(expectedTime);
     }
 
     @Test
@@ -179,8 +180,8 @@
         final double testMillis = 47 * DateUtils.HOUR_IN_MILLIS;
         final String expectedTime = "47 hours ago";
 
-        assertThat(StringUtil.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo(
-                expectedTime);
+        assertThat(StringUtil.formatRelativeTime(mContext, testMillis, true,
+                RelativeDateTimeFormatter.Style.LONG).toString()).isEqualTo(expectedTime);
     }
 
     @Test
@@ -188,8 +189,8 @@
         final double testMillis = 2 * DateUtils.DAY_IN_MILLIS;
         final String expectedTime = "2 days ago";
 
-        assertThat(StringUtil.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo(
-                expectedTime);
+        assertThat(StringUtil.formatRelativeTime(mContext, testMillis, true,
+                RelativeDateTimeFormatter.Style.LONG).toString()).isEqualTo(expectedTime);
     }
 
     @Test
@@ -197,8 +198,8 @@
         final double testMillis = 0;
         final String expectedTime = "Just now";
 
-        assertThat(StringUtil.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo(
-                expectedTime);
+        assertThat(StringUtil.formatRelativeTime(mContext, testMillis, true,
+                RelativeDateTimeFormatter.Style.LONG).toString()).isEqualTo(expectedTime);
     }
 
     @Test
@@ -206,7 +207,7 @@
         final double testMillis = 0;
         final String expectedTime = "0 minutes ago";
 
-        assertThat(StringUtil.formatRelativeTime(mContext, testMillis, false).toString()).isEqualTo(
-                expectedTime);
+        assertThat(StringUtil.formatRelativeTime(mContext, testMillis, false,
+                RelativeDateTimeFormatter.Style.LONG).toString()).isEqualTo(expectedTime);
     }
 }
diff --git a/packages/SystemUI/res/layout/biometric_dialog.xml b/packages/SystemUI/res/layout/biometric_dialog.xml
index 1e8cd5a..83557f2 100644
--- a/packages/SystemUI/res/layout/biometric_dialog.xml
+++ b/packages/SystemUI/res/layout/biometric_dialog.xml
@@ -39,152 +39,158 @@
             android:layout_height="0dp"
             android:layout_weight="1" />
 
-        <LinearLayout
+        <ScrollView
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="horizontal">
-
-            <!-- This is not a Space since Spaces cannot be clicked. The width of this changes depending
-             on horizontal/portrait orientation -->
-            <View
-                android:id="@+id/left_space"
-                android:layout_weight="1"
-                android:layout_width="0dp"
-                android:layout_height="match_parent"/>
+            android:layout_height="wrap_content">
 
             <LinearLayout
-                android:id="@+id/dialog"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:orientation="vertical"
-                android:background="@drawable/biometric_dialog_bg"
-                android:layout_marginBottom="@dimen/biometric_dialog_border_padding"
-                android:layout_marginLeft="@dimen/biometric_dialog_border_padding"
-                android:layout_marginRight="@dimen/biometric_dialog_border_padding">
+                android:orientation="horizontal">
 
-                <TextView
-                    android:id="@+id/title"
-                    android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:layout_marginEnd="24dp"
-                    android:layout_marginStart="24dp"
-                    android:layout_marginTop="24dp"
-                    android:gravity="@integer/biometric_dialog_text_gravity"
-                    android:textSize="20sp"
-                    android:maxLines="1"
-                    android:singleLine="true"
-                    android:ellipsize="marquee"
-                    android:marqueeRepeatLimit="marquee_forever"
-                    android:textColor="?android:attr/textColorPrimary"/>
+                <!-- This is not a Space since Spaces cannot be clicked. The width of this changes
+                depending on horizontal/portrait orientation -->
+                <View
+                    android:id="@+id/left_space"
+                    android:layout_weight="1"
+                    android:layout_width="0dp"
+                    android:layout_height="match_parent"/>
 
-                <TextView
-                    android:id="@+id/subtitle"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:layout_marginTop="8dp"
-                    android:layout_marginStart="24dp"
-                    android:layout_marginEnd="24dp"
-                    android:gravity="@integer/biometric_dialog_text_gravity"
-                    android:textSize="16sp"
-                    android:maxLines="1"
-                    android:singleLine="true"
-                    android:ellipsize="marquee"
-                    android:marqueeRepeatLimit="marquee_forever"
-                    android:textColor="?android:attr/textColorPrimary"/>
+                    <LinearLayout
+                        android:id="@+id/dialog"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:orientation="vertical"
+                        android:background="@drawable/biometric_dialog_bg"
+                        android:layout_marginBottom="@dimen/biometric_dialog_border_padding"
+                        android:layout_marginLeft="@dimen/biometric_dialog_border_padding"
+                        android:layout_marginRight="@dimen/biometric_dialog_border_padding">
 
-                <TextView
-                    android:id="@+id/description"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:layout_marginEnd="24dp"
-                    android:layout_marginStart="24dp"
-                    android:gravity="@integer/biometric_dialog_text_gravity"
-                    android:paddingTop="8dp"
-                    android:textSize="16sp"
-                    android:maxLines="4"
-                    android:textColor="?android:attr/textColorPrimary"/>
+                        <TextView
+                            android:id="@+id/title"
+                            android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:layout_marginEnd="24dp"
+                            android:layout_marginStart="24dp"
+                            android:layout_marginTop="24dp"
+                            android:gravity="@integer/biometric_dialog_text_gravity"
+                            android:textSize="20sp"
+                            android:maxLines="1"
+                            android:singleLine="true"
+                            android:ellipsize="marquee"
+                            android:marqueeRepeatLimit="marquee_forever"
+                            android:textColor="?android:attr/textColorPrimary"/>
 
-                <ImageView
-                    android:id="@+id/biometric_icon"
-                    android:layout_width="@dimen/biometric_dialog_biometric_icon_size"
-                    android:layout_height="@dimen/biometric_dialog_biometric_icon_size"
-                    android:layout_gravity="center_horizontal"
-                    android:layout_marginTop="48dp"
-                    android:scaleType="fitXY" />
+                        <TextView
+                            android:id="@+id/subtitle"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:layout_marginTop="8dp"
+                            android:layout_marginStart="24dp"
+                            android:layout_marginEnd="24dp"
+                            android:gravity="@integer/biometric_dialog_text_gravity"
+                            android:textSize="16sp"
+                            android:maxLines="1"
+                            android:singleLine="true"
+                            android:ellipsize="marquee"
+                            android:marqueeRepeatLimit="marquee_forever"
+                            android:textColor="?android:attr/textColorPrimary"/>
 
-                <TextView
-                    android:id="@+id/error"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:layout_marginEnd="24dp"
-                    android:layout_marginStart="24dp"
-                    android:paddingTop="16dp"
-                    android:paddingBottom="24dp"
-                    android:textSize="12sp"
-                    android:gravity="center_horizontal"
-                    android:accessibilityLiveRegion="polite"
-                    android:contentDescription="@string/accessibility_biometric_dialog_help_area"
-                    android:textColor="?android:attr/textColorSecondary"/>
+                        <TextView
+                            android:id="@+id/description"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:layout_marginEnd="24dp"
+                            android:layout_marginStart="24dp"
+                            android:gravity="@integer/biometric_dialog_text_gravity"
+                            android:paddingTop="8dp"
+                            android:textSize="16sp"
+                            android:maxLines="4"
+                            android:textColor="?android:attr/textColorPrimary"/>
 
-                <LinearLayout
-                    android:layout_width="match_parent"
-                    android:layout_height="72dip"
-                    android:paddingTop="24dp"
-                    android:layout_gravity="center_vertical"
-                    style="?android:attr/buttonBarStyle"
-                    android:orientation="horizontal"
-                    android:measureWithLargestChild="true">
-                    <Space android:id="@+id/leftSpacer"
-                        android:layout_width="12dp"
-                        android:layout_height="match_parent"
-                        android:visibility="visible" />
-                    <!-- Negative Button -->
-                    <Button android:id="@+id/button2"
-                        android:layout_width="wrap_content"
-                        android:layout_height="match_parent"
-                        style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored"
-                        android:gravity="center"
-                        android:maxLines="2" />
-                    <Space android:id="@+id/middleSpacer"
-                        android:layout_width="0dp"
-                        android:layout_height="match_parent"
-                        android:layout_weight="1"
-                        android:visibility="visible" />
-                    <!-- Positive Button -->
-                    <Button android:id="@+id/button1"
-                        android:layout_width="wrap_content"
-                        android:layout_height="match_parent"
-                        style="@*android:style/Widget.DeviceDefault.Button.Colored"
-                        android:gravity="center"
-                        android:maxLines="2"
-                        android:text="@string/biometric_dialog_confirm"
-                        android:visibility="gone"/>
-                    <!-- Try Again Button -->
-                    <Button android:id="@+id/button_try_again"
-                        android:layout_width="wrap_content"
-                        android:layout_height="match_parent"
-                        style="@*android:style/Widget.DeviceDefault.Button.Colored"
-                        android:gravity="center"
-                        android:maxLines="2"
-                        android:text="@string/biometric_dialog_try_again"
-                        android:visibility="gone"/>
-                    <Space android:id="@+id/rightSpacer"
-                        android:layout_width="12dip"
-                        android:layout_height="match_parent"
-                        android:visibility="visible" />
-                </LinearLayout>
+                        <ImageView
+                            android:id="@+id/biometric_icon"
+                            android:layout_width="@dimen/biometric_dialog_biometric_icon_size"
+                            android:layout_height="@dimen/biometric_dialog_biometric_icon_size"
+                            android:layout_gravity="center_horizontal"
+                            android:layout_marginTop="48dp"
+                            android:scaleType="fitXY" />
+
+                        <TextView
+                            android:id="@+id/error"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:layout_marginEnd="24dp"
+                            android:layout_marginStart="24dp"
+                            android:paddingTop="16dp"
+                            android:paddingBottom="24dp"
+                            android:textSize="12sp"
+                            android:gravity="center_horizontal"
+                            android:accessibilityLiveRegion="polite"
+                            android:contentDescription="@string/accessibility_biometric_dialog_help_area"
+                            android:textColor="?android:attr/textColorSecondary"/>
+
+                        <LinearLayout
+                            android:layout_width="match_parent"
+                            android:layout_height="72dip"
+                            android:paddingTop="24dp"
+                            android:layout_gravity="center_vertical"
+                            style="?android:attr/buttonBarStyle"
+                            android:orientation="horizontal"
+                            android:measureWithLargestChild="true">
+                            <Space android:id="@+id/leftSpacer"
+                                android:layout_width="12dp"
+                                android:layout_height="match_parent"
+                                android:visibility="visible" />
+                            <!-- Negative Button -->
+                            <Button android:id="@+id/button2"
+                                android:layout_width="wrap_content"
+                                android:layout_height="match_parent"
+                                style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored"
+                                android:gravity="center"
+                                android:maxLines="2" />
+                            <Space android:id="@+id/middleSpacer"
+                                android:layout_width="0dp"
+                                android:layout_height="match_parent"
+                                android:layout_weight="1"
+                                android:visibility="visible" />
+                            <!-- Positive Button -->
+                            <Button android:id="@+id/button1"
+                                android:layout_width="wrap_content"
+                                android:layout_height="match_parent"
+                                style="@*android:style/Widget.DeviceDefault.Button.Colored"
+                                android:gravity="center"
+                                android:maxLines="2"
+                                android:text="@string/biometric_dialog_confirm"
+                                android:visibility="gone"/>
+                            <!-- Try Again Button -->
+                            <Button android:id="@+id/button_try_again"
+                                android:layout_width="wrap_content"
+                                android:layout_height="match_parent"
+                                style="@*android:style/Widget.DeviceDefault.Button.Colored"
+                                android:gravity="center"
+                                android:maxLines="2"
+                                android:text="@string/biometric_dialog_try_again"
+                                android:visibility="gone"/>
+                            <Space android:id="@+id/rightSpacer"
+                                android:layout_width="12dip"
+                                android:layout_height="match_parent"
+                                android:visibility="visible" />
+                        </LinearLayout>
+                    </LinearLayout>
+
+                <!-- This is not a Space since Spaces cannot be clicked. The width of this changes
+                depending on horizontal/portrait orientation -->
+                <View
+                    android:id="@+id/right_space"
+                    android:layout_weight="1"
+                    android:layout_width="0dp"
+                    android:layout_height="match_parent" />
+
             </LinearLayout>
 
-            <!-- This is not a Space since Spaces cannot be clicked. The width of this changes depending
-             on horizontal/portrait orientation -->
-            <View
-                android:id="@+id/right_space"
-                android:layout_weight="1"
-                android:layout_width="0dp"
-                android:layout_height="match_parent" />
-
-        </LinearLayout>
+        </ScrollView>
 
     </LinearLayout>
 
diff --git a/packages/SystemUI/res/layout/global_actions_grid.xml b/packages/SystemUI/res/layout/global_actions_grid.xml
index d90d5e9..8651e5a 100644
--- a/packages/SystemUI/res/layout/global_actions_grid.xml
+++ b/packages/SystemUI/res/layout/global_actions_grid.xml
@@ -31,7 +31,6 @@
             android:paddingTop="@dimen/global_actions_grid_vertical_padding"
             android:paddingBottom="@dimen/global_actions_grid_vertical_padding"
             android:orientation="vertical"
-            android:background="?android:attr/colorBackgroundFloating"
             android:gravity="center"
             android:translationZ="@dimen/global_actions_translate"
         />
@@ -48,7 +47,6 @@
             android:paddingRight="@dimen/global_actions_grid_horizontal_padding"
             android:paddingTop="@dimen/global_actions_grid_vertical_padding"
             android:paddingBottom="@dimen/global_actions_grid_vertical_padding"
-            android:background="?android:attr/colorBackgroundFloating"
         >
             <LinearLayout
                 android:layout_width="wrap_content"
diff --git a/packages/SystemUI/res/values-night/colors.xml b/packages/SystemUI/res/values-night/colors.xml
index 5803bf1..d74d258 100644
--- a/packages/SystemUI/res/values-night/colors.xml
+++ b/packages/SystemUI/res/values-night/colors.xml
@@ -47,4 +47,16 @@
 
     <!-- The color of the background in the bottom part of QSCustomizer -->
     <color name="qs_customize_decoration">@color/GM2_grey_800</color>
+
+    <!-- The color of the background in the separated list of the Global Actions menu -->
+    <color name="global_actions_separated_background">@color/GM2_grey_900</color>
+
+    <!-- The color of the background in the grid of the Global Actions menu -->
+    <color name="global_actions_grid_background">@color/GM2_grey_800</color>
+
+    <!-- The color of the text in the Global Actions menu -->
+    <color name="global_actions_text">@color/GM2_grey_200</color>
+
+    <!-- The color of the text in the Global Actions menu -->
+    <color name="global_actions_alert_text">@color/GM2_red_300</color>
 </resources>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 0e4ffee..b82c250 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -38,6 +38,18 @@
     <color name="qs_customize_background">@color/GM2_grey_50</color>
     <color name="qs_customize_decoration">@color/GM2_grey_100</color>
 
+    <!-- The color of the background in the separated list of the Global Actions menu -->
+    <color name="global_actions_separated_background">@color/GM2_grey_300</color>
+
+    <!-- The color of the background in the grid of the Global Actions menu -->
+    <color name="global_actions_grid_background">@color/GM2_grey_200</color>
+
+    <!-- The color of the text in the Global Actions menu -->
+    <color name="global_actions_text">@color/GM2_grey_900</color>
+
+    <!-- The color of the text in the Global Actions menu -->
+    <color name="global_actions_alert_text">@color/GM2_red_500</color>
+
     <!-- Tint color for the content on the notification overflow card. -->
     <color name="keyguard_overflow_content_color">#ff686868</color>
 
@@ -149,4 +161,7 @@
     <color name="GM2_grey_700">#5F6368</color>
     <color name="GM2_grey_800">#3C4043</color>
     <color name="GM2_grey_900">#202124</color>
+
+    <color name="GM2_red_300">#F28B82</color>
+    <color name="GM2_red_500">#B71C1C</color>
 </resources>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index d40fa66..ce65b5a 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -60,8 +60,8 @@
      */
     private ViewGroup mBigClockContainer;
     /**
-     * Status area (date and other stuff) shown below the clock. Plugin can decide whether
-     * or not to show it below the alternate clock.
+     * Status area (date and other stuff) shown below the clock. Plugin can decide whether or not to
+     * show it below the alternate clock.
      */
     private View mKeyguardStatusArea;
     /**
@@ -75,24 +75,19 @@
     private boolean mSupportsDarkText;
     private int[] mColorPalette;
 
+    /**
+     * Track the state of the status bar to know when to hide the big_clock_container.
+     */
+    private int mStatusBarState;
+
     private final StatusBarStateController.StateListener mStateListener =
             new StatusBarStateController.StateListener() {
                 @Override
                 public void onStateChanged(int newState) {
-                    if (mBigClockContainer == null) {
-                        return;
-                    }
-                    if (newState == StatusBarState.SHADE) {
-                        if (mBigClockContainer.getVisibility() == View.VISIBLE) {
-                            mBigClockContainer.setVisibility(View.INVISIBLE);
-                        }
-                    } else {
-                        if (mBigClockContainer.getVisibility() == View.INVISIBLE) {
-                            mBigClockContainer.setVisibility(View.VISIBLE);
-                        }
-                    }
+                    mStatusBarState = newState;
+                    updateBigClockVisibility();
                 }
-    };
+            };
 
     private ClockManager.ClockChangedListener mClockChangedListener = this::setClockPlugin;
 
@@ -139,7 +134,9 @@
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         Dependency.get(ClockManager.class).addOnClockChangedListener(mClockChangedListener);
-        Dependency.get(StatusBarStateController.class).addCallback(mStateListener);
+        StatusBarStateController stateController = Dependency.get(StatusBarStateController.class);
+        stateController.addCallback(mStateListener);
+        mStateListener.onStateChanged(stateController.getState());
         SysuiColorExtractor colorExtractor = Dependency.get(SysuiColorExtractor.class);
         colorExtractor.addOnColorsChangedListener(mColorsListener);
         updateColors(colorExtractor);
@@ -151,7 +148,7 @@
         Dependency.get(ClockManager.class).removeOnClockChangedListener(mClockChangedListener);
         Dependency.get(StatusBarStateController.class).removeCallback(mStateListener);
         Dependency.get(SysuiColorExtractor.class)
-            .removeOnColorsChangedListener(mColorsListener);
+                .removeOnColorsChangedListener(mColorsListener);
         setClockPlugin(null);
     }
 
@@ -164,7 +161,7 @@
             }
             if (mBigClockContainer != null) {
                 mBigClockContainer.removeAllViews();
-                mBigClockContainer.setVisibility(View.GONE);
+                updateBigClockVisibility();
             }
             mClockPlugin = null;
         }
@@ -184,7 +181,7 @@
         View bigClockView = plugin.getBigClockView();
         if (bigClockView != null && mBigClockContainer != null) {
             mBigClockContainer.addView(bigClockView);
-            mBigClockContainer.setVisibility(View.VISIBLE);
+            updateBigClockVisibility();
         }
         // Hide default clock.
         if (!plugin.shouldShowStatusArea()) {
@@ -208,12 +205,10 @@
             View bigClockView = mClockPlugin.getBigClockView();
             if (bigClockView != null) {
                 container.addView(bigClockView);
-                if (container.getVisibility() == View.GONE) {
-                    container.setVisibility(View.VISIBLE);
-                }
             }
         }
         mBigClockContainer = container;
+        updateBigClockVisibility();
     }
 
     /**
@@ -254,6 +249,7 @@
 
     /**
      * Set the amount (ratio) that the device has transitioned to doze.
+     *
      * @param darkAmount Amount of transition to doze: 1f for doze and 0f for awake.
      */
     public void setDarkAmount(float darkAmount) {
@@ -307,9 +303,24 @@
         }
     }
 
+    private void updateBigClockVisibility() {
+        if (mBigClockContainer == null) {
+            return;
+        }
+        final boolean inDisplayState = mStatusBarState == StatusBarState.KEYGUARD
+                || mStatusBarState == StatusBarState.SHADE_LOCKED;
+        final int visibility =
+                inDisplayState && mBigClockContainer.getChildCount() != 0 ? View.VISIBLE
+                        : View.GONE;
+        if (mBigClockContainer.getVisibility() != visibility) {
+            mBigClockContainer.setVisibility(visibility);
+        }
+    }
+
     /**
-     * Sets if the keyguard slice is showing a center-aligned header. We need a smaller clock
-     * in these cases.
+     * Sets if the keyguard slice is showing a center-aligned header. We need a smaller clock in
+     * these
+     * cases.
      */
     public void setKeyguardShowingHeader(boolean hasHeader) {
         if (mShowingHeader == hasHeader || hasCustomClock()) {
@@ -327,12 +338,12 @@
                 mClockView.getPaddingRight(), paddingBottom);
     }
 
-    @VisibleForTesting (otherwise = VisibleForTesting.NONE)
+    @VisibleForTesting(otherwise = VisibleForTesting.NONE)
     ClockManager.ClockChangedListener getClockChangedListener() {
         return mClockChangedListener;
     }
 
-    @VisibleForTesting (otherwise = VisibleForTesting.NONE)
+    @VisibleForTesting(otherwise = VisibleForTesting.NONE)
     StatusBarStateController.StateListener getStateListener() {
         return mStateListener;
     }
@@ -352,7 +363,8 @@
 
     /**
      * Special layout transition that scales the clock view as its bounds change, to make it look
-     * like the text is shrinking.
+     * like
+     * the text is shrinking.
      */
     private class ClockBoundsTransition extends ChangeBounds {
 
diff --git a/packages/SystemUI/src/com/android/systemui/HardwareBgDrawable.java b/packages/SystemUI/src/com/android/systemui/HardwareBgDrawable.java
index 97d7999..d631cf3 100644
--- a/packages/SystemUI/src/com/android/systemui/HardwareBgDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/HardwareBgDrawable.java
@@ -115,4 +115,4 @@
     public void setRotatedBackground(boolean rotatedBackground) {
         mRotatedBackground = rotatedBackground;
     }
-}
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
index 016b8fe9..4028109 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
@@ -191,32 +191,41 @@
         mCurrentDialogArgs = args;
         final int type = args.argi1;
 
+        // Create a new dialog but do not replace the current one yet.
+        BiometricDialogView newDialog;
         if (type == BiometricAuthenticator.TYPE_FINGERPRINT) {
-            mCurrentDialog = new FingerprintDialogView(mContext, mCallback);
+            newDialog = new FingerprintDialogView(mContext, mCallback);
         } else if (type == BiometricAuthenticator.TYPE_FACE) {
-            mCurrentDialog = new FaceDialogView(mContext, mCallback);
+            newDialog = new FaceDialogView(mContext, mCallback);
         } else {
             Log.e(TAG, "Unsupported type: " + type);
-        }
-
-        if (savedState != null) {
-            mCurrentDialog.restoreState(savedState);
-        }
-
-        if (DEBUG) Log.d(TAG, "handleShowDialog, isAnimatingAway: "
-                + mCurrentDialog.isAnimatingAway() + " type: " + type);
-
-        if (mCurrentDialog.isAnimatingAway()) {
-            mCurrentDialog.forceRemove();
-        } else if (mDialogShowing) {
-            Log.w(TAG, "Dialog already showing");
             return;
         }
+
+        if (DEBUG) Log.d(TAG, "handleShowDialog, "
+                + " savedState: " + savedState
+                + " mCurrentDialog: " + mCurrentDialog
+                + " newDialog: " + newDialog
+                + " type: " + type);
+
+        if (savedState != null) {
+            // SavedState is only non-null if it's from onConfigurationChanged. Restore the state
+            // even though it may be removed / re-created again
+            newDialog.restoreState(savedState);
+        } else if (mCurrentDialog != null && mDialogShowing) {
+            // If somehow we're asked to show a dialog, the old one doesn't need to be animated
+            // away. This can happen if the app cancels and re-starts auth during configuration
+            // change. This is ugly because we also have to do things on onConfigurationChanged
+            // here.
+            mCurrentDialog.forceRemove();
+        }
+
         mReceiver = (IBiometricServiceReceiverInternal) args.arg2;
-        mCurrentDialog.setBundle((Bundle)args.arg1);
-        mCurrentDialog.setRequireConfirmation((boolean) args.arg3);
-        mCurrentDialog.setUserId(args.argi2);
-        mCurrentDialog.setSkipIntro(skipAnimation);
+        newDialog.setBundle((Bundle) args.arg1);
+        newDialog.setRequireConfirmation((boolean) args.arg3);
+        newDialog.setUserId(args.argi2);
+        newDialog.setSkipIntro(skipAnimation);
+        mCurrentDialog = newDialog;
         mWindowManager.addView(mCurrentDialog, mCurrentDialog.getLayoutParams());
         mDialogShowing = true;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index b98ce2698..f07887e 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -92,8 +92,6 @@
 import com.android.systemui.plugins.GlobalActionsPanelPlugin;
 import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
-import com.android.systemui.statusbar.policy.ExtensionController;
-import com.android.systemui.statusbar.policy.ExtensionController.Extension;
 import com.android.systemui.util.EmergencyDialerConstants;
 import com.android.systemui.util.leak.RotationUtils;
 import com.android.systemui.volume.SystemUIInterpolators.LogAccelerateInterpolator;
@@ -161,9 +159,8 @@
     private final EmergencyAffordanceManager mEmergencyAffordanceManager;
     private final ScreenshotHelper mScreenshotHelper;
     private final ScreenRecordHelper mScreenRecordHelper;
-
-    private final Extension<GlobalActionsPanelPlugin> mPanelExtension;
-    private ActivityStarter mActivityStarter;
+    private final ActivityStarter mActivityStarter;
+    private GlobalActionsPanelPlugin mPanelPlugin;
 
     /**
      * @param context everything needs a context :(
@@ -209,10 +206,6 @@
 
         Dependency.get(ConfigurationController.class).addCallback(this);
 
-        mPanelExtension = Dependency.get(ExtensionController.class)
-            .newExtension(GlobalActionsPanelPlugin.class)
-            .withPlugin(GlobalActionsPanelPlugin.class)
-            .build();
         mActivityStarter = Dependency.get(ActivityStarter.class);
     }
 
@@ -221,9 +214,11 @@
      *
      * @param keyguardShowing True if keyguard is showing
      */
-    public void showDialog(boolean keyguardShowing, boolean isDeviceProvisioned) {
+    public void showDialog(boolean keyguardShowing, boolean isDeviceProvisioned,
+            GlobalActionsPanelPlugin panelPlugin) {
         mKeyguardShowing = keyguardShowing;
         mDeviceProvisioned = isDeviceProvisioned;
+        mPanelPlugin = panelPlugin;
         if (mDialog != null) {
             mDialog.dismiss();
             mDialog = null;
@@ -383,8 +378,7 @@
                     mHasLogoutButton = true;
                 }
             } else if (GLOBAL_ACTION_KEY_EMERGENCY.equals(actionKey)) {
-                if (shouldUseSeparatedView()
-                        && !mEmergencyAffordanceManager.needsEmergencyAffordance()) {
+                if (!mEmergencyAffordanceManager.needsEmergencyAffordance()) {
                     mItems.add(new EmergencyDialerAction());
                 }
             } else {
@@ -395,14 +389,14 @@
         }
 
         if (mEmergencyAffordanceManager.needsEmergencyAffordance()) {
-            mItems.add(getEmergencyAction());
+            mItems.add(new EmergencyAffordanceAction());
         }
 
         mAdapter = new MyAdapter();
 
         GlobalActionsPanelPlugin.PanelViewController panelViewController =
-                mPanelExtension.get() != null
-                        ? mPanelExtension.get().onPanelShown(
+                mPanelPlugin != null
+                        ? mPanelPlugin.onPanelShown(
                                 new GlobalActionsPanelPlugin.Callbacks() {
                                     @Override
                                     public void dismissGlobalActionsMenu() {
@@ -484,7 +478,59 @@
         }
     }
 
-    private class EmergencyDialerAction extends SinglePressAction {
+    private abstract class EmergencyAction extends SinglePressAction {
+        EmergencyAction(int iconResId, int messageResId) {
+            super(iconResId, messageResId);
+        }
+
+        @Override
+        public boolean shouldBeSeparated() {
+            return shouldUseSeparatedView();
+        }
+
+        @Override
+        public View create(
+                Context context, View convertView, ViewGroup parent, LayoutInflater inflater) {
+            View v = super.create(context, convertView, parent, inflater);
+            int textColor;
+            if (shouldBeSeparated()) {
+                textColor = v.getResources().getColor(
+                        com.android.systemui.R.color.global_actions_alert_text);
+            } else {
+                textColor = v.getResources().getColor(
+                        com.android.systemui.R.color.global_actions_text);
+            }
+            TextView messageView = v.findViewById(R.id.message);
+            messageView.setTextColor(textColor);
+            ImageView icon = (ImageView) v.findViewById(R.id.icon);
+            icon.getDrawable().setTint(textColor);
+            return v;
+        }
+
+        @Override
+        public boolean showDuringKeyguard() {
+            return true;
+        }
+
+        @Override
+        public boolean showBeforeProvisioning() {
+            return true;
+        }
+    }
+
+    private class EmergencyAffordanceAction extends EmergencyAction {
+        EmergencyAffordanceAction() {
+            super(R.drawable.emergency_icon,
+                    R.string.global_action_emergency);
+        }
+
+        @Override
+        public void onPress() {
+            mEmergencyAffordanceManager.performEmergencyCall();
+        }
+    }
+
+    private class EmergencyDialerAction extends EmergencyAction {
         private EmergencyDialerAction() {
             super(R.drawable.ic_faster_emergency,
                     R.string.global_action_emergency);
@@ -501,21 +547,6 @@
                     EmergencyDialerConstants.ENTRY_TYPE_POWER_MENU);
             mContext.startActivityAsUser(intent, UserHandle.CURRENT);
         }
-
-        @Override
-        public boolean showDuringKeyguard() {
-            return true;
-        }
-
-        @Override
-        public boolean showBeforeProvisioning() {
-            return true;
-        }
-
-        @Override
-        public boolean shouldBeSeparated() {
-            return true;
-        }
     }
 
     private final class RestartAction extends SinglePressAction implements LongPressAction {
@@ -703,32 +734,6 @@
         };
     }
 
-    private Action getEmergencyAction() {
-        Drawable emergencyIcon = mContext.getDrawable(R.drawable.emergency_icon);
-        if (!shouldUseSeparatedView()) {
-            // use un-colored legacy treatment
-            emergencyIcon.setTintList(null);
-        }
-
-        return new SinglePressAction(R.drawable.emergency_icon,
-                R.string.global_action_emergency) {
-            @Override
-            public void onPress() {
-                mEmergencyAffordanceManager.performEmergencyCall();
-            }
-
-            @Override
-            public boolean showDuringKeyguard() {
-                return true;
-            }
-
-            @Override
-            public boolean showBeforeProvisioning() {
-                return true;
-            }
-        };
-    }
-
     private Action getAssistAction() {
         return new SinglePressAction(R.drawable.ic_action_assist_focused,
                 R.string.global_action_assist) {
@@ -1494,12 +1499,12 @@
         private final Context mContext;
         private final MyAdapter mAdapter;
         private MultiListLayout mGlobalActionsLayout;
-        private final Drawable mBackgroundDrawable;
+        private Drawable mBackgroundDrawable;
         private final ColorExtractor mColorExtractor;
         private final GlobalActionsPanelPlugin.PanelViewController mPanelController;
         private boolean mKeyguardShowing;
         private boolean mShowing;
-        private final float mScrimAlpha;
+        private float mScrimAlpha;
 
         ActionsDialog(Context context, MyAdapter adapter,
                 GlobalActionsPanelPlugin.PanelViewController plugin) {
@@ -1526,49 +1531,37 @@
                     | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                     | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
             window.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
-
-            initializeLayout();
-
             setTitle(R.string.global_actions);
 
             mPanelController = plugin;
-            View panelView = initializePanel();
-            if (panelView == null) {
-                mBackgroundDrawable = new GradientDrawable(context);
-                mScrimAlpha = ScrimController.GRADIENT_SCRIM_ALPHA;
-            } else {
-                mBackgroundDrawable = context.getDrawable(
-                        com.android.systemui.R.drawable.global_action_panel_scrim);
-                mScrimAlpha = 1f;
-                addContentView(
-                        panelView,
-                        new ViewGroup.LayoutParams(
-                                ViewGroup.LayoutParams.MATCH_PARENT,
-                                ViewGroup.LayoutParams.MATCH_PARENT));
-            }
-            window.setBackgroundDrawable(mBackgroundDrawable);
+            initializeLayout();
         }
 
-        private View initializePanel() {
-            if (isPanelEnabled(mContext) && mPanelController != null) {
-                View panelView = mPanelController.getPanelContent();
-                if (panelView != null) {
-                    FrameLayout panelContainer = new FrameLayout(mContext);
-                    FrameLayout.LayoutParams panelParams =
-                            new FrameLayout.LayoutParams(
-                                    FrameLayout.LayoutParams.MATCH_PARENT,
-                                    FrameLayout.LayoutParams.WRAP_CONTENT);
-                    panelContainer.addView(panelView, panelParams);
-                    return panelContainer;
-                }
+        private boolean initializePanel() {
+            if (!isPanelEnabled(mContext) || mPanelController == null) {
+                return false;
             }
-            return null;
+            View panelView = mPanelController.getPanelContent();
+            if (panelView == null) {
+                return false;
+            }
+            FrameLayout panelContainer = new FrameLayout(mContext);
+            FrameLayout.LayoutParams panelParams =
+                    new FrameLayout.LayoutParams(
+                            FrameLayout.LayoutParams.MATCH_PARENT,
+                            FrameLayout.LayoutParams.WRAP_CONTENT);
+            panelContainer.addView(panelView, panelParams);
+            addContentView(
+                    panelContainer,
+                    new ViewGroup.LayoutParams(
+                            ViewGroup.LayoutParams.MATCH_PARENT,
+                            ViewGroup.LayoutParams.MATCH_PARENT));
+            return true;
         }
 
         private void initializeLayout() {
             setContentView(getGlobalActionsLayoutId(mContext));
-            mGlobalActionsLayout = (MultiListLayout)
-                    findViewById(com.android.systemui.R.id.global_actions_view);
+            mGlobalActionsLayout = findViewById(com.android.systemui.R.id.global_actions_view);
             mGlobalActionsLayout.setOutsideTouchListener(view -> dismiss());
             mGlobalActionsLayout.setListViewAccessibilityDelegate(new View.AccessibilityDelegate() {
                 @Override
@@ -1581,8 +1574,18 @@
             });
             mGlobalActionsLayout.setRotationListener(this::onRotate);
             mGlobalActionsLayout.setAdapter(mAdapter);
-            mGlobalActionsLayout.setSnapToEdge(isPanelEnabled(mContext)
-                    && mPanelController != null);
+
+            boolean panelEnabled = initializePanel();
+            if (!panelEnabled) {
+                mBackgroundDrawable = new GradientDrawable(mContext);
+                mScrimAlpha = ScrimController.GRADIENT_SCRIM_ALPHA;
+            } else {
+                mBackgroundDrawable = mContext.getDrawable(
+                        com.android.systemui.R.drawable.global_action_panel_scrim);
+                mScrimAlpha = 1f;
+            }
+            mGlobalActionsLayout.setSnapToEdge(panelEnabled);
+            getWindow().setBackgroundDrawable(mBackgroundDrawable);
         }
 
         private int getGlobalActionsLayoutId(Context context) {
@@ -1738,7 +1741,8 @@
      */
     private static boolean isPanelEnabled(Context context) {
         return FeatureFlagUtils.isEnabled(
-                context, FeatureFlagUtils.GLOBAL_ACTIONS_PANEL_ENABLED);    }
+                context, FeatureFlagUtils.GLOBAL_ACTIONS_PANEL_ENABLED);
+    }
 
     /**
      * Determines whether the Global Actions menu should use a separated view for emergency actions.
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java
index 058ea60..9a0759c 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java
@@ -42,11 +42,16 @@
     }
 
     private void setBackgrounds() {
+        int gridBackgroundColor = getResources().getColor(
+                com.android.systemui.R.color.global_actions_grid_background, null);
+        int separatedBackgroundColor = getResources().getColor(
+                com.android.systemui.R.color.global_actions_separated_background, null);
         HardwareBgDrawable listBackground  = new HardwareBgDrawable(true, true, getContext());
-        HardwareBgDrawable separatedViewBackground = new HardwareBgDrawable(true, true,
-                getContext());
+        HardwareBgDrawable separatedBackground = new HardwareBgDrawable(true, true, getContext());
+        listBackground.setTint(gridBackgroundColor);
+        separatedBackground.setTint(separatedBackgroundColor);
         getListView().setBackground(listBackground);
-        getSeparatedView().setBackground(separatedViewBackground);
+        getSeparatedView().setBackground(separatedBackground);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
index 19a7cea..4cf58b7 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
@@ -37,8 +37,10 @@
 import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.plugins.GlobalActions;
+import com.android.systemui.plugins.GlobalActionsPanelPlugin;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.ExtensionController;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
 
 public class GlobalActionsImpl implements GlobalActions, CommandQueue.Callbacks {
@@ -48,6 +50,7 @@
     private final Context mContext;
     private final KeyguardMonitor mKeyguardMonitor;
     private final DeviceProvisionedController mDeviceProvisionedController;
+    private final ExtensionController.Extension<GlobalActionsPanelPlugin> mPanelExtension;
     private GlobalActionsDialog mGlobalActions;
     private boolean mDisabled;
 
@@ -56,6 +59,10 @@
         mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
         mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
         SysUiServiceProvider.getComponent(context, CommandQueue.class).addCallback(this);
+        mPanelExtension = Dependency.get(ExtensionController.class)
+                .newExtension(GlobalActionsPanelPlugin.class)
+                .withPlugin(GlobalActionsPanelPlugin.class)
+                .build();
     }
 
     @Override
@@ -74,7 +81,8 @@
             mGlobalActions = new GlobalActionsDialog(mContext, manager);
         }
         mGlobalActions.showDialog(mKeyguardMonitor.isShowing(),
-                mDeviceProvisionedController.isDeviceProvisioned());
+                mDeviceProvisionedController.isDeviceProvisioned(),
+                mPanelExtension.get());
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java
index 7a42b03..1478a07 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java
@@ -20,7 +20,6 @@
 import android.hardware.input.InputManager;
 import android.os.Handler;
 import android.os.SystemClock;
-import android.view.HapticFeedbackConstants;
 import android.view.InputDevice;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
@@ -103,7 +102,6 @@
     private void performBack() {
         sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK);
         sendEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK);
-        mNavigationBarView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
     }
 
     private boolean shouldExecuteBackOnUp() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java
index fcf5893..4c7fdb0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java
@@ -22,6 +22,7 @@
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.PixelFormat;
+import android.os.SystemClock;
 import android.util.FloatProperty;
 import android.util.MathUtils;
 import android.view.Gravity;
@@ -31,6 +32,7 @@
 import android.view.WindowManager;
 
 import com.android.systemui.R;
+import com.android.systemui.shared.system.QuickStepContract;
 
 public class NavigationBarEdgePanel extends View {
     private static final String TAG = "NavigationBarEdgePanel";
@@ -48,6 +50,7 @@
     private static final float START_POINTING_RATIO = 0.3f;
     private static final float POINTEDNESS_BEFORE_SNAP_RATIO = 0.4f;
     private static final int ANIM_DURATION_MS = 150;
+    private static final long HAPTIC_TIMEOUT_MS = 200;
 
     private final Paint mPaint = new Paint();
     private final Paint mProtectionPaint = new Paint();
@@ -65,6 +68,8 @@
     private float mStartY;
     private float mStartX;
 
+    private boolean mDragSlopPassed;
+    private long mLastSlopHapticTime;
     private boolean mGestureDetected;
     private boolean mArrowsPointLeft;
     private float mGestureLength;
@@ -169,6 +174,7 @@
     public boolean onTouchEvent(MotionEvent event) {
         switch (event.getActionMasked()) {
             case MotionEvent.ACTION_DOWN : {
+                mDragSlopPassed = false;
                 show(event.getX(), event.getY());
                 break;
             }
@@ -263,6 +269,13 @@
     private void handleNewSwipePoint(float x) {
         float dist = MathUtils.abs(x - mStartX);
 
+        // Apply a haptic on drag slop passed
+        if (!mDragSlopPassed && dist > QuickStepContract.getQuickStepDragSlopPx()) {
+            mDragSlopPassed = true;
+            performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK);
+            mLastSlopHapticTime = SystemClock.uptimeMillis();
+        }
+
         setDragProgress(MathUtils.constrainedMap(
                 0, 1.0f,
                 0, mGestureLength * TRACK_LENGTH_MULTIPLIER,
@@ -286,7 +299,10 @@
             }
         } else {
             if (!mGestureDetected) {
-                performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK);
+                // Prevent another haptic if it was just used
+                if (SystemClock.uptimeMillis() - mLastSlopHapticTime > HAPTIC_TIMEOUT_MS) {
+                    performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK);
+                }
                 mGestureDetected = true;
 
                 mLegAnimator.setFloatValues(1f);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index d4049826..024404d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.policy;
 
 import static android.view.Display.INVALID_DISPLAY;
+import static android.view.KeyEvent.KEYCODE_UNKNOWN;
 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK;
 
@@ -101,7 +102,7 @@
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.KeyButtonView,
                 defStyle, 0);
 
-        mCode = a.getInteger(R.styleable.KeyButtonView_keyCode, 0);
+        mCode = a.getInteger(R.styleable.KeyButtonView_keyCode, KEYCODE_UNKNOWN);
 
         mSupportsLongpress = a.getBoolean(R.styleable.KeyButtonView_keyRepeat, true);
         mPlaySounds = a.getBoolean(R.styleable.KeyButtonView_playSound, true);
@@ -124,7 +125,7 @@
 
     @Override
     public boolean isClickable() {
-        return mCode != 0 || super.isClickable();
+        return mCode != KEYCODE_UNKNOWN || super.isClickable();
     }
 
     public void setCode(int code) {
@@ -163,7 +164,7 @@
     @Override
     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfo(info);
-        if (mCode != 0) {
+        if (mCode != KEYCODE_UNKNOWN) {
             info.addAction(new AccessibilityNodeInfo.AccessibilityAction(ACTION_CLICK, null));
             if (mSupportsLongpress || isLongClickable()) {
                 info.addAction(
@@ -182,13 +183,13 @@
 
     @Override
     public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
-        if (action == ACTION_CLICK && mCode != 0) {
+        if (action == ACTION_CLICK && mCode != KEYCODE_UNKNOWN) {
             sendEvent(KeyEvent.ACTION_DOWN, 0, SystemClock.uptimeMillis());
             sendEvent(KeyEvent.ACTION_UP, 0);
             sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
             playSoundEffect(SoundEffectConstants.CLICK);
             return true;
-        } else if (action == ACTION_LONG_CLICK && mCode != 0) {
+        } else if (action == ACTION_LONG_CLICK && mCode != KEYCODE_UNKNOWN) {
             sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
             sendEvent(KeyEvent.ACTION_UP, 0);
             sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
@@ -197,6 +198,7 @@
         return super.performAccessibilityActionInternal(action, arguments);
     }
 
+    @Override
     public boolean onTouchEvent(MotionEvent ev) {
         final boolean showSwipeUI = mOverviewProxyService.shouldShowSwipeUpUI();
         final int action = ev.getAction();
@@ -218,7 +220,7 @@
                 // Use raw X and Y to detect gestures in case a parent changes the x and y values
                 mTouchDownX = (int) ev.getRawX();
                 mTouchDownY = (int) ev.getRawY();
-                if (mCode != 0) {
+                if (mCode != KEYCODE_UNKNOWN) {
                     sendEvent(KeyEvent.ACTION_DOWN, 0, mDownTime);
                 } else {
                     // Provide the same haptic feedback that the system offers for virtual keys.
@@ -249,7 +251,7 @@
                 break;
             case MotionEvent.ACTION_CANCEL:
                 setPressed(false);
-                if (mCode != 0) {
+                if (mCode != KEYCODE_UNKNOWN) {
                     sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED);
                 }
                 removeCallbacks(mCheckLongPress);
@@ -269,7 +271,7 @@
                     // and it feels weird to sometimes get a release haptic and other times not.
                     performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY_RELEASE);
                 }
-                if (mCode != 0) {
+                if (mCode != KEYCODE_UNKNOWN) {
                     if (doIt) {
                         sendEvent(KeyEvent.ACTION_UP, 0);
                         sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
@@ -299,7 +301,7 @@
         sendEvent(action, flags, SystemClock.uptimeMillis());
     }
 
-    void sendEvent(int action, int flags, long when) {
+    private void sendEvent(int action, int flags, long when) {
         mMetricsLogger.write(new LogMaker(MetricsEvent.ACTION_NAV_BUTTON_EVENT)
                 .setType(MetricsEvent.TYPE_ACTION)
                 .setSubtype(mCode)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 3deede0..d3164a0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -22,7 +22,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.provider.Settings.Global;
-import android.telephony.NetworkRegistrationState;
+import android.telephony.NetworkRegistrationInfo;
 import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
@@ -475,7 +475,7 @@
         if (mServiceState == null) return null;
 
         int nrStatus = mServiceState.getNrStatus();
-        if (nrStatus == NetworkRegistrationState.NR_STATUS_CONNECTED) {
+        if (nrStatus == NetworkRegistrationInfo.NR_STATUS_CONNECTED) {
             // Check if the NR 5G is using millimeter wave and the icon is config.
             if (mServiceState.getNrFrequencyRange() == ServiceState.FREQUENCY_RANGE_MMWAVE) {
                 if (mConfig.nr5GIconMap.containsKey(Config.NR_CONNECTED_MMWAVE)) {
@@ -488,11 +488,11 @@
             if (mConfig.nr5GIconMap.containsKey(Config.NR_CONNECTED)) {
                 return mConfig.nr5GIconMap.get(Config.NR_CONNECTED);
             }
-        } else if (nrStatus == NetworkRegistrationState.NR_STATUS_NOT_RESTRICTED) {
+        } else if (nrStatus == NetworkRegistrationInfo.NR_STATUS_NOT_RESTRICTED) {
             if (mConfig.nr5GIconMap.containsKey(Config.NR_NOT_RESTRICTED)) {
                 return mConfig.nr5GIconMap.get(Config.NR_NOT_RESTRICTED);
             }
-        } else if (nrStatus == NetworkRegistrationState.NR_STATUS_RESTRICTED) {
+        } else if (nrStatus == NetworkRegistrationInfo.NR_STATUS_RESTRICTED) {
             if (mConfig.nr5GIconMap.containsKey(Config.NR_RESTRICTED)) {
                 return mConfig.nr5GIconMap.get(Config.NR_RESTRICTED);
             }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
index b0d1106..29505a2 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
@@ -101,6 +101,8 @@
         // AND the plugin returns a view for the big clock
         ClockPlugin plugin = mock(ClockPlugin.class);
         when(plugin.getBigClockView()).thenReturn(mBigClock);
+        // AND in the keyguard state
+        mStateListener.onStateChanged(StatusBarState.KEYGUARD);
         // WHEN the plugin is connected
         mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
         // THEN the big clock container is visible and it is the parent of the
@@ -166,6 +168,8 @@
         ClockPlugin plugin = mock(ClockPlugin.class);
         TextClock pluginView = new TextClock(getContext());
         when(plugin.getBigClockView()).thenReturn(pluginView);
+        // AND in the keyguard state
+        mStateListener.onStateChanged(StatusBarState.KEYGUARD);
         // WHEN the plugin is connected and then disconnected
         mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
         mKeyguardClockSwitch.getClockChangedListener().onClockChanged(null);
@@ -245,21 +249,25 @@
     }
 
     @Test
-    public void onStateChanged_InvisibleInShade() {
+    public void onStateChanged_GoneInShade() {
         // GIVEN that the big clock container is visible
         mBigClockContainer.setVisibility(View.VISIBLE);
         mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer);
         // WHEN transitioned to SHADE state
         mStateListener.onStateChanged(StatusBarState.SHADE);
-        // THEN the container is invisible.
-        assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.INVISIBLE);
+        // THEN the container is gone.
+        assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.GONE);
     }
 
     @Test
     public void onStateChanged_VisibleInKeyguard() {
-        // GIVEN that the big clock container is invisible
-        mBigClockContainer.setVisibility(View.INVISIBLE);
+        // GIVEN that the big clock container is gone
+        mBigClockContainer.setVisibility(View.GONE);
         mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer);
+        // AND GIVEN that a plugin is active.
+        ClockPlugin plugin = mock(ClockPlugin.class);
+        when(plugin.getBigClockView()).thenReturn(mBigClock);
+        mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
         // WHEN transitioned to KEYGUARD state
         mStateListener.onStateChanged(StatusBarState.KEYGUARD);
         // THEN the container is visible.
@@ -274,6 +282,8 @@
         ClockPlugin plugin = mock(ClockPlugin.class);
         when(plugin.getBigClockView()).thenReturn(mBigClock);
         mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
+        // AND in the keyguard state
+        mStateListener.onStateChanged(StatusBarState.KEYGUARD);
         // WHEN the container is associated with the clock switch
         mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer);
         // THEN the container remains visible.
@@ -281,20 +291,6 @@
     }
 
     @Test
-    public void setBigClockContainer_invisible() {
-        // GIVEN that the big clock container is invisible
-        mBigClockContainer.setVisibility(View.INVISIBLE);
-        // AND GIVEN that a plugin is active.
-        ClockPlugin plugin = mock(ClockPlugin.class);
-        when(plugin.getBigClockView()).thenReturn(mBigClock);
-        mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
-        // WHEN the container is associated with the clock switch
-        mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer);
-        // THEN the container remains invisible.
-        assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.INVISIBLE);
-    }
-
-    @Test
     public void setBigClockContainer_gone() {
         // GIVEN that the big clock container is gone
         mBigClockContainer.setVisibility(View.GONE);
@@ -302,6 +298,8 @@
         ClockPlugin plugin = mock(ClockPlugin.class);
         when(plugin.getBigClockView()).thenReturn(mBigClock);
         mKeyguardClockSwitch.getClockChangedListener().onClockChanged(plugin);
+        // AND in the keyguard state
+        mStateListener.onStateChanged(StatusBarState.KEYGUARD);
         // WHEN the container is associated with the clock switch
         mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer);
         // THEN the container is made visible.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index 2baea1a..5786796 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -7,7 +7,7 @@
 
 import android.net.NetworkCapabilities;
 import android.os.Looper;
-import android.telephony.NetworkRegistrationState;
+import android.telephony.NetworkRegistrationInfo;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -151,7 +151,7 @@
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
                 TelephonyManager.NETWORK_TYPE_LTE);
         ServiceState ss = Mockito.mock(ServiceState.class);
-        doReturn(NetworkRegistrationState.NR_STATUS_CONNECTED).when(ss).getNrStatus();
+        doReturn(NetworkRegistrationInfo.NR_STATUS_CONNECTED).when(ss).getNrStatus();
         doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(ss).getNrFrequencyRange();
         mPhoneStateListener.onServiceStateChanged(ss);
 
@@ -165,7 +165,7 @@
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
                 TelephonyManager.NETWORK_TYPE_LTE);
         ServiceState ss = Mockito.mock(ServiceState.class);
-        doReturn(NetworkRegistrationState.NR_STATUS_CONNECTED).when(ss).getNrStatus();
+        doReturn(NetworkRegistrationInfo.NR_STATUS_CONNECTED).when(ss).getNrStatus();
         doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(ss).getNrFrequencyRange();
         mPhoneStateListener.onServiceStateChanged(ss);
 
@@ -179,7 +179,7 @@
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
                 TelephonyManager.NETWORK_TYPE_LTE);
         ServiceState ss = Mockito.mock(ServiceState.class);
-        doReturn(NetworkRegistrationState.NR_STATUS_RESTRICTED).when(ss).getNrStatus();
+        doReturn(NetworkRegistrationInfo.NR_STATUS_RESTRICTED).when(ss).getNrStatus();
         mPhoneStateListener.onServiceStateChanged(mServiceState);
 
         verifyDataIndicators(TelephonyIcons.ICON_LTE);
diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto
index bc42863..f106228 100644
--- a/proto/src/metrics_constants/metrics_constants.proto
+++ b/proto/src/metrics_constants/metrics_constants.proto
@@ -7117,6 +7117,9 @@
     // overridden by the system.
     FIELD_NOTIFICATION_IMPORTANCE_ASST = 1691;
 
+    // Open: Settings > Special App Access > Do not disturb control for app
+    ZEN_ACCESS_DETAIL = 1692;
+
     // ---- End Q Constants, all Q constants go above this line ----
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS
diff --git a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
index 65e31f3..1e3f20e 100644
--- a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
@@ -809,13 +809,9 @@
 
         // Announce the end of the gesture recognition.
         sendAccessibilityEvent(AccessibilityEvent.TYPE_GESTURE_DETECTION_END);
+        // Don't announce the end of a the touch interaction if users didn't lift their fingers.
         if (interactionEnd) {
-            // Announce the end of a the touch interaction.
             sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END);
-        } else {
-            // If gesture detection is end, but user doesn't release the finger, announce the
-            // transition to exploration state.
-            sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START);
         }
 
         mExitGestureDetectionModeDelayed.cancel();
@@ -1151,10 +1147,7 @@
         public void run() {
             // Announce the end of gesture recognition.
             sendAccessibilityEvent(AccessibilityEvent.TYPE_GESTURE_DETECTION_END);
-            // Clearing puts is in touch exploration state with a finger already
-            // down, so announce the transition to exploration state.
             clear();
-            sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START);
         }
     }
 
diff --git a/services/backup/java/com/android/server/backup/params/RestoreParams.java b/services/backup/java/com/android/server/backup/params/RestoreParams.java
index 5125b0d..c9a6b60 100644
--- a/services/backup/java/com/android/server/backup/params/RestoreParams.java
+++ b/services/backup/java/com/android/server/backup/params/RestoreParams.java
@@ -105,7 +105,7 @@
     /**
      * Caller specifies whether is considered a system-level restore.
      */
-    public static RestoreParams createForRestoreSome(
+    public static RestoreParams createForRestorePackages(
             TransportClient transportClient,
             IRestoreObserver observer,
             IBackupManagerMonitor monitor,
diff --git a/services/backup/java/com/android/server/backup/restore/ActiveRestoreSession.java b/services/backup/java/com/android/server/backup/restore/ActiveRestoreSession.java
index 0fa0f89..10304c3 100644
--- a/services/backup/java/com/android/server/backup/restore/ActiveRestoreSession.java
+++ b/services/backup/java/com/android/server/backup/restore/ActiveRestoreSession.java
@@ -22,6 +22,7 @@
 import static com.android.server.backup.internal.BackupHandler.MSG_RUN_GET_RESTORE_SETS;
 import static com.android.server.backup.internal.BackupHandler.MSG_RUN_RESTORE;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.backup.IBackupManagerMonitor;
 import android.app.backup.IRestoreObserver;
@@ -192,18 +193,22 @@
     }
 
     // Restores of more than a single package are treated as 'system' restores
-    public synchronized int restoreSome(long token, IRestoreObserver observer,
-            IBackupManagerMonitor monitor, String[] packages) {
+    public synchronized int restorePackages(long token, @Nullable IRestoreObserver observer,
+            @NonNull String[] packages, @Nullable IBackupManagerMonitor monitor) {
         mBackupManagerService.getContext().enforceCallingOrSelfPermission(
                 android.Manifest.permission.BACKUP,
                 "performRestore");
 
         if (DEBUG) {
             StringBuilder b = new StringBuilder(128);
-            b.append("restoreSome token=");
+            b.append("restorePackages token=");
             b.append(Long.toHexString(token));
             b.append(" observer=");
-            b.append(observer.toString());
+            if (observer == null) {
+                b.append("null");
+            } else {
+                b.append(observer.toString());
+            }
             b.append(" monitor=");
             if (monitor == null) {
                 b.append("null");
@@ -260,7 +265,7 @@
                     try {
                         return sendRestoreToHandlerLocked(
                                 (transportClient, listener) ->
-                                        RestoreParams.createForRestoreSome(
+                                        RestoreParams.createForRestorePackages(
                                                 transportClient,
                                                 observer,
                                                 monitor,
@@ -268,7 +273,7 @@
                                                 packages,
                                                 /* isSystemRestore */ packages.length > 1,
                                                 listener),
-                                "RestoreSession.restoreSome(" + packages.length + " packages)");
+                                "RestoreSession.restorePackages(" + packages.length + " packages)");
                     } finally {
                         Binder.restoreCallingIdentity(oldId);
                     }
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 343cee1..b2ee686 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -41,7 +41,6 @@
 import static android.net.NetworkPolicyManager.RULE_NONE;
 import static android.net.NetworkPolicyManager.uidRulesToString;
 import static android.net.shared.NetworkMonitorUtils.isValidationRequired;
-import static android.net.shared.NetworkParcelableUtil.toStableParcelable;
 import static android.os.Process.INVALID_UID;
 import static android.system.OsConstants.IPPROTO_TCP;
 import static android.system.OsConstants.IPPROTO_UDP;
@@ -5390,7 +5389,7 @@
         final long token = Binder.clearCallingIdentity();
         try {
             getNetworkStack().makeNetworkMonitor(
-                    toStableParcelable(nai.network), name, new NetworkMonitorCallbacks(nai));
+                    nai.network, name, new NetworkMonitorCallbacks(nai));
         } finally {
             Binder.restoreCallingIdentity(token);
         }
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index c2a0611..7fab2b96 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -501,6 +501,8 @@
         }
 
         if (broadcast) {
+            // needs to be sent to everyone because we don't know which user may have changed
+            // LOCATION_MODE state.
             mContext.sendBroadcastAsUser(
                     new Intent(LocationManager.MODE_CHANGED_ACTION),
                     UserHandle.ALL);
@@ -1212,6 +1214,13 @@
                             "-" + mName,
                             mCurrentUserId);
                 }
+
+                // needs to be sent to all users because whether or not a provider is enabled for
+                // a given user is complicated... we broadcast to everyone and let them figure it
+                // out via isProviderEnabled()
+                Intent intent = new Intent(LocationManager.PROVIDERS_CHANGED_ACTION);
+                intent.putExtra(LocationManager.EXTRA_PROVIDER_NAME, mName);
+                mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
             }
 
             if (useable == mUseable) {
@@ -1232,10 +1241,6 @@
             }
 
             updateProviderUseableLocked(this);
-
-            mContext.sendBroadcastAsUser(
-                    new Intent(LocationManager.PROVIDERS_CHANGED_ACTION),
-                    UserHandle.ALL);
         }
 
         @GuardedBy("mLock")
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 6270106..e357ce8 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -1600,6 +1600,11 @@
                     "BIND_TREAT_LIKE_ACTIVITY");
         }
 
+        if ((flags & Context.BIND_SCHEDULE_LIKE_TOP_APP) != 0 && !isCallerSystem) {
+            throw new SecurityException("Non-system caller (pid=" + Binder.getCallingPid()
+                    + ") set BIND_SCHEDULE_LIKE_TOP_APP when binding service " + service);
+        }
+
         if ((flags & Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0 && !isCallerSystem) {
             throw new SecurityException(
                     "Non-system caller " + caller + " (pid=" + Binder.getCallingPid()
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 7c6049c..8225476 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -5492,6 +5492,12 @@
         }
     }
 
+    private boolean isAppBad(ApplicationInfo info) {
+        synchronized (this) {
+            return mAppErrors.isBadProcessLocked(info);
+        }
+    }
+
     // NOTE: this is an internal method used by the OnShellCommand implementation only and should
     // be guarded by permission checking.
     int getUidState(int uid) {
@@ -18078,6 +18084,11 @@
         }
 
         @Override
+        public boolean isAppBad(ApplicationInfo info) {
+            return ActivityManagerService.this.isAppBad(info);
+        }
+
+        @Override
         public void clearPendingBackup(int userId) {
             ActivityManagerService.this.clearPendingBackup(userId);
         }
diff --git a/services/core/java/com/android/server/am/AppCompactor.java b/services/core/java/com/android/server/am/AppCompactor.java
index 1f21160..438538f 100644
--- a/services/core/java/com/android/server/am/AppCompactor.java
+++ b/services/core/java/com/android/server/am/AppCompactor.java
@@ -211,7 +211,7 @@
         mPendingCompactionProcesses.add(app);
         mCompactionHandler.sendMessage(
             mCompactionHandler.obtainMessage(
-                COMPACT_PROCESS_MSG, app.curAdj, app.setProcState));
+                COMPACT_PROCESS_MSG, app.setAdj, app.setProcState));
     }
 
     @GuardedBy("mAm")
@@ -220,7 +220,7 @@
         mPendingCompactionProcesses.add(app);
         mCompactionHandler.sendMessage(
             mCompactionHandler.obtainMessage(
-                COMPACT_PROCESS_MSG, app.curAdj, app.setProcState));
+                COMPACT_PROCESS_MSG, app.setAdj, app.setProcState));
 
     }
 
diff --git a/services/core/java/com/android/server/am/ConnectionRecord.java b/services/core/java/com/android/server/am/ConnectionRecord.java
index af1031e..a1c941e 100644
--- a/services/core/java/com/android/server/am/ConnectionRecord.java
+++ b/services/core/java/com/android/server/am/ConnectionRecord.java
@@ -192,6 +192,9 @@
         if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
             sb.append("LACT ");
         }
+        if ((flags & Context.BIND_SCHEDULE_LIKE_TOP_APP) != 0) {
+            sb.append("SLTA ");
+        }
         if ((flags&Context.BIND_VISIBLE) != 0) {
             sb.append("VIS ");
         }
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 4e03b72..9056f76 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -1294,6 +1294,11 @@
                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
                             }
                         }
+                        if (schedGroup < ProcessList.SCHED_GROUP_TOP_APP
+                                && (cr.flags & Context.BIND_SCHEDULE_LIKE_TOP_APP) != 0) {
+                            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
+                        }
+
                         if (!trackedProcState) {
                             cr.trackProcState(clientProcState, mAdjSeq, now);
                         }
diff --git a/services/core/java/com/android/server/attention/AttentionManagerService.java b/services/core/java/com/android/server/attention/AttentionManagerService.java
index 7da848c..4e0380d 100644
--- a/services/core/java/com/android/server/attention/AttentionManagerService.java
+++ b/services/core/java/com/android/server/attention/AttentionManagerService.java
@@ -59,6 +59,7 @@
 import com.android.internal.util.Preconditions;
 import com.android.server.SystemService;
 
+import java.io.FileDescriptor;
 import java.io.PrintWriter;
 
 /**
@@ -103,6 +104,7 @@
 
     @Override
     public void onStart() {
+        publishBinderService(Context.ATTENTION_SERVICE, new BinderService());
         publishLocalService(AttentionManagerInternal.class, new LocalService());
     }
 
@@ -329,17 +331,15 @@
         return null;
     }
 
-    private void dumpInternal(PrintWriter pw) {
-        if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) return;
-        IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
-        ipw.println("Attention Manager Service (dumpsys attention)\n");
+    private void dumpInternal(IndentingPrintWriter ipw) {
+        ipw.println("Attention Manager Service (dumpsys attention) state:\n");
 
         ipw.printPair("context", mContext);
-        pw.println();
+        ipw.println();
         synchronized (mLock) {
             int size = mUserStates.size();
             ipw.print("Number user states: ");
-            pw.println(size);
+            ipw.println(size);
             if (size > 0) {
                 ipw.increaseIndent();
                 for (int i = 0; i < size; i++) {
@@ -591,4 +591,15 @@
             }
         }
     }
+
+    private final class BinderService extends Binder {
+        @Override
+        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+            if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) {
+                return;
+            }
+
+            dumpInternal(new IndentingPrintWriter(pw, "  "));
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index ddd416e..f313e1d 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -57,6 +57,7 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
+import android.os.Message;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
@@ -68,6 +69,7 @@
 import android.util.StatsLog;
 
 import com.android.internal.R;
+import com.android.internal.os.SomeArgs;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.server.SystemService;
 
@@ -85,22 +87,137 @@
 
     private static final String TAG = "BiometricService";
 
+    private static final int MSG_ON_TASK_STACK_CHANGED = 1;
+    private static final int MSG_ON_AUTHENTICATION_SUCCEEDED = 2;
+    private static final int MSG_ON_AUTHENTICATION_FAILED = 3;
+    private static final int MSG_ON_ERROR = 4;
+    private static final int MSG_ON_ACQUIRED = 5;
+    private static final int MSG_ON_DISMISSED = 6;
+    private static final int MSG_ON_TRY_AGAIN_PRESSED = 7;
+    private static final int MSG_ON_READY_FOR_AUTHENTICATION = 8;
+    private static final int MSG_AUTHENTICATE = 9;
+    private static final int MSG_CANCEL_AUTHENTICATION = 10;
+
     private static final int[] FEATURE_ID = {
         TYPE_FINGERPRINT,
         TYPE_IRIS,
         TYPE_FACE
     };
 
+    /**
+     * Authentication either just called and we have not transitioned to the CALLED state, or
+     * authentication terminated (success or error).
+     */
+    private static final int STATE_AUTH_IDLE = 0;
+    /**
+     * Authentication was called and we are waiting for the <Biometric>Services to return their
+     * cookies before starting the hardware and showing the BiometricPrompt.
+     */
+    private static final int STATE_AUTH_CALLED = 1;
+    /**
+     * Authentication started, BiometricPrompt is showing and the hardware is authenticating.
+     */
+    private static final int STATE_AUTH_STARTED = 2;
+    /**
+     * Authentication is paused, waiting for the user to press "try again" button. Only
+     * passive modalities such as Face or Iris should have this state. Note that for passive
+     * modalities, the HAL enters the idle state after onAuthenticated(false) which differs from
+     * fingerprint.
+     */
+    private static final int STATE_AUTH_PAUSED = 3;
+    /**
+     * Authentication is successful, but we're waiting for the user to press "confirm" button.
+     */
+    private static final int STATE_AUTH_PENDING_CONFIRM = 5;
+
+    private final class AuthSession {
+        // Map of Authenticator/Cookie pairs. We expect to receive the cookies back from
+        // <Biometric>Services before we can start authenticating. Pairs that have been returned
+        // are moved to mModalitiesMatched.
+        final HashMap<Integer, Integer> mModalitiesWaiting;
+        // Pairs that have been matched.
+        final HashMap<Integer, Integer> mModalitiesMatched = new HashMap<>();
+
+        // The following variables are passed to authenticateInternal, which initiates the
+        // appropriate <Biometric>Services.
+        final IBinder mToken;
+        final long mSessionId;
+        final int mUserId;
+        // Original receiver from BiometricPrompt.
+        final IBiometricServiceReceiver mClientReceiver;
+        final String mOpPackageName;
+        // Info to be shown on BiometricDialog when all cookies are returned.
+        final Bundle mBundle;
+        final int mCallingUid;
+        final int mCallingPid;
+        final int mCallingUserId;
+        // Continue authentication with the same modality/modalities after "try again" is
+        // pressed
+        final int mModality;
+        final boolean mRequireConfirmation;
+
+        // The current state, which can be either idle, called, or started
+        private int mState = STATE_AUTH_IDLE;
+        // For explicit confirmation, do not send to keystore until the user has confirmed
+        // the authentication.
+        byte[] mTokenEscrow;
+
+        // Timestamp when hardware authentication occurred
+        private long mAuthenticatedTimeMs;
+
+        AuthSession(HashMap<Integer, Integer> modalities, IBinder token, long sessionId,
+                int userId, IBiometricServiceReceiver receiver, String opPackageName,
+                Bundle bundle, int callingUid, int callingPid, int callingUserId,
+                int modality, boolean requireConfirmation) {
+            mModalitiesWaiting = modalities;
+            mToken = token;
+            mSessionId = sessionId;
+            mUserId = userId;
+            mClientReceiver = receiver;
+            mOpPackageName = opPackageName;
+            mBundle = bundle;
+            mCallingUid = callingUid;
+            mCallingPid = callingPid;
+            mCallingUserId = callingUserId;
+            mModality = modality;
+            mRequireConfirmation = requireConfirmation;
+        }
+
+        boolean isCrypto() {
+            return mSessionId != 0;
+        }
+
+        boolean containsCookie(int cookie) {
+            if (mModalitiesWaiting != null && mModalitiesWaiting.containsValue(cookie)) {
+                return true;
+            }
+            if (mModalitiesMatched != null && mModalitiesMatched.containsValue(cookie)) {
+                return true;
+            }
+            return false;
+        }
+    }
+
+    private final class BiometricTaskStackListener extends TaskStackListener {
+        @Override
+        public void onTaskStackChanged() {
+            mHandler.sendEmptyMessage(MSG_ON_TASK_STACK_CHANGED);
+        }
+    }
+
     private final AppOpsManager mAppOps;
-    private final Handler mHandler;
     private final boolean mHasFeatureFingerprint;
     private final boolean mHasFeatureIris;
     private final boolean mHasFeatureFace;
     private final SettingObserver mSettingObserver;
     private final List<EnabledOnKeyguardCallback> mEnabledOnKeyguardCallbacks;
+    private final BiometricTaskStackListener mTaskStackListener = new BiometricTaskStackListener();
+    private final Random mRandom = new Random();
 
     private IFingerprintService mFingerprintService;
     private IFaceService mFaceService;
+    private IActivityTaskManager mActivityTaskManager;
+    private IStatusBarService mStatusBarService;
 
     // Get and cache the available authenticator (manager) classes. Used since aidl doesn't support
     // polymorphism :/
@@ -113,6 +230,108 @@
     // should be safe.
     private int mCurrentModality;
 
+    // The current authentication session, null if idle/done. We need to track both the current
+    // and pending sessions since errors may be sent to either.
+    private AuthSession mCurrentAuthSession;
+    private AuthSession mPendingAuthSession;
+
+    private final Handler mHandler = new Handler(Looper.getMainLooper()) {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_ON_TASK_STACK_CHANGED: {
+                    handleTaskStackChanged();
+                    break;
+                }
+
+                case MSG_ON_AUTHENTICATION_SUCCEEDED: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    handleAuthenticationSucceeded(
+                            (boolean) args.arg1 /* requireConfirmation */,
+                            (byte[]) args.arg2 /* token */);
+                    args.recycle();
+                    break;
+                }
+
+                case MSG_ON_AUTHENTICATION_FAILED: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    handleAuthenticationFailed(
+                            args.argi1 /* cookie */,
+                            (boolean) args.arg1 /* requireConfirmation */);
+                    args.recycle();
+                    break;
+                }
+
+                case MSG_ON_ERROR: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    handleOnError(
+                            args.argi1 /* cookie */,
+                            args.argi2 /* error */,
+                            (String) args.arg1 /* message */);
+                    args.recycle();
+                    break;
+                }
+
+                case MSG_ON_ACQUIRED: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    handleOnAcquired(
+                            args.argi1 /* acquiredInfo */,
+                            (String) args.arg1 /* message */);
+                    args.recycle();
+                    break;
+                }
+
+                case MSG_ON_DISMISSED: {
+                    handleOnDismissed(msg.arg1);
+                    break;
+                }
+
+                case MSG_ON_TRY_AGAIN_PRESSED: {
+                    handleOnTryAgainPressed();
+                    break;
+                }
+
+                case MSG_ON_READY_FOR_AUTHENTICATION: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    handleOnReadyForAuthentication(
+                            args.argi1 /* cookie */,
+                            (boolean) args.arg1 /* requireConfirmation */,
+                            args.argi2 /* userId */);
+                    args.recycle();
+                    break;
+                }
+
+                case MSG_AUTHENTICATE: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    handleAuthenticate(
+                            (IBinder) args.arg1 /* token */,
+                            (long) args.arg2 /* sessionId */,
+                            args.argi1 /* userid */,
+                            (IBiometricServiceReceiver) args.arg3 /* receiver */,
+                            (String) args.arg4 /* opPackageName */,
+                            (Bundle) args.arg5 /* bundle */,
+                            args.argi2 /* callingUid */,
+                            args.argi3 /* callingPid */,
+                            args.argi4 /* callingUserId */);
+                    args.recycle();
+                    break;
+                }
+
+                case MSG_CANCEL_AUTHENTICATION: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    handleCancelAuthentication(
+                            (IBinder) args.arg1 /* token */,
+                            (String) args.arg2 /* opPackageName */);
+                    args.recycle();
+                    break;
+                }
+
+                default:
+                    break;
+            }
+        }
+    };
+
     private final class Authenticator {
         int mType;
         BiometricAuthenticator mAuthenticator;
@@ -251,142 +470,62 @@
         }
     }
 
+    // Wrap the client's receiver so we can do things with the BiometricDialog first
+    private final IBiometricServiceReceiverInternal mInternalReceiver =
+            new IBiometricServiceReceiverInternal.Stub() {
+        @Override
+        public void onAuthenticationSucceeded(boolean requireConfirmation, byte[] token)
+                throws RemoteException {
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = requireConfirmation;
+            args.arg2 = token;
+            mHandler.obtainMessage(MSG_ON_AUTHENTICATION_SUCCEEDED, args).sendToTarget();
+        }
+
+        @Override
+        public void onAuthenticationFailed(int cookie, boolean requireConfirmation)
+                throws RemoteException {
+            SomeArgs args = SomeArgs.obtain();
+            args.argi1 = cookie;
+            args.arg1 = requireConfirmation;
+            mHandler.obtainMessage(MSG_ON_AUTHENTICATION_FAILED, args).sendToTarget();
+        }
+
+        @Override
+        public void onError(int cookie, int error, String message) throws RemoteException {
+            SomeArgs args = SomeArgs.obtain();
+            args.argi1 = cookie;
+            args.argi2 = error;
+            args.arg1 = message;
+            mHandler.obtainMessage(MSG_ON_ERROR, args).sendToTarget();
+        }
+
+        @Override
+        public void onAcquired(int acquiredInfo, String message) throws RemoteException {
+            SomeArgs args = SomeArgs.obtain();
+            args.argi1 = acquiredInfo;
+            args.arg1 = message;
+            mHandler.obtainMessage(MSG_ON_ACQUIRED, args).sendToTarget();
+        }
+
+        @Override
+        public void onDialogDismissed(int reason) throws RemoteException {
+            mHandler.obtainMessage(MSG_ON_DISMISSED, reason, 0 /* arg2 */).sendToTarget();
+        }
+
+        @Override
+        public void onTryAgainPressed() {
+            mHandler.sendEmptyMessage(MSG_ON_TRY_AGAIN_PRESSED);
+        }
+    };
+
+
     /**
      * This is just a pass-through service that wraps Fingerprint, Iris, Face services. This service
      * should not carry any state. The reality is we need to keep a tiny amount of state so that
      * cancelAuthentication() can go to the right place.
      */
     private final class BiometricServiceWrapper extends IBiometricService.Stub {
-
-        /**
-         * Authentication either just called and we have not transitioned to the CALLED state, or
-         * authentication terminated (success or error).
-         */
-        private static final int STATE_AUTH_IDLE = 0;
-        /**
-         * Authentication was called and we are waiting for the <Biometric>Services to return their
-         * cookies before starting the hardware and showing the BiometricPrompt.
-         */
-        private static final int STATE_AUTH_CALLED = 1;
-        /**
-         * Authentication started, BiometricPrompt is showing and the hardware is authenticating.
-         */
-        private static final int STATE_AUTH_STARTED = 2;
-        /**
-         * Authentication is paused, waiting for the user to press "try again" button. Only
-         * passive modalities such as Face or Iris should have this state. Note that for passive
-         * modalities, the HAL enters the idle state after onAuthenticated(false) which differs from
-         * fingerprint.
-         */
-        private static final int STATE_AUTH_PAUSED = 3;
-        /**
-         * Authentication is successful, but we're waiting for the user to press "confirm" button.
-         */
-        private static final int STATE_AUTH_PENDING_CONFIRM = 5;
-
-        final class AuthSession {
-            // Map of Authenticator/Cookie pairs. We expect to receive the cookies back from
-            // <Biometric>Services before we can start authenticating. Pairs that have been returned
-            // are moved to mModalitiesMatched.
-            final HashMap<Integer, Integer> mModalitiesWaiting;
-            // Pairs that have been matched.
-            final HashMap<Integer, Integer> mModalitiesMatched = new HashMap<>();
-
-            // The following variables are passed to authenticateInternal, which initiates the
-            // appropriate <Biometric>Services.
-            final IBinder mToken;
-            final long mSessionId;
-            final int mUserId;
-            // Original receiver from BiometricPrompt.
-            final IBiometricServiceReceiver mClientReceiver;
-            final String mOpPackageName;
-            // Info to be shown on BiometricDialog when all cookies are returned.
-            final Bundle mBundle;
-            final int mCallingUid;
-            final int mCallingPid;
-            final int mCallingUserId;
-            // Continue authentication with the same modality/modalities after "try again" is
-            // pressed
-            final int mModality;
-            final boolean mRequireConfirmation;
-
-            // The current state, which can be either idle, called, or started
-            private int mState = STATE_AUTH_IDLE;
-            // For explicit confirmation, do not send to keystore until the user has confirmed
-            // the authentication.
-            byte[] mTokenEscrow;
-
-            // Timestamp when hardware authentication occurred
-            private long mAuthenticatedTimeMs;
-
-            AuthSession(HashMap<Integer, Integer> modalities, IBinder token, long sessionId,
-                    int userId, IBiometricServiceReceiver receiver, String opPackageName,
-                    Bundle bundle, int callingUid, int callingPid, int callingUserId,
-                    int modality, boolean requireConfirmation) {
-                mModalitiesWaiting = modalities;
-                mToken = token;
-                mSessionId = sessionId;
-                mUserId = userId;
-                mClientReceiver = receiver;
-                mOpPackageName = opPackageName;
-                mBundle = bundle;
-                mCallingUid = callingUid;
-                mCallingPid = callingPid;
-                mCallingUserId = callingUserId;
-                mModality = modality;
-                mRequireConfirmation = requireConfirmation;
-            }
-
-            boolean isCrypto() {
-                return mSessionId != 0;
-            }
-
-            boolean containsCookie(int cookie) {
-                if (mModalitiesWaiting != null && mModalitiesWaiting.containsValue(cookie)) {
-                    return true;
-                }
-                if (mModalitiesMatched != null && mModalitiesMatched.containsValue(cookie)) {
-                    return true;
-                }
-                return false;
-            }
-        }
-
-        final class BiometricTaskStackListener extends TaskStackListener {
-            @Override
-            public void onTaskStackChanged() {
-                try {
-                    final List<ActivityManager.RunningTaskInfo> runningTasks =
-                            mActivityTaskManager.getTasks(1);
-                    if (!runningTasks.isEmpty()) {
-                        final String topPackage = runningTasks.get(0).topActivity.getPackageName();
-                        if (mCurrentAuthSession != null
-                                && !topPackage.contentEquals(mCurrentAuthSession.mOpPackageName)) {
-                            mStatusBarService.hideBiometricDialog();
-                            mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener);
-                            mCurrentAuthSession.mClientReceiver.onError(
-                                    BiometricConstants.BIOMETRIC_ERROR_CANCELED,
-                                    getContext().getString(
-                                            com.android.internal.R.string.biometric_error_canceled)
-                            );
-                            mCurrentAuthSession.mState = STATE_AUTH_IDLE;
-                            mCurrentAuthSession = null;
-                        }
-                    }
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Unable to get running tasks", e);
-                }
-            }
-        }
-
-        private final IActivityTaskManager mActivityTaskManager = getContext().getSystemService(
-                ActivityTaskManager.class).getService();
-        private final IStatusBarService mStatusBarService = IStatusBarService.Stub.asInterface(
-                ServiceManager.getService(Context.STATUS_BAR_SERVICE));
-        private final BiometricTaskStackListener mTaskStackListener =
-                new BiometricTaskStackListener();
-        private final Random mRandom = new Random();
-
         // TODO(b/123378871): Remove when moved.
         // When BiometricPrompt#setAllowDeviceCredentials is set to true, we need to store the
         // client (app) receiver. BiometricService internally launches CDCA which invokes
@@ -395,331 +534,15 @@
         // to this receiver.
         private IBiometricServiceReceiver mConfirmDeviceCredentialReceiver;
 
-        // The current authentication session, null if idle/done. We need to track both the current
-        // and pending sessions since errors may be sent to either.
-        private AuthSession mCurrentAuthSession;
-        private AuthSession mPendingAuthSession;
-
-        // Wrap the client's receiver so we can do things with the BiometricDialog first
-        private final IBiometricServiceReceiverInternal mInternalReceiver =
-                new IBiometricServiceReceiverInternal.Stub() {
-            @Override
-            public void onAuthenticationSucceeded(boolean requireConfirmation, byte[] token)
-                    throws RemoteException {
-                try {
-                    // Should never happen, log this to catch bad HAL behavior (e.g. auth succeeded
-                    // after user dismissed/canceled dialog).
-                    if (mCurrentAuthSession == null) {
-                        Slog.e(TAG, "onAuthenticationSucceeded(): Auth session is null");
-                        return;
-                    }
-
-                    if (!requireConfirmation) {
-                        mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener);
-                        KeyStore.getInstance().addAuthToken(token);
-                        mCurrentAuthSession.mClientReceiver.onAuthenticationSucceeded();
-                        mCurrentAuthSession.mState = STATE_AUTH_IDLE;
-                        mCurrentAuthSession = null;
-                    } else {
-                        mCurrentAuthSession.mAuthenticatedTimeMs = System.currentTimeMillis();
-                        // Store the auth token and submit it to keystore after the confirmation
-                        // button has been pressed.
-                        mCurrentAuthSession.mTokenEscrow = token;
-                        mCurrentAuthSession.mState = STATE_AUTH_PENDING_CONFIRM;
-                    }
-
-                    // Notify SysUI that the biometric has been authenticated. SysUI already knows
-                    // the implicit/explicit state and will react accordingly.
-                    mStatusBarService.onBiometricAuthenticated(true);
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Remote exception", e);
-                }
-            }
-
-            @Override
-            public void onAuthenticationFailed(int cookie, boolean requireConfirmation)
-                    throws RemoteException {
-                try {
-                    // Should never happen, log this to catch bad HAL behavior (e.g. auth succeeded
-                    // after user dismissed/canceled dialog).
-                    if (mCurrentAuthSession == null) {
-                        Slog.e(TAG, "onAuthenticationFailed(): Auth session is null");
-                        return;
-                    }
-
-                    mStatusBarService.onBiometricAuthenticated(false);
-
-                    // TODO: This logic will need to be updated if BP is multi-modal
-                    if ((mCurrentAuthSession.mModality & TYPE_FACE) != 0) {
-                        // Pause authentication. onBiometricAuthenticated(false) causes the
-                        // dialog to show a "try again" button for passive modalities.
-                        mCurrentAuthSession.mState = STATE_AUTH_PAUSED;
-                    }
-
-                    mCurrentAuthSession.mClientReceiver.onAuthenticationFailed();
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Remote exception", e);
-                }
-            }
-
-            @Override
-            public void onError(int cookie, int error, String message) throws RemoteException {
-                Slog.d(TAG, "Error: " + error + " cookie: " + cookie);
-                // Errors can either be from the current auth session or the pending auth session.
-                // The pending auth session may receive errors such as ERROR_LOCKOUT before
-                // it becomes the current auth session. Similarly, the current auth session may
-                // receive errors such as ERROR_CANCELED while the pending auth session is preparing
-                // to be started. Thus we must match error messages with their cookies to be sure
-                // of their intended receivers.
-                try {
-                    if (mCurrentAuthSession != null && mCurrentAuthSession.containsCookie(cookie)) {
-                        if (mCurrentAuthSession.mState == STATE_AUTH_STARTED) {
-                            mStatusBarService.onBiometricError(message);
-                            if (error == BiometricConstants.BIOMETRIC_ERROR_CANCELED) {
-                                    mActivityTaskManager.unregisterTaskStackListener(
-                                            mTaskStackListener);
-                                    mCurrentAuthSession.mClientReceiver.onError(error, message);
-                                    mCurrentAuthSession.mState = STATE_AUTH_IDLE;
-                                    mCurrentAuthSession = null;
-                                    mStatusBarService.hideBiometricDialog();
-                            } else {
-                                // Send errors after the dialog is dismissed.
-                                mHandler.postDelayed(() -> {
-                                    try {
-                                        if (mCurrentAuthSession != null) {
-                                            mActivityTaskManager.unregisterTaskStackListener(
-                                                    mTaskStackListener);
-                                            mCurrentAuthSession.mClientReceiver.onError(error,
-                                                    message);
-                                            mCurrentAuthSession.mState = STATE_AUTH_IDLE;
-                                            mCurrentAuthSession = null;
-                                        }
-                                    } catch (RemoteException e) {
-                                        Slog.e(TAG, "Remote exception", e);
-                                    }
-                                }, BiometricPrompt.HIDE_DIALOG_DELAY);
-                            }
-                        } else if (mCurrentAuthSession.mState == STATE_AUTH_PAUSED) {
-                            // In the "try again" state, we should forward canceled errors to
-                            // the client and and clean up.
-                            mCurrentAuthSession.mClientReceiver.onError(error, message);
-                            mStatusBarService.onBiometricError(message);
-                            mActivityTaskManager.unregisterTaskStackListener(
-                                    mTaskStackListener);
-                            mCurrentAuthSession.mState = STATE_AUTH_IDLE;
-                            mCurrentAuthSession = null;
-                        } else {
-                            Slog.e(TAG, "Impossible session error state: "
-                                    + mCurrentAuthSession.mState);
-                        }
-                    } else if (mPendingAuthSession != null
-                            && mPendingAuthSession.containsCookie(cookie)) {
-                        if (mPendingAuthSession.mState == STATE_AUTH_CALLED) {
-                            mPendingAuthSession.mClientReceiver.onError(error, message);
-                            mPendingAuthSession.mState = STATE_AUTH_IDLE;
-                            mPendingAuthSession = null;
-                        } else {
-                            Slog.e(TAG, "Impossible pending session error state: "
-                                    + mPendingAuthSession.mState);
-                        }
-                    }
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Remote exception", e);
-                }
-            }
-
-            @Override
-            public void onAcquired(int acquiredInfo, String message) throws RemoteException {
-                // Should never happen, log this to catch bad HAL behavior (e.g. auth succeeded
-                // after user dismissed/canceled dialog).
-                if (mCurrentAuthSession == null) {
-                    Slog.e(TAG, "onAcquired(): Auth session is null");
-                    return;
-                }
-
-                if (acquiredInfo != BiometricConstants.BIOMETRIC_ACQUIRED_GOOD) {
-                    try {
-                        mStatusBarService.onBiometricHelp(message);
-                    } catch (RemoteException e) {
-                        Slog.e(TAG, "Remote exception", e);
-                    }
-                }
-            }
-
-            @Override
-            public void onDialogDismissed(int reason) throws RemoteException {
-                if (mCurrentAuthSession == null) {
-                    Slog.e(TAG, "onDialogDismissed: " + reason + ", auth session null");
-                    return;
-                }
-
-                logDialogDismissed(reason);
-
-                if (reason != BiometricPrompt.DISMISSED_REASON_POSITIVE) {
-                    // Positive button is used by passive modalities as a "confirm" button,
-                    // do not send to client
-                    mCurrentAuthSession.mClientReceiver.onDialogDismissed(reason);
-                    // Cancel authentication. Skip the token/package check since we are cancelling
-                    // from system server. The interface is permission protected so this is fine.
-                    cancelInternal(null /* token */, null /* package */, false /* fromClient */);
-                }
-                if (reason == BiometricPrompt.DISMISSED_REASON_USER_CANCEL) {
-                    mCurrentAuthSession.mClientReceiver.onError(
-                            BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED,
-                            getContext().getString(
-                                    com.android.internal.R.string.biometric_error_user_canceled));
-                } else if (reason == BiometricPrompt.DISMISSED_REASON_POSITIVE) {
-                    // Have the service send the token to KeyStore, and send onAuthenticated
-                    // to the application
-                    KeyStore.getInstance().addAuthToken(mCurrentAuthSession.mTokenEscrow);
-                    mCurrentAuthSession.mClientReceiver.onAuthenticationSucceeded();
-                }
-                mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener);
-                mCurrentAuthSession.mState = STATE_AUTH_IDLE;
-                mCurrentAuthSession = null;
-            }
-
-            @Override
-            public void onTryAgainPressed() {
-                Slog.d(TAG, "onTryAgainPressed");
-                // No need to check permission, since it can only be invoked by SystemUI
-                // (or system server itself).
-                mHandler.post(() -> {
-                    authenticateInternal(mCurrentAuthSession.mToken,
-                            mCurrentAuthSession.mSessionId,
-                            mCurrentAuthSession.mUserId,
-                            mCurrentAuthSession.mClientReceiver,
-                            mCurrentAuthSession.mOpPackageName,
-                            mCurrentAuthSession.mBundle,
-                            mCurrentAuthSession.mCallingUid,
-                            mCurrentAuthSession.mCallingPid,
-                            mCurrentAuthSession.mCallingUserId,
-                            mCurrentAuthSession.mModality);
-                });
-            }
-
-            private void logDialogDismissed(int reason) {
-                if (reason == BiometricPrompt.DISMISSED_REASON_POSITIVE) {
-                    // Explicit auth, authentication confirmed.
-                    // Latency in this case is authenticated -> confirmed. <Biometric>Service
-                    // should have the first half (first acquired -> authenticated).
-                    final long latency = System.currentTimeMillis()
-                            - mCurrentAuthSession.mAuthenticatedTimeMs;
-
-                    if (LoggableMonitor.DEBUG) {
-                        Slog.v(LoggableMonitor.TAG, "Confirmed! Modality: " + statsModality()
-                                + ", User: " + mCurrentAuthSession.mUserId
-                                + ", IsCrypto: " + mCurrentAuthSession.isCrypto()
-                                + ", Client: " + BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT
-                                + ", RequireConfirmation: "
-                                    + mCurrentAuthSession.mRequireConfirmation
-                                + ", State: " + StatsLog.BIOMETRIC_AUTHENTICATED__STATE__CONFIRMED
-                                + ", Latency: " + latency);
-                    }
-
-                    StatsLog.write(StatsLog.BIOMETRIC_AUTHENTICATED,
-                            statsModality(),
-                            mCurrentAuthSession.mUserId,
-                            mCurrentAuthSession.isCrypto(),
-                            BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
-                            mCurrentAuthSession.mRequireConfirmation,
-                            StatsLog.BIOMETRIC_AUTHENTICATED__STATE__CONFIRMED,
-                            latency);
-                } else {
-                    int error = reason == BiometricPrompt.DISMISSED_REASON_NEGATIVE
-                            ? BiometricConstants.BIOMETRIC_ERROR_NEGATIVE_BUTTON
-                            : reason == BiometricPrompt.DISMISSED_REASON_USER_CANCEL
-                                    ? BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED
-                                    : 0;
-                    if (LoggableMonitor.DEBUG) {
-                        Slog.v(LoggableMonitor.TAG, "Dismissed! Modality: " + statsModality()
-                                + ", User: " + mCurrentAuthSession.mUserId
-                                + ", IsCrypto: " + mCurrentAuthSession.isCrypto()
-                                + ", Action: " + BiometricsProtoEnums.ACTION_AUTHENTICATE
-                                + ", Client: " + BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT
-                                + ", Error: " + error);
-                    }
-                    // Auth canceled
-                    StatsLog.write(StatsLog.BIOMETRIC_ERROR_OCCURRED,
-                            statsModality(),
-                            mCurrentAuthSession.mUserId,
-                            mCurrentAuthSession.isCrypto(),
-                            BiometricsProtoEnums.ACTION_AUTHENTICATE,
-                            BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
-                            error,
-                            0 /* vendorCode */);
-                }
-            }
-
-            private int statsModality() {
-                int modality = 0;
-                if (mCurrentAuthSession == null) {
-                    return BiometricsProtoEnums.MODALITY_UNKNOWN;
-                }
-                if ((mCurrentAuthSession.mModality & BiometricAuthenticator.TYPE_FINGERPRINT)
-                        != 0) {
-                    modality |= BiometricsProtoEnums.MODALITY_FINGERPRINT;
-                }
-                if ((mCurrentAuthSession.mModality & BiometricAuthenticator.TYPE_IRIS) != 0) {
-                    modality |= BiometricsProtoEnums.MODALITY_IRIS;
-                }
-                if ((mCurrentAuthSession.mModality & BiometricAuthenticator.TYPE_FACE) != 0) {
-                    modality |= BiometricsProtoEnums.MODALITY_FACE;
-                }
-                return modality;
-            }
-        };
-
         @Override // Binder call
         public void onReadyForAuthentication(int cookie, boolean requireConfirmation, int userId) {
             checkInternalPermission();
 
-            Iterator it = mPendingAuthSession.mModalitiesWaiting.entrySet().iterator();
-            while (it.hasNext()) {
-                Map.Entry<Integer, Integer> pair = (Map.Entry) it.next();
-                if (pair.getValue() == cookie) {
-                    mPendingAuthSession.mModalitiesMatched.put(pair.getKey(), pair.getValue());
-                    mPendingAuthSession.mModalitiesWaiting.remove(pair.getKey());
-                    Slog.d(TAG, "Matched cookie: " + cookie + ", "
-                            + mPendingAuthSession.mModalitiesWaiting.size() + " remaining");
-                    break;
-                }
-            }
-
-            if (mPendingAuthSession.mModalitiesWaiting.isEmpty()) {
-                final boolean continuing = mCurrentAuthSession != null &&
-                        (mCurrentAuthSession.mState == STATE_AUTH_PAUSED);
-
-                mCurrentAuthSession = mPendingAuthSession;
-                mPendingAuthSession = null;
-
-                mCurrentAuthSession.mState = STATE_AUTH_STARTED;
-                try {
-                    int modality = TYPE_NONE;
-                    it = mCurrentAuthSession.mModalitiesMatched.entrySet().iterator();
-                    while (it.hasNext()) {
-                        Map.Entry<Integer, Integer> pair = (Map.Entry) it.next();
-                        if (pair.getKey() == TYPE_FINGERPRINT) {
-                            mFingerprintService.startPreparedClient(pair.getValue());
-                        } else if (pair.getKey() == TYPE_IRIS) {
-                            Slog.e(TAG, "Iris unsupported");
-                        } else if (pair.getKey() == TYPE_FACE) {
-                            mFaceService.startPreparedClient(pair.getValue());
-                        } else {
-                            Slog.e(TAG, "Unknown modality: " + pair.getKey());
-                        }
-                        modality |= pair.getKey();
-                    }
-
-                    if (!continuing) {
-                        mStatusBarService.showBiometricDialog(mCurrentAuthSession.mBundle,
-                                mInternalReceiver, modality, requireConfirmation, userId);
-                        mActivityTaskManager.registerTaskStackListener(mTaskStackListener);
-                    }
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Remote exception", e);
-                }
-            }
+            SomeArgs args = SomeArgs.obtain();
+            args.argi1 = cookie;
+            args.arg1 = requireConfirmation;
+            args.argi2 = userId;
+            mHandler.obtainMessage(MSG_ON_READY_FOR_AUTHENTICATION, args).sendToTarget();
         }
 
         @Override // Binder call
@@ -754,25 +577,23 @@
                 checkInternalPermission();
                 // Set the default title if necessary
                 try {
-                    if (useDefaultTitle) {
-                        final List<ActivityManager.RunningAppProcessInfo> procs =
-                                ActivityManager.getService().getRunningAppProcesses();
-                        for (int i = 0; i < procs.size(); i++) {
-                            final ActivityManager.RunningAppProcessInfo info = procs.get(i);
-                            if (info.uid == callingUid
-                                    && info.importance == IMPORTANCE_FOREGROUND) {
-                                PackageManager pm = getContext().getPackageManager();
-                                final CharSequence label = pm.getApplicationLabel(
-                                        pm.getApplicationInfo(info.processName,
-                                                PackageManager.GET_META_DATA));
-                                final String title = getContext()
-                                        .getString(R.string.biometric_dialog_default_title, label);
-                                if (TextUtils.isEmpty(
-                                        bundle.getCharSequence(BiometricPrompt.KEY_TITLE))) {
-                                    bundle.putCharSequence(BiometricPrompt.KEY_TITLE, title);
-                                }
-                                break;
+                    final List<ActivityManager.RunningAppProcessInfo> procs =
+                            ActivityManager.getService().getRunningAppProcesses();
+                    for (int i = 0; i < procs.size(); i++) {
+                        final ActivityManager.RunningAppProcessInfo info = procs.get(i);
+                        if (info.uid == callingUid
+                                && info.importance == IMPORTANCE_FOREGROUND) {
+                            PackageManager pm = getContext().getPackageManager();
+                            final CharSequence label = pm.getApplicationLabel(
+                                    pm.getApplicationInfo(info.processName,
+                                            PackageManager.GET_META_DATA));
+                            final String title = getContext()
+                                    .getString(R.string.biometric_dialog_default_title, label);
+                            if (TextUtils.isEmpty(
+                                    bundle.getCharSequence(BiometricPrompt.KEY_TITLE))) {
+                                bundle.putCharSequence(BiometricPrompt.KEY_TITLE, title);
                             }
+                            break;
                         }
                     }
                 } catch (RemoteException e) {
@@ -792,7 +613,8 @@
                             KeyguardManager.class);
                     if (!kgm.isDeviceSecure()) {
                         try {
-                            receiver.onError(BiometricConstants.BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL,
+                            receiver.onError(
+                                    BiometricConstants.BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL,
                                     getContext().getString(
                                             R.string.biometric_error_device_not_secured));
                         } catch (RemoteException e) {
@@ -811,160 +633,63 @@
                 return;
             }
 
-            mHandler.post(() -> {
-                final Pair<Integer, Integer> result = checkAndGetBiometricModality(userId);
-                final int modality = result.first;
-                final int error = result.second;
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = token;
+            args.arg2 = sessionId;
+            args.argi1 = userId;
+            args.arg3 = receiver;
+            args.arg4 = opPackageName;
+            args.arg5 = bundle;
+            args.argi2 = callingUid;
+            args.argi3 = callingPid;
+            args.argi4 = callingUserId;
 
-                // Check for errors, notify callback, and return
-                if (error != BiometricConstants.BIOMETRIC_SUCCESS) {
-                    try {
-                        final String hardwareUnavailable =
-                                getContext().getString(R.string.biometric_error_hw_unavailable);
-                        switch (error) {
-                            case BiometricConstants.BIOMETRIC_ERROR_HW_NOT_PRESENT:
-                                receiver.onError(error, hardwareUnavailable);
-                                break;
-                            case BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE:
-                                receiver.onError(error, hardwareUnavailable);
-                                break;
-                            case BiometricConstants.BIOMETRIC_ERROR_NO_BIOMETRICS:
-                                receiver.onError(error,
-                                        getErrorString(modality, error, 0 /* vendorCode */));
-                                break;
-                            default:
-                                Slog.e(TAG, "Unhandled error");
-                                break;
-                        }
-                    } catch (RemoteException e) {
-                        Slog.e(TAG, "Unable to send error", e);
-                    }
-                    return;
-                }
-
-                mCurrentModality = modality;
-
-                // Start preparing for authentication. Authentication starts when
-                // all modalities requested have invoked onReadyForAuthentication.
-                authenticateInternal(token, sessionId, userId, receiver, opPackageName, bundle,
-                        callingUid, callingPid, callingUserId, modality);
-            });
+            mHandler.obtainMessage(MSG_AUTHENTICATE, args).sendToTarget();
         }
 
         @Override // Binder call
         public void onConfirmDeviceCredentialSuccess() {
             checkInternalPermission();
-            if (mConfirmDeviceCredentialReceiver == null) {
-                Slog.w(TAG, "onCDCASuccess null!");
-                return;
-            }
-            try {
-                mConfirmDeviceCredentialReceiver.onAuthenticationSucceeded();
-            } catch (RemoteException e) {
-                Slog.e(TAG, "RemoteException", e);
-            }
-            mConfirmDeviceCredentialReceiver = null;
+            mHandler.post(() -> {
+                if (mConfirmDeviceCredentialReceiver == null) {
+                    Slog.w(TAG, "onCDCASuccess null!");
+                    return;
+                }
+                try {
+                    mConfirmDeviceCredentialReceiver.onAuthenticationSucceeded();
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "RemoteException", e);
+                }
+                mConfirmDeviceCredentialReceiver = null;
+            });
         }
 
         @Override // Binder call
         public void onConfirmDeviceCredentialError(int error, String message) {
             checkInternalPermission();
-            if (mConfirmDeviceCredentialReceiver == null) {
-                Slog.w(TAG, "onCDCAError null! Error: " + error + " " + message);
-                return;
-            }
-            try {
-                mConfirmDeviceCredentialReceiver.onError(error, message);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "RemoteException", e);
-            }
-            mConfirmDeviceCredentialReceiver = null;
-        }
-
-        /**
-         * authenticate() (above) which is called from BiometricPrompt determines which
-         * modality/modalities to start authenticating with. authenticateInternal() should only be
-         * used for:
-         * 1) Preparing <Biometric>Services for authentication when BiometricPrompt#authenticate is,
-         *    invoked, shortly after which BiometricPrompt is shown and authentication starts
-         * 2) Preparing <Biometric>Services for authentication when BiometricPrompt is already shown
-         *    and the user has pressed "try again"
-         */
-        private void authenticateInternal(IBinder token, long sessionId, int userId,
-                IBiometricServiceReceiver receiver, String opPackageName, Bundle bundle,
-                int callingUid, int callingPid, int callingUserId, int modality) {
-            try {
-                boolean requireConfirmation = bundle.getBoolean(
-                        BiometricPrompt.KEY_REQUIRE_CONFIRMATION, true /* default */);
-                if ((modality & TYPE_FACE) != 0) {
-                    // Check if the user has forced confirmation to be required in Settings.
-                    requireConfirmation = requireConfirmation
-                            || mSettingObserver.getFaceAlwaysRequireConfirmation();
+            mHandler.post(() -> {
+                if (mConfirmDeviceCredentialReceiver == null) {
+                    Slog.w(TAG, "onCDCAError null! Error: " + error + " " + message);
+                    return;
                 }
-                // Generate random cookies to pass to the services that should prepare to start
-                // authenticating. Store the cookie here and wait for all services to "ack"
-                // with the cookie. Once all cookies are received, we can show the prompt
-                // and let the services start authenticating. The cookie should be non-zero.
-                final int cookie = mRandom.nextInt(Integer.MAX_VALUE - 1) + 1;
-                Slog.d(TAG, "Creating auth session. Modality: " + modality
-                        + ", cookie: " + cookie);
-                final HashMap<Integer, Integer> authenticators = new HashMap<>();
-                authenticators.put(modality, cookie);
-                mPendingAuthSession = new AuthSession(authenticators, token, sessionId, userId,
-                        receiver, opPackageName, bundle, callingUid, callingPid, callingUserId,
-                        modality, requireConfirmation);
-                mPendingAuthSession.mState = STATE_AUTH_CALLED;
-                // No polymorphism :(
-                if ((modality & TYPE_FINGERPRINT) != 0) {
-                    mFingerprintService.prepareForAuthentication(token, sessionId, userId,
-                            mInternalReceiver, opPackageName, cookie,
-                            callingUid, callingPid, callingUserId);
+                try {
+                    mConfirmDeviceCredentialReceiver.onError(error, message);
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "RemoteException", e);
                 }
-                if ((modality & TYPE_IRIS) != 0) {
-                    Slog.w(TAG, "Iris unsupported");
-                }
-                if ((modality & TYPE_FACE) != 0) {
-                    mFaceService.prepareForAuthentication(requireConfirmation,
-                            token, sessionId, userId, mInternalReceiver, opPackageName,
-                            cookie, callingUid, callingPid, callingUserId);
-                }
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Unable to start authentication", e);
-            }
+                mConfirmDeviceCredentialReceiver = null;
+            });
         }
 
         @Override // Binder call
         public void cancelAuthentication(IBinder token, String opPackageName)
                 throws RemoteException {
             checkPermission();
-            if (token == null || opPackageName == null) {
-                Slog.e(TAG, "Unable to cancel, one or more null arguments");
-                return;
-            }
 
-            // We need to check the current authenticators state. If we're pending confirm
-            // or idle, we need to dismiss the dialog and send an ERROR_CANCELED to the client,
-            // since we won't be getting an onError from the driver.
-            if (mCurrentAuthSession != null && mCurrentAuthSession.mState != STATE_AUTH_STARTED) {
-                mHandler.post(() -> {
-                    try {
-                        // Send error to client
-                        mCurrentAuthSession.mClientReceiver.onError(
-                                BiometricConstants.BIOMETRIC_ERROR_CANCELED,
-                                getContext().getString(
-                                        com.android.internal.R.string.biometric_error_user_canceled)
-                        );
-
-                        mCurrentAuthSession.mState = STATE_AUTH_IDLE;
-                        mCurrentAuthSession = null;
-                        mStatusBarService.hideBiometricDialog();
-                    } catch (RemoteException e) {
-                        Slog.e(TAG, "Remote exception", e);
-                    }
-                });
-            } else {
-                cancelInternal(token, opPackageName, true /* fromClient */);
-            }
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = token;
+            args.arg2 = opPackageName;
+            mHandler.obtainMessage(MSG_CANCEL_AUTHENTICATION, args).sendToTarget();
         }
 
         @Override // Binder call
@@ -1027,31 +752,6 @@
                 Binder.restoreCallingIdentity(ident);
             }
         }
-
-        void cancelInternal(IBinder token, String opPackageName, boolean fromClient) {
-            final int callingUid = Binder.getCallingUid();
-            final int callingPid = Binder.getCallingPid();
-            final int callingUserId = UserHandle.getCallingUserId();
-            mHandler.post(() -> {
-                try {
-                    // TODO: For multiple modalities, send a single ERROR_CANCELED only when all
-                    // drivers have canceled authentication.
-                    if ((mCurrentModality & TYPE_FINGERPRINT) != 0) {
-                        mFingerprintService.cancelAuthenticationFromService(token, opPackageName,
-                                callingUid, callingPid, callingUserId, fromClient);
-                    }
-                    if ((mCurrentModality & TYPE_IRIS) != 0) {
-                        Slog.w(TAG, "Iris unsupported");
-                    }
-                    if ((mCurrentModality & TYPE_FACE) != 0) {
-                        mFaceService.cancelAuthenticationFromService(token, opPackageName,
-                                callingUid, callingPid, callingUserId, fromClient);
-                    }
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Unable to cancel authentication");
-                }
-            });
-        }
     }
 
     private void checkAppOp(String opPackageName, int callingUid) {
@@ -1088,7 +788,6 @@
         super(context);
 
         mAppOps = context.getSystemService(AppOpsManager.class);
-        mHandler = new Handler(Looper.getMainLooper());
         mEnabledOnKeyguardCallbacks = new ArrayList<>();
         mSettingObserver = new SettingObserver(mHandler);
 
@@ -1123,6 +822,10 @@
                     ServiceManager.getService(Context.FACE_SERVICE));
         }
 
+        mActivityTaskManager = ActivityTaskManager.getService();
+        mStatusBarService = IStatusBarService.Stub.asInterface(
+                ServiceManager.getService(Context.STATUS_BAR_SERVICE));
+
         // Cache the authenticators
         for (int i = 0; i < FEATURE_ID.length; i++) {
             if (hasFeature(FEATURE_ID[i])) {
@@ -1259,4 +962,491 @@
                 return false;
         }
     }
+
+    private void logDialogDismissed(int reason) {
+        if (reason == BiometricPrompt.DISMISSED_REASON_POSITIVE) {
+            // Explicit auth, authentication confirmed.
+            // Latency in this case is authenticated -> confirmed. <Biometric>Service
+            // should have the first half (first acquired -> authenticated).
+            final long latency = System.currentTimeMillis()
+                    - mCurrentAuthSession.mAuthenticatedTimeMs;
+
+            if (LoggableMonitor.DEBUG) {
+                Slog.v(LoggableMonitor.TAG, "Confirmed! Modality: " + statsModality()
+                        + ", User: " + mCurrentAuthSession.mUserId
+                        + ", IsCrypto: " + mCurrentAuthSession.isCrypto()
+                        + ", Client: " + BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT
+                        + ", RequireConfirmation: "
+                        + mCurrentAuthSession.mRequireConfirmation
+                        + ", State: " + StatsLog.BIOMETRIC_AUTHENTICATED__STATE__CONFIRMED
+                        + ", Latency: " + latency);
+            }
+
+            StatsLog.write(StatsLog.BIOMETRIC_AUTHENTICATED,
+                    statsModality(),
+                    mCurrentAuthSession.mUserId,
+                    mCurrentAuthSession.isCrypto(),
+                    BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
+                    mCurrentAuthSession.mRequireConfirmation,
+                    StatsLog.BIOMETRIC_AUTHENTICATED__STATE__CONFIRMED,
+                    latency);
+        } else {
+            int error = reason == BiometricPrompt.DISMISSED_REASON_NEGATIVE
+                    ? BiometricConstants.BIOMETRIC_ERROR_NEGATIVE_BUTTON
+                    : reason == BiometricPrompt.DISMISSED_REASON_USER_CANCEL
+                            ? BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED
+                            : 0;
+            if (LoggableMonitor.DEBUG) {
+                Slog.v(LoggableMonitor.TAG, "Dismissed! Modality: " + statsModality()
+                        + ", User: " + mCurrentAuthSession.mUserId
+                        + ", IsCrypto: " + mCurrentAuthSession.isCrypto()
+                        + ", Action: " + BiometricsProtoEnums.ACTION_AUTHENTICATE
+                        + ", Client: " + BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT
+                        + ", Error: " + error);
+            }
+            // Auth canceled
+            StatsLog.write(StatsLog.BIOMETRIC_ERROR_OCCURRED,
+                    statsModality(),
+                    mCurrentAuthSession.mUserId,
+                    mCurrentAuthSession.isCrypto(),
+                    BiometricsProtoEnums.ACTION_AUTHENTICATE,
+                    BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
+                    error,
+                    0 /* vendorCode */);
+        }
+    }
+
+    private int statsModality() {
+        int modality = 0;
+        if (mCurrentAuthSession == null) {
+            return BiometricsProtoEnums.MODALITY_UNKNOWN;
+        }
+        if ((mCurrentAuthSession.mModality & BiometricAuthenticator.TYPE_FINGERPRINT)
+                != 0) {
+            modality |= BiometricsProtoEnums.MODALITY_FINGERPRINT;
+        }
+        if ((mCurrentAuthSession.mModality & BiometricAuthenticator.TYPE_IRIS) != 0) {
+            modality |= BiometricsProtoEnums.MODALITY_IRIS;
+        }
+        if ((mCurrentAuthSession.mModality & BiometricAuthenticator.TYPE_FACE) != 0) {
+            modality |= BiometricsProtoEnums.MODALITY_FACE;
+        }
+        return modality;
+    }
+
+    private void handleTaskStackChanged() {
+        try {
+            final List<ActivityManager.RunningTaskInfo> runningTasks =
+                    mActivityTaskManager.getTasks(1);
+            if (!runningTasks.isEmpty()) {
+                final String topPackage = runningTasks.get(0).topActivity.getPackageName();
+                if (mCurrentAuthSession != null
+                        && !topPackage.contentEquals(mCurrentAuthSession.mOpPackageName)) {
+                    mStatusBarService.hideBiometricDialog();
+                    mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener);
+                    mCurrentAuthSession.mClientReceiver.onError(
+                            BiometricConstants.BIOMETRIC_ERROR_CANCELED,
+                            getContext().getString(
+                                    com.android.internal.R.string.biometric_error_canceled)
+                    );
+                    mCurrentAuthSession.mState = STATE_AUTH_IDLE;
+                    mCurrentAuthSession = null;
+                }
+            }
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Unable to get running tasks", e);
+        }
+    }
+
+    private void handleAuthenticationSucceeded(boolean requireConfirmation, byte[] token) {
+
+        try {
+            // Should never happen, log this to catch bad HAL behavior (e.g. auth succeeded
+            // after user dismissed/canceled dialog).
+            if (mCurrentAuthSession == null) {
+                Slog.e(TAG, "onAuthenticationSucceeded(): Auth session is null");
+                return;
+            }
+
+            if (!requireConfirmation) {
+                mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener);
+                KeyStore.getInstance().addAuthToken(token);
+                mCurrentAuthSession.mClientReceiver.onAuthenticationSucceeded();
+                mCurrentAuthSession.mState = STATE_AUTH_IDLE;
+                mCurrentAuthSession = null;
+            } else {
+                mCurrentAuthSession.mAuthenticatedTimeMs = System.currentTimeMillis();
+                // Store the auth token and submit it to keystore after the confirmation
+                // button has been pressed.
+                mCurrentAuthSession.mTokenEscrow = token;
+                mCurrentAuthSession.mState = STATE_AUTH_PENDING_CONFIRM;
+            }
+
+            // Notify SysUI that the biometric has been authenticated. SysUI already knows
+            // the implicit/explicit state and will react accordingly.
+            mStatusBarService.onBiometricAuthenticated(true);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Remote exception", e);
+        }
+    }
+
+    private void handleAuthenticationFailed(int cookie, boolean requireConfirmation) {
+        try {
+            // Should never happen, log this to catch bad HAL behavior (e.g. auth succeeded
+            // after user dismissed/canceled dialog).
+            if (mCurrentAuthSession == null) {
+                Slog.e(TAG, "onAuthenticationFailed(): Auth session is null");
+                return;
+            }
+
+            mStatusBarService.onBiometricAuthenticated(false);
+
+            // TODO: This logic will need to be updated if BP is multi-modal
+            if ((mCurrentAuthSession.mModality & TYPE_FACE) != 0) {
+                // Pause authentication. onBiometricAuthenticated(false) causes the
+                // dialog to show a "try again" button for passive modalities.
+                mCurrentAuthSession.mState = STATE_AUTH_PAUSED;
+            }
+
+            mCurrentAuthSession.mClientReceiver.onAuthenticationFailed();
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Remote exception", e);
+        }
+    }
+
+    private void handleOnError(int cookie, int error, String message) {
+        Slog.d(TAG, "Error: " + error + " cookie: " + cookie);
+        // Errors can either be from the current auth session or the pending auth session.
+        // The pending auth session may receive errors such as ERROR_LOCKOUT before
+        // it becomes the current auth session. Similarly, the current auth session may
+        // receive errors such as ERROR_CANCELED while the pending auth session is preparing
+        // to be started. Thus we must match error messages with their cookies to be sure
+        // of their intended receivers.
+        try {
+            if (mCurrentAuthSession != null && mCurrentAuthSession.containsCookie(cookie)) {
+                if (mCurrentAuthSession.mState == STATE_AUTH_STARTED) {
+                    mStatusBarService.onBiometricError(message);
+                    if (error == BiometricConstants.BIOMETRIC_ERROR_CANCELED) {
+                        mActivityTaskManager.unregisterTaskStackListener(
+                                mTaskStackListener);
+                        mCurrentAuthSession.mClientReceiver.onError(error, message);
+                        mCurrentAuthSession.mState = STATE_AUTH_IDLE;
+                        mCurrentAuthSession = null;
+                        mStatusBarService.hideBiometricDialog();
+                    } else {
+                        // Send errors after the dialog is dismissed.
+                        mHandler.postDelayed(() -> {
+                            try {
+                                if (mCurrentAuthSession != null) {
+                                    mActivityTaskManager.unregisterTaskStackListener(
+                                            mTaskStackListener);
+                                    mCurrentAuthSession.mClientReceiver.onError(error,
+                                            message);
+                                    mCurrentAuthSession.mState = STATE_AUTH_IDLE;
+                                    mCurrentAuthSession = null;
+                                }
+                            } catch (RemoteException e) {
+                                Slog.e(TAG, "Remote exception", e);
+                            }
+                        }, BiometricPrompt.HIDE_DIALOG_DELAY);
+                    }
+                } else if (mCurrentAuthSession.mState == STATE_AUTH_PAUSED) {
+                    // In the "try again" state, we should forward canceled errors to
+                    // the client and and clean up.
+                    mCurrentAuthSession.mClientReceiver.onError(error, message);
+                    mStatusBarService.onBiometricError(message);
+                    mActivityTaskManager.unregisterTaskStackListener(
+                            mTaskStackListener);
+                    mCurrentAuthSession.mState = STATE_AUTH_IDLE;
+                    mCurrentAuthSession = null;
+                } else {
+                    Slog.e(TAG, "Impossible session error state: "
+                            + mCurrentAuthSession.mState);
+                }
+            } else if (mPendingAuthSession != null
+                    && mPendingAuthSession.containsCookie(cookie)) {
+                if (mPendingAuthSession.mState == STATE_AUTH_CALLED) {
+                    mPendingAuthSession.mClientReceiver.onError(error, message);
+                    mPendingAuthSession.mState = STATE_AUTH_IDLE;
+                    mPendingAuthSession = null;
+                } else {
+                    Slog.e(TAG, "Impossible pending session error state: "
+                            + mPendingAuthSession.mState);
+                }
+            }
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Remote exception", e);
+        }
+    }
+
+    private void handleOnAcquired(int acquiredInfo, String message) {
+        // Should never happen, log this to catch bad HAL behavior (e.g. auth succeeded
+        // after user dismissed/canceled dialog).
+        if (mCurrentAuthSession == null) {
+            Slog.e(TAG, "onAcquired(): Auth session is null");
+            return;
+        }
+
+        if (acquiredInfo != BiometricConstants.BIOMETRIC_ACQUIRED_GOOD) {
+            try {
+                mStatusBarService.onBiometricHelp(message);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote exception", e);
+            }
+        }
+    }
+
+    private void handleOnDismissed(int reason) {
+        if (mCurrentAuthSession == null) {
+            Slog.e(TAG, "onDialogDismissed: " + reason + ", auth session null");
+            return;
+        }
+
+        logDialogDismissed(reason);
+
+        try {
+            if (reason != BiometricPrompt.DISMISSED_REASON_POSITIVE) {
+                // Positive button is used by passive modalities as a "confirm" button,
+                // do not send to client
+                mCurrentAuthSession.mClientReceiver.onDialogDismissed(reason);
+                // Cancel authentication. Skip the token/package check since we are cancelling
+                // from system server. The interface is permission protected so this is fine.
+                cancelInternal(null /* token */, null /* package */, false /* fromClient */);
+            }
+            if (reason == BiometricPrompt.DISMISSED_REASON_USER_CANCEL) {
+                mCurrentAuthSession.mClientReceiver.onError(
+                        BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED,
+                        getContext().getString(
+                                com.android.internal.R.string.biometric_error_user_canceled));
+            } else if (reason == BiometricPrompt.DISMISSED_REASON_POSITIVE) {
+                // Have the service send the token to KeyStore, and send onAuthenticated
+                // to the application
+                KeyStore.getInstance().addAuthToken(mCurrentAuthSession.mTokenEscrow);
+                mCurrentAuthSession.mClientReceiver.onAuthenticationSucceeded();
+            }
+            mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener);
+            mCurrentAuthSession.mState = STATE_AUTH_IDLE;
+            mCurrentAuthSession = null;
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Remote exception", e);
+        }
+    }
+
+    private void handleOnTryAgainPressed() {
+        Slog.d(TAG, "onTryAgainPressed");
+        // No need to check permission, since it can only be invoked by SystemUI
+        // (or system server itself).
+        authenticateInternal(mCurrentAuthSession.mToken,
+                mCurrentAuthSession.mSessionId,
+                mCurrentAuthSession.mUserId,
+                mCurrentAuthSession.mClientReceiver,
+                mCurrentAuthSession.mOpPackageName,
+                mCurrentAuthSession.mBundle,
+                mCurrentAuthSession.mCallingUid,
+                mCurrentAuthSession.mCallingPid,
+                mCurrentAuthSession.mCallingUserId,
+                mCurrentAuthSession.mModality);
+    }
+
+    private void handleOnReadyForAuthentication(int cookie, boolean requireConfirmation,
+            int userId) {
+        Iterator it = mPendingAuthSession.mModalitiesWaiting.entrySet().iterator();
+        while (it.hasNext()) {
+            Map.Entry<Integer, Integer> pair = (Map.Entry) it.next();
+            if (pair.getValue() == cookie) {
+                mPendingAuthSession.mModalitiesMatched.put(pair.getKey(), pair.getValue());
+                mPendingAuthSession.mModalitiesWaiting.remove(pair.getKey());
+                Slog.d(TAG, "Matched cookie: " + cookie + ", "
+                        + mPendingAuthSession.mModalitiesWaiting.size() + " remaining");
+                break;
+            }
+        }
+
+        if (mPendingAuthSession.mModalitiesWaiting.isEmpty()) {
+            final boolean continuing = mCurrentAuthSession != null
+                    && mCurrentAuthSession.mState == STATE_AUTH_PAUSED;
+
+            mCurrentAuthSession = mPendingAuthSession;
+            mPendingAuthSession = null;
+
+            mCurrentAuthSession.mState = STATE_AUTH_STARTED;
+            try {
+                int modality = TYPE_NONE;
+                it = mCurrentAuthSession.mModalitiesMatched.entrySet().iterator();
+                while (it.hasNext()) {
+                    Map.Entry<Integer, Integer> pair = (Map.Entry) it.next();
+                    if (pair.getKey() == TYPE_FINGERPRINT) {
+                        mFingerprintService.startPreparedClient(pair.getValue());
+                    } else if (pair.getKey() == TYPE_IRIS) {
+                        Slog.e(TAG, "Iris unsupported");
+                    } else if (pair.getKey() == TYPE_FACE) {
+                        mFaceService.startPreparedClient(pair.getValue());
+                    } else {
+                        Slog.e(TAG, "Unknown modality: " + pair.getKey());
+                    }
+                    modality |= pair.getKey();
+                }
+
+                if (!continuing) {
+                    mStatusBarService.showBiometricDialog(mCurrentAuthSession.mBundle,
+                            mInternalReceiver, modality, requireConfirmation, userId);
+                    mActivityTaskManager.registerTaskStackListener(mTaskStackListener);
+                }
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote exception", e);
+            }
+        }
+    }
+
+    private void handleAuthenticate(IBinder token, long sessionId, int userId,
+            IBiometricServiceReceiver receiver, String opPackageName, Bundle bundle,
+            int callingUid, int callingPid, int callingUserId) {
+
+        mHandler.post(() -> {
+            final Pair<Integer, Integer> result = checkAndGetBiometricModality(userId);
+            final int modality = result.first;
+            final int error = result.second;
+
+            // Check for errors, notify callback, and return
+            if (error != BiometricConstants.BIOMETRIC_SUCCESS) {
+                try {
+                    final String hardwareUnavailable =
+                            getContext().getString(R.string.biometric_error_hw_unavailable);
+                    switch (error) {
+                        case BiometricConstants.BIOMETRIC_ERROR_HW_NOT_PRESENT:
+                            receiver.onError(error, hardwareUnavailable);
+                            break;
+                        case BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE:
+                            receiver.onError(error, hardwareUnavailable);
+                            break;
+                        case BiometricConstants.BIOMETRIC_ERROR_NO_BIOMETRICS:
+                            receiver.onError(error,
+                                    getErrorString(modality, error, 0 /* vendorCode */));
+                            break;
+                        default:
+                            Slog.e(TAG, "Unhandled error");
+                            break;
+                    }
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "Unable to send error", e);
+                }
+                return;
+            }
+
+            mCurrentModality = modality;
+
+            // Start preparing for authentication. Authentication starts when
+            // all modalities requested have invoked onReadyForAuthentication.
+            authenticateInternal(token, sessionId, userId, receiver, opPackageName, bundle,
+                    callingUid, callingPid, callingUserId, modality);
+        });
+    }
+
+    /**
+     * authenticate() (above) which is called from BiometricPrompt determines which
+     * modality/modalities to start authenticating with. authenticateInternal() should only be
+     * used for:
+     * 1) Preparing <Biometric>Services for authentication when BiometricPrompt#authenticate is,
+     *    invoked, shortly after which BiometricPrompt is shown and authentication starts
+     * 2) Preparing <Biometric>Services for authentication when BiometricPrompt is already shown
+     *    and the user has pressed "try again"
+     */
+    private void authenticateInternal(IBinder token, long sessionId, int userId,
+            IBiometricServiceReceiver receiver, String opPackageName, Bundle bundle,
+            int callingUid, int callingPid, int callingUserId, int modality) {
+        try {
+            boolean requireConfirmation = bundle.getBoolean(
+                    BiometricPrompt.KEY_REQUIRE_CONFIRMATION, true /* default */);
+            if ((modality & TYPE_FACE) != 0) {
+                // Check if the user has forced confirmation to be required in Settings.
+                requireConfirmation = requireConfirmation
+                        || mSettingObserver.getFaceAlwaysRequireConfirmation();
+            }
+            // Generate random cookies to pass to the services that should prepare to start
+            // authenticating. Store the cookie here and wait for all services to "ack"
+            // with the cookie. Once all cookies are received, we can show the prompt
+            // and let the services start authenticating. The cookie should be non-zero.
+            final int cookie = mRandom.nextInt(Integer.MAX_VALUE - 1) + 1;
+            Slog.d(TAG, "Creating auth session. Modality: " + modality
+                    + ", cookie: " + cookie);
+            final HashMap<Integer, Integer> authenticators = new HashMap<>();
+            authenticators.put(modality, cookie);
+            mPendingAuthSession = new AuthSession(authenticators, token, sessionId, userId,
+                    receiver, opPackageName, bundle, callingUid, callingPid, callingUserId,
+                    modality, requireConfirmation);
+            mPendingAuthSession.mState = STATE_AUTH_CALLED;
+            // No polymorphism :(
+            if ((modality & TYPE_FINGERPRINT) != 0) {
+                mFingerprintService.prepareForAuthentication(token, sessionId, userId,
+                        mInternalReceiver, opPackageName, cookie,
+                        callingUid, callingPid, callingUserId);
+            }
+            if ((modality & TYPE_IRIS) != 0) {
+                Slog.w(TAG, "Iris unsupported");
+            }
+            if ((modality & TYPE_FACE) != 0) {
+                mFaceService.prepareForAuthentication(requireConfirmation,
+                        token, sessionId, userId, mInternalReceiver, opPackageName,
+                        cookie, callingUid, callingPid, callingUserId);
+            }
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Unable to start authentication", e);
+        }
+    }
+
+    private void handleCancelAuthentication(IBinder token, String opPackageName) {
+        if (token == null || opPackageName == null) {
+            Slog.e(TAG, "Unable to cancel, one or more null arguments");
+            return;
+        }
+
+        // We need to check the current authenticators state. If we're pending confirm
+        // or idle, we need to dismiss the dialog and send an ERROR_CANCELED to the client,
+        // since we won't be getting an onError from the driver.
+        if (mCurrentAuthSession != null && mCurrentAuthSession.mState != STATE_AUTH_STARTED) {
+            try {
+                // Send error to client
+                mCurrentAuthSession.mClientReceiver.onError(
+                        BiometricConstants.BIOMETRIC_ERROR_CANCELED,
+                        getContext().getString(
+                                com.android.internal.R.string.biometric_error_user_canceled)
+                );
+
+                mCurrentAuthSession.mState = STATE_AUTH_IDLE;
+                mCurrentAuthSession = null;
+                mStatusBarService.hideBiometricDialog();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote exception", e);
+            }
+        } else {
+            cancelInternal(token, opPackageName, true /* fromClient */);
+        }
+    }
+
+
+    void cancelInternal(IBinder token, String opPackageName, boolean fromClient) {
+        final int callingUid = Binder.getCallingUid();
+        final int callingPid = Binder.getCallingPid();
+        final int callingUserId = UserHandle.getCallingUserId();
+        mHandler.post(() -> {
+            try {
+                // TODO: For multiple modalities, send a single ERROR_CANCELED only when all
+                // drivers have canceled authentication.
+                if ((mCurrentModality & TYPE_FINGERPRINT) != 0) {
+                    mFingerprintService.cancelAuthenticationFromService(token, opPackageName,
+                            callingUid, callingPid, callingUserId, fromClient);
+                }
+                if ((mCurrentModality & TYPE_IRIS) != 0) {
+                    Slog.w(TAG, "Iris unsupported");
+                }
+                if ((mCurrentModality & TYPE_FACE) != 0) {
+                    mFaceService.cancelAuthenticationFromService(token, opPackageName,
+                            callingUid, callingPid, callingUserId, fromClient);
+                }
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Unable to cancel authentication");
+            }
+        });
+    }
+
 }
diff --git a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
index ebb9e06..3e48445 100644
--- a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
+++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
@@ -1223,6 +1223,9 @@
                     BiometricsProtoEnums.ISSUE_UNKNOWN_TEMPLATE_ENROLLED_HAL);
         } else {
             clearEnumerateState();
+            if (mPendingClient != null) {
+                startClient(mPendingClient, false /* initiatedByClient */);
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/display/color/ColorDisplayService.java b/services/core/java/com/android/server/display/color/ColorDisplayService.java
index 23117760..45567e5 100644
--- a/services/core/java/com/android/server/display/color/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/color/ColorDisplayService.java
@@ -402,6 +402,10 @@
         cr.registerContentObserver(Secure.getUriFor(Secure.DISPLAY_WHITE_BALANCE_ENABLED),
                 false /* notifyForDescendants */, mContentObserver, mCurrentUser);
 
+        // Apply the accessibility settings first, since they override most other settings.
+        onAccessibilityInversionChanged();
+        onAccessibilityDaltonizerChanged();
+
         // Set the color mode, if valid, and immediately apply the updated tint matrix based on the
         // existing activated state. This ensures consistency of tint across the color mode change.
         onDisplayColorModeChanged(getColorModeInternal());
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 150303a..647e952 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -231,7 +231,8 @@
             Context.BIND_AUTO_CREATE
             | Context.BIND_TREAT_LIKE_ACTIVITY
             | Context.BIND_FOREGROUND_SERVICE
-            | Context.BIND_SHOWING_UI;
+            | Context.BIND_SHOWING_UI
+            | Context.BIND_SCHEDULE_LIKE_TOP_APP;
 
     @Retention(SOURCE)
     @IntDef({HardKeyboardBehavior.WIRELESS_AFFORDANCE, HardKeyboardBehavior.WIRED_AFFORDANCE})
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index cefe583..14b7301 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -2494,24 +2494,33 @@
             }
         }
 
-        // The expensive check last: validate that the defined package+service is
+        // The expensive check: validate that the defined package+service is
         // still present & viable.
-        final boolean componentPresent;
+        final ServiceInfo service;
         try {
-            componentPresent = (AppGlobals.getPackageManager().getServiceInfo(
+            service = AppGlobals.getPackageManager().getServiceInfo(
                     job.getServiceComponent(), PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
-                    job.getUserId()) != null);
+                    job.getUserId());
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }
 
-        if (DEBUG) {
-            Slog.v(TAG, "isReadyToBeExecutedLocked: " + job.toShortString()
-                    + " componentPresent=" + componentPresent);
+        if (service == null) {
+            if (DEBUG) {
+                Slog.v(TAG, "isReadyToBeExecutedLocked: " + job.toShortString()
+                        + " component not present");
+            }
+            return false;
         }
 
         // Everything else checked out so far, so this is the final yes/no check
-        return componentPresent;
+        final boolean appIsBad = mActivityManagerInternal.isAppBad(service.applicationInfo);
+        if (DEBUG) {
+            if (appIsBad) {
+                Slog.i(TAG, "App is bad for " + job.toShortString() + " so not runnable");
+            }
+        }
+        return !appIsBad;
     }
 
     private void evaluateControllerStatesLocked(final JobStatus job) {
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index a53ab84..293813a 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -2699,6 +2699,14 @@
         }
     }
 
+    @Override
+    public boolean hasPendingEscrowToken(int userId) {
+        checkPasswordReadPermission(userId);
+        synchronized (mSpManager) {
+            return !mSpManager.getPendingTokensForUser(userId).isEmpty();
+        }
+    }
+
     private boolean removeEscrowToken(long handle, int userId) {
         synchronized (mSpManager) {
             if (handle == getSyntheticPasswordHandleLocked(userId)) {
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
index 142ad53..1ba0e8c 100644
--- a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
@@ -751,7 +751,7 @@
 
     /**
      * Create a token based Synthetic password for the given user.
-     * @return
+     * @return the handle of the token
      */
     public long createTokenBasedSyntheticPassword(byte[] token, int userId,
             @Nullable EscrowTokenStateChangeCallback changeCallback) {
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 152cf7f..7b691b4 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -24,17 +24,18 @@
 import android.media.AudioManagerInternal;
 import android.media.AudioSystem;
 import android.media.MediaMetadata;
+import android.media.MediaParceledListSlice;
 import android.media.Rating;
 import android.media.VolumeProvider;
 import android.media.session.ControllerCallbackLink;
-import android.media.session.ControllerLink;
+import android.media.session.ISession;
+import android.media.session.ISessionController;
 import android.media.session.MediaController;
 import android.media.session.MediaController.PlaybackInfo;
 import android.media.session.MediaSession;
 import android.media.session.MediaSession.QueueItem;
 import android.media.session.PlaybackState;
 import android.media.session.SessionCallbackLink;
-import android.media.session.SessionLink;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
@@ -44,6 +45,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.Process;
+import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.SystemClock;
 import android.util.Log;
@@ -78,9 +80,9 @@
     private final String mPackageName;
     private final String mTag;
     private final Bundle mSessionInfo;
-    private final ControllerLink mController;
+    private final ControllerStub mController;
     private final MediaSession.Token mSessionToken;
-    private final SessionLink mSession;
+    private final SessionStub mSession;
     private final SessionCb mSessionCb;
     private final MediaSessionService.ServiceImpl mService;
     private final Context mContext;
@@ -130,9 +132,9 @@
         mPackageName = ownerPackageName;
         mTag = tag;
         mSessionInfo = sessionInfo;
-        mController = new ControllerLink(new ControllerStub());
+        mController = new ControllerStub();
         mSessionToken = new MediaSession.Token(mController);
-        mSession = new SessionLink(new SessionStub());
+        mSession = new SessionStub();
         mSessionCb = new SessionCb(cb);
         mService = service;
         mContext = mService.getContext();
@@ -143,20 +145,20 @@
     }
 
     /**
-     * Get the session link for the {@link MediaSession}.
+     * Get the session binder for the {@link MediaSession}.
      *
-     * @return The session link apps talk to.
+     * @return The session binder apps talk to.
      */
-    public SessionLink getSessionBinder() {
+    public ISession getSessionBinder() {
         return mSession;
     }
 
     /**
-     * Get the controller link for the {@link MediaController}.
+     * Get the controller binder for the {@link MediaController}.
      *
-     * @return The controller link apps talk to.
+     * @return The controller binder apps talk to.
      */
-    public ControllerLink getControllerLink() {
+    public ISessionController getControllerBinder() {
         return mController;
     }
 
@@ -817,9 +819,9 @@
         }
     };
 
-    private final class SessionStub extends SessionLink.SessionStub {
+    private final class SessionStub extends ISession.Stub {
         @Override
-        public void destroySession() {
+        public void destroySession() throws RemoteException {
             final long token = Binder.clearCallingIdentity();
             try {
                 mService.destroySession(MediaSessionRecord.this);
@@ -829,18 +831,18 @@
         }
 
         @Override
-        public void sendEvent(String event, Bundle data) {
+        public void sendEvent(String event, Bundle data) throws RemoteException {
             mHandler.post(MessageHandler.MSG_SEND_EVENT, event,
                     data == null ? null : new Bundle(data));
         }
 
         @Override
-        public ControllerLink getController() {
+        public ISessionController getController() throws RemoteException {
             return mController;
         }
 
         @Override
-        public void setActive(boolean active) {
+        public void setActive(boolean active) throws RemoteException {
             mIsActive = active;
             final long token = Binder.clearCallingIdentity();
             try {
@@ -852,7 +854,7 @@
         }
 
         @Override
-        public void setFlags(int flags) {
+        public void setFlags(int flags) throws RemoteException {
             if ((flags & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY) != 0) {
                 int pid = Binder.getCallingPid();
                 int uid = Binder.getCallingUid();
@@ -871,7 +873,7 @@
         }
 
         @Override
-        public void setMediaButtonReceiver(PendingIntent pi) {
+        public void setMediaButtonReceiver(PendingIntent pi) throws RemoteException {
             mMediaButtonReceiver = pi;
             final long token = Binder.clearCallingIdentity();
             try {
@@ -882,12 +884,13 @@
         }
 
         @Override
-        public void setLaunchPendingIntent(PendingIntent pi) {
+        public void setLaunchPendingIntent(PendingIntent pi) throws RemoteException {
             mLaunchIntent = pi;
         }
 
         @Override
-        public void setMetadata(MediaMetadata metadata, long duration, String metadataDescription) {
+        public void setMetadata(MediaMetadata metadata, long duration, String metadataDescription)
+                throws RemoteException {
             synchronized (mLock) {
                 MediaMetadata temp = metadata == null ? null : new MediaMetadata.Builder(metadata)
                         .build();
@@ -905,7 +908,7 @@
         }
 
         @Override
-        public void setPlaybackState(PlaybackState state) {
+        public void setPlaybackState(PlaybackState state) throws RemoteException {
             int oldState = mPlaybackState == null
                     ? PlaybackState.STATE_NONE : mPlaybackState.getState();
             int newState = state == null
@@ -923,21 +926,21 @@
         }
 
         @Override
-        public void setQueue(List<QueueItem> queue) {
+        public void setQueue(MediaParceledListSlice queue) throws RemoteException {
             synchronized (mLock) {
-                mQueue = queue;
+                mQueue = queue == null ? null : (List<QueueItem>) queue.getList();
             }
             mHandler.post(MessageHandler.MSG_UPDATE_QUEUE);
         }
 
         @Override
-        public void setQueueTitle(CharSequence title) {
+        public void setQueueTitle(CharSequence title) throws RemoteException {
             mQueueTitle = title;
             mHandler.post(MessageHandler.MSG_UPDATE_QUEUE_TITLE);
         }
 
         @Override
-        public void setExtras(Bundle extras) {
+        public void setExtras(Bundle extras) throws RemoteException {
             synchronized (mLock) {
                 mExtras = extras == null ? null : new Bundle(extras);
             }
@@ -945,18 +948,18 @@
         }
 
         @Override
-        public void setRatingType(int type) {
+        public void setRatingType(int type) throws RemoteException {
             mRatingType = type;
         }
 
         @Override
-        public void setCurrentVolume(int volume) {
+        public void setCurrentVolume(int volume) throws RemoteException {
             mCurrentVolume = volume;
             mHandler.post(MessageHandler.MSG_UPDATE_VOLUME);
         }
 
         @Override
-        public void setPlaybackToLocal(AudioAttributes attributes) {
+        public void setPlaybackToLocal(AudioAttributes attributes) throws RemoteException {
             boolean typeChanged;
             synchronized (mLock) {
                 typeChanged = mVolumeType == PlaybackInfo.PLAYBACK_TYPE_REMOTE;
@@ -979,7 +982,7 @@
         }
 
         @Override
-        public void setPlaybackToRemote(int control, int max) {
+        public void setPlaybackToRemote(int control, int max) throws RemoteException {
             boolean typeChanged;
             synchronized (mLock) {
                 typeChanged = mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL;
@@ -1248,7 +1251,7 @@
         }
     }
 
-    class ControllerStub extends ControllerLink.ControllerStub {
+    class ControllerStub extends ISessionController.Stub {
         @Override
         public void sendCommand(String packageName, ControllerCallbackLink caller,
                 String command, Bundle args, ResultReceiver cb) {
@@ -1488,9 +1491,9 @@
         }
 
         @Override
-        public List<QueueItem> getQueue() {
+        public MediaParceledListSlice getQueue() {
             synchronized (mLock) {
-                return mQueue;
+                return mQueue == null ? null : new MediaParceledListSlice<>(mQueue);
             }
         }
 
diff --git a/services/core/java/com/android/server/media/MediaSessionServiceImpl.java b/services/core/java/com/android/server/media/MediaSessionServiceImpl.java
index 94f289f2..7c8dc74 100644
--- a/services/core/java/com/android/server/media/MediaSessionServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaSessionServiceImpl.java
@@ -49,12 +49,12 @@
 import android.media.session.ICallback;
 import android.media.session.IOnMediaKeyListener;
 import android.media.session.IOnVolumeKeyLongPressListener;
+import android.media.session.ISession;
 import android.media.session.ISession2TokensListener;
 import android.media.session.ISessionManager;
 import android.media.session.MediaSession;
 import android.media.session.MediaSessionManager;
 import android.media.session.SessionCallbackLink;
-import android.media.session.SessionLink;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
@@ -1001,7 +1001,7 @@
         private boolean mVoiceButtonHandled = false;
 
         @Override
-        public SessionLink createSession(String packageName, SessionCallbackLink cb, String tag,
+        public ISession createSession(String packageName, SessionCallbackLink cb, String tag,
                 Bundle sessionInfo, int userId) throws RemoteException {
             final int pid = Binder.getCallingPid();
             final int uid = Binder.getCallingUid();
diff --git a/services/core/java/com/android/server/media/MediaSessionStack.java b/services/core/java/com/android/server/media/MediaSessionStack.java
index 9ba50ee..a5e7d8e 100644
--- a/services/core/java/com/android/server/media/MediaSessionStack.java
+++ b/services/core/java/com/android/server/media/MediaSessionStack.java
@@ -144,7 +144,7 @@
      */
     public MediaSessionRecord getMediaSessionRecord(MediaSession.Token sessionToken) {
         for (MediaSessionRecord record : mSessions) {
-            if (Objects.equals(record.getControllerLink(), sessionToken.getControllerLink())) {
+            if (Objects.equals(record.getControllerBinder(), sessionToken.getBinder())) {
                 return record;
             }
         }
diff --git a/services/core/java/com/android/server/media/OWNERS b/services/core/java/com/android/server/media/OWNERS
index 8adea0e..4bc9373 100644
--- a/services/core/java/com/android/server/media/OWNERS
+++ b/services/core/java/com/android/server/media/OWNERS
@@ -1,4 +1,6 @@
-lajos@google.com
 elaurent@google.com
-sungsoo@google.com
+hdmoon@google.com
+insun@google.com
 jaewan@google.com
+lajos@google.com
+sungsoo@google.com
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 88e697c..4a215cf 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2504,15 +2504,20 @@
         }
 
         @Override
-        public boolean canNotifyAsPackage(String callingPkg, String targetPkg) {
+        public boolean canNotifyAsPackage(String callingPkg, String targetPkg, int userId) {
             checkCallerIsSameApp(callingPkg);
             final int callingUid = Binder.getCallingUid();
             UserHandle user = UserHandle.getUserHandleForUid(callingUid);
+            if (user.getIdentifier() != userId) {
+                getContext().enforceCallingPermission(
+                        android.Manifest.permission.INTERACT_ACROSS_USERS,
+                        "canNotifyAsPackage for user " + userId);
+            }
             try {
                 ApplicationInfo info =
                         mPackageManager.getApplicationInfo(targetPkg,
                                 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
-                                user.getIdentifier());
+                                userId);
                 if (info != null) {
                     return mPreferencesHelper.isDelegateAllowed(
                             targetPkg, info.uid, callingPkg, callingUid);
diff --git a/services/core/java/com/android/server/om/IdmapManager.java b/services/core/java/com/android/server/om/IdmapManager.java
index 9e0cb0f..fd68a8b 100644
--- a/services/core/java/com/android/server/om/IdmapManager.java
+++ b/services/core/java/com/android/server/om/IdmapManager.java
@@ -82,7 +82,7 @@
         final String overlayPath = overlayPackage.applicationInfo.getBaseCodePath();
         try {
             if (FEATURE_FLAG_IDMAP2) {
-                int policies = determineFulfilledPolicies(targetPackage, overlayPackage, userId);
+                int policies = calculateFulfilledPolicies(targetPackage, overlayPackage, userId);
                 boolean enforce = enforceOverlayable(overlayPackage);
                 if (mIdmap2Service.verifyIdmap(overlayPath, policies, enforce, userId)) {
                     return true;
@@ -184,28 +184,25 @@
             return true;
         }
 
-        if (ai.isVendor() && !VENDOR_IS_Q_OR_LATER) {
+        if (ai.isVendor()) {
             // If the overlay is on a pre-Q vendor partition, do not enforce overlayable
             // restrictions on this overlay because the pre-Q platform has no understanding of
             // overlayable.
-            return false;
+            return VENDOR_IS_Q_OR_LATER;
         }
 
-        // Do not enforce overlayable restrictions on pre-Q overlays signed with the
-        // platform signature.
-        return !ai.isSignedWithPlatformKey();
+        // Do not enforce overlayable restrictions on pre-Q overlays that are signed with the
+        // platform signature or that are preinstalled.
+        return !(ai.isSystemApp() || ai.isSignedWithPlatformKey());
     }
 
     /**
-     * Retrieves a bitmask for idmap2 that represents the policies the specified overlay fulfills.
-     * @throws SecurityException if the overlay is not allowed to overlay any resource
+     * Retrieves a bitmask for idmap2 that represents the policies the overlay fulfills.
      */
-    private int determineFulfilledPolicies(@NonNull final PackageInfo targetPackage,
-            @NonNull final PackageInfo overlayPackage, int userId) throws SecurityException {
+    private int calculateFulfilledPolicies(@NonNull final PackageInfo targetPackage,
+            @NonNull final PackageInfo overlayPackage, int userId)  {
         final ApplicationInfo ai = overlayPackage.applicationInfo;
-        final boolean overlayIsQOrLater = ai.targetSdkVersion >= VERSION_CODES.Q;
-
-        int fulfilledPolicies = 0;
+        int fulfilledPolicies = IIdmap2.POLICY_PUBLIC;
 
         // Overlay matches target signature
         if (mPackageManager.signaturesMatching(targetPackage.packageName,
@@ -215,32 +212,25 @@
 
         // Vendor partition (/vendor)
         if (ai.isVendor()) {
-            if (overlayIsQOrLater) {
-                fulfilledPolicies |= IIdmap2.POLICY_VENDOR_PARTITION;
-            } else if (VENDOR_IS_Q_OR_LATER) {
-                throw new SecurityException("Overlay must target Q sdk or higher");
-            }
+            return fulfilledPolicies | IIdmap2.POLICY_VENDOR_PARTITION;
         }
 
         // Product partition (/product)
         if (ai.isProduct()) {
-            if (overlayIsQOrLater) {
-                fulfilledPolicies |= IIdmap2.POLICY_PRODUCT_PARTITION;
-            } else {
-                throw new SecurityException("Overlay must target Q sdk or higher");
-            }
+            return fulfilledPolicies | IIdmap2.POLICY_PRODUCT_PARTITION;
         }
 
-        // System partition (/system)
+        // Check partitions for which there exists no policy so overlays on these partitions will
+        // not fulfill the system policy.
+        if (ai.isOem() || ai.isProductServices()) {
+            return fulfilledPolicies;
+        }
+
+        // Check this last since every partition except for data is scanned as system in the PMS.
         if (ai.isSystemApp()) {
-            if (overlayIsQOrLater) {
-                fulfilledPolicies |= IIdmap2.POLICY_SYSTEM_PARTITION;
-            } else {
-                throw new SecurityException("Overlay must target Q sdk or higher");
-            }
+            return fulfilledPolicies | IIdmap2.POLICY_SYSTEM_PARTITION;
         }
 
-        // All overlays can overlay resources with the public policy
-        return fulfilledPolicies | IIdmap2.POLICY_PUBLIC;
+        return fulfilledPolicies;
     }
 }
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 7f057f0..18cfa4a 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -45,8 +45,6 @@
 import android.content.pm.ShortcutInfo;
 import android.content.pm.ShortcutServiceInternal;
 import android.content.pm.ShortcutServiceInternal.ShortcutChangeListener;
-import android.content.pm.Signature;
-import android.content.pm.SigningInfo;
 import android.content.pm.UserInfo;
 import android.graphics.Rect;
 import android.net.Uri;
@@ -62,31 +60,21 @@
 import android.os.UserManager;
 import android.os.UserManagerInternal;
 import android.provider.Settings;
-import android.util.ByteStringUtils;
 import android.util.Log;
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.os.BackgroundThread;
-import com.android.internal.util.DumpUtils;
 import com.android.internal.util.Preconditions;
-import com.android.internal.util.StatLogger;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.wm.ActivityTaskManagerInternal;
 
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * Service that manages requests and callbacks for launchers that support
@@ -125,16 +113,6 @@
         private static final boolean DEBUG = false;
         private static final String TAG = "LauncherAppsService";
 
-        // Stats
-        @VisibleForTesting
-        interface Stats {
-            int INIT_VOUCHED_SIGNATURES = 0;
-            int COUNT = INIT_VOUCHED_SIGNATURES + 1;
-        }
-        private final StatLogger mStatLogger = new StatLogger(new String[] {
-                "initVouchedSignatures"
-        });
-
         private final Context mContext;
         private final UserManager mUm;
         private final UserManagerInternal mUserManagerInternal;
@@ -145,16 +123,11 @@
         private final PackageCallbackList<IOnAppsChangedListener> mListeners
                 = new PackageCallbackList<IOnAppsChangedListener>();
         private final DevicePolicyManager mDpm;
-        private final ConcurrentHashMap<UserHandle, Set<String>> mVouchedSignaturesByUser;
-        private final Set<String> mVouchProviders;
 
         private final MyPackageMonitor mPackageMonitor = new MyPackageMonitor();
-        private final VouchesChangedMonitor mVouchesChangedMonitor = new VouchesChangedMonitor();
 
         private final Handler mCallbackHandler;
 
-        private final Object mVouchedSignaturesLocked = new Object();
-
         private PackageInstallerService mPackageInstallerService;
 
         public LauncherAppsImpl(Context context) {
@@ -173,9 +146,6 @@
             mShortcutServiceInternal.addListener(mPackageMonitor);
             mCallbackHandler = BackgroundThread.getHandler();
             mDpm = (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
-            mVouchedSignaturesByUser = new ConcurrentHashMap<>();
-            mVouchProviders = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());
-            mVouchesChangedMonitor.register(mContext, UserHandle.ALL, true, mCallbackHandler);
         }
 
         @VisibleForTesting
@@ -468,32 +438,9 @@
             if (appInfo == null || appInfo.isSystemApp() || appInfo.isUpdatedSystemApp()) {
                 return false;
             }
-            if (!mVouchedSignaturesByUser.containsKey(user)) {
-                initVouchedSignatures(user);
-            }
             if (isManagedProfileAdmin(user, appInfo.packageName)) {
                 return false;
             }
-            if (mVouchProviders.contains(appInfo.packageName)) {
-                // If it's a vouching packages then we must show hidden app
-                return true;
-            }
-            // If app's signature is in vouch list, do not show hidden app
-            final Set<String> vouches = mVouchedSignaturesByUser.get(user);
-            try {
-                final PackageInfo pkgInfo = mContext.getPackageManager().getPackageInfo(
-                        appInfo.packageName, PackageManager.GET_SIGNING_CERTIFICATES);
-                final Signature[] signatures = getLatestSignatures(pkgInfo.signingInfo);
-                // If any of the signatures appears in vouches, then we don't show hidden app
-                for (Signature signature : signatures) {
-                    final String certDigest = computePackageCertDigest(signature);
-                    if (vouches.contains(certDigest)) {
-                        return false;
-                    }
-                }
-            } catch (PackageManager.NameNotFoundException e) {
-                // Should not happen
-            }
             return true;
         }
 
@@ -515,100 +462,6 @@
             return false;
         }
 
-        @VisibleForTesting
-        static String computePackageCertDigest(Signature signature) {
-            MessageDigest messageDigest;
-            try {
-                messageDigest = MessageDigest.getInstance("SHA1");
-            } catch (NoSuchAlgorithmException e) {
-                // Should not happen
-                return null;
-            }
-            messageDigest.update(signature.toByteArray());
-            final byte[] digest = messageDigest.digest();
-            return ByteStringUtils.toHexString(digest);
-        }
-
-        @VisibleForTesting
-        static Signature[] getLatestSignatures(SigningInfo signingInfo) {
-            if (signingInfo.hasMultipleSigners()) {
-                return signingInfo.getApkContentsSigners();
-            } else {
-                final Signature[] signatures = signingInfo.getSigningCertificateHistory();
-                return new Signature[]{signatures[0]};
-            }
-        }
-
-        private void updateVouches(String packageName, UserHandle user) {
-            final PackageManagerInternal pmInt =
-                    LocalServices.getService(PackageManagerInternal.class);
-            ApplicationInfo appInfo = pmInt.getApplicationInfo(packageName,
-                    PackageManager.GET_META_DATA, Binder.getCallingUid(), user.getIdentifier());
-            if (appInfo == null) {
-                Log.w(TAG, "appInfo " + packageName + " is null");
-                return;
-            }
-            updateVouches(appInfo, user);
-        }
-
-        private void updateVouches(ApplicationInfo appInfo, UserHandle user) {
-            if (appInfo == null || appInfo.metaData == null) {
-                // No meta-data
-                return;
-            }
-            int tokenResourceId = appInfo.metaData.getInt(LauncherApps.VOUCHED_CERTS_KEY);
-            if (tokenResourceId == 0) {
-                // No xml file
-                return;
-            }
-            mVouchProviders.add(appInfo.packageName);
-            Set<String> vouches = mVouchedSignaturesByUser.get(user);
-            try {
-                List<String> signatures = Arrays.asList(
-                        mContext.getPackageManager().getResourcesForApplication(
-                                appInfo.packageName).getStringArray(tokenResourceId));
-                for (String signature : signatures) {
-                    vouches.add(signature.toUpperCase());
-                }
-            } catch (PackageManager.NameNotFoundException e) {
-                // Should not happen
-            }
-        }
-
-        private void initVouchedSignatures(UserHandle user) {
-            synchronized (mVouchedSignaturesLocked) {
-                if (mVouchedSignaturesByUser.contains(user)) {
-                    return;
-                }
-                final long startTime = mStatLogger.getTime();
-
-                Set<String> vouches = Collections.newSetFromMap(
-                        new ConcurrentHashMap<String, Boolean>());
-
-                final int callingUid = injectBinderCallingUid();
-                long ident = Binder.clearCallingIdentity();
-                try {
-                    final PackageManagerInternal pmInt =
-                            LocalServices.getService(PackageManagerInternal.class);
-                    List<ApplicationInfo> installedPackages = pmInt.getInstalledApplications(
-                            PackageManager.GET_META_DATA, user.getIdentifier(), callingUid);
-                    for (ApplicationInfo appInfo : installedPackages) {
-                        updateVouches(appInfo, user);
-                    }
-                } finally {
-                    Binder.restoreCallingIdentity(ident);
-                }
-                mVouchedSignaturesByUser.putIfAbsent(user, vouches);
-                mStatLogger.logDurationStat(Stats.INIT_VOUCHED_SIGNATURES, startTime);
-            }
-        }
-
-        @Override
-        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-            if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
-            mStatLogger.dump(pw, "  ");
-        }
-
         @Override
         public ActivityInfo resolveActivity(
                 String callingPackage, ComponentName component, UserHandle user)
@@ -1022,18 +875,6 @@
             mCallbackHandler.post(r);
         }
 
-        private class VouchesChangedMonitor extends PackageMonitor {
-            @Override
-            public void onPackageAdded(String packageName, int uid) {
-                updateVouches(packageName, new UserHandle(getChangingUserId()));
-            }
-
-            @Override
-            public void onPackageModified(String packageName) {
-                updateVouches(packageName, new UserHandle(getChangingUserId()));
-            }
-        }
-
         private class MyPackageMonitor extends PackageMonitor implements ShortcutChangeListener {
 
             // TODO Simplify with lambdas.
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index e5b6397..4e8ef71 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -160,9 +160,9 @@
 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.PackageBackwardCompatibility;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageInfoLite;
 import android.content.pm.PackageInstaller;
@@ -232,6 +232,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.UserManagerInternal;
+import android.os.storage.DiskInfo;
 import android.os.storage.IStorageManager;
 import android.os.storage.StorageEventListener;
 import android.os.storage.StorageManager;
@@ -245,6 +246,7 @@
 import android.security.KeyStore;
 import android.security.SystemKeyStore;
 import android.service.pm.PackageServiceDumpProto;
+import android.stats.storage.StorageEnums;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.text.TextUtils;
@@ -269,6 +271,7 @@
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
+import android.util.StatsLog;
 import android.util.TimingsTraceLog;
 import android.util.Xml;
 import android.util.jar.StrictJarFile;
@@ -1912,6 +1915,15 @@
 
                 // Send broadcast package appeared if external for all users
                 if (isExternal(res.pkg)) {
+                    if (!update) {
+                        int packageExternalStorageType =
+                                getPackageExternalStorageType(res.pkg);
+                        // If the package was installed externally, log it.
+                        if (packageExternalStorageType != StorageEnums.UNKNOWN) {
+                            StatsLog.write(StatsLog.APP_INSTALL_ON_EXTERNAL_STORAGE_REPORTED,
+                                    packageExternalStorageType, res.pkg.packageName);
+                        }
+                    }
                     if (DEBUG_INSTALL) {
                         Slog.i(TAG, "upgrading pkg " + res.pkg + " is external");
                     }
@@ -2000,6 +2012,32 @@
         }
     }
 
+    /**
+     * Gets the type of the external storage a package is installed on.
+     * @param pkg The package for which to get the external storage type.
+     * @return {@link StorageEnum#TYPE_UNKNOWN} if it is not stored externally or the corresponding
+     * {@link StorageEnum} storage type value if it is.
+     */
+    private int getPackageExternalStorageType(PackageParser.Package pkg) {
+        final StorageManager storage = mContext.getSystemService(StorageManager.class);
+        VolumeInfo volume = storage.findVolumeByUuid(pkg.applicationInfo.storageUuid.toString());
+        if (volume != null) {
+            DiskInfo disk = volume.getDisk();
+            if (disk != null) {
+                if (disk.isSd()) {
+                    return StorageEnums.SD_CARD;
+                }
+                if (disk.isUsb()) {
+                    return StorageEnums.USB;
+                }
+                if (isExternal(pkg)) {
+                    return StorageEnums.OTHER;
+                }
+            }
+        }
+        return StorageEnums.UNKNOWN;
+    }
+
     private StorageEventListener mStorageListener = new StorageEventListener() {
         @Override
         public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 3744f68..316a9c0 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1144,6 +1144,19 @@
     }
 
     @Override
+    public String getUserName() {
+        if (!hasManageUsersOrPermission(android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED)) {
+            throw new SecurityException("You need MANAGE_USERS or GET_ACCOUNTS_PRIVILEGED "
+                    + "permissions to: get user name");
+        }
+        final int userId = UserHandle.getUserId(Binder.getCallingUid());
+        synchronized (mUsersLock) {
+            UserInfo userInfo = userWithName(getUserInfoLU(userId));
+            return userInfo == null ? "" : userInfo.name;
+        }
+    }
+
+    @Override
     public long getUserStartRealtime() {
         final int userId = UserHandle.getUserId(Binder.getCallingUid());
         synchronized (mUsersLock) {
@@ -1299,7 +1312,12 @@
             }
         }
         if (changed) {
-            sendUserInfoChangedBroadcast(userId);
+            long ident = Binder.clearCallingIdentity();
+            try {
+                sendUserInfoChangedBroadcast(userId);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
         }
     }
 
@@ -1324,7 +1342,10 @@
 
     @Override
     public ParcelFileDescriptor getUserIcon(int targetUserId) {
-        checkManageUsersPermission("get user icon");
+        if (!hasManageUsersOrPermission(android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED)) {
+            throw new SecurityException("You need MANAGE_USERS or GET_ACCOUNTS_PRIVILEGED "
+                    + "permissions to: get user icon");
+        }
         String iconPath;
         synchronized (mPackagesLock) {
             UserInfo targetUserInfo = getUserInfoNoChecks(targetUserId);
@@ -1941,15 +1962,23 @@
 
     /**
      * @return whether the calling UID is system UID or root's UID or the calling app has the
-     * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} or
-     * {@link android.Manifest.permission#CREATE_USERS CREATE_USERS}.
+     * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} or the provided permission.
      */
-    private static final boolean hasManageOrCreateUsersPermission() {
+    private static final boolean hasManageUsersOrPermission(String alternativePermission) {
         final int callingUid = Binder.getCallingUid();
         return UserHandle.isSameApp(callingUid, Process.SYSTEM_UID)
                 || callingUid == Process.ROOT_UID
                 || hasPermissionGranted(android.Manifest.permission.MANAGE_USERS, callingUid)
-                || hasPermissionGranted(android.Manifest.permission.CREATE_USERS, callingUid);
+                || hasPermissionGranted(alternativePermission, callingUid);
+    }
+
+    /**
+     * @return whether the calling UID is system UID or root's UID or the calling app has the
+     * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} or
+     * {@link android.Manifest.permission#CREATE_USERS CREATE_USERS}.
+     */
+    private static final boolean hasManageOrCreateUsersPermission() {
+        return hasManageUsersOrPermission(android.Manifest.permission.CREATE_USERS);
     }
 
     /**
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 5810636..e7c9a081 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -104,7 +104,6 @@
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
-import android.app.ActivityOptions;
 import android.app.ActivityTaskManager;
 import android.app.AppOpsManager;
 import android.app.IUiModeManager;
@@ -5114,6 +5113,7 @@
             awakenDreams();
         }
 
+        // Start dock.
         Intent dock = createHomeDockIntent();
         if (dock != null) {
             try {
@@ -5126,21 +5126,9 @@
             }
         }
 
-        Intent intent;
-
-        if (fromHomeKey) {
-            intent = new Intent(mHomeIntent);
-            intent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, fromHomeKey);
-        } else {
-            intent = mHomeIntent;
-        }
-        final Bundle bundle = getLaunchDisplayIdBundle(displayId);
-        startActivityAsUser(intent, bundle, UserHandle.CURRENT);
-    }
-
-    private @Nullable Bundle getLaunchDisplayIdBundle(int displayId) {
-        return (displayId == INVALID_DISPLAY) ? null
-                : ActivityOptions.makeBasic().setLaunchDisplayId(displayId).toBundle();
+        // Start home.
+        mActivityTaskManagerInternal.startHomeOnDisplay(mCurrentUserId, "startDockOrHome",
+                displayId, fromHomeKey);
     }
 
     /**
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
index 5adcf35..f0e4625 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
@@ -115,9 +115,41 @@
     public static final int REASON_SETTING_CHANGED = 8;
     public static final int REASON_DYNAMIC_POWER_SAVINGS_AUTOMATIC_ON = 9;
     public static final int REASON_DYNAMIC_POWER_SAVINGS_AUTOMATIC_OFF = 10;
-    public static final int REASON_STICKY_RESTORE_OFF = 11;
-    public static final int REASON_ADAPTIVE_DYNAMIC_POWER_SAVINGS_CHANGED = 12;
-    public static final int REASON_TIMEOUT = 13;
+    public static final int REASON_ADAPTIVE_DYNAMIC_POWER_SAVINGS_CHANGED = 11;
+    public static final int REASON_TIMEOUT = 12;
+
+    static String reasonToString(int reason) {
+        switch (reason) {
+            case BatterySaverController.REASON_PERCENTAGE_AUTOMATIC_ON:
+                return "Percentage Auto ON";
+            case BatterySaverController.REASON_PERCENTAGE_AUTOMATIC_OFF:
+                return "Percentage Auto OFF";
+            case BatterySaverController.REASON_MANUAL_ON:
+                return "Manual ON";
+            case BatterySaverController.REASON_MANUAL_OFF:
+                return "Manual OFF";
+            case BatterySaverController.REASON_STICKY_RESTORE:
+                return "Sticky restore";
+            case BatterySaverController.REASON_INTERACTIVE_CHANGED:
+                return "Interactivity changed";
+            case BatterySaverController.REASON_POLICY_CHANGED:
+                return "Policy changed";
+            case BatterySaverController.REASON_PLUGGED_IN:
+                return "Plugged in";
+            case BatterySaverController.REASON_SETTING_CHANGED:
+                return "Setting changed";
+            case BatterySaverController.REASON_DYNAMIC_POWER_SAVINGS_AUTOMATIC_ON:
+                return "Dynamic Warning Auto ON";
+            case BatterySaverController.REASON_DYNAMIC_POWER_SAVINGS_AUTOMATIC_OFF:
+                return "Dynamic Warning Auto OFF";
+            case BatterySaverController.REASON_ADAPTIVE_DYNAMIC_POWER_SAVINGS_CHANGED:
+                return "Adaptive Power Savings changed";
+            case BatterySaverController.REASON_TIMEOUT:
+                return "timeout";
+            default:
+                return "Unknown reason: " + reason;
+        }
+    }
 
     /**
      * Plugin interface. All methods are guaranteed to be called on the same (handler) thread.
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
index af5d40bf..8f2e997 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
@@ -15,6 +15,8 @@
  */
 package com.android.server.power.batterysaver;
 
+import static com.android.server.power.batterysaver.BatterySaverController.reasonToString;
+
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
@@ -49,6 +51,42 @@
  * Do not call out with the lock held. (Settings provider is okay.)
  *
  * Test: atest com.android.server.power.batterysaver.BatterySaverStateMachineTest
+ *
+ * Current state machine. This can be visualized using Graphviz:
+   <pre>
+
+   digraph {
+     STATE_OFF
+     STATE_MANUAL_ON [label="STATE_MANUAL_ON\nTurned on manually by the user"]
+     STATE_AUTOMATIC_ON [label="STATE_AUTOMATIC_ON\nTurned on automatically by the system"]
+     STATE_OFF_AUTOMATIC_SNOOZED [
+       label="STATE_OFF_AUTOMATIC_SNOOZED\nTurned off manually by the user."
+           + " The system should not turn it back on automatically."
+     ]
+     STATE_PENDING_STICKY_ON [
+       label="STATE_PENDING_STICKY_ON\n"
+           + " Turned on manually by the user and then plugged in. Will turn back on after unplug."
+     ]
+
+     STATE_OFF -> STATE_MANUAL_ON [label="manual"]
+     STATE_OFF -> STATE_AUTOMATIC_ON [label="Auto on AND charge <= auto threshold"]
+
+     STATE_MANUAL_ON -> STATE_OFF [label="manual\nOR\nPlugged & sticky disabled"]
+     STATE_MANUAL_ON -> STATE_PENDING_STICKY_ON [label="Plugged & sticky enabled"]
+
+     STATE_PENDING_STICKY_ON -> STATE_MANUAL_ON [label="Unplugged & sticky enabled"]
+     STATE_PENDING_STICKY_ON -> STATE_OFF [
+       label="Sticky disabled\nOR\nSticky auto off enabled AND charge >= sticky auto off threshold"
+     ]
+
+     STATE_AUTOMATIC_ON -> STATE_OFF [label="Plugged"]
+     STATE_AUTOMATIC_ON -> STATE_OFF_AUTOMATIC_SNOOZED [label="Manual"]
+
+     STATE_OFF_AUTOMATIC_SNOOZED -> STATE_OFF [label="Plug\nOR\nCharge > auto threshold"]
+     STATE_OFF_AUTOMATIC_SNOOZED -> STATE_MANUAL_ON [label="manual"]
+
+     </pre>
+   }
  */
 public class BatterySaverStateMachine {
     private static final String TAG = "BatterySaverStateMachine";
@@ -60,6 +98,25 @@
 
     private static final long ADAPTIVE_CHANGE_TIMEOUT_MS = 24 * 60 * 60 * 1000L;
 
+    /** Turn off adaptive battery saver if the device has charged above this level. */
+    private static final int ADAPTIVE_AUTO_DISABLE_BATTERY_LEVEL = 80;
+
+    private static final int STATE_OFF = BatterySaverStateMachineProto.STATE_OFF;
+
+    /** Turned on manually by the user. */
+    private static final int STATE_MANUAL_ON = BatterySaverStateMachineProto.STATE_MANUAL_ON;
+
+    /** Turned on automatically by the system. */
+    private static final int STATE_AUTOMATIC_ON = BatterySaverStateMachineProto.STATE_AUTOMATIC_ON;
+
+    /** Turned off manually by the user. The system should not turn it back on automatically. */
+    private static final int STATE_OFF_AUTOMATIC_SNOOZED =
+            BatterySaverStateMachineProto.STATE_OFF_AUTOMATIC_SNOOZED;
+
+    /** Turned on manually by the user and then plugged in. Will turn back on after unplug. */
+    private static final int STATE_PENDING_STICKY_ON =
+            BatterySaverStateMachineProto.STATE_PENDING_STICKY_ON;
+
     private final Context mContext;
     private final BatterySaverController mBatterySaverController;
 
@@ -75,6 +132,9 @@
     @GuardedBy("mLock")
     private boolean mBatteryStatusSet;
 
+    @GuardedBy("mLock")
+    private int mState;
+
     /** Whether the device is connected to any power source. */
     @GuardedBy("mLock")
     private boolean mIsPowered;
@@ -142,13 +202,6 @@
     private boolean mDynamicPowerSavingsBatterySaver;
 
     /**
-     * Whether BS has been manually disabled while the battery level is low, in which case we
-     * shouldn't auto re-enable it until the battery level is not low.
-     */
-    @GuardedBy("mLock")
-    private boolean mBatterySaverSnoozing;
-
-    /**
      * Last reason passed to {@link #enableBatterySaverLocked}.
      */
     @GuardedBy("mLock")
@@ -181,6 +234,7 @@
         mLock = lock;
         mContext = context;
         mBatterySaverController = batterySaverController;
+        mState = STATE_OFF;
 
         mBatterySaverStickyBehaviourDisabled = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_batterySaverStickyBehaviourDisabled);
@@ -188,8 +242,36 @@
                 com.android.internal.R.integer.config_dynamicPowerSavingsDefaultDisableThreshold);
     }
 
-    private boolean isAutoBatterySaverConfiguredLocked() {
-        return mSettingBatterySaverTriggerThreshold > 0;
+    /** @return true if the automatic percentage based mode should be used */
+    private boolean isAutomaticModeActiveLocked() {
+        return mSettingAutomaticBatterySaver == PowerManager.POWER_SAVER_MODE_PERCENTAGE
+                && mSettingBatterySaverTriggerThreshold > 0;
+    }
+
+    /**
+     * The returned value won't necessarily make sense if {@link #isAutomaticModeActiveLocked()}
+     * returns {@code false}.
+     *
+     * @return true if the battery level is below automatic's threshold.
+     */
+    private boolean isInAutomaticLowZoneLocked() {
+        return mIsBatteryLevelLow;
+    }
+
+    /** @return true if the dynamic mode should be used */
+    private boolean isDynamicModeActiveLocked() {
+        return mSettingAutomaticBatterySaver == PowerManager.POWER_SAVER_MODE_DYNAMIC
+                && mDynamicPowerSavingsBatterySaver;
+    }
+
+    /**
+     * The returned value won't necessarily make sense if {@link #isDynamicModeActiveLocked()}
+     * returns {@code false}.
+     *
+     * @return true if the battery level is below dynamic's threshold.
+     */
+    private boolean isInDynamicLowZoneLocked() {
+        return mBatteryLevel <= mDynamicPowerSavingsDisableThreshold;
     }
 
     /**
@@ -233,7 +315,14 @@
                     Settings.Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_LEVEL),
                     false, mSettingsObserver, UserHandle.USER_SYSTEM);
 
+
             synchronized (mLock) {
+                final boolean lowPowerModeEnabledSticky = getGlobalSetting(
+                        Settings.Global.LOW_POWER_MODE_STICKY, 0) != 0;
+
+                if (lowPowerModeEnabledSticky) {
+                    mState = STATE_PENDING_STICKY_ON;
+                }
 
                 mBootCompleted = true;
 
@@ -362,6 +451,8 @@
                     ? "Global.low_power changed to 1" : "Global.low_power changed to 0";
             enableBatterySaverLocked(/*enable=*/ batterySaverEnabled, /*manual=*/ true,
                     BatterySaverController.REASON_SETTING_CHANGED, reason);
+        } else {
+            doAutoBatterySaverLocked();
         }
     }
 
@@ -428,17 +519,6 @@
         }
     }
 
-    @GuardedBy("mLock")
-    private boolean isBatteryLowLocked() {
-        final boolean percentageLow =
-                mSettingAutomaticBatterySaver == PowerManager.POWER_SAVER_MODE_PERCENTAGE
-                && mIsBatteryLevelLow;
-        final boolean dynamicPowerSavingsLow =
-                mSettingAutomaticBatterySaver == PowerManager.POWER_SAVER_MODE_DYNAMIC
-                && mBatteryLevel <= mDynamicPowerSavingsDisableThreshold;
-        return percentageLow || dynamicPowerSavingsLow;
-    }
-
     /**
      * Decide whether to auto-start / stop battery saver.
      */
@@ -449,7 +529,6 @@
                     + " mSettingsLoaded=" + mSettingsLoaded
                     + " mBatteryStatusSet=" + mBatteryStatusSet
                     + " mIsBatteryLevelLow=" + mIsBatteryLevelLow
-                    + " mBatterySaverSnoozing=" + mBatterySaverSnoozing
                     + " mIsPowered=" + mIsPowered
                     + " mSettingAutomaticBatterySaver=" + mSettingAutomaticBatterySaver
                     + " mSettingBatterySaverEnabledSticky=" + mSettingBatterySaverEnabledSticky
@@ -460,66 +539,166 @@
             return; // Not fully initialized yet.
         }
 
-        if (!isBatteryLowLocked()) {
-            updateSnoozingLocked(false, "Battery not low");
-        }
+        updateStateLocked(false, false);
 
+        // Adaptive control.
         if (SystemClock.elapsedRealtime() - mLastAdaptiveBatterySaverChangedExternallyElapsed
                 > ADAPTIVE_CHANGE_TIMEOUT_MS) {
             mBatterySaverController.setAdaptivePolicyEnabledLocked(
                     false, BatterySaverController.REASON_TIMEOUT);
             mBatterySaverController.resetAdaptivePolicyLocked(
                     BatterySaverController.REASON_TIMEOUT);
+        } else if (mIsPowered && mBatteryLevel >= ADAPTIVE_AUTO_DISABLE_BATTERY_LEVEL) {
+            mBatterySaverController.setAdaptivePolicyEnabledLocked(false,
+                    BatterySaverController.REASON_PLUGGED_IN);
+        }
+    }
+
+    /**
+     * Update the state machine based on the current settings and battery/charge status.
+     *
+     * @param manual Whether the change was made by the user.
+     * @param enable Whether the user wants to turn battery saver on or off. Is only used if {@param
+     *               manual} is true.
+     */
+    @GuardedBy("mLock")
+    private void updateStateLocked(boolean manual, boolean enable) {
+        if (!manual && !(mBootCompleted && mSettingsLoaded && mBatteryStatusSet)) {
+            return; // Not fully initialized yet.
         }
 
-        if (mIsPowered) {
-            updateSnoozingLocked(false, "Plugged in");
-            enableBatterySaverLocked(/*enable=*/ false, /*manual=*/ false,
-                    BatterySaverController.REASON_PLUGGED_IN,
-                    "Plugged in");
-
-            if (mBatteryLevel >= 80 /* Arbitrary level */) {
-                mBatterySaverController.setAdaptivePolicyEnabledLocked(
-                        false, BatterySaverController.REASON_PLUGGED_IN);
+        switch (mState) {
+            case STATE_OFF: {
+                if (!mIsPowered) {
+                    if (manual) {
+                        if (!enable) {
+                            Slog.e(TAG, "Tried to disable BS when it's already OFF");
+                            return;
+                        }
+                        enableBatterySaverLocked(/*enable*/ true, /*manual*/ true,
+                                BatterySaverController.REASON_MANUAL_ON);
+                        mState = STATE_MANUAL_ON;
+                    } else if (isAutomaticModeActiveLocked() && isInAutomaticLowZoneLocked()) {
+                        enableBatterySaverLocked(/*enable*/ true, /*manual*/ false,
+                                BatterySaverController.REASON_PERCENTAGE_AUTOMATIC_ON);
+                        mState = STATE_AUTOMATIC_ON;
+                    } else if (isDynamicModeActiveLocked() && isInDynamicLowZoneLocked()) {
+                        enableBatterySaverLocked(/*enable*/ true, /*manual*/ false,
+                                BatterySaverController.REASON_DYNAMIC_POWER_SAVINGS_AUTOMATIC_ON);
+                        mState = STATE_AUTOMATIC_ON;
+                    }
+                }
+                break;
             }
 
-        } else if (mSettingBatterySaverEnabledSticky && !mBatterySaverStickyBehaviourDisabled) {
-            if (mSettingBatterySaverStickyAutoDisableEnabled
-                    && mBatteryLevel >= mSettingBatterySaverStickyAutoDisableThreshold) {
-                setStickyActive(false);
-            } else {
-                // Re-enable BS.
-                enableBatterySaverLocked(/*enable=*/ true, /*manual=*/ true,
-                        BatterySaverController.REASON_STICKY_RESTORE,
-                        "Sticky restore");
+            case STATE_MANUAL_ON: {
+                if (manual) {
+                    if (enable) {
+                        Slog.e(TAG, "Tried to enable BS when it's already MANUAL_ON");
+                        return;
+                    }
+                    enableBatterySaverLocked(/*enable*/ false, /*manual*/ true,
+                            BatterySaverController.REASON_MANUAL_OFF);
+                    mState = STATE_OFF;
+                } else if (mIsPowered) {
+                    enableBatterySaverLocked(/*enable*/ false, /*manual*/ false,
+                            BatterySaverController.REASON_PLUGGED_IN);
+                    if (mSettingBatterySaverEnabledSticky
+                            && !mBatterySaverStickyBehaviourDisabled) {
+                        mState = STATE_PENDING_STICKY_ON;
+                    } else {
+                        mState = STATE_OFF;
+                    }
+                }
+                break;
             }
 
-        } else if (mSettingAutomaticBatterySaver
-                == PowerManager.POWER_SAVER_MODE_PERCENTAGE
-                && isAutoBatterySaverConfiguredLocked()) {
-            if (mIsBatteryLevelLow && !mBatterySaverSnoozing) {
-                enableBatterySaverLocked(/*enable=*/ true, /*manual=*/ false,
-                        BatterySaverController.REASON_PERCENTAGE_AUTOMATIC_ON,
-                        "Percentage Auto ON");
-            } else {
-                // Battery not low
-                enableBatterySaverLocked(/*enable=*/ false, /*manual=*/ false,
-                        BatterySaverController.REASON_PERCENTAGE_AUTOMATIC_OFF,
-                        "Percentage Auto OFF");
+            case STATE_AUTOMATIC_ON: {
+                if (mIsPowered) {
+                    enableBatterySaverLocked(/*enable*/ false, /*manual*/ false,
+                            BatterySaverController.REASON_PLUGGED_IN);
+                    mState = STATE_OFF;
+                } else if (manual) {
+                    if (enable) {
+                        Slog.e(TAG, "Tried to enable BS when it's already AUTO_ON");
+                        return;
+                    }
+                    enableBatterySaverLocked(/*enable*/ false, /*manual*/ true,
+                            BatterySaverController.REASON_MANUAL_OFF);
+                    // When battery saver is disabled manually (while battery saver is enabled)
+                    // when the battery level is low, we "snooze" BS -- i.e. disable auto battery
+                    // saver.
+                    // We resume auto-BS once the battery level is not low, or the device is
+                    // plugged in.
+                    mState = STATE_OFF_AUTOMATIC_SNOOZED;
+                } else if (isAutomaticModeActiveLocked() && !isInAutomaticLowZoneLocked()) {
+                    enableBatterySaverLocked(/*enable*/ false, /*manual*/ false,
+                            BatterySaverController.REASON_PERCENTAGE_AUTOMATIC_OFF);
+                    mState = STATE_OFF;
+                } else if (isDynamicModeActiveLocked() && !isInDynamicLowZoneLocked()) {
+                    enableBatterySaverLocked(/*enable*/ false, /*manual*/ false,
+                            BatterySaverController.REASON_DYNAMIC_POWER_SAVINGS_AUTOMATIC_OFF);
+                    mState = STATE_OFF;
+                } else if (!isAutomaticModeActiveLocked() && !isDynamicModeActiveLocked()) {
+                    enableBatterySaverLocked(/*enable*/ false, /*manual*/ false,
+                            BatterySaverController.REASON_SETTING_CHANGED);
+                    mState = STATE_OFF;
+                }
+                break;
             }
-        } else if (mSettingAutomaticBatterySaver
-                == PowerManager.POWER_SAVER_MODE_DYNAMIC) {
-            if (mBatteryLevel >= mDynamicPowerSavingsDisableThreshold) {
-                enableBatterySaverLocked(/*enable=*/ false, /*manual=*/ false,
-                        BatterySaverController.REASON_DYNAMIC_POWER_SAVINGS_AUTOMATIC_OFF,
-                        "Dynamic Warning Auto OFF");
-            } else if (mDynamicPowerSavingsBatterySaver && !mBatterySaverSnoozing) {
-                enableBatterySaverLocked(/*enable=*/ true, /*manual=*/ false,
-                        BatterySaverController.REASON_DYNAMIC_POWER_SAVINGS_AUTOMATIC_ON,
-                        "Dynamic Warning Auto ON");
+
+            case STATE_OFF_AUTOMATIC_SNOOZED: {
+                if (manual) {
+                    if (!enable) {
+                        Slog.e(TAG, "Tried to disable BS when it's already AUTO_SNOOZED");
+                        return;
+                    }
+                    enableBatterySaverLocked(/*enable*/ true, /*manual*/ true,
+                            BatterySaverController.REASON_MANUAL_ON);
+                    mState = STATE_MANUAL_ON;
+                } else if (mIsPowered // Plugging in resets snooze.
+                        || (isAutomaticModeActiveLocked() && !isInAutomaticLowZoneLocked())
+                        || (isDynamicModeActiveLocked() && !isInDynamicLowZoneLocked())
+                        || (!isAutomaticModeActiveLocked() && !isDynamicModeActiveLocked())) {
+                    mState = STATE_OFF;
+                }
+                break;
             }
+
+            case STATE_PENDING_STICKY_ON: {
+                if (manual) {
+                    // This shouldn't be possible. We'll only be in this state when the device is
+                    // plugged in, so the user shouldn't be able to manually change state.
+                    Slog.e(TAG, "Tried to manually change BS state from PENDING_STICKY_ON");
+                    return;
+                }
+                final boolean shouldTurnOffSticky = mSettingBatterySaverStickyAutoDisableEnabled
+                        && mBatteryLevel >= mSettingBatterySaverStickyAutoDisableThreshold;
+                final boolean isStickyDisabled =
+                        mBatterySaverStickyBehaviourDisabled || !mSettingBatterySaverEnabledSticky;
+                if (isStickyDisabled || shouldTurnOffSticky) {
+                    setStickyActive(false);
+                    mState = STATE_OFF;
+                } else if (!mIsPowered) {
+                    // Re-enable BS.
+                    enableBatterySaverLocked(/*enable*/ true, /*manual*/ true,
+                            BatterySaverController.REASON_STICKY_RESTORE);
+                    mState = STATE_MANUAL_ON;
+                }
+                break;
+            }
+
+            default:
+                Slog.wtf(TAG, "Unknown state: " + mState);
+                break;
         }
-        // do nothing if automatic battery saver mode = PERCENTAGE and low warning threshold = 0%
+    }
+
+    @VisibleForTesting
+    int getState() {
+        synchronized (mLock) {
+            return mState;
+        }
     }
 
     /**
@@ -533,13 +712,17 @@
             Slog.d(TAG, "setBatterySaverEnabledManually: enabled=" + enabled);
         }
         synchronized (mLock) {
-            enableBatterySaverLocked(/*enable=*/ enabled, /*manual=*/ true,
-                    (enabled ? BatterySaverController.REASON_MANUAL_ON
-                            : BatterySaverController.REASON_MANUAL_OFF),
-                    (enabled ? "Manual ON" : "Manual OFF"));
+            updateStateLocked(true, enabled);
+            // TODO: maybe turn off adaptive if it's on and advertiseIsEnabled is true and
+            //  enabled is false
         }
     }
 
+    @GuardedBy("mLock")
+    private void enableBatterySaverLocked(boolean enable, boolean manual, int intReason) {
+        enableBatterySaverLocked(enable, manual, intReason, reasonToString(intReason));
+    }
+
     /**
      * Actually enable / disable battery saver. Write the new state to the global settings
      * and propagate it to {@link #mBatterySaverController}.
@@ -566,20 +749,6 @@
         mLastChangedIntReason = intReason;
         mLastChangedStrReason = strReason;
 
-        if (manual) {
-            if (enable) {
-                updateSnoozingLocked(false, "Manual snooze OFF");
-            } else {
-                // When battery saver is disabled manually (while battery saver is enabled)
-                // when the battery level is low, we "snooze" BS -- i.e. disable auto battery saver.
-                // We resume auto-BS once the battery level is not low, or the device is plugged in.
-                if (mBatterySaverController.isFullEnabled() && isBatteryLowLocked()) {
-                    updateSnoozingLocked(true, "Manual snooze");
-                }
-                // TODO: maybe turn off adaptive if it's on and advertiseIsEnabled is true
-            }
-        }
-
         mSettingBatterySaverEnabled = enable;
         putGlobalSetting(Settings.Global.LOW_POWER_MODE, enable ? 1 : 0);
 
@@ -641,15 +810,6 @@
         manager.cancel(DYNAMIC_MODE_NOTIFICATION_ID);
     }
 
-    @GuardedBy("mLock")
-    private void updateSnoozingLocked(boolean snoozing, String reason) {
-        if (mBatterySaverSnoozing == snoozing) {
-            return;
-        }
-        if (DEBUG) Slog.d(TAG, "Snooze: " + (snoozing ? "start" : "stop")  + " reason=" + reason);
-        mBatterySaverSnoozing = snoozing;
-    }
-
     private void setStickyActive(boolean active) {
         mSettingBatterySaverEnabledSticky = active;
         putGlobalSetting(Settings.Global.LOW_POWER_MODE_STICKY,
@@ -684,6 +844,8 @@
                 pw.print(")");
             }
             pw.println();
+            pw.print("  mState=");
+            pw.println(mState);
 
             pw.print("  mLastChangedIntReason=");
             pw.println(mLastChangedIntReason);
@@ -697,9 +859,6 @@
             pw.print("  mBatteryStatusSet=");
             pw.println(mBatteryStatusSet);
 
-            pw.print("  mBatterySaverSnoozing=");
-            pw.println(mBatterySaverSnoozing);
-
             pw.print("  mIsPowered=");
             pw.println(mIsPowered);
             pw.print("  mBatteryLevel=");
@@ -731,6 +890,7 @@
 
             proto.write(BatterySaverStateMachineProto.ENABLED,
                     mBatterySaverController.isEnabled());
+            proto.write(BatterySaverStateMachineProto.STATE, mState);
             proto.write(BatterySaverStateMachineProto.IS_FULL_ENABLED,
                     mBatterySaverController.isFullEnabled());
             proto.write(BatterySaverStateMachineProto.IS_ADAPTIVE_ENABLED,
@@ -742,8 +902,6 @@
             proto.write(BatterySaverStateMachineProto.SETTINGS_LOADED, mSettingsLoaded);
             proto.write(BatterySaverStateMachineProto.BATTERY_STATUS_SET, mBatteryStatusSet);
 
-            proto.write(BatterySaverStateMachineProto.BATTERY_SAVER_SNOOZING,
-                    mBatterySaverSnoozing);
 
             proto.write(BatterySaverStateMachineProto.IS_POWERED, mIsPowered);
             proto.write(BatterySaverStateMachineProto.BATTERY_LEVEL, mBatteryLevel);
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index 7cea458..d7c9bc7 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -2453,46 +2453,43 @@
                 mService.getTaskChangeNotificationController()
                         .notifyActivityLaunchOnSecondaryDisplayFailed(task.getTaskInfo(),
                                 preferredDisplayId);
-                return;
-            } else if (!forceNonResizable && handleForcedResizableTask(task,
-                    FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY)) {
-                return;
+            } else if (!forceNonResizable) {
+                handleForcedResizableTaskIfNeeded(task, FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY);
             }
+            // The information about not support secondary display should already be notified, we
+            // don't want to show another message on default display about split-screen. And it may
+            // be the case that a resizable activity is launched on a non-resizable task.
+            return;
         }
 
         if (!task.supportsSplitScreenWindowingMode() || forceNonResizable) {
-            // Display a warning toast that we tried to put an app that doesn't support split-screen
-            // in split-screen.
-            mService.getTaskChangeNotificationController().notifyActivityDismissingDockedStack();
-
             // Dismiss docked stack. If task appeared to be in docked stack but is not resizable -
             // we need to move it to top of fullscreen stack, otherwise it will be covered.
 
             final ActivityStack dockedStack =
                     task.getStack().getDisplay().getSplitScreenPrimaryStack();
             if (dockedStack != null) {
+                // Display a warning toast that we tried to put an app that doesn't support
+                // split-screen in split-screen.
+                mService.getTaskChangeNotificationController()
+                        .notifyActivityDismissingDockedStack();
                 moveTasksToFullscreenStackLocked(dockedStack, actualStack == dockedStack);
             }
             return;
         }
 
-        handleForcedResizableTask(task, FORCED_RESIZEABLE_REASON_SPLIT_SCREEN);
+        handleForcedResizableTaskIfNeeded(task, FORCED_RESIZEABLE_REASON_SPLIT_SCREEN);
     }
 
-    /**
-     * @return {@code true} if the top activity of the task is forced to be resizable and the user
-     *         was notified about activity being forced resized.
-     */
-    private boolean handleForcedResizableTask(TaskRecord task, int reason) {
+    /** Notifies that the top activity of the task is forced to be resizeable. */
+    private void handleForcedResizableTaskIfNeeded(TaskRecord task, int reason) {
         final ActivityRecord topActivity = task.getTopActivity();
-        if (topActivity != null && topActivity.isNonResizableOrForcedResizable()
-                && !topActivity.noDisplay) {
-            final String packageName = topActivity.appInfo.packageName;
-            mService.getTaskChangeNotificationController().notifyActivityForcedResizable(
-                    task.taskId, reason, packageName);
-            return true;
+        if (topActivity == null || topActivity.noDisplay
+                || !topActivity.isNonResizableOrForcedResizable()) {
+            return;
         }
-        return false;
+        mService.getTaskChangeNotificationController().notifyActivityForcedResizable(
+                task.taskId, reason, topActivity.appInfo.packageName);
     }
 
     void activityRelaunchedLocked(IBinder token) {
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index 5a20959..b262a00 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -352,6 +352,19 @@
     /** @return The intent used to launch the home activity. */
     public abstract Intent getHomeIntent();
     public abstract boolean startHomeActivity(int userId, String reason);
+    /**
+     * This starts home activity on displays that can have system decorations based on displayId -
+     * Default display always use primary home component.
+     * For Secondary displays, the home activity must have category SECONDARY_HOME and then resolves
+     * according to the priorities listed below.
+     *  - If default home is not set, always use the secondary home defined in the config.
+     *  - Use currently selected primary home activity.
+     *  - Use the activity in the same package as currently selected primary home activity.
+     *    If there are multiple activities matched, use first one.
+     *  - Use the secondary home defined in the config.
+     */
+    public abstract boolean startHomeOnDisplay(int userId, String reason, int displayId,
+            boolean fromHomeKey);
     /** Start home activities on all displays that support system decorations. */
     public abstract boolean startHomeOnAllDisplays(int userId, String reason);
     /** @return true if the given process is the factory test process. */
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 794a4b8..118eb5b 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -748,6 +748,7 @@
             mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
             mWindowManager.setSupportsFreeformWindowManagement(mSupportsFreeformWindowManagement);
             mWindowManager.setIsPc(isPc);
+            mWindowManager.mRoot.onSettingsRetrieved();
             // This happens before any activities are started, so we can change global configuration
             // in-place.
             updateConfigurationLocked(configuration, null, true);
@@ -6490,6 +6491,13 @@
         }
 
         @Override
+        public boolean startHomeOnDisplay(int userId, String reason, int displayId,
+                boolean fromHomeKey) {
+            return mRootActivityContainer.startHomeOnDisplay(userId, reason, displayId,
+                    fromHomeKey);
+        }
+
+        @Override
         public boolean startHomeOnAllDisplays(int userId, String reason) {
             synchronized (mGlobalLock) {
                 return mRootActivityContainer.startHomeOnAllDisplays(userId, reason);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index bcfbefe..b00cafd 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -3284,7 +3284,11 @@
     }
 
     private void updateImeParent() {
-        final SurfaceControl newParent = computeImeParent();
+        // Force attaching IME to the display when magnifying, or it would be magnified with
+        // target app together.
+        final boolean shouldAttachToDisplay = (mMagnificationSpec != null);
+        final SurfaceControl newParent =
+                shouldAttachToDisplay ? mWindowingLayer : computeImeParent();
         if (newParent != null) {
             mPendingTransaction.reparent(mImeWindowsContainers.mSurfaceControl, newParent);
             scheduleAnimation();
@@ -4699,6 +4703,8 @@
         } else {
             mMagnificationSpec = null;
         }
+        // Re-parent IME's SurfaceControl when MagnificationSpec changed.
+        updateImeParent();
 
         applyMagnificationSpec(getPendingTransaction(), spec);
         getPendingTransaction().apply();
diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettings.java b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
index 4617890..db96847 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowSettings.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
@@ -352,6 +352,24 @@
         dc.mDisplayScalingDisabled = entry.mForcedScalingMode == FORCE_SCALING_MODE_DISABLED;
     }
 
+    /**
+     * Updates settings for the given display after system features are loaded into window manager
+     * service, e.g. if this device is PC and if this device supports freeform.
+     *
+     * @param dc the given display.
+     * @return {@code true} if any settings for this display has changed; {@code false} if nothing
+     * changed.
+     */
+    boolean updateSettingsForDisplay(DisplayContent dc) {
+        if (dc.getWindowingMode() != getWindowingModeLocked(dc)) {
+            // For the time being the only thing that may change is windowing mode, so just update
+            // that.
+            dc.setWindowingMode(getWindowingModeLocked(dc));
+            return true;
+        }
+        return false;
+    }
+
     private void readSettings() {
         FileInputStream stream;
         try {
diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java
index f964b57..24cf7f1 100644
--- a/services/core/java/com/android/server/wm/RootActivityContainer.java
+++ b/services/core/java/com/android/server/wm/RootActivityContainer.java
@@ -114,6 +114,7 @@
 import com.android.server.am.ActivityManagerService;
 import com.android.server.am.AppTimeTracker;
 import com.android.server.am.UserState;
+import com.android.server.policy.WindowManagerPolicy;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -345,6 +346,10 @@
         }
     }
 
+    boolean startHomeOnDisplay(int userId, String reason, int displayId) {
+        return startHomeOnDisplay(userId, reason, displayId, false /*fromHomeKey*/);
+    }
+
     /**
      * This starts home activity on displays that can have system decorations based on displayId -
      * Default display always use primary home component.
@@ -356,7 +361,12 @@
      *    If there are multiple activities matched, use first one.
      *  - Use the secondary home defined in the config.
      */
-    boolean startHomeOnDisplay(int userId, String reason, int displayId) {
+    boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean fromHomeKey) {
+        // Fallback to top focused display if the displayId is invalid.
+        if (displayId == INVALID_DISPLAY) {
+            displayId = getTopDisplayFocusedStack().mDisplayId;
+        }
+
         Intent homeIntent;
         ActivityInfo aInfo;
         if (displayId == DEFAULT_DISPLAY) {
@@ -380,6 +390,10 @@
         // Updates the home component of the intent.
         homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
         homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
+        // Updates the extra information of the intent.
+        if (fromHomeKey) {
+            homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true);
+        }
         // Update the reason for ANR debugging to verify if the user activity is the one that
         // actually launched.
         final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index db7613a..8f4e842 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -245,6 +245,34 @@
         return dc;
     }
 
+    /**
+     * Called when DisplayWindowSettings values may change.
+     */
+    void onSettingsRetrieved() {
+        final int numDisplays = mChildren.size();
+        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+            final DisplayContent displayContent = mChildren.get(displayNdx);
+            final boolean changed = mWmService.mDisplayWindowSettings.updateSettingsForDisplay(
+                    displayContent);
+            if (!changed) {
+                continue;
+            }
+
+            displayContent.initializeDisplayOverrideConfiguration();
+            mWmService.reconfigureDisplayLocked(displayContent);
+
+            // We need to update global configuration as well if config of default display has
+            // changed. Do it inline because ATMS#retrieveSettings() will soon update the
+            // configuration inline, which will overwrite the new windowing mode.
+            if (displayContent.isDefaultDisplay) {
+                final Configuration newConfig = mWmService.computeNewConfiguration(
+                        displayContent.getDisplayId());
+                mWmService.mAtmService.updateConfigurationLocked(newConfig, null /* starting */,
+                        false /* initLocale */);
+            }
+        }
+    }
+
     boolean isLayoutNeeded() {
         final int numDisplays = mChildren.size();
         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
diff --git a/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java b/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java
index bdb76c2..bd4e542 100644
--- a/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java
+++ b/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java
@@ -83,7 +83,12 @@
     }
 
     public void systemReady() {
-        mGestureDetector = new GestureDetector(mContext, new FlingGestureDetector(), mHandler);
+        // GestureDetector records statistics about gesture classification events to inform gesture
+        // usage trends. SystemGesturesPointerEventListener creates a lot of noise in these
+        // statistics because it passes every touch event though a GestureDetector. By creating an
+        // anonymous subclass of GestureDetector, these statistics will be recorded with a unique
+        // source name that can be filtered.
+        mGestureDetector = new GestureDetector(mContext, new FlingGestureDetector(), mHandler) {};
     }
 
     @Override
diff --git a/services/net/java/android/net/NetworkStackClient.java b/services/net/java/android/net/NetworkStackClient.java
index fe447fc..cc09fe3 100644
--- a/services/net/java/android/net/NetworkStackClient.java
+++ b/services/net/java/android/net/NetworkStackClient.java
@@ -120,8 +120,7 @@
      *
      * <p>The INetworkMonitor will be returned asynchronously through the provided callbacks.
      */
-    public void makeNetworkMonitor(
-            NetworkParcelable network, String name, INetworkMonitorCallbacks cb) {
+    public void makeNetworkMonitor(Network network, String name, INetworkMonitorCallbacks cb) {
         requestConnector(connector -> {
             try {
                 connector.makeNetworkMonitor(network, name, cb);
diff --git a/services/net/java/android/net/ip/IpClientUtil.java b/services/net/java/android/net/ip/IpClientUtil.java
index bf917bf..90624e0 100644
--- a/services/net/java/android/net/ip/IpClientUtil.java
+++ b/services/net/java/android/net/ip/IpClientUtil.java
@@ -17,12 +17,10 @@
 package android.net.ip;
 
 import static android.net.shared.IpConfigurationParcelableUtil.fromStableParcelable;
-import static android.net.shared.LinkPropertiesParcelableUtil.fromStableParcelable;
 
 import android.content.Context;
 import android.net.DhcpResultsParcelable;
 import android.net.LinkProperties;
-import android.net.LinkPropertiesParcelable;
 import android.net.NetworkStackClient;
 import android.os.ConditionVariable;
 
@@ -122,18 +120,18 @@
         }
 
         @Override
-        public void onProvisioningSuccess(LinkPropertiesParcelable newLp) {
-            mCb.onProvisioningSuccess(fromStableParcelable(newLp));
+        public void onProvisioningSuccess(LinkProperties newLp) {
+            mCb.onProvisioningSuccess(newLp);
         }
         @Override
-        public void onProvisioningFailure(LinkPropertiesParcelable newLp) {
-            mCb.onProvisioningFailure(fromStableParcelable(newLp));
+        public void onProvisioningFailure(LinkProperties newLp) {
+            mCb.onProvisioningFailure(newLp);
         }
 
         // Invoked on LinkProperties changes.
         @Override
-        public void onLinkPropertiesChange(LinkPropertiesParcelable newLp) {
-            mCb.onLinkPropertiesChange(fromStableParcelable(newLp));
+        public void onLinkPropertiesChange(LinkProperties newLp) {
+            mCb.onLinkPropertiesChange(newLp);
         }
 
         // Called when the internal IpReachabilityMonitor (if enabled) has
diff --git a/services/net/java/android/net/shared/InitialConfiguration.java b/services/net/java/android/net/shared/InitialConfiguration.java
index 4ad7138..e423d62 100644
--- a/services/net/java/android/net/shared/InitialConfiguration.java
+++ b/services/net/java/android/net/shared/InitialConfiguration.java
@@ -23,13 +23,12 @@
 import android.net.InetAddresses;
 import android.net.InitialConfigurationParcelable;
 import android.net.IpPrefix;
-import android.net.IpPrefixParcelable;
 import android.net.LinkAddress;
-import android.net.LinkAddressParcelable;
 import android.net.RouteInfo;
 
 import java.net.Inet4Address;
 import java.net.InetAddress;
+import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -148,10 +147,8 @@
      */
     public InitialConfigurationParcelable toStableParcelable() {
         final InitialConfigurationParcelable p = new InitialConfigurationParcelable();
-        p.ipAddresses = toParcelableArray(ipAddresses,
-                LinkPropertiesParcelableUtil::toStableParcelable, LinkAddressParcelable.class);
-        p.directlyConnectedRoutes = toParcelableArray(directlyConnectedRoutes,
-                LinkPropertiesParcelableUtil::toStableParcelable, IpPrefixParcelable.class);
+        p.ipAddresses = ipAddresses.toArray(new LinkAddress[0]);
+        p.directlyConnectedRoutes = directlyConnectedRoutes.toArray(new IpPrefix[0]);
         p.dnsServers = toParcelableArray(
                 dnsServers, IpConfigurationParcelableUtil::parcelAddress, String.class);
         return p;
@@ -164,10 +161,8 @@
     public static InitialConfiguration fromStableParcelable(InitialConfigurationParcelable p) {
         if (p == null) return null;
         final InitialConfiguration config = new InitialConfiguration();
-        config.ipAddresses.addAll(fromParcelableArray(
-                p.ipAddresses, LinkPropertiesParcelableUtil::fromStableParcelable));
-        config.directlyConnectedRoutes.addAll(fromParcelableArray(
-                p.directlyConnectedRoutes, LinkPropertiesParcelableUtil::fromStableParcelable));
+        config.ipAddresses.addAll(Arrays.asList(p.ipAddresses));
+        config.directlyConnectedRoutes.addAll(Arrays.asList(p.directlyConnectedRoutes));
         config.dnsServers.addAll(
                 fromParcelableArray(p.dnsServers, IpConfigurationParcelableUtil::unparcelAddress));
         return config;
diff --git a/services/net/java/android/net/shared/IpConfigurationParcelableUtil.java b/services/net/java/android/net/shared/IpConfigurationParcelableUtil.java
index 1f0525e..6b5826f 100644
--- a/services/net/java/android/net/shared/IpConfigurationParcelableUtil.java
+++ b/services/net/java/android/net/shared/IpConfigurationParcelableUtil.java
@@ -44,7 +44,7 @@
             @Nullable StaticIpConfiguration config) {
         if (config == null) return null;
         final StaticIpConfigurationParcelable p = new StaticIpConfigurationParcelable();
-        p.ipAddress = LinkPropertiesParcelableUtil.toStableParcelable(config.getIpAddress());
+        p.ipAddress = config.getIpAddress();
         p.gateway = parcelAddress(config.getGateway());
         p.dnsServers = toParcelableArray(
                 config.getDnsServers(), IpConfigurationParcelableUtil::parcelAddress, String.class);
@@ -59,7 +59,7 @@
             @Nullable StaticIpConfigurationParcelable p) {
         if (p == null) return null;
         final StaticIpConfiguration config = new StaticIpConfiguration();
-        config.setIpAddress(LinkPropertiesParcelableUtil.fromStableParcelable(p.ipAddress));
+        config.setIpAddress(p.ipAddress);
         config.setGateway(unparcelAddress(p.gateway));
         for (InetAddress addr : fromParcelableArray(
                 p.dnsServers, IpConfigurationParcelableUtil::unparcelAddress)) {
diff --git a/services/net/java/android/net/shared/LinkPropertiesParcelableUtil.java b/services/net/java/android/net/shared/LinkPropertiesParcelableUtil.java
index 51d955d..1729da6 100644
--- a/services/net/java/android/net/shared/LinkPropertiesParcelableUtil.java
+++ b/services/net/java/android/net/shared/LinkPropertiesParcelableUtil.java
@@ -16,25 +16,9 @@
 
 package android.net.shared;
 
-import static android.net.shared.IpConfigurationParcelableUtil.parcelAddress;
-import static android.net.shared.IpConfigurationParcelableUtil.unparcelAddress;
-import static android.net.shared.ParcelableUtil.fromParcelableArray;
-import static android.net.shared.ParcelableUtil.toParcelableArray;
-
 import android.annotation.Nullable;
-import android.net.IpPrefix;
-import android.net.IpPrefixParcelable;
-import android.net.LinkAddress;
-import android.net.LinkAddressParcelable;
 import android.net.LinkProperties;
-import android.net.LinkPropertiesParcelable;
 import android.net.ProxyInfo;
-import android.net.ProxyInfoParcelable;
-import android.net.RouteInfo;
-import android.net.RouteInfoParcelable;
-import android.net.Uri;
-
-import java.util.Arrays;
 
 /**
  * Collection of utility methods to convert to and from stable AIDL parcelables for LinkProperties
@@ -42,177 +26,22 @@
  * @hide
  */
 public final class LinkPropertiesParcelableUtil {
+    // Temporary methods to facilitate migrating clients away from LinkPropertiesParcelable
+    // TODO: remove the following methods after migrating clients.
 
     /**
-     * Convert a ProxyInfo to a ProxyInfoParcelable
+     * @deprecated conversion to stable parcelable is no longer necessary.
      */
-    public static ProxyInfoParcelable toStableParcelable(@Nullable ProxyInfo proxyInfo) {
-        if (proxyInfo == null) {
-            return null;
-        }
-        final ProxyInfoParcelable parcel = new ProxyInfoParcelable();
-        parcel.host = proxyInfo.getHost();
-        parcel.port = proxyInfo.getPort();
-        parcel.exclusionList = proxyInfo.getExclusionList();
-        parcel.pacFileUrl = proxyInfo.getPacFileUrl().toString();
-        return parcel;
-    }
-
-    /**
-     * Convert a ProxyInfoParcelable to a ProxyInfo
-     */
-    public static ProxyInfo fromStableParcelable(@Nullable ProxyInfoParcelable parcel) {
-        if (parcel == null) {
-            return null;
-        }
-        if (Uri.EMPTY.toString().equals(parcel.pacFileUrl)) {
-            return ProxyInfo.buildDirectProxy(
-                    parcel.host, parcel.port, Arrays.asList(parcel.exclusionList));
-        } else {
-            return ProxyInfo.buildPacProxy(Uri.parse(parcel.pacFileUrl));
-        }
-    }
-
-    /**
-     * Convert an IpPrefixParcelable to an IpPrefix
-     */
-    public static IpPrefixParcelable toStableParcelable(@Nullable IpPrefix ipPrefix) {
-        if (ipPrefix == null) {
-            return null;
-        }
-        final IpPrefixParcelable parcel = new IpPrefixParcelable();
-        parcel.address = parcelAddress(ipPrefix.getAddress());
-        parcel.prefixLength = ipPrefix.getPrefixLength();
-        return parcel;
-    }
-
-    /**
-     * Convert an IpPrefix to an IpPrefixParcelable
-     */
-    public static IpPrefix fromStableParcelable(@Nullable IpPrefixParcelable parcel) {
-        if (parcel == null) {
-            return null;
-        }
-        return new IpPrefix(unparcelAddress(parcel.address), parcel.prefixLength);
-    }
-
-    /**
-     * Convert a RouteInfoParcelable to a RouteInfo
-     */
-    public static RouteInfoParcelable toStableParcelable(@Nullable RouteInfo routeInfo) {
-        if (routeInfo == null) {
-            return null;
-        }
-        final RouteInfoParcelable parcel = new RouteInfoParcelable();
-        parcel.destination = toStableParcelable(routeInfo.getDestination());
-        parcel.gatewayAddr = parcelAddress(routeInfo.getGateway());
-        parcel.ifaceName = routeInfo.getInterface();
-        parcel.type = routeInfo.getType();
-        return parcel;
-    }
-
-    /**
-     * Convert a RouteInfo to a RouteInfoParcelable
-     */
-    public static RouteInfo fromStableParcelable(@Nullable RouteInfoParcelable parcel) {
-        if (parcel == null) {
-            return null;
-        }
-        final IpPrefix destination = fromStableParcelable(parcel.destination);
-        return new RouteInfo(
-                destination, unparcelAddress(parcel.gatewayAddr),
-                parcel.ifaceName, parcel.type);
-    }
-
-    /**
-     * Convert a LinkAddressParcelable to a LinkAddress
-     */
-    public static LinkAddressParcelable toStableParcelable(@Nullable LinkAddress la) {
-        if (la == null) {
-            return null;
-        }
-        final LinkAddressParcelable parcel = new LinkAddressParcelable();
-        parcel.address = parcelAddress(la.getAddress());
-        parcel.prefixLength = la.getPrefixLength();
-        parcel.flags = la.getFlags();
-        parcel.scope = la.getScope();
-        return parcel;
-    }
-
-    /**
-     * Convert a LinkAddress to a LinkAddressParcelable
-     */
-    public static LinkAddress fromStableParcelable(@Nullable LinkAddressParcelable parcel) {
-        if (parcel == null) {
-            return null;
-        }
-        return new LinkAddress(
-                unparcelAddress(parcel.address),
-                parcel.prefixLength,
-                parcel.flags,
-                parcel.scope);
-    }
-
-    /**
-     * Convert a LinkProperties to a LinkPropertiesParcelable
-     */
-    public static LinkPropertiesParcelable toStableParcelable(@Nullable LinkProperties lp) {
-        if (lp == null) {
-            return null;
-        }
-        final LinkPropertiesParcelable parcel = new LinkPropertiesParcelable();
-        parcel.ifaceName = lp.getInterfaceName();
-        parcel.linkAddresses = toParcelableArray(
-                lp.getLinkAddresses(),
-                LinkPropertiesParcelableUtil::toStableParcelable,
-                LinkAddressParcelable.class);
-        parcel.dnses = toParcelableArray(
-                lp.getDnsServers(), IpConfigurationParcelableUtil::parcelAddress, String.class);
-        parcel.pcscfs = toParcelableArray(
-                lp.getPcscfServers(), IpConfigurationParcelableUtil::parcelAddress, String.class);
-        parcel.validatedPrivateDnses = toParcelableArray(lp.getValidatedPrivateDnsServers(),
-                IpConfigurationParcelableUtil::parcelAddress, String.class);
-        parcel.usePrivateDns = lp.isPrivateDnsActive();
-        parcel.privateDnsServerName = lp.getPrivateDnsServerName();
-        parcel.domains = lp.getDomains();
-        parcel.routes = toParcelableArray(
-                lp.getRoutes(), LinkPropertiesParcelableUtil::toStableParcelable,
-                RouteInfoParcelable.class);
-        parcel.httpProxy = toStableParcelable(lp.getHttpProxy());
-        parcel.mtu = lp.getMtu();
-        parcel.tcpBufferSizes = lp.getTcpBufferSizes();
-        parcel.nat64Prefix = toStableParcelable(lp.getNat64Prefix());
-        return parcel;
-    }
-
-    /**
-     * Convert a LinkPropertiesParcelable to a LinkProperties
-     */
-    public static LinkProperties fromStableParcelable(@Nullable LinkPropertiesParcelable parcel) {
-        if (parcel == null) {
-            return null;
-        }
-        final LinkProperties lp = new LinkProperties();
-        lp.setInterfaceName(parcel.ifaceName);
-        lp.setLinkAddresses(fromParcelableArray(parcel.linkAddresses,
-                LinkPropertiesParcelableUtil::fromStableParcelable));
-        lp.setDnsServers(fromParcelableArray(
-                parcel.dnses, IpConfigurationParcelableUtil::unparcelAddress));
-        lp.setPcscfServers(fromParcelableArray(
-                parcel.pcscfs, IpConfigurationParcelableUtil::unparcelAddress));
-        lp.setValidatedPrivateDnsServers(
-                fromParcelableArray(parcel.validatedPrivateDnses,
-                IpConfigurationParcelableUtil::unparcelAddress));
-        lp.setUsePrivateDns(parcel.usePrivateDns);
-        lp.setPrivateDnsServerName(parcel.privateDnsServerName);
-        lp.setDomains(parcel.domains);
-        for (RouteInfoParcelable route : parcel.routes) {
-            lp.addRoute(fromStableParcelable(route));
-        }
-        lp.setHttpProxy(fromStableParcelable(parcel.httpProxy));
-        lp.setMtu(parcel.mtu);
-        lp.setTcpBufferSizes(parcel.tcpBufferSizes);
-        lp.setNat64Prefix(fromStableParcelable(parcel.nat64Prefix));
+    @Deprecated
+    public static LinkProperties toStableParcelable(@Nullable LinkProperties lp) {
         return lp;
     }
+
+    /**
+     * @deprecated conversion to stable parcelable is no longer necessary.
+     */
+    @Deprecated
+    public static ProxyInfo toStableParcelable(@Nullable ProxyInfo info) {
+        return info;
+    }
 }
diff --git a/services/net/java/android/net/shared/NetworkParcelableUtil.java b/services/net/java/android/net/shared/NetworkParcelableUtil.java
deleted file mode 100644
index d0b54b8..0000000
--- a/services/net/java/android/net/shared/NetworkParcelableUtil.java
+++ /dev/null
@@ -1,50 +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.
- */
-
-package android.net.shared;
-
-import android.annotation.Nullable;
-import android.net.Network;
-import android.net.NetworkParcelable;
-
-/**
- * Utility methods to convert to/from stable AIDL parcelables for network attribute classes.
- * @hide
- */
-public final class NetworkParcelableUtil {
-    /**
-     * Convert from a Network to a NetworkParcelable.
-     */
-    public static NetworkParcelable toStableParcelable(@Nullable Network network) {
-        if (network == null) {
-            return null;
-        }
-        final NetworkParcelable p = new NetworkParcelable();
-        p.networkHandle = network.getNetworkHandle();
-
-        return p;
-    }
-
-    /**
-     * Convert from a NetworkParcelable to a Network.
-     */
-    public static Network fromStableParcelable(@Nullable NetworkParcelable p) {
-        if (p == null) {
-            return null;
-        }
-        return Network.fromNetworkHandle(p.networkHandle);
-    }
-}
diff --git a/services/net/java/android/net/shared/ProvisioningConfiguration.java b/services/net/java/android/net/shared/ProvisioningConfiguration.java
index f937065..0aceb22 100644
--- a/services/net/java/android/net/shared/ProvisioningConfiguration.java
+++ b/services/net/java/android/net/shared/ProvisioningConfiguration.java
@@ -239,7 +239,7 @@
         p.apfCapabilities = IpConfigurationParcelableUtil.toStableParcelable(mApfCapabilities);
         p.provisioningTimeoutMs = mProvisioningTimeoutMs;
         p.ipv6AddrGenMode = mIPv6AddrGenMode;
-        p.network = NetworkParcelableUtil.toStableParcelable(mNetwork);
+        p.network = mNetwork;
         p.displayName = mDisplayName;
         return p;
     }
@@ -263,7 +263,7 @@
                 p.apfCapabilities);
         config.mProvisioningTimeoutMs = p.provisioningTimeoutMs;
         config.mIPv6AddrGenMode = p.ipv6AddrGenMode;
-        config.mNetwork = NetworkParcelableUtil.fromStableParcelable(p.network);
+        config.mNetwork = p.network;
         config.mDisplayName = p.displayName;
         return config;
     }
diff --git a/services/robotests/backup/src/com/android/server/backup/restore/ActiveRestoreSessionTest.java b/services/robotests/backup/src/com/android/server/backup/restore/ActiveRestoreSessionTest.java
index f17a9fe..f4cea7a 100644
--- a/services/robotests/backup/src/com/android/server/backup/restore/ActiveRestoreSessionTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/restore/ActiveRestoreSessionTest.java
@@ -326,15 +326,14 @@
     }
 
     @Test
-    public void testRestoreSome_for2Packages() throws Exception {
+    public void testRestorePackages_for2Packages() throws Exception {
         mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
         TransportMock transportMock = setUpTransport(mTransport);
         IRestoreSession restoreSession =
                 createActiveRestoreSessionWithRestoreSets(null, mTransport, mRestoreSet1);
 
-        int result =
-                restoreSession.restoreSome(
-                        TOKEN_1, mObserver, mMonitor, new String[] {PACKAGE_1, PACKAGE_2});
+        int result = restoreSession.restorePackages(TOKEN_1, mObserver,
+                new String[] {PACKAGE_1, PACKAGE_2}, mMonitor);
 
         mShadowBackupLooper.runToEndOfTasks();
         assertThat(result).isEqualTo(0);
@@ -349,27 +348,27 @@
     }
 
     @Test
-    public void testRestoreSome_for2Packages_createsSystemRestoreTask() throws Exception {
+    public void testRestorePackages_for2Packages_createsSystemRestoreTask() throws Exception {
         mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
         setUpTransport(mTransport);
         IRestoreSession restoreSession =
                 createActiveRestoreSessionWithRestoreSets(null, mTransport, mRestoreSet1);
 
-        restoreSession.restoreSome(
-                TOKEN_1, mObserver, mMonitor, new String[] {PACKAGE_1, PACKAGE_2});
+        restoreSession.restorePackages(TOKEN_1, mObserver, new String[] {PACKAGE_1, PACKAGE_2},
+                mMonitor);
 
         mShadowBackupLooper.runToEndOfTasks();
         assertThat(ShadowPerformUnifiedRestoreTask.getLastCreated().isFullSystemRestore()).isTrue();
     }
 
     @Test
-    public void testRestoreSome_for1Package() throws Exception {
+    public void testRestorePackages_for1Package() throws Exception {
         mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
         setUpTransport(mTransport);
         IRestoreSession restoreSession =
                 createActiveRestoreSessionWithRestoreSets(null, mTransport, mRestoreSet1);
 
-        restoreSession.restoreSome(TOKEN_1, mObserver, mMonitor, new String[] {PACKAGE_1});
+        restoreSession.restorePackages(TOKEN_1, mObserver, new String[] {PACKAGE_1}, mMonitor);
 
         mShadowBackupLooper.runToEndOfTasks();
         ShadowPerformUnifiedRestoreTask shadowTask =
@@ -379,13 +378,13 @@
     }
 
     @Test
-    public void testRestoreSome_for1Package_createsNonSystemRestoreTask() throws Exception {
+    public void testRestorePackages_for1Package_createsNonSystemRestoreTask() throws Exception {
         mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
         setUpTransport(mTransport);
         IRestoreSession restoreSession =
                 createActiveRestoreSessionWithRestoreSets(null, mTransport, mRestoreSet1);
 
-        restoreSession.restoreSome(TOKEN_1, mObserver, mMonitor, new String[] {PACKAGE_1});
+        restoreSession.restorePackages(TOKEN_1, mObserver, new String[] {PACKAGE_1}, mMonitor);
 
         mShadowBackupLooper.runToEndOfTasks();
         assertThat(ShadowPerformUnifiedRestoreTask.getLastCreated().isFullSystemRestore())
@@ -393,32 +392,32 @@
     }
 
     @Test
-    public void testRestoreSome_whenNoRestoreSets() throws Exception {
+    public void testRestorePackages_whenNoRestoreSets() throws Exception {
         mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
         setUpTransport(mTransport);
         IRestoreSession restoreSession = createActiveRestoreSession(null, mTransport);
 
-        int result =
-                restoreSession.restoreSome(TOKEN_1, mObserver, mMonitor, new String[] {PACKAGE_1});
+        int result = restoreSession.restorePackages(TOKEN_1, mObserver, new String[] {PACKAGE_1},
+                mMonitor);
 
         assertThat(result).isEqualTo(-1);
     }
 
     @Test
-    public void testRestoreSome_whenSinglePackageSession() throws Exception {
+    public void testRestorePackages_whenSinglePackageSession() throws Exception {
         mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
         setUpTransport(mTransport);
         IRestoreSession restoreSession =
                 createActiveRestoreSessionWithRestoreSets(PACKAGE_1, mTransport, mRestoreSet1);
 
-        int result =
-                restoreSession.restoreSome(TOKEN_1, mObserver, mMonitor, new String[] {PACKAGE_2});
+        int result = restoreSession.restorePackages(TOKEN_1, mObserver, new String[] {PACKAGE_2},
+                mMonitor);
 
         assertThat(result).isEqualTo(-1);
     }
 
     @Test
-    public void testRestoreSome_whenSessionEnded() throws Exception {
+    public void testRestorePackages_whenSessionEnded() throws Exception {
         mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
         setUpTransport(mTransport);
         IRestoreSession restoreSession =
@@ -429,19 +428,19 @@
         expectThrows(
                 IllegalStateException.class,
                 () ->
-                        restoreSession.restoreSome(
-                                TOKEN_1, mObserver, mMonitor, new String[] {PACKAGE_1}));
+                        restoreSession.restorePackages(TOKEN_1, mObserver, new String[] {PACKAGE_1},
+                                mMonitor));
     }
 
     @Test
-    public void testRestoreSome_whenTransportNotRegistered() throws Exception {
+    public void testRestorePackages_whenTransportNotRegistered() throws Exception {
         mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
         setUpTransport(mTransport.unregistered());
         IRestoreSession restoreSession =
                 createActiveRestoreSessionWithRestoreSets(null, mTransport, mRestoreSet1);
 
-        int result =
-                restoreSession.restoreSome(TOKEN_1, mObserver, mMonitor, new String[] {PACKAGE_1});
+        int result = restoreSession.restorePackages(TOKEN_1, mObserver, new String[] {PACKAGE_1},
+                mMonitor);
 
         assertThat(result).isEqualTo(-1);
     }
diff --git a/services/tests/mockingservicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java b/services/tests/mockingservicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java
index 86e8598..2e5efbd 100644
--- a/services/tests/mockingservicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java
@@ -28,6 +28,7 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.res.Resources;
+import android.os.PowerManager;
 import android.provider.Settings.Global;
 
 import androidx.test.filters.SmallTest;
@@ -452,6 +453,21 @@
         assertEquals(true, mDevice.batterySaverEnabled);
         assertEquals(30, mPersistedState.batteryLevel);
         assertEquals(true, mPersistedState.batteryLow);
+
+        // Disable auto battery saver.
+        mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
+        mDevice.setBatteryLevel(25);
+
+        assertEquals(false, mDevice.batterySaverEnabled);
+        assertEquals(25, mPersistedState.batteryLevel);
+        assertEquals(false, mPersistedState.batteryLow);
+
+        // PowerManager sets batteryLow to true at 15% if battery saver trigger level is lower.
+        mDevice.setBatteryLevel(15);
+
+        assertEquals(false, mDevice.batterySaverEnabled);
+        assertEquals(15, mPersistedState.batteryLevel);
+        assertEquals(true, mPersistedState.batteryLow);
     }
 
     @Test
@@ -542,6 +558,12 @@
         assertEquals(100, mPersistedState.batteryLevel);
         assertEquals(false, mPersistedState.batteryLow);
 
+        mDevice.setBatteryLevel(97);
+
+        assertEquals(true, mDevice.batterySaverEnabled); // Stays on.
+        assertEquals(97, mPersistedState.batteryLevel);
+        assertEquals(false, mPersistedState.batteryLow);
+
         mDevice.setBatteryLevel(95);
 
         assertEquals(true, mDevice.batterySaverEnabled); // Stays on.
@@ -719,6 +741,48 @@
     }
 
     @Test
+    public void testAutoBatterySaver_withSticky_withAutoOffToggled() {
+        mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 50);
+        mDevice.putGlobalSetting(Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED, 1);
+        mDevice.putGlobalSetting(Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_LEVEL, 90);
+
+        // Scenario 1: User turns BS on manually above the threshold, it shouldn't turn off even
+        // with battery level change above threshold.
+        mDevice.setBatteryLevel(100);
+        mTarget.setBatterySaverEnabledManually(true);
+
+        assertEquals(true, mDevice.batterySaverEnabled);
+        assertEquals(100, mPersistedState.batteryLevel);
+        assertEquals(false, mPersistedState.batteryLow);
+
+        mDevice.setBatteryLevel(95);
+
+        assertEquals(true, mDevice.batterySaverEnabled); // Stays on.
+        assertEquals(95, mPersistedState.batteryLevel);
+        assertEquals(false, mPersistedState.batteryLow);
+
+        // Disable auto disable while in the pending sticky state. BS should reactivate after
+        // unplug.
+        mDevice.setPowered(true);
+        mDevice.putGlobalSetting(Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED, 0);
+        mDevice.setPowered(false);
+
+        assertEquals(true, mDevice.batterySaverEnabled); // Sticky BS should activate.
+        assertEquals(95, mPersistedState.batteryLevel);
+        assertEquals(false, mPersistedState.batteryLow);
+
+        // Enable auto disable while in the pending sticky state. Sticky should turn off after
+        // unplug.
+        mDevice.setPowered(true);
+        mDevice.putGlobalSetting(Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED, 1);
+        mDevice.setPowered(false);
+
+        assertEquals(false, mDevice.batterySaverEnabled); // Sticky BS no longer enabled.
+        assertEquals(95, mPersistedState.batteryLevel);
+        assertEquals(false, mPersistedState.batteryLow);
+    }
+
+    @Test
     public void testAutoBatterySaver_withStickyDisabled() {
         when(mMockResources.getBoolean(
                 com.android.internal.R.bool.config_batterySaverStickyBehaviourDisabled))
@@ -739,7 +803,9 @@
         assertEquals(30, mPersistedState.batteryLevel);
         assertEquals(true, mPersistedState.batteryLow);
 
+        mDevice.setPowered(true);
         mDevice.setBatteryLevel(80);
+        mDevice.setPowered(false);
 
         assertEquals(false, mDevice.batterySaverEnabled); // Not sticky.
         assertEquals(80, mPersistedState.batteryLevel);
@@ -830,10 +896,9 @@
         assertEquals(90, mPersistedState.batteryLevel);
         assertEquals(false, mPersistedState.batteryLow);
 
-        // Reboot -- setting BS from adb is also sticky.
+        // Reboot -- LOW_POWER_MODE shouldn't be persisted.
         initDevice();
-
-        assertEquals(true, mDevice.batterySaverEnabled);
+        assertEquals(false, mDevice.batterySaverEnabled);
         assertEquals(90, mPersistedState.batteryLevel);
         assertEquals(false, mPersistedState.batteryLow);
     }
@@ -841,7 +906,8 @@
     @Test
     public void testAutoBatterySaver_smartBatterySaverEnabled() {
         mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 50);
-        mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVER_MODE, 1);
+        mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVER_MODE,
+                PowerManager.POWER_SAVER_MODE_DYNAMIC);
         mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_ENABLED, 0);
 
         assertEquals(false, mDevice.batterySaverEnabled);
@@ -922,8 +988,8 @@
         mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 71);
         mDevice.setBatteryLevel(mPersistedState.batteryLevel);
 
-        // changes are only registered if some battery level changed
-        assertEquals(false, mDevice.batterySaverEnabled);
+        // Changes should register immediately.
+        assertEquals(true, mDevice.batterySaverEnabled);
         assertEquals(70, mPersistedState.batteryLevel);
 
         mDevice.setBatteryLevel(69);
@@ -935,8 +1001,8 @@
         mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 60);
         mDevice.setBatteryLevel(mPersistedState.batteryLevel);
 
-        // changes are only registered if battery level changed
-        assertEquals(true, mDevice.batterySaverEnabled);
+        // Changes should register immediately.
+        assertEquals(false, mDevice.batterySaverEnabled);
         assertEquals(69, mPersistedState.batteryLevel);
 
         mDevice.setBatteryLevel(68);
@@ -956,4 +1022,220 @@
         assertEquals(true, mDevice.batterySaverEnabled);
         assertEquals(30, mPersistedState.batteryLevel);
     }
+
+    @Test
+    public void testAutoBatterySaver_snoozed_autoEnabled() {
+        mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 30);
+        // Test dynamic threshold higher than automatic to make sure it doesn't interfere when it's
+        // not enabled.
+        mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 50);
+        mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVER_MODE,
+                PowerManager.POWER_SAVER_MODE_PERCENTAGE);
+        mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_ENABLED, 0);
+
+        assertEquals(false, mDevice.batterySaverEnabled);
+        assertEquals(100, mPersistedState.batteryLevel);
+
+        mDevice.setBatteryLevel(90);
+
+        assertEquals(false, mDevice.batterySaverEnabled);
+        assertEquals(90, mPersistedState.batteryLevel);
+
+        mDevice.setBatteryLevel(51);
+
+        assertEquals(false, mDevice.batterySaverEnabled);
+        assertEquals(51, mPersistedState.batteryLevel);
+
+        // Hit dynamic threshold. BS should be disabled since dynamic is off
+        mDevice.setBatteryLevel(50);
+
+        assertEquals(false, mDevice.batterySaverEnabled);
+        assertEquals(50, mPersistedState.batteryLevel);
+
+        mDevice.setBatteryLevel(30);
+
+        assertEquals(true, mDevice.batterySaverEnabled);
+        assertEquals(30, mPersistedState.batteryLevel);
+
+        mDevice.setPowered(true);
+
+        assertEquals(false, mDevice.batterySaverEnabled);
+        assertEquals(30, mPersistedState.batteryLevel);
+
+        mDevice.setPowered(false);
+
+        assertEquals(true, mDevice.batterySaverEnabled);
+        assertEquals(30, mPersistedState.batteryLevel);
+
+        mTarget.setBatterySaverEnabledManually(false); // Manually disable -> snooze.
+
+        assertEquals(false, mDevice.batterySaverEnabled);
+        assertEquals(30, mPersistedState.batteryLevel);
+
+        mDevice.setBatteryLevel(20);
+
+        assertEquals(false, mDevice.batterySaverEnabled);
+        assertEquals(20, mPersistedState.batteryLevel);
+
+        // Lower threshold. Level is still below, so should still be snoozed.
+        mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 25);
+
+        assertEquals(false, mDevice.batterySaverEnabled);
+        assertEquals(20, mPersistedState.batteryLevel);
+
+        // Lower threshold even more. Battery no longer considered "low" so snoozing should be
+        // disabled.
+        mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 10);
+        // "batteryLow" is set in setBatteryLevel.
+        mDevice.setBatteryLevel(19);
+
+        assertEquals(false, mDevice.batterySaverEnabled);
+        assertEquals(19, mPersistedState.batteryLevel);
+
+        mDevice.setBatteryLevel(10);
+
+        assertEquals(true, mDevice.batterySaverEnabled); // No longer snoozing.
+        assertEquals(10, mPersistedState.batteryLevel);
+
+        mTarget.setBatterySaverEnabledManually(false); // Manually disable -> snooze.
+
+        // Plug in and out, snooze will reset.
+        mDevice.setPowered(true);
+        mDevice.setPowered(false);
+
+        assertEquals(true, mDevice.batterySaverEnabled);
+        assertEquals(10, mPersistedState.batteryLevel);
+
+        mDevice.setPowered(true);
+        mDevice.setBatteryLevel(60);
+
+        assertEquals(false, mDevice.batterySaverEnabled);
+        assertEquals(60, mPersistedState.batteryLevel);
+
+        // Test toggling resets snooze.
+        mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 50);
+        mDevice.setPowered(false);
+        mDevice.setBatteryLevel(45);
+
+        assertEquals(true, mDevice.batterySaverEnabled);
+        assertEquals(45, mPersistedState.batteryLevel);
+
+        mTarget.setBatterySaverEnabledManually(false); // Manually disable -> snooze.
+        assertEquals(false, mDevice.batterySaverEnabled);
+        assertEquals(45, mPersistedState.batteryLevel);
+
+        // Disable and re-enable.
+        mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
+        mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 50);
+
+        assertEquals(true, mDevice.batterySaverEnabled); // Snooze reset
+        assertEquals(45, mPersistedState.batteryLevel);
+    }
+
+    @Test
+    public void testAutoBatterySaver_snoozed_dynamicEnabled() {
+        // Test auto threshold higher than dynamic to make sure it doesn't interfere when it's
+        // not enabled.
+        mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 50);
+        mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 30);
+        mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVER_MODE,
+                PowerManager.POWER_SAVER_MODE_DYNAMIC);
+        mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_ENABLED, 1);
+
+        assertEquals(false, mDevice.batterySaverEnabled);
+        assertEquals(100, mPersistedState.batteryLevel);
+
+        mDevice.setBatteryLevel(90);
+
+        assertEquals(false, mDevice.batterySaverEnabled);
+        assertEquals(90, mPersistedState.batteryLevel);
+
+        mDevice.setBatteryLevel(51);
+
+        assertEquals(false, mDevice.batterySaverEnabled);
+        assertEquals(51, mPersistedState.batteryLevel);
+
+        // Hit automatic threshold. BS should be disabled since automatic is off
+        mDevice.setBatteryLevel(50);
+
+        assertEquals(false, mDevice.batterySaverEnabled);
+        assertEquals(50, mPersistedState.batteryLevel);
+
+        mDevice.setBatteryLevel(30);
+
+        assertEquals(true, mDevice.batterySaverEnabled);
+        assertEquals(30, mPersistedState.batteryLevel);
+
+        mDevice.setPowered(true);
+
+        assertEquals(false, mDevice.batterySaverEnabled);
+        assertEquals(30, mPersistedState.batteryLevel);
+
+        mDevice.setPowered(false);
+
+        assertEquals(true, mDevice.batterySaverEnabled);
+        assertEquals(30, mPersistedState.batteryLevel);
+
+        mTarget.setBatterySaverEnabledManually(false); // Manually disable -> snooze.
+
+        assertEquals(false, mDevice.batterySaverEnabled);
+        assertEquals(30, mPersistedState.batteryLevel);
+
+        mDevice.setBatteryLevel(20);
+
+        assertEquals(false, mDevice.batterySaverEnabled);
+        assertEquals(20, mPersistedState.batteryLevel);
+
+        // Lower threshold. Level is still below, so should still be snoozed.
+        mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 25);
+
+        assertEquals(false, mDevice.batterySaverEnabled);
+        assertEquals(20, mPersistedState.batteryLevel);
+
+        // Lower threshold even more. Battery no longer considered "low" so snoozing should be
+        // disabled.
+        mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 10);
+
+        assertEquals(false, mDevice.batterySaverEnabled);
+        assertEquals(20, mPersistedState.batteryLevel);
+
+        mDevice.setBatteryLevel(10);
+
+        assertEquals(true, mDevice.batterySaverEnabled); // No longer snoozing.
+        assertEquals(10, mPersistedState.batteryLevel);
+
+        mTarget.setBatterySaverEnabledManually(false); // Manually disable -> snooze.
+
+        // Plug in and out, snooze will reset.
+        mDevice.setPowered(true);
+        mDevice.setPowered(false);
+
+        assertEquals(true, mDevice.batterySaverEnabled);
+        assertEquals(10, mPersistedState.batteryLevel);
+
+        mDevice.setPowered(true);
+        mDevice.setBatteryLevel(60);
+
+        assertEquals(false, mDevice.batterySaverEnabled);
+        assertEquals(60, mPersistedState.batteryLevel);
+
+        // Test toggling resets snooze.
+        mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 50);
+        mDevice.setPowered(false);
+        mDevice.setBatteryLevel(45);
+
+        assertEquals(true, mDevice.batterySaverEnabled);
+        assertEquals(45, mPersistedState.batteryLevel);
+
+        mTarget.setBatterySaverEnabledManually(false); // Manually disable -> snooze.
+        assertEquals(false, mDevice.batterySaverEnabled);
+        assertEquals(45, mPersistedState.batteryLevel);
+
+        // Disable and re-enable.
+        mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_ENABLED, 0);
+        mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_ENABLED, 1);
+
+        assertEquals(true, mDevice.batterySaverEnabled); // Snooze reset
+        assertEquals(45, mPersistedState.batteryLevel);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
index 77515258..6a07a45e 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
@@ -338,12 +338,15 @@
         initializeCredentialUnderSP(password, PRIMARY_USER_ID);
         final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
 
+        assertFalse(mService.hasPendingEscrowToken(PRIMARY_USER_ID));
         long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID, null);
         assertFalse(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+        assertTrue(mService.hasPendingEscrowToken(PRIMARY_USER_ID));
 
         mService.verifyCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0,
                 PRIMARY_USER_ID).getResponseCode();
         assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+        assertFalse(mService.hasPendingEscrowToken(PRIMARY_USER_ID));
 
         mLocalService.setLockCredentialWithToken(pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
                 handle, token, PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID);
diff --git a/services/tests/servicestests/src/com/android/server/pm/LauncherAppsServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/LauncherAppsServiceTest.java
deleted file mode 100644
index d7dc58d..0000000
--- a/services/tests/servicestests/src/com/android/server/pm/LauncherAppsServiceTest.java
+++ /dev/null
@@ -1,87 +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.
- */
-
-package com.android.server.pm;
-
-import static org.junit.Assert.assertEquals;
-
-import android.content.pm.PackageParser;
-import android.content.pm.Signature;
-import android.content.pm.SigningInfo;
-import android.platform.test.annotations.Presubmit;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.junit.MockitoJUnitRunner;
-
-@Presubmit
-@RunWith(MockitoJUnitRunner.class)
-public class LauncherAppsServiceTest {
-
-    private static final Signature SIGNATURE_1 = new Signature(new byte[]{0x00, 0x01, 0x02, 0x03});
-    private static final Signature SIGNATURE_2 = new Signature(new byte[]{0x04, 0x05, 0x06, 0x07});
-    private static final Signature SIGNATURE_3 = new Signature(new byte[]{0x08, 0x09, 0x10, 0x11});
-
-    @Test
-    public void testComputePackageCertDigest() {
-        String digest = LauncherAppsService.LauncherAppsImpl.computePackageCertDigest(SIGNATURE_1);
-        assertEquals("A02A05B025B928C039CF1AE7E8EE04E7C190C0DB", digest);
-    }
-
-    @Test
-    public void testGetLatestSignaturesWithSingleCert() {
-        SigningInfo signingInfo = new SigningInfo(
-                new PackageParser.SigningDetails(
-                        new Signature[]{SIGNATURE_1},
-                        PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
-                        null,
-                        null));
-        Signature[] signatures = LauncherAppsService.LauncherAppsImpl.getLatestSignatures(
-                signingInfo);
-        assertEquals(1, signatures.length);
-        assertEquals(SIGNATURE_1, signatures[0]);
-    }
-
-    @Test
-    public void testGetLatestSignaturesWithMultiCert() {
-        SigningInfo signingInfo = new SigningInfo(
-                new PackageParser.SigningDetails(
-                        new Signature[]{SIGNATURE_1, SIGNATURE_2},
-                        PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
-                        null,
-                        null));
-        Signature[] signatures = LauncherAppsService.LauncherAppsImpl.getLatestSignatures(
-                signingInfo);
-        assertEquals(2, signatures.length);
-        assertEquals(SIGNATURE_1, signatures[0]);
-        assertEquals(SIGNATURE_2, signatures[1]);
-    }
-
-    @Test
-    public void testGetLatestSignaturesWithCertHistory() {
-        SigningInfo signingInfo = new SigningInfo(
-                new PackageParser.SigningDetails(
-                        new Signature[]{SIGNATURE_1},
-                        PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
-                        null,
-                        new Signature[]{SIGNATURE_2, SIGNATURE_3}));
-        Signature[] signatures = LauncherAppsService.LauncherAppsImpl.getLatestSignatures(
-                signingInfo);
-        assertEquals(1, signatures.length);
-        assertEquals(SIGNATURE_2, signatures[0]);
-    }
-
-}
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 4626840..6f96759 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -37,6 +37,7 @@
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
 import static android.content.pm.PackageManager.FEATURE_WATCH;
 import static android.content.pm.PackageManager.PERMISSION_DENIED;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.Build.VERSION_CODES.O_MR1;
 import static android.os.Build.VERSION_CODES.P;
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
@@ -111,6 +112,7 @@
 import android.testing.TestableContext;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
+import android.testing.TestablePermissions;
 import android.text.Html;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -4171,6 +4173,25 @@
     }
 
     @Test
+    public void testCanNotifyAsUser_crossUser() throws Exception {
+        // same user no problem
+        mBinderService.canNotifyAsPackage("src", "target", mContext.getUserId());
+
+        // cross user, no permission, problem
+        try {
+            mBinderService.canNotifyAsPackage("src", "target", mContext.getUserId() + 1);
+            fail("Should not be callable cross user without cross user permission");
+        } catch (SecurityException e) {
+            // good
+        }
+
+        // cross user, with permission, no problem
+        TestablePermissions perms = mContext.getTestablePermissions();
+        perms.setPermission(android.Manifest.permission.INTERACT_ACROSS_USERS, PERMISSION_GRANTED);
+        mBinderService.canNotifyAsPackage("src", "target", mContext.getUserId() + 1);
+    }
+
+    @Test
     public void setDefaultAssistantForUser_fromConfigXml() {
         clearDeviceConfig();
         ComponentName xmlConfig = new ComponentName("config", "xml");
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
index 59e71c4..9583b8ac 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
@@ -18,32 +18,26 @@
 
 import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
 import static android.app.ActivityManager.START_TASK_TO_FRONT;
+import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.contains;
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 
 import android.app.WaitResult;
+import android.content.pm.ActivityInfo;
 import android.platform.test.annotations.Presubmit;
 
 import androidx.test.filters.MediumTest;
@@ -112,4 +106,44 @@
             assertEquals(deliverToTopWait.who, firstActivity.mActivityComponent);
         }
     }
+
+    /**
+     * Ensures that {@link TaskChangeNotificationController} notifies only when an activity is
+     * forced to resize on secondary display.
+     */
+    @Test
+    public void testHandleNonResizableTaskOnSecondaryDisplay() {
+        // Create an unresizable task on secondary display.
+        final ActivityDisplay newDisplay = addNewActivityDisplayAt(ActivityDisplay.POSITION_TOP);
+        final ActivityStack stack = new StackBuilder(mRootActivityContainer)
+                .setDisplay(newDisplay).build();
+        final ActivityRecord unresizableActivity = stack.getTopActivity();
+        final TaskRecord task = unresizableActivity.getTaskRecord();
+        unresizableActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
+        task.setResizeMode(unresizableActivity.info.resizeMode);
+
+        final TaskChangeNotificationController taskChangeNotifier =
+                mService.getTaskChangeNotificationController();
+        spyOn(taskChangeNotifier);
+
+        mSupervisor.handleNonResizableTaskIfNeeded(task, newDisplay.getWindowingMode(),
+                newDisplay.mDisplayId, stack);
+        // The top activity is unresizable, so it should notify the activity is forced resizing.
+        verify(taskChangeNotifier).notifyActivityForcedResizable(eq(task.taskId),
+                eq(FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY),
+                eq(unresizableActivity.packageName));
+        reset(taskChangeNotifier);
+
+        // Put a resizable activity on top of the unresizable task.
+        final ActivityRecord resizableActivity = new ActivityBuilder(mService)
+                .setTask(task).build();
+        resizableActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
+
+        mSupervisor.handleNonResizableTaskIfNeeded(task, newDisplay.getWindowingMode(),
+                newDisplay.mDisplayId, stack);
+        // For the resizable activity, it is no need to force resizing or dismiss the docked stack.
+        verify(taskChangeNotifier, never()).notifyActivityForcedResizable(anyInt() /* taskId */,
+                anyInt() /* reason */, anyString() /* packageName */);
+        verify(taskChangeNotifier, never()).notifyActivityDismissingDockedStack();
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
index 2dad187..9a8a732 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
@@ -148,6 +148,19 @@
     }
 
     @Test
+    public void testPrimaryDisplayUpdateToFreeform_HasFreeformSupport_IsPc() {
+        mTarget.applySettingsToDisplayLocked(mPrimaryDisplay);
+
+        mWm.setSupportsFreeformWindowManagement(true);
+        mWm.setIsPc(true);
+
+        mTarget.updateSettingsForDisplay(mPrimaryDisplay);
+
+        assertEquals(WindowConfiguration.WINDOWING_MODE_FREEFORM,
+                mPrimaryDisplay.getWindowingMode());
+    }
+
+    @Test
     public void testSecondaryDisplayDefaultToFullscreen_NoFreeformSupport() {
         mTarget.applySettingsToDisplayLocked(mSecondaryDisplay);
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index 45fe5d2..35a8ec3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -20,9 +20,11 @@
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
+import android.app.WindowConfiguration;
 import android.platform.test.annotations.Presubmit;
 
 import androidx.test.filters.SmallTest;
@@ -71,5 +73,21 @@
         assertFalse(app.isVisible());
         assertFalse(mWm.mRoot.isAnyNonToastWindowVisibleForUid(FAKE_CALLING_UID));
     }
+
+    @Test
+    public void testUpdateDefaultDisplayWindowingModeOnSettingsRetrieved() {
+        synchronized (mWm.mGlobalLock) {
+            assertEquals(WindowConfiguration.WINDOWING_MODE_FULLSCREEN,
+                    mWm.getDefaultDisplayContentLocked().getWindowingMode());
+
+            mWm.mIsPc = true;
+            mWm.mSupportsFreeformWindowManagement = true;
+
+            mWm.mRoot.onSettingsRetrieved();
+
+            assertEquals(WindowConfiguration.WINDOWING_MODE_FREEFORM,
+                    mWm.getDefaultDisplayContentLocked().getWindowingMode());
+        }
+    }
 }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java
index 1b396f5..00e479fc 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java
@@ -32,7 +32,6 @@
 import android.platform.test.annotations.Presubmit;
 import android.view.InputChannel;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
 import org.junit.Before;
@@ -89,7 +88,6 @@
         assertNull(mTarget.getDragWindowHandleLocked());
     }
 
-    @FlakyTest(bugId = 69229402)
     @Test
     public void testHandleTapOutsideTask() {
         synchronized (mWm.mGlobalLock) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
index 2fc6efa..7d7c3985 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
@@ -43,7 +43,6 @@
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
 import org.junit.After;
@@ -212,7 +211,6 @@
         return createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, name);
     }
 
-    @FlakyTest(bugId = 124088319)
     @Test
     public void testAssignWindowLayers_ForImeWithNoTarget() {
         mDisplayContent.mInputMethodTarget = null;
@@ -230,7 +228,6 @@
         assertWindowHigher(mImeDialogWindow, mImeWindow);
     }
 
-    @FlakyTest(bugId = 124088319)
     @Test
     public void testAssignWindowLayers_ForImeWithAppTarget() {
         final WindowState imeAppTarget = createWindow("imeAppTarget");
@@ -250,7 +247,6 @@
         assertWindowHigher(mImeDialogWindow, mImeWindow);
     }
 
-    @FlakyTest(bugId = 124088319)
     @Test
     public void testAssignWindowLayers_ForImeWithAppTargetWithChildWindows() {
         final WindowState imeAppTarget = createWindow("imeAppTarget");
@@ -277,7 +273,6 @@
         assertWindowHigher(mImeDialogWindow, mImeWindow);
     }
 
-    @FlakyTest(bugId = 124088319)
     @Test
     public void testAssignWindowLayers_ForImeWithAppTargetAndAppAbove() {
         final WindowState appBelowImeTarget = createWindow("appBelowImeTarget");
@@ -301,7 +296,6 @@
         assertWindowHigher(mImeDialogWindow, mImeWindow);
     }
 
-    @FlakyTest(bugId = 124088319)
     @Test
     public void testAssignWindowLayers_ForImeNonAppImeTarget() {
         final WindowState imeSystemOverlayTarget = createWindow(null, TYPE_SYSTEM_OVERLAY,
@@ -329,7 +323,6 @@
         assertWindowHigher(mImeDialogWindow, mImeWindow);
     }
 
-    @FlakyTest(bugId = 124088319)
     @Test
     public void testAssignWindowLayers_ForStatusBarImeTarget() {
         mDisplayContent.mInputMethodTarget = mStatusBarWindow;
@@ -344,7 +337,6 @@
         assertWindowHigher(mImeDialogWindow, mImeWindow);
     }
 
-    @FlakyTest(bugId = 124088319)
     @Test
     public void testStackLayers() {
         final WindowState anyWindow1 = createWindow("anyWindow");
@@ -432,7 +424,6 @@
         }
     }
 
-    @FlakyTest(bugId = 124088319)
     @Test
     public void testDockedDividerPosition() {
         final WindowState pinnedStackWindow = createWindowOnStack(null, WINDOWING_MODE_PINNED,
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index dcaa499..c05a346 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -144,6 +144,16 @@
     public static final String EXTRA_LAST_EMERGENCY_CALLBACK_TIME_MILLIS =
             "android.telecom.extra.LAST_EMERGENCY_CALLBACK_TIME_MILLIS";
 
+
+    /**
+     * Extra key used to indicate whether a {@link CallScreeningService} has requested to silence
+     * the ringtone for a call.  If the {@link InCallService} declares
+     * {@link TelecomManager#METADATA_IN_CALL_SERVICE_RINGING} in its manifest, it should not
+     * play a ringtone for an incoming call with this extra key set.
+     */
+    public static final String EXTRA_SILENT_RINGING_REQUESTED =
+            "android.telecom.extra.SILENT_RINGING_REQUESTED";
+
     /**
      * Call event sent from a {@link Call} via {@link #sendCallEvent(String, Bundle)} to inform
      * Telecom that the user has requested that the current {@link Call} should be handed over
diff --git a/telecomm/java/android/telecom/CallScreeningService.java b/telecomm/java/android/telecom/CallScreeningService.java
index 2fa388f..b1aece7 100644
--- a/telecomm/java/android/telecom/CallScreeningService.java
+++ b/telecomm/java/android/telecom/CallScreeningService.java
@@ -259,12 +259,14 @@
     public static class CallResponse {
         private final boolean mShouldDisallowCall;
         private final boolean mShouldRejectCall;
+        private final boolean mShouldSilenceCall;
         private final boolean mShouldSkipCallLog;
         private final boolean mShouldSkipNotification;
 
         private CallResponse(
                 boolean shouldDisallowCall,
                 boolean shouldRejectCall,
+                boolean shouldSilenceCall,
                 boolean shouldSkipCallLog,
                 boolean shouldSkipNotification) {
             if (!shouldDisallowCall
@@ -276,6 +278,7 @@
             mShouldRejectCall = shouldRejectCall;
             mShouldSkipCallLog = shouldSkipCallLog;
             mShouldSkipNotification = shouldSkipNotification;
+            mShouldSilenceCall = shouldSilenceCall;
         }
 
         /*
@@ -294,6 +297,13 @@
         }
 
         /*
+         * @return Whether the ringtone should be silenced for the incoming call.
+         */
+        public boolean getSilenceCall() {
+            return mShouldSilenceCall;
+        }
+
+        /*
          * @return Whether the incoming call should not be displayed in the call log.
          */
         public boolean getSkipCallLog() {
@@ -310,6 +320,7 @@
         public static class Builder {
             private boolean mShouldDisallowCall;
             private boolean mShouldRejectCall;
+            private boolean mShouldSilenceCall;
             private boolean mShouldSkipCallLog;
             private boolean mShouldSkipNotification;
 
@@ -331,6 +342,21 @@
             }
 
             /**
+             * Sets whether ringing should be silenced for the incoming call.  When set
+             * to {@code true}, the Telecom framework will not play a ringtone for the call.
+             * The call will, however, still be sent to the default dialer app if it is not blocked.
+             * A {@link CallScreeningService} can use this to ensure a potential nuisance call is
+             * still surfaced to the user, but in a less intrusive manner.
+             *
+             * Setting this to true only makes sense when the call has not been disallowed
+             * using {@link #setDisallowCall(boolean)}.
+             */
+            public @NonNull Builder setSilenceCall(boolean shouldSilenceCall) {
+                mShouldSilenceCall = shouldSilenceCall;
+                return this;
+            }
+
+            /**
              * Sets whether the incoming call should not be displayed in the call log. This property
              * should only be set to true if the call is disallowed.
              * <p>
@@ -356,6 +382,7 @@
                 return new CallResponse(
                         mShouldDisallowCall,
                         mShouldRejectCall,
+                        mShouldSilenceCall,
                         mShouldSkipCallLog,
                         mShouldSkipNotification);
             }
@@ -411,10 +438,11 @@
     public abstract void onScreenCall(@NonNull Call.Details callDetails);
 
     /**
-     * Responds to the given incoming call, either allowing it or disallowing it.
+     * Responds to the given incoming call, either allowing it, silencing it or disallowing it.
      * <p>
      * The {@link CallScreeningService} calls this method to inform the system whether the call
-     * should be silently blocked or not.
+     * should be silently blocked or not. In the event that it should not be blocked, it may
+     * also be requested to ring silently.
      * <p>
      * Calls to this method are ignored unless the {@link Call.Details#getCallDirection()} is
      * {@link Call.Details#DIRECTION_INCOMING}.
@@ -436,6 +464,8 @@
                         !response.getSkipCallLog(),
                         !response.getSkipNotification(),
                         new ComponentName(getPackageName(), getClass().getName()));
+            } else if (response.getSilenceCall()) {
+                mCallScreeningAdapter.silenceCall(callDetails.getTelecomCallId());
             } else {
                 mCallScreeningAdapter.allowCall(callDetails.getTelecomCallId());
             }
diff --git a/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl b/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl
index a86c830..1160d27 100644
--- a/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl
@@ -29,6 +29,8 @@
 oneway interface ICallScreeningAdapter {
     void allowCall(String callId);
 
+    void silenceCall(String callId);
+
     void disallowCall(
             String callId,
             boolean shouldReject,
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 524d080..5f9ef3c 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1520,6 +1520,14 @@
             "carrier_app_no_wake_signal_config";
 
     /**
+     * Determines whether the carrier app needed to be involved when users try to finish setting up
+     * the SIM card to get network service.
+     * @hide
+     */
+    public static final String KEY_CARRIER_APP_REQUIRED_DURING_SIM_SETUP_BOOL =
+            "carrier_app_required_during_setup_bool";
+
+    /**
      * Default value for {@link Settings.Global#DATA_ROAMING}
      * @hide
      */
@@ -2307,9 +2315,9 @@
             "undelivered_sms_message_expiration_time";
 
     /**
-     * Specifies a carrier-defined {@link CallRedirectionService} which Telecom will bind
-     * to for outgoing calls.  An empty string indicates that no carrier-defined
-     * {@link CallRedirectionService} is specified.
+     * Specifies a carrier-defined {@link android.telecom.CallRedirectionService} which Telecom
+     * will bind to for outgoing calls.  An empty string indicates that no carrier-defined
+     * {@link android.telecom.CallRedirectionService} is specified.
      * @hide
      */
     public static final String KEY_CALL_REDIRECTION_SERVICE_COMPONENT_NAME_STRING =
@@ -2867,6 +2875,7 @@
         sDefaults.putString(KEY_CARRIER_NAME_STRING, "");
         sDefaults.putString(KEY_SIM_COUNTRY_ISO_OVERRIDE_STRING, "");
         sDefaults.putString(KEY_CARRIER_CALL_SCREENING_APP_STRING, "");
+        sDefaults.putString(KEY_CALL_REDIRECTION_SERVICE_COMPONENT_NAME_STRING, null);
         sDefaults.putBoolean(KEY_CDMA_HOME_REGISTERED_PLMN_NAME_OVERRIDE_BOOL, false);
         sDefaults.putString(KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING, "");
         sDefaults.putBoolean(KEY_SUPPORT_DIRECT_FDN_DIALING_BOOL, false);
@@ -2922,6 +2931,7 @@
                                 + "com.android.internal.telephony.CARRIER_SIGNAL_RESET"
                 });
         sDefaults.putStringArray(KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY, null);
+        sDefaults.putBoolean(KEY_CARRIER_APP_REQUIRED_DURING_SIM_SETUP_BOOL, false);
 
 
         // Default carrier app configurations
diff --git a/telephony/java/android/telephony/INetworkService.aidl b/telephony/java/android/telephony/INetworkService.aidl
index 9ef7186..67e5650 100644
--- a/telephony/java/android/telephony/INetworkService.aidl
+++ b/telephony/java/android/telephony/INetworkService.aidl
@@ -25,7 +25,7 @@
 {
     void createNetworkServiceProvider(int slotId);
     void removeNetworkServiceProvider(int slotId);
-    void getNetworkRegistrationState(int slotId, int domain, INetworkServiceCallback callback);
-    void registerForNetworkRegistrationStateChanged(int slotId, INetworkServiceCallback callback);
-    void unregisterForNetworkRegistrationStateChanged(int slotId, INetworkServiceCallback callback);
+    void getNetworkRegistrationInfo(int slotId, int domain, INetworkServiceCallback callback);
+    void registerForNetworkRegistrationInfoChanged(int slotId, INetworkServiceCallback callback);
+    void unregisterForNetworkRegistrationInfoChanged(int slotId, INetworkServiceCallback callback);
 }
diff --git a/telephony/java/android/telephony/INetworkServiceCallback.aidl b/telephony/java/android/telephony/INetworkServiceCallback.aidl
index 520598f..33b3ac0 100644
--- a/telephony/java/android/telephony/INetworkServiceCallback.aidl
+++ b/telephony/java/android/telephony/INetworkServiceCallback.aidl
@@ -16,7 +16,7 @@
 
 package android.telephony;
 
-import android.telephony.NetworkRegistrationState;
+import android.telephony.NetworkRegistrationInfo;
 
 /**
  * Network service call back interface
@@ -24,6 +24,6 @@
  */
 oneway interface INetworkServiceCallback
 {
-    void onGetNetworkRegistrationStateComplete(int result, in NetworkRegistrationState state);
+    void onGetNetworkRegistrationInfoComplete(int result, in NetworkRegistrationInfo state);
     void onNetworkStateChanged();
 }
diff --git a/telephony/java/android/telephony/NetworkRegistrationState.aidl b/telephony/java/android/telephony/NetworkRegistrationInfo.aidl
similarity index 94%
rename from telephony/java/android/telephony/NetworkRegistrationState.aidl
rename to telephony/java/android/telephony/NetworkRegistrationInfo.aidl
index 98cba77..5c803bf 100644
--- a/telephony/java/android/telephony/NetworkRegistrationState.aidl
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.aidl
@@ -16,4 +16,4 @@
 
 package android.telephony;
 
-parcelable NetworkRegistrationState;
+parcelable NetworkRegistrationInfo;
diff --git a/telephony/java/android/telephony/NetworkRegistrationState.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
similarity index 88%
rename from telephony/java/android/telephony/NetworkRegistrationState.java
rename to telephony/java/android/telephony/NetworkRegistrationInfo.java
index eff3285..c31a14e 100644
--- a/telephony/java/android/telephony/NetworkRegistrationState.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -32,11 +32,11 @@
 import java.util.stream.Collectors;
 
 /**
- * Description of a mobile network registration state
+ * Description of a mobile network registration info
  * @hide
  */
 @SystemApi
-public class NetworkRegistrationState implements Parcelable {
+public class NetworkRegistrationInfo implements Parcelable {
     /**
      * Network domain
      * @hide
@@ -184,12 +184,12 @@
      * @param cellIdentity The identity representing a unique cell or wifi AP. Set to null if the
      * information is not available.
      */
-    public NetworkRegistrationState(@Domain int domain, @TransportType int transportType,
-                                    @RegState int regState,
-                                    @NetworkType int accessNetworkTechnology, int rejectCause,
-                                    boolean emergencyOnly,
-                                    @NonNull @ServiceType int[] availableServices,
-                                    @Nullable CellIdentity cellIdentity) {
+    public NetworkRegistrationInfo(@Domain int domain, @TransportType int transportType,
+                                   @RegState int regState,
+                                   @NetworkType int accessNetworkTechnology, int rejectCause,
+                                   boolean emergencyOnly,
+                                   @NonNull @ServiceType int[] availableServices,
+                                   @Nullable CellIdentity cellIdentity) {
         mDomain = domain;
         mTransportType = transportType;
         mRegState = regState;
@@ -204,13 +204,15 @@
     }
 
     /**
-     * Constructor for voice network registration states.
+     * Constructor for voice network registration info.
      * @hide
      */
-    public NetworkRegistrationState(int domain, @TransportType int transportType, int regState,
-            int accessNetworkTechnology, int rejectCause, boolean emergencyOnly,
-            int[] availableServices, @Nullable CellIdentity cellIdentity, boolean cssSupported,
-            int roamingIndicator, int systemIsInPrl, int defaultRoamingIndicator) {
+    public NetworkRegistrationInfo(int domain, @TransportType int transportType, int regState,
+                                   int accessNetworkTechnology, int rejectCause,
+                                   boolean emergencyOnly, int[] availableServices,
+                                   @Nullable CellIdentity cellIdentity, boolean cssSupported,
+                                   int roamingIndicator, int systemIsInPrl,
+                                   int defaultRoamingIndicator) {
         this(domain, transportType, regState, accessNetworkTechnology, rejectCause, emergencyOnly,
                 availableServices, cellIdentity);
 
@@ -219,14 +221,16 @@
     }
 
     /**
-     * Constructor for data network registration states.
+     * Constructor for data network registration info.
      * @hide
      */
-    public NetworkRegistrationState(int domain, @TransportType int transportType, int regState,
-            int accessNetworkTechnology, int rejectCause, boolean emergencyOnly,
-            int[] availableServices, @Nullable CellIdentity cellIdentity, int maxDataCalls,
-            boolean isDcNrRestricted, boolean isNrAvailable, boolean isEndcAvailable,
-            LteVopsSupportInfo lteVopsSupportInfo) {
+    public NetworkRegistrationInfo(int domain, @TransportType int transportType, int regState,
+                                   int accessNetworkTechnology, int rejectCause,
+                                   boolean emergencyOnly, int[] availableServices,
+                                   @Nullable CellIdentity cellIdentity, int maxDataCalls,
+                                   boolean isDcNrRestricted, boolean isNrAvailable,
+                                   boolean isEndcAvailable,
+                                   LteVopsSupportInfo lteVopsSupportInfo) {
         this(domain, transportType, regState, accessNetworkTechnology, rejectCause, emergencyOnly,
                 availableServices, cellIdentity);
 
@@ -235,7 +239,7 @@
         updateNrStatus(mDataSpecificStates);
     }
 
-    private NetworkRegistrationState(Parcel source) {
+    private NetworkRegistrationInfo(Parcel source) {
         mDomain = source.readInt();
         mTransportType = source.readInt();
         mRegState = source.readInt();
@@ -433,7 +437,7 @@
 
     @Override
     public String toString() {
-        return new StringBuilder("NetworkRegistrationState{")
+        return new StringBuilder("NetworkRegistrationInfo{")
                 .append(" domain=").append((mDomain == DOMAIN_CS) ? "CS" : "PS")
                 .append(" transportType=").append(
                         AccessNetworkConstants.transportTypeToString(mTransportType))
@@ -465,11 +469,11 @@
     public boolean equals(Object o) {
         if (this == o) return true;
 
-        if (!(o instanceof NetworkRegistrationState)) {
+        if (!(o instanceof NetworkRegistrationInfo)) {
             return false;
         }
 
-        NetworkRegistrationState other = (NetworkRegistrationState) o;
+        NetworkRegistrationInfo other = (NetworkRegistrationInfo) o;
         return mDomain == other.mDomain
                 && mTransportType == other.mTransportType
                 && mRegState == other.mRegState
@@ -528,46 +532,46 @@
         }
     }
 
-    public static final @android.annotation.NonNull Parcelable.Creator<NetworkRegistrationState> CREATOR =
-            new Parcelable.Creator<NetworkRegistrationState>() {
-        @Override
-        public NetworkRegistrationState createFromParcel(Parcel source) {
-            return new NetworkRegistrationState(source);
-        }
+    public static final @NonNull Parcelable.Creator<NetworkRegistrationInfo> CREATOR =
+            new Parcelable.Creator<NetworkRegistrationInfo>() {
+                @Override
+                public NetworkRegistrationInfo createFromParcel(Parcel source) {
+                    return new NetworkRegistrationInfo(source);
+                }
 
-        @Override
-        public NetworkRegistrationState[] newArray(int size) {
-            return new NetworkRegistrationState[size];
-        }
-    };
+                @Override
+                public NetworkRegistrationInfo[] newArray(int size) {
+                    return new NetworkRegistrationInfo[size];
+                }
+            };
 
     /**
      * @hide
      */
-    public NetworkRegistrationState sanitizeLocationInfo() {
-        NetworkRegistrationState result = copy();
+    public NetworkRegistrationInfo sanitizeLocationInfo() {
+        NetworkRegistrationInfo result = copy();
         result.mCellIdentity = null;
         return result;
     }
 
-    private NetworkRegistrationState copy() {
+    private NetworkRegistrationInfo copy() {
         Parcel p = Parcel.obtain();
         this.writeToParcel(p, 0);
         p.setDataPosition(0);
-        NetworkRegistrationState result = new NetworkRegistrationState(p);
+        NetworkRegistrationInfo result = new NetworkRegistrationInfo(p);
         p.recycle();
         return result;
     }
 
     /**
-     * Provides a convenient way to set the fields of a {@link NetworkRegistrationState} when
+     * Provides a convenient way to set the fields of a {@link NetworkRegistrationInfo} when
      * creating a new instance.
      *
-     * <p>The example below shows how you might create a new {@code NetworkRegistrationState}:
+     * <p>The example below shows how you might create a new {@code NetworkRegistrationInfo}:
      *
      * <pre><code>
      *
-     * NetworkRegistrationState nrs = new NetworkRegistrationState.Builder()
+     * NetworkRegistrationInfo nrs = new NetworkRegistrationInfo.Builder()
      *     .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS)
      *     .setApnName("apn.example.com")
      *     .setEntryName("Example Carrier APN")
@@ -736,12 +740,12 @@
         }
 
         /**
-         * Build the NetworkRegistrationState.
+         * Build the NetworkRegistrationInfo.
          *
-         * @return the NetworkRegistrationState object.
+         * @return the NetworkRegistrationInfo object.
          */
-        public @NonNull NetworkRegistrationState build() {
-            return new NetworkRegistrationState(mDomain, mTransportType, mRegState,
+        public @NonNull NetworkRegistrationInfo build() {
+            return new NetworkRegistrationInfo(mDomain, mTransportType, mRegState,
                     mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices,
                     mCellIdentity);
         }
diff --git a/telephony/java/android/telephony/NetworkService.java b/telephony/java/android/telephony/NetworkService.java
index f1240e9fc..bc989dd 100644
--- a/telephony/java/android/telephony/NetworkService.java
+++ b/telephony/java/android/telephony/NetworkService.java
@@ -27,7 +27,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
-import android.telephony.NetworkRegistrationState.Domain;
+import android.telephony.NetworkRegistrationInfo.Domain;
 import android.util.SparseArray;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -59,10 +59,10 @@
     private static final int NETWORK_SERVICE_CREATE_NETWORK_SERVICE_PROVIDER                 = 1;
     private static final int NETWORK_SERVICE_REMOVE_NETWORK_SERVICE_PROVIDER                 = 2;
     private static final int NETWORK_SERVICE_REMOVE_ALL_NETWORK_SERVICE_PROVIDERS            = 3;
-    private static final int NETWORK_SERVICE_GET_REGISTRATION_STATE                          = 4;
-    private static final int NETWORK_SERVICE_REGISTER_FOR_STATE_CHANGE                       = 5;
-    private static final int NETWORK_SERVICE_UNREGISTER_FOR_STATE_CHANGE                     = 6;
-    private static final int NETWORK_SERVICE_INDICATION_NETWORK_STATE_CHANGED                = 7;
+    private static final int NETWORK_SERVICE_GET_REGISTRATION_INFO                           = 4;
+    private static final int NETWORK_SERVICE_REGISTER_FOR_INFO_CHANGE                        = 5;
+    private static final int NETWORK_SERVICE_UNREGISTER_FOR_INFO_CHANGE                      = 6;
+    private static final int NETWORK_SERVICE_INDICATION_NETWORK_INFO_CHANGED                 = 7;
 
 
     private final HandlerThread mHandlerThread;
@@ -86,7 +86,7 @@
         private final int mSlotIndex;
 
         private final List<INetworkServiceCallback>
-                mNetworkRegistrationStateChangedCallbacks = new ArrayList<>();
+                mNetworkRegistrationInfoChangedCallbacks = new ArrayList<>();
 
         /**
          * Constructor
@@ -104,38 +104,38 @@
         }
 
         /**
-         * API to get network registration state. The result will be passed to the callback.
+         * API to get network registration info. The result will be passed to the callback.
          * @param domain Network domain
-         * @param callback The callback for reporting network registration state
+         * @param callback The callback for reporting network registration info
          */
-        public void getNetworkRegistrationState(@Domain int domain,
-                                                @NonNull NetworkServiceCallback callback) {
-            callback.onGetNetworkRegistrationStateComplete(
+        public void getNetworkRegistrationInfo(@Domain int domain,
+                                               @NonNull NetworkServiceCallback callback) {
+            callback.onGetNetworkRegistrationInfoComplete(
                     NetworkServiceCallback.RESULT_ERROR_UNSUPPORTED, null);
         }
 
         /**
-         * Notify the system that network registration state is changed.
+         * Notify the system that network registration info is changed.
          */
-        public final void notifyNetworkRegistrationStateChanged() {
-            mHandler.obtainMessage(NETWORK_SERVICE_INDICATION_NETWORK_STATE_CHANGED,
+        public final void notifyNetworkRegistrationInfoChanged() {
+            mHandler.obtainMessage(NETWORK_SERVICE_INDICATION_NETWORK_INFO_CHANGED,
                     mSlotIndex, 0, null).sendToTarget();
         }
 
-        private void registerForStateChanged(@NonNull INetworkServiceCallback callback) {
-            synchronized (mNetworkRegistrationStateChangedCallbacks) {
-                mNetworkRegistrationStateChangedCallbacks.add(callback);
+        private void registerForInfoChanged(@NonNull INetworkServiceCallback callback) {
+            synchronized (mNetworkRegistrationInfoChangedCallbacks) {
+                mNetworkRegistrationInfoChangedCallbacks.add(callback);
             }
         }
 
-        private void unregisterForStateChanged(@NonNull INetworkServiceCallback callback) {
-            synchronized (mNetworkRegistrationStateChangedCallbacks) {
-                mNetworkRegistrationStateChangedCallbacks.remove(callback);
+        private void unregisterForInfoChanged(@NonNull INetworkServiceCallback callback) {
+            synchronized (mNetworkRegistrationInfoChangedCallbacks) {
+                mNetworkRegistrationInfoChangedCallbacks.remove(callback);
             }
         }
 
-        private void notifyStateChangedToCallbacks() {
-            for (INetworkServiceCallback callback : mNetworkRegistrationStateChangedCallbacks) {
+        private void notifyInfoChangedToCallbacks() {
+            for (INetworkServiceCallback callback : mNetworkRegistrationInfoChangedCallbacks) {
                 try {
                     callback.onNetworkStateChanged();
                 } catch (RemoteException exception) {
@@ -189,24 +189,24 @@
                     }
                     mServiceMap.clear();
                     break;
-                case NETWORK_SERVICE_GET_REGISTRATION_STATE:
+                case NETWORK_SERVICE_GET_REGISTRATION_INFO:
                     if (serviceProvider == null) break;
                     int domainId = message.arg2;
-                    serviceProvider.getNetworkRegistrationState(domainId,
+                    serviceProvider.getNetworkRegistrationInfo(domainId,
                             new NetworkServiceCallback(callback));
 
                     break;
-                case NETWORK_SERVICE_REGISTER_FOR_STATE_CHANGE:
+                case NETWORK_SERVICE_REGISTER_FOR_INFO_CHANGE:
                     if (serviceProvider == null) break;
-                    serviceProvider.registerForStateChanged(callback);
+                    serviceProvider.registerForInfoChanged(callback);
                     break;
-                case NETWORK_SERVICE_UNREGISTER_FOR_STATE_CHANGE:
+                case NETWORK_SERVICE_UNREGISTER_FOR_INFO_CHANGE:
                     if (serviceProvider == null) break;
-                    serviceProvider.unregisterForStateChanged(callback);
+                    serviceProvider.unregisterForInfoChanged(callback);
                     break;
-                case NETWORK_SERVICE_INDICATION_NETWORK_STATE_CHANGED:
+                case NETWORK_SERVICE_INDICATION_NETWORK_INFO_CHANGED:
                     if (serviceProvider == null) break;
-                    serviceProvider.notifyStateChangedToCallbacks();
+                    serviceProvider.notifyInfoChangedToCallbacks();
                     break;
                 default:
                     break;
@@ -280,23 +280,23 @@
         }
 
         @Override
-        public void getNetworkRegistrationState(
+        public void getNetworkRegistrationInfo(
                 int slotIndex, int domain, INetworkServiceCallback callback) {
-            mHandler.obtainMessage(NETWORK_SERVICE_GET_REGISTRATION_STATE, slotIndex,
+            mHandler.obtainMessage(NETWORK_SERVICE_GET_REGISTRATION_INFO, slotIndex,
                     domain, callback).sendToTarget();
         }
 
         @Override
-        public void registerForNetworkRegistrationStateChanged(
+        public void registerForNetworkRegistrationInfoChanged(
                 int slotIndex, INetworkServiceCallback callback) {
-            mHandler.obtainMessage(NETWORK_SERVICE_REGISTER_FOR_STATE_CHANGE, slotIndex,
+            mHandler.obtainMessage(NETWORK_SERVICE_REGISTER_FOR_INFO_CHANGE, slotIndex,
                     0, callback).sendToTarget();
         }
 
         @Override
-        public void unregisterForNetworkRegistrationStateChanged(
+        public void unregisterForNetworkRegistrationInfoChanged(
                 int slotIndex, INetworkServiceCallback callback) {
-            mHandler.obtainMessage(NETWORK_SERVICE_UNREGISTER_FOR_STATE_CHANGE, slotIndex,
+            mHandler.obtainMessage(NETWORK_SERVICE_UNREGISTER_FOR_INFO_CHANGE, slotIndex,
                     0, callback).sendToTarget();
         }
     }
diff --git a/telephony/java/android/telephony/NetworkServiceCallback.java b/telephony/java/android/telephony/NetworkServiceCallback.java
index c2fcfb7..cc25240 100644
--- a/telephony/java/android/telephony/NetworkServiceCallback.java
+++ b/telephony/java/android/telephony/NetworkServiceCallback.java
@@ -28,8 +28,8 @@
 
 /**
  * Network service callback. Object of this class is passed to NetworkServiceProvider upon
- * calling getNetworkRegistrationState, to receive asynchronous feedback from NetworkServiceProvider
- * upon onGetNetworkRegistrationStateComplete. It's like a wrapper of INetworkServiceCallback
+ * calling getNetworkRegistrationInfo, to receive asynchronous feedback from NetworkServiceProvider
+ * upon onGetNetworkRegistrationInfoComplete. It's like a wrapper of INetworkServiceCallback
  * because INetworkServiceCallback can't be a parameter type in public APIs.
  *
  * @hide
@@ -70,20 +70,20 @@
 
     /**
      * Called to indicate result of
-     * {@link NetworkServiceProvider#getNetworkRegistrationState(int, NetworkServiceCallback)}
+     * {@link NetworkServiceProvider#getNetworkRegistrationInfo(int, NetworkServiceCallback)}
      *
      * @param result Result status like {@link NetworkServiceCallback#RESULT_SUCCESS} or
      *                {@link NetworkServiceCallback#RESULT_ERROR_UNSUPPORTED}
      * @param state The state information to be returned to callback.
      */
-    public void onGetNetworkRegistrationStateComplete(int result,
-                                                      @Nullable NetworkRegistrationState state) {
+    public void onGetNetworkRegistrationInfoComplete(int result,
+                                                      @Nullable NetworkRegistrationInfo state) {
         INetworkServiceCallback callback = mCallback.get();
         if (callback != null) {
             try {
-                callback.onGetNetworkRegistrationStateComplete(result, state);
+                callback.onGetNetworkRegistrationInfoComplete(result, state);
             } catch (RemoteException e) {
-                Rlog.e(mTag, "Failed to onGetNetworkRegistrationStateComplete on the remote");
+                Rlog.e(mTag, "Failed to onGetNetworkRegistrationInfoComplete on the remote");
             }
         } else {
             Rlog.e(mTag, "Weak reference of callback is null.");
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 687c6f4..adbe2955 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -29,8 +29,8 @@
 import android.os.Parcelable;
 import android.telephony.AccessNetworkConstants.AccessNetworkType;
 import android.telephony.AccessNetworkConstants.TransportType;
-import android.telephony.NetworkRegistrationState.Domain;
-import android.telephony.NetworkRegistrationState.NRStatus;
+import android.telephony.NetworkRegistrationInfo.Domain;
+import android.telephony.NetworkRegistrationInfo.NRStatus;
 import android.text.TextUtils;
 
 import java.lang.annotation.Retention;
@@ -349,7 +349,7 @@
      * Reference: 3GPP TS 36.104 5.4.3 */
     private int mLteEarfcnRsrpBoost = 0;
 
-    private List<NetworkRegistrationState> mNetworkRegistrationStates = new ArrayList<>();
+    private List<NetworkRegistrationInfo> mNetworkRegistrationInfos = new ArrayList<>();
 
     /**
      * get String description of roaming type
@@ -432,8 +432,8 @@
         mCellBandwidths = s.mCellBandwidths == null ? null :
                 Arrays.copyOf(s.mCellBandwidths, s.mCellBandwidths.length);
         mLteEarfcnRsrpBoost = s.mLteEarfcnRsrpBoost;
-        mNetworkRegistrationStates = s.mNetworkRegistrationStates == null ? null :
-                new ArrayList<>(s.mNetworkRegistrationStates);
+        mNetworkRegistrationInfos = s.mNetworkRegistrationInfos == null ? null :
+                new ArrayList<>(s.mNetworkRegistrationInfos);
         mNrFrequencyRange = s.mNrFrequencyRange;
     }
 
@@ -466,8 +466,8 @@
         mIsEmergencyOnly = in.readInt() != 0;
         mIsUsingCarrierAggregation = in.readInt() != 0;
         mLteEarfcnRsrpBoost = in.readInt();
-        mNetworkRegistrationStates = new ArrayList<>();
-        in.readList(mNetworkRegistrationStates, NetworkRegistrationState.class.getClassLoader());
+        mNetworkRegistrationInfos = new ArrayList<>();
+        in.readList(mNetworkRegistrationInfos, NetworkRegistrationInfo.class.getClassLoader());
         mChannelNumber = in.readInt();
         mCellBandwidths = in.createIntArray();
         mNrFrequencyRange = in.readInt();
@@ -495,7 +495,7 @@
         out.writeInt(mIsEmergencyOnly ? 1 : 0);
         out.writeInt(mIsUsingCarrierAggregation ? 1 : 0);
         out.writeInt(mLteEarfcnRsrpBoost);
-        out.writeList(mNetworkRegistrationStates);
+        out.writeList(mNetworkRegistrationInfos);
         out.writeInt(mChannelNumber);
         out.writeIntArray(mCellBandwidths);
         out.writeInt(mNrFrequencyRange);
@@ -620,8 +620,8 @@
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     public @RoamingType int getVoiceRoamingType() {
-        final NetworkRegistrationState regState = getNetworkRegistrationState(
-                NetworkRegistrationState.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        final NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
+                NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
         if (regState != null) {
             return regState.getRoamingType();
         }
@@ -644,10 +644,10 @@
      * @hide
      */
     public boolean getDataRoamingFromRegistration() {
-        final NetworkRegistrationState regState = getNetworkRegistrationState(
-                NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        final NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
+                NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
         if (regState != null) {
-            return (regState.getRegState() == NetworkRegistrationState.REG_STATE_ROAMING);
+            return (regState.getRegState() == NetworkRegistrationInfo.REG_STATE_ROAMING);
         }
         return false;
     }
@@ -659,8 +659,8 @@
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     public @RoamingType int getDataRoamingType() {
-        final NetworkRegistrationState regState = getNetworkRegistrationState(
-                NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        final NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
+                NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
         if (regState != null) {
             return regState.getRoamingType();
         }
@@ -858,7 +858,7 @@
                 mIsEmergencyOnly,
                 mIsUsingCarrierAggregation,
                 mLteEarfcnRsrpBoost,
-                mNetworkRegistrationStates,
+                mNetworkRegistrationInfos,
                 mNrFrequencyRange);
     }
 
@@ -888,9 +888,9 @@
                         s.mCdmaDefaultRoamingIndicator)
                 && mIsEmergencyOnly == s.mIsEmergencyOnly
                 && mIsUsingCarrierAggregation == s.mIsUsingCarrierAggregation)
-                && (mNetworkRegistrationStates == null ? s.mNetworkRegistrationStates == null :
-                        s.mNetworkRegistrationStates != null &&
-                        mNetworkRegistrationStates.containsAll(s.mNetworkRegistrationStates))
+                && (mNetworkRegistrationInfos == null
+                ? s.mNetworkRegistrationInfos == null : s.mNetworkRegistrationInfos != null
+                && mNetworkRegistrationInfos.containsAll(s.mNetworkRegistrationInfos))
                 && mNrFrequencyRange == s.mNrFrequencyRange;
     }
 
@@ -1043,7 +1043,7 @@
             .append(", mIsEmergencyOnly=").append(mIsEmergencyOnly)
             .append(", mIsUsingCarrierAggregation=").append(mIsUsingCarrierAggregation)
             .append(", mLteEarfcnRsrpBoost=").append(mLteEarfcnRsrpBoost)
-            .append(", mNetworkRegistrationStates=").append(mNetworkRegistrationStates)
+            .append(", mNetworkRegistrationInfos=").append(mNetworkRegistrationInfos)
             .append(", mNrFrequencyRange=").append(mNrFrequencyRange)
             .append("}").toString();
     }
@@ -1073,7 +1073,7 @@
         mIsEmergencyOnly = false;
         mIsUsingCarrierAggregation = false;
         mLteEarfcnRsrpBoost = 0;
-        mNetworkRegistrationStates = new ArrayList<>();
+        mNetworkRegistrationInfos = new ArrayList<>();
         mNrFrequencyRange = FREQUENCY_RANGE_UNKNOWN;
     }
 
@@ -1130,14 +1130,14 @@
     /** @hide */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     public void setVoiceRoamingType(@RoamingType int type) {
-        NetworkRegistrationState regState = getNetworkRegistrationState(
-                NetworkRegistrationState.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
+                NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
         if (regState == null) {
-            regState = new NetworkRegistrationState(
-                    NetworkRegistrationState.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+            regState = new NetworkRegistrationInfo(
+                    NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                     ServiceState.ROAMING_TYPE_NOT_ROAMING, TelephonyManager.NETWORK_TYPE_UNKNOWN, 0,
                     false, null, null);
-            addNetworkRegistrationState(regState);
+            addNetworkRegistrationInfo(regState);
         }
         regState.setRoamingType(type);
     }
@@ -1151,14 +1151,14 @@
     /** @hide */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     public void setDataRoamingType(@RoamingType int type) {
-        NetworkRegistrationState regState = getNetworkRegistrationState(
-                NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
+                NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
         if (regState == null) {
-            regState = new NetworkRegistrationState(
-                    NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+            regState = new NetworkRegistrationInfo(
+                    NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                     ServiceState.ROAMING_TYPE_NOT_ROAMING, TelephonyManager.NETWORK_TYPE_UNKNOWN, 0,
                     false, null, null);
-            addNetworkRegistrationState(regState);
+            addNetworkRegistrationInfo(regState);
         }
         regState.setRoamingType(type);
     }
@@ -1326,14 +1326,14 @@
         this.mRilVoiceRadioTechnology = rt;
 
         // sync to network registration state
-        NetworkRegistrationState regState = getNetworkRegistrationState(
-                NetworkRegistrationState.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
+                NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
         if (regState == null) {
-            regState = new NetworkRegistrationState(
-                    NetworkRegistrationState.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+            regState = new NetworkRegistrationInfo(
+                    NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                     ServiceState.ROAMING_TYPE_NOT_ROAMING, TelephonyManager.NETWORK_TYPE_UNKNOWN,
                     0, false, null, null);
-            addNetworkRegistrationState(regState);
+            addNetworkRegistrationInfo(regState);
         }
         regState.setAccessNetworkTechnology(
                 rilRadioTechnologyToNetworkType(mRilVoiceRadioTechnology));
@@ -1353,15 +1353,15 @@
                 mRilDataRadioTechnology);
 
         // sync to network registration state
-        NetworkRegistrationState regState = getNetworkRegistrationState(
-                NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
+                NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
 
         if (regState == null) {
-            regState = new NetworkRegistrationState(
-                    NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+            regState = new NetworkRegistrationInfo(
+                    NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                     ServiceState.ROAMING_TYPE_NOT_ROAMING, TelephonyManager.NETWORK_TYPE_UNKNOWN,
                     0, false, null, null);
-            addNetworkRegistrationState(regState);
+            addNetworkRegistrationInfo(regState);
         }
         regState.setAccessNetworkTechnology(
                 rilRadioTechnologyToNetworkType(mRilDataRadioTechnology));
@@ -1391,9 +1391,9 @@
      * @hide
      */
     public @NRStatus int getNrStatus() {
-        final NetworkRegistrationState regState = getNetworkRegistrationState(
-                NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-        if (regState == null) return NetworkRegistrationState.NR_STATUS_NONE;
+        final NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
+                NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        if (regState == null) return NetworkRegistrationInfo.NR_STATUS_NONE;
         return regState.getNrStatus();
     }
 
@@ -1576,19 +1576,19 @@
     /** @hide */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     public @TelephonyManager.NetworkType int getDataNetworkType() {
-        final NetworkRegistrationState iwlanRegState = getNetworkRegistrationState(
-                NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
+        final NetworkRegistrationInfo iwlanRegState = getNetworkRegistrationInfo(
+                NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
         if (iwlanRegState != null
-                && iwlanRegState.getRegState() == NetworkRegistrationState.REG_STATE_HOME) {
+                && iwlanRegState.getRegState() == NetworkRegistrationInfo.REG_STATE_HOME) {
             // If the device is on IWLAN, return IWLAN as the network type. This is to simulate the
             // behavior of legacy mode device. In the future caller should use
-            // getNetworkRegistrationState() to retrieve the actual data network type on cellular
+            // getNetworkRegistrationInfo() to retrieve the actual data network type on cellular
             // or on IWLAN.
             return iwlanRegState.getAccessNetworkTechnology();
         }
 
-        final NetworkRegistrationState regState = getNetworkRegistrationState(
-                NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        final NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
+                NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
         if (regState != null) {
             return regState.getAccessNetworkTechnology();
         }
@@ -1598,8 +1598,8 @@
     /** @hide */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     public @TelephonyManager.NetworkType int getVoiceNetworkType() {
-        final NetworkRegistrationState regState = getNetworkRegistrationState(
-                NetworkRegistrationState.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        final NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
+                NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
         if (regState != null) {
             return regState.getAccessNetworkTechnology();
         }
@@ -1762,52 +1762,36 @@
     }
 
     /**
-     * Get all of the available network registration states.
+     * Get all of the available network registration info.
      *
-     * @return List of {@link NetworkRegistrationState}
+     * @return List of {@link NetworkRegistrationInfo}
      * @hide
      */
     @NonNull
     @SystemApi
-    public List<NetworkRegistrationState> getNetworkRegistrationStates() {
-        synchronized (mNetworkRegistrationStates) {
-            return new ArrayList<>(mNetworkRegistrationStates);
+    public List<NetworkRegistrationInfo> getNetworkRegistrationInfoList() {
+        synchronized (mNetworkRegistrationInfos) {
+            return new ArrayList<>(mNetworkRegistrationInfos);
         }
     }
 
     /**
-     * Get the network registration states for the transport type.
+     * Get the network registration info list for the transport type.
      *
      * @param transportType The transport type
-     * @return List of {@link NetworkRegistrationState}
-     * @hide
-     *
-     * @deprecated Use {@link #getNetworkRegistrationStatesForTransportType(int)}
-     */
-    @NonNull
-    @Deprecated
-    @SystemApi
-    public List<NetworkRegistrationState> getNetworkRegistrationStates(int transportType) {
-        return getNetworkRegistrationStatesForTransportType(transportType);
-    }
-
-    /**
-     * Get the network registration states for the transport type.
-     *
-     * @param transportType The transport type
-     * @return List of {@link NetworkRegistrationState}
+     * @return List of {@link NetworkRegistrationInfo}
      * @hide
      */
     @NonNull
     @SystemApi
-    public List<NetworkRegistrationState> getNetworkRegistrationStatesForTransportType(
+    public List<NetworkRegistrationInfo> getNetworkRegistrationInfoListForTransportType(
             @TransportType int transportType) {
-        List<NetworkRegistrationState> list = new ArrayList<>();
+        List<NetworkRegistrationInfo> list = new ArrayList<>();
 
-        synchronized (mNetworkRegistrationStates) {
-            for (NetworkRegistrationState networkRegistrationState : mNetworkRegistrationStates) {
-                if (networkRegistrationState.getTransportType() == transportType) {
-                    list.add(networkRegistrationState);
+        synchronized (mNetworkRegistrationInfos) {
+            for (NetworkRegistrationInfo networkRegistrationInfo : mNetworkRegistrationInfos) {
+                if (networkRegistrationInfo.getTransportType() == transportType) {
+                    list.add(networkRegistrationInfo);
                 }
             }
         }
@@ -1816,22 +1800,22 @@
     }
 
     /**
-     * Get the network registration states for the network domain.
+     * Get the network registration info list for the network domain.
      *
-     * @param domain The network {@link NetworkRegistrationState.Domain domain}
-     * @return List of {@link NetworkRegistrationState}
+     * @param domain The network {@link NetworkRegistrationInfo.Domain domain}
+     * @return List of {@link NetworkRegistrationInfo}
      * @hide
      */
     @NonNull
     @SystemApi
-    public List<NetworkRegistrationState> getNetworkRegistrationStatesForDomain(
+    public List<NetworkRegistrationInfo> getNetworkRegistrationInfoListForDomain(
             @Domain int domain) {
-        List<NetworkRegistrationState> list = new ArrayList<>();
+        List<NetworkRegistrationInfo> list = new ArrayList<>();
 
-        synchronized (mNetworkRegistrationStates) {
-            for (NetworkRegistrationState networkRegistrationState : mNetworkRegistrationStates) {
-                if (networkRegistrationState.getDomain() == domain) {
-                    list.add(networkRegistrationState);
+        synchronized (mNetworkRegistrationInfos) {
+            for (NetworkRegistrationInfo networkRegistrationInfo : mNetworkRegistrationInfos) {
+                if (networkRegistrationInfo.getDomain() == domain) {
+                    list.add(networkRegistrationInfo);
                 }
             }
         }
@@ -1842,39 +1826,21 @@
     /**
      * Get the network registration state for the transport type and network domain.
      *
-     * @param domain The network {@link NetworkRegistrationState.Domain domain}
+     * @param domain The network {@link NetworkRegistrationInfo.Domain domain}
      * @param transportType The transport type
-     * @return The matching {@link NetworkRegistrationState}
-     * @hide
-     *
-     * @deprecated Use {@link #getNetworkRegistrationState(int, int)}
-     */
-    @Nullable
-    @Deprecated
-    @SystemApi
-    public NetworkRegistrationState getNetworkRegistrationStates(@Domain int domain,
-                                                                 @TransportType int transportType) {
-        return getNetworkRegistrationState(domain, transportType);
-    }
-
-    /**
-     * Get the network registration state for the transport type and network domain.
-     *
-     * @param domain The network {@link NetworkRegistrationState.Domain domain}
-     * @param transportType The transport type
-     * @return The matching {@link NetworkRegistrationState}
+     * @return The matching {@link NetworkRegistrationInfo}
      * @hide
      *
      */
     @Nullable
     @SystemApi
-    public NetworkRegistrationState getNetworkRegistrationState(@Domain int domain,
-                                                                @TransportType int transportType) {
-        synchronized (mNetworkRegistrationStates) {
-            for (NetworkRegistrationState networkRegistrationState : mNetworkRegistrationStates) {
-                if (networkRegistrationState.getTransportType() == transportType
-                        && networkRegistrationState.getDomain() == domain) {
-                    return networkRegistrationState;
+    public NetworkRegistrationInfo getNetworkRegistrationInfo(@Domain int domain,
+                                                              @TransportType int transportType) {
+        synchronized (mNetworkRegistrationInfos) {
+            for (NetworkRegistrationInfo networkRegistrationInfo : mNetworkRegistrationInfos) {
+                if (networkRegistrationInfo.getTransportType() == transportType
+                        && networkRegistrationInfo.getDomain() == domain) {
+                    return networkRegistrationInfo;
                 }
             }
         }
@@ -1885,20 +1851,20 @@
     /**
      * @hide
      */
-    public void addNetworkRegistrationState(NetworkRegistrationState regState) {
+    public void addNetworkRegistrationInfo(NetworkRegistrationInfo regState) {
         if (regState == null) return;
 
-        synchronized (mNetworkRegistrationStates) {
-            for (int i = 0; i < mNetworkRegistrationStates.size(); i++) {
-                NetworkRegistrationState curRegState = mNetworkRegistrationStates.get(i);
+        synchronized (mNetworkRegistrationInfos) {
+            for (int i = 0; i < mNetworkRegistrationInfos.size(); i++) {
+                NetworkRegistrationInfo curRegState = mNetworkRegistrationInfos.get(i);
                 if (curRegState.getTransportType() == regState.getTransportType()
                         && curRegState.getDomain() == regState.getDomain()) {
-                    mNetworkRegistrationStates.remove(i);
+                    mNetworkRegistrationInfos.remove(i);
                     break;
                 }
             }
 
-            mNetworkRegistrationStates.add(regState);
+            mNetworkRegistrationInfos.add(regState);
         }
     }
 
@@ -1913,15 +1879,15 @@
 
     /**
      * Returns a copy of self with location-identifying information removed.
-     * Always clears the NetworkRegistrationState's CellIdentity fields, but if removeCoarseLocation
+     * Always clears the NetworkRegistrationInfo's CellIdentity fields, but if removeCoarseLocation
      * is true, clears other info as well.
      * @hide
      */
     public ServiceState sanitizeLocationInfo(boolean removeCoarseLocation) {
         ServiceState state = new ServiceState(this);
-        if (state.mNetworkRegistrationStates != null) {
-            state.mNetworkRegistrationStates = state.mNetworkRegistrationStates.stream()
-                    .map(NetworkRegistrationState::sanitizeLocationInfo)
+        if (state.mNetworkRegistrationInfos != null) {
+            state.mNetworkRegistrationInfos = state.mNetworkRegistrationInfos.stream()
+                    .map(NetworkRegistrationInfo::sanitizeLocationInfo)
                     .collect(Collectors.toList());
         }
         if (!removeCoarseLocation) return state;
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index f7ab921..99032bc 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -58,6 +58,8 @@
 import android.os.WorkSource;
 import android.provider.Settings.SettingNotFoundException;
 import android.service.carrier.CarrierIdentifier;
+import android.telecom.CallScreeningService;
+import android.telecom.InCallService;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
@@ -617,7 +619,13 @@
      * <p class="note">
      * Retrieve with
      * {@link android.content.Intent#getStringExtra(String)}.
+     * <p>
+     *
+     * @deprecated Companion apps for wearable devices should use the {@link InCallService} API
+     * to retrieve the phone number for calls instead.  Apps performing call screening should use
+     * the {@link CallScreeningService} API instead.
      */
+    @Deprecated
     public static final String EXTRA_INCOMING_NUMBER = "incoming_number";
 
     /**
@@ -9857,8 +9865,11 @@
      * <p>Requires Permission:
      *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
      *
+     *
+     * @deprecated
      * @hide
      */
+    @Deprecated
     @TestApi
     public void setCarrierTestOverride(String mccmnc, String imsi, String iccid, String gid1,
             String gid2, String plmn, String spn) {
@@ -9866,7 +9877,35 @@
             ITelephony telephony = getITelephony();
             if (telephony != null) {
                 telephony.setCarrierTestOverride(
-                        getSubId(), mccmnc, imsi, iccid, gid1, gid2, plmn, spn);
+                        getSubId(), mccmnc, imsi, iccid, gid1, gid2, plmn, spn,
+                        null, null);
+            }
+        } catch (RemoteException ex) {
+            // This could happen if binder process crashes.
+        }
+    }
+
+    /**
+     * A test API to override carrier information including mccmnc, imsi, iccid, gid1, gid2,
+     * plmn, spn, apn and carrier priviledge. This would be handy for, eg, forcing a particular
+     * carrier id, carrier's config (also any country or carrier overlays) to be loaded when using
+     * a test SIM with a call box.
+     *
+     * <p>Requires Permission:
+     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
+     *
+     * @hide
+     */
+    @TestApi
+    public void setCarrierTestOverride(String mccmnc, String imsi, String iccid, String gid1,
+                                       String gid2, String plmn, String spn,
+                                       String carrierPriviledgeRules, String apn) {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                telephony.setCarrierTestOverride(
+                        getSubId(), mccmnc, imsi, iccid, gid1, gid2, plmn, spn,
+                        carrierPriviledgeRules, apn);
             }
         } catch (RemoteException ex) {
             // This could happen if binder process crashes.
diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java
index e651783..875bd78 100644
--- a/telephony/java/android/telephony/euicc/EuiccManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccManager.java
@@ -285,6 +285,8 @@
      * {@link #ACTION_DELETE_SUBSCRIPTION_PRIVILEGED}, and
      * {@link #ACTION_RENAME_SUBSCRIPTION_PRIVILEGED} providing the ID of the targeted subscription.
      *
+     * <p>Expected type of the extra data: int
+     *
      * @hide
      */
     @SystemApi
@@ -295,6 +297,8 @@
      * Key for an extra set on {@link #ACTION_TOGGLE_SUBSCRIPTION_PRIVILEGED} providing a boolean
      * value of whether to enable or disable the targeted subscription.
      *
+     * <p>Expected type of the extra data: boolean
+     *
      * @hide
      */
     @SystemApi
@@ -305,6 +309,8 @@
      * Key for an extra set on {@link #ACTION_RENAME_SUBSCRIPTION_PRIVILEGED} providing a new
      * nickname for the targeted subscription.
      *
+     * <p>Expected type of the extra data: String
+     *
      * @hide
      */
     @SystemApi
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 62b92fd..c2c31cc 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -1683,7 +1683,7 @@
      * (also any country or carrier overlays) to be loaded when using a test SIM with a call box.
      */
     void setCarrierTestOverride(int subId, String mccmnc, String imsi, String iccid, String gid1,
-            String gid2, String plmn, String spn);
+            String gid2, String plmn, String spn, String carrierPrivilegeRules, String apn);
 
     /**
      * A test API to return installed carrier id list version.
diff --git a/tests/net/java/android/net/shared/LinkPropertiesParcelableUtilTest.java b/tests/net/java/android/net/shared/LinkPropertiesParcelableUtilTest.java
deleted file mode 100644
index 2d0e03d..0000000
--- a/tests/net/java/android/net/shared/LinkPropertiesParcelableUtilTest.java
+++ /dev/null
@@ -1,184 +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.
- */
-
-package android.net.shared;
-
-import static android.net.shared.LinkPropertiesParcelableUtil.fromStableParcelable;
-import static android.net.shared.LinkPropertiesParcelableUtil.toStableParcelable;
-import static android.net.shared.ParcelableTestUtil.assertFieldCountEquals;
-
-import static org.junit.Assert.assertEquals;
-
-import android.net.InetAddresses;
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.ProxyInfo;
-import android.net.RouteInfo;
-import android.net.Uri;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Arrays;
-import java.util.Collections;
-
-/**
- * Tests for {@link LinkPropertiesParcelableUtil}
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class LinkPropertiesParcelableUtilTest {
-    private LinkProperties mLinkProperties;
-
-    private static final String TEST_LINKPROPS_IFACE = "TEST_IFACE";
-
-    @Before
-    public void setUp() {
-        mLinkProperties = new LinkProperties();
-        mLinkProperties.setInterfaceName(TEST_LINKPROPS_IFACE);
-        mLinkProperties.setLinkAddresses(Arrays.asList(
-                new LinkAddress(InetAddresses.parseNumericAddress("192.168.0.42"), 16),
-                new LinkAddress(InetAddresses.parseNumericAddress("2001:db8::7"), 42)));
-        mLinkProperties.setDnsServers(Arrays.asList(
-                InetAddresses.parseNumericAddress("2001:db8::42"),
-                InetAddresses.parseNumericAddress("192.168.1.1")
-        ));
-        mLinkProperties.setValidatedPrivateDnsServers(Arrays.asList(
-                InetAddresses.parseNumericAddress("2001:db8::43"),
-                InetAddresses.parseNumericAddress("192.168.42.43")
-        ));
-        mLinkProperties.setPcscfServers(Arrays.asList(
-                InetAddresses.parseNumericAddress("2001:db8::47"),
-                InetAddresses.parseNumericAddress("192.168.42.47")
-        ));
-        mLinkProperties.setUsePrivateDns(true);
-        mLinkProperties.setPrivateDnsServerName("test.example.com");
-        mLinkProperties.setDomains("test1.example.com,test2.example.com");
-        mLinkProperties.addRoute(new RouteInfo(
-                new IpPrefix(InetAddresses.parseNumericAddress("2001:db8::44"), 45),
-                InetAddresses.parseNumericAddress("2001:db8::45"),
-                TEST_LINKPROPS_IFACE,
-                RouteInfo.RTN_UNICAST
-        ));
-        mLinkProperties.addRoute(new RouteInfo(
-                new IpPrefix(InetAddresses.parseNumericAddress("192.168.44.45"), 16),
-                InetAddresses.parseNumericAddress("192.168.45.1"),
-                TEST_LINKPROPS_IFACE,
-                RouteInfo.RTN_THROW
-        ));
-        mLinkProperties.setHttpProxy(new ProxyInfo("test3.example.com", 8000,
-                "excl1.example.com,excl2.example.com"));
-        mLinkProperties.setMtu(5000);
-        mLinkProperties.setTcpBufferSizes("1,2,3,4,5,6");
-        mLinkProperties.setNat64Prefix(
-                new IpPrefix(InetAddresses.parseNumericAddress("2001:db8::48"), 96));
-
-        // Verify that this test does not miss any new field added later.
-        // If any added field is not included in LinkProperties#equals, assertLinkPropertiesEquals
-        // must also be updated.
-        assertFieldCountEquals(14, LinkProperties.class);
-    }
-
-    @Test
-    public void testParcelUnparcel() {
-        doParcelUnparcelTest();
-    }
-
-    @Test
-    public void testParcelUnparcel_NullInterface() {
-        mLinkProperties.setInterfaceName(null);
-        doParcelUnparcelTest();
-    }
-
-    @Test
-    public void testParcelUnparcel_NullPrivateDnsServer() {
-        mLinkProperties.setPrivateDnsServerName(null);
-        doParcelUnparcelTest();
-    }
-
-    @Test
-    public void testParcelUnparcel_NullDomains() {
-        mLinkProperties.setDomains(null);
-        doParcelUnparcelTest();
-    }
-
-    @Test
-    public void testParcelUnparcel_NullProxy() {
-        mLinkProperties.setHttpProxy(null);
-        doParcelUnparcelTest();
-    }
-
-    @Test
-    public void testParcelUnparcel_NullTcpBufferSizes() {
-        mLinkProperties.setTcpBufferSizes(null);
-        doParcelUnparcelTest();
-    }
-
-    @Test
-    public void testParcelUnparcel_EmptyLinkAddresses() {
-        mLinkProperties.setLinkAddresses(Collections.emptyList());
-        doParcelUnparcelTest();
-    }
-
-    @Test
-    public void testParcelUnparcel_EmptyDnses() {
-        mLinkProperties.setDnsServers(Collections.emptyList());
-        doParcelUnparcelTest();
-    }
-
-    @Test
-    public void testParcelUnparcel_EmptyValidatedPrivateDnses() {
-        mLinkProperties.setValidatedPrivateDnsServers(Collections.emptyList());
-        doParcelUnparcelTest();
-    }
-
-    @Test
-    public void testParcelUnparcel_EmptyRoutes() {
-        for (RouteInfo r : mLinkProperties.getAllRoutes()) {
-            mLinkProperties.removeRoute(r);
-        }
-        doParcelUnparcelTest();
-    }
-
-    @Test
-    public void testParcelUnparcel_PacFileProxyInfo() {
-        mLinkProperties.setHttpProxy(new ProxyInfo(Uri.parse("http://pacfile.example.com")));
-        doParcelUnparcelTest();
-    }
-
-    @Test
-    public void testParcelUnparcel_NullNat64Prefix() {
-        mLinkProperties.setNat64Prefix(null);
-        doParcelUnparcelTest();
-    }
-
-    private void doParcelUnparcelTest() {
-        final LinkProperties unparceled = fromStableParcelable(toStableParcelable(mLinkProperties));
-        assertLinkPropertiesEquals(mLinkProperties, unparceled);
-    }
-
-    private static void assertLinkPropertiesEquals(LinkProperties expected, LinkProperties actual) {
-        assertEquals(expected, actual);
-
-        // Equality on stacked links is not tested as they should not be passed to processes using
-        // LinkPropertiesParcelable.
-    }
-}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 0633322..3263ef9 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -60,7 +60,6 @@
 import static android.net.NetworkPolicyManager.RULE_NONE;
 import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
 import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
-import static android.net.shared.NetworkParcelableUtil.fromStableParcelable;
 
 import static com.android.internal.util.TestUtils.waitForIdleHandler;
 import static com.android.internal.util.TestUtils.waitForIdleLooper;
@@ -125,7 +124,6 @@
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.DetailedState;
 import android.net.NetworkMisc;
-import android.net.NetworkParcelable;
 import android.net.NetworkRequest;
 import android.net.NetworkSpecifier;
 import android.net.NetworkStackClient;
@@ -502,8 +500,7 @@
                 fail(e.getMessage());
             }
 
-            final ArgumentCaptor<NetworkParcelable> nmNetworkCaptor =
-                    ArgumentCaptor.forClass(NetworkParcelable.class);
+            final ArgumentCaptor<Network> nmNetworkCaptor = ArgumentCaptor.forClass(Network.class);
             final ArgumentCaptor<INetworkMonitorCallbacks> nmCbCaptor =
                     ArgumentCaptor.forClass(INetworkMonitorCallbacks.class);
             doNothing().when(mNetworkStack).makeNetworkMonitor(
@@ -543,8 +540,7 @@
                 }
             };
 
-            assertEquals(
-                    mNetworkAgent.netId, fromStableParcelable(nmNetworkCaptor.getValue()).netId);
+            assertEquals(mNetworkAgent.netId, nmNetworkCaptor.getValue().netId);
             mNmCallbacks = nmCbCaptor.getValue();
 
             try {
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
index 7a505a2..950c6f8 100644
--- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
+++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
@@ -139,6 +139,8 @@
     private X509Certificate[] mClientCertificateChain;
     private int mEapMethod = Eap.NONE;
     private int mPhase2Method = Phase2.NONE;
+    private boolean mIsAppInstalledDeviceKeyAndCert = false;
+    private boolean mIsAppInstalledCaCert = false;
 
     private static final String TAG = "WifiEnterpriseConfig";
 
@@ -181,6 +183,8 @@
         }
         mEapMethod = source.mEapMethod;
         mPhase2Method = source.mPhase2Method;
+        mIsAppInstalledDeviceKeyAndCert = source.mIsAppInstalledDeviceKeyAndCert;
+        mIsAppInstalledCaCert = source.mIsAppInstalledCaCert;
     }
 
     /**
@@ -224,6 +228,8 @@
         ParcelUtil.writeCertificates(dest, mCaCerts);
         ParcelUtil.writePrivateKey(dest, mClientPrivateKey);
         ParcelUtil.writeCertificates(dest, mClientCertificateChain);
+        dest.writeBoolean(mIsAppInstalledDeviceKeyAndCert);
+        dest.writeBoolean(mIsAppInstalledCaCert);
     }
 
     public static final @android.annotation.NonNull Creator<WifiEnterpriseConfig> CREATOR =
@@ -243,6 +249,8 @@
                     enterpriseConfig.mCaCerts = ParcelUtil.readCertificates(in);
                     enterpriseConfig.mClientPrivateKey = ParcelUtil.readPrivateKey(in);
                     enterpriseConfig.mClientCertificateChain = ParcelUtil.readCertificates(in);
+                    enterpriseConfig.mIsAppInstalledDeviceKeyAndCert = in.readBoolean();
+                    enterpriseConfig.mIsAppInstalledCaCert = in.readBoolean();
                     return enterpriseConfig;
                 }
 
@@ -652,8 +660,10 @@
     public void setCaCertificate(@Nullable X509Certificate cert) {
         if (cert != null) {
             if (cert.getBasicConstraints() >= 0) {
+                mIsAppInstalledCaCert = true;
                 mCaCerts = new X509Certificate[] {cert};
             } else {
+                mCaCerts = null;
                 throw new IllegalArgumentException("Not a CA certificate");
             }
         } else {
@@ -694,10 +704,12 @@
                 if (certs[i].getBasicConstraints() >= 0) {
                     newCerts[i] = certs[i];
                 } else {
+                    mCaCerts = null;
                     throw new IllegalArgumentException("Not a CA certificate");
                 }
             }
             mCaCerts = newCerts;
+            mIsAppInstalledCaCert = true;
         } else {
             mCaCerts = null;
         }
@@ -853,6 +865,7 @@
 
         mClientPrivateKey = privateKey;
         mClientCertificateChain = newCerts;
+        mIsAppInstalledDeviceKeyAndCert = true;
     }
 
     /**
@@ -1147,4 +1160,30 @@
         }
         return true;
     }
+
+    /**
+     * Check if certificate was installed by an app, or manually (not by an app). If true,
+     * certificate and keys will be removed from key storage when this network is removed. If not,
+     * then certificates and keys remain persistent until the user manually removes them.
+     *
+     * @return true if certificate was installed by an app, false if certificate was installed
+     * manually by the user.
+     * @hide
+     */
+    public boolean isAppInstalledDeviceKeyAndCert() {
+        return mIsAppInstalledDeviceKeyAndCert;
+    }
+
+    /**
+     * Check if CA certificate was installed by an app, or manually (not by an app). If true,
+     * CA certificate will be removed from key storage when this network is removed. If not,
+     * then certificates and keys remain persistent until the user manually removes them.
+     *
+     * @return true if CA certificate was installed by an app, false if CA certificate was installed
+     * manually by the user.
+     * @hide
+     */
+    public boolean isAppInstalledCaCert() {
+        return mIsAppInstalledCaCert;
+    }
 }
diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
index 32a7a47..a9c9939 100644
--- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
+++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
@@ -403,7 +403,7 @@
          *      .setWpa3Passphrase("test6789")
          *      .build()
          * final List<WifiNetworkSuggestion> suggestionsList =
-         *      new ArrayList<WifiNetworkSuggestion> {{
+         *      new ArrayList<WifiNetworkSuggestion> &#123;{
          *          add(suggestion1);
          *          add(suggestion2);
          *          add(suggestion3);
diff --git a/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java b/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java
index 6ec64ff..beed666 100644
--- a/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java
@@ -423,4 +423,68 @@
         mEnterpriseConfig.setPassword(password);
         assertFalse(mEnterpriseConfig.toString().contains(password));
     }
+
+    /** Verifies that certificate ownership flag is set correctly */
+    @Test
+    public void testIsAppInstalledDeviceKeyAndCert() {
+        // First make sure that app didn't install anything
+        assertFalse(mEnterpriseConfig.isAppInstalledDeviceKeyAndCert());
+        assertFalse(mEnterpriseConfig.isAppInstalledCaCert());
+
+        // Then app loads keys via the enterprise config API
+        PrivateKey clientKey = FakeKeys.RSA_KEY1;
+        X509Certificate cert0 = FakeKeys.CLIENT_CERT;
+        X509Certificate cert1 = FakeKeys.CA_CERT1;
+        X509Certificate[] clientChain = new X509Certificate[] {cert0, cert1};
+        mEnterpriseConfig.setClientKeyEntryWithCertificateChain(clientKey, clientChain);
+        X509Certificate[] result = mEnterpriseConfig.getClientCertificateChain();
+        assertEquals(result.length, 2);
+        assertTrue(result[0] == cert0 && result[1] == cert1);
+        assertTrue(mEnterpriseConfig.getClientCertificate() == cert0);
+
+        // Make sure it is the owner now
+        assertTrue(mEnterpriseConfig.isAppInstalledDeviceKeyAndCert());
+        assertFalse(mEnterpriseConfig.isAppInstalledCaCert());
+    }
+
+    /** Verifies that certificate ownership flag is set correctly */
+    @Test
+    public void testIsAppInstalledCaCert() {
+        // First make sure that app didn't install anything
+        assertFalse(mEnterpriseConfig.isAppInstalledDeviceKeyAndCert());
+        assertFalse(mEnterpriseConfig.isAppInstalledCaCert());
+
+        // Then app loads CA cert via the enterprise config API
+        X509Certificate cert = FakeKeys.CA_CERT1;
+        mEnterpriseConfig.setCaCertificate(cert);
+        X509Certificate result = mEnterpriseConfig.getCaCertificate();
+        assertTrue(result == cert);
+
+        // Make sure it is the owner now
+        assertFalse(mEnterpriseConfig.isAppInstalledDeviceKeyAndCert());
+        assertTrue(mEnterpriseConfig.isAppInstalledCaCert());
+    }
+
+    /** Verifies that certificate ownership flag is set correctly */
+    @Test
+    public void testIsAppInstalledCaCerts() {
+        // First make sure that app didn't install anything
+        assertFalse(mEnterpriseConfig.isAppInstalledDeviceKeyAndCert());
+        assertFalse(mEnterpriseConfig.isAppInstalledCaCert());
+
+        // Then app loads CA cert via the enterprise config API
+        X509Certificate cert0 = FakeKeys.CA_CERT0;
+        X509Certificate cert1 = FakeKeys.CA_CERT1;
+        X509Certificate[] cert = new X509Certificate[] {cert0, cert1};
+
+        mEnterpriseConfig.setCaCertificates(cert);
+        X509Certificate[] result = mEnterpriseConfig.getCaCertificates();
+        assertEquals(result.length, 2);
+        assertTrue(result[0] == cert0 && result[1] == cert1);
+//        assertTrue(mEnterpriseConfig.getClientCertificate() == cert0);
+
+        // Make sure it is the owner now
+        assertFalse(mEnterpriseConfig.isAppInstalledDeviceKeyAndCert());
+        assertTrue(mEnterpriseConfig.isAppInstalledCaCert());
+    }
 }