Merge "Cache Feedback Enabled Setting in Controller"
diff --git a/apex/jobscheduler/framework/java/android/app/AlarmManager.java b/apex/jobscheduler/framework/java/android/app/AlarmManager.java
index 12ec9eb4..7851087 100644
--- a/apex/jobscheduler/framework/java/android/app/AlarmManager.java
+++ b/apex/jobscheduler/framework/java/android/app/AlarmManager.java
@@ -803,8 +803,8 @@
      * <b>only</b> be used for situations where it is actually required that the alarm go off while
      * in idle -- a reasonable example would be for a calendar notification that should make a
      * sound so the user is aware of it.  When the alarm is dispatched, the app will also be
-     * added to the system's temporary whitelist for approximately 10 seconds to allow that
-     * application to acquire further wake locks in which to complete its work.</p>
+     * added to the system's temporary power exemption list for approximately 10 seconds to allow
+     * that application to acquire further wake locks in which to complete its work.</p>
      *
      * <p>These alarms can significantly impact the power use
      * of the device when idle (and thus cause significant battery blame to the app scheduling
@@ -855,8 +855,8 @@
      * be used for situations where it is actually required that the alarm go off while in
      * idle -- a reasonable example would be for a calendar notification that should make a
      * sound so the user is aware of it.  When the alarm is dispatched, the app will also be
-     * added to the system's temporary whitelist for approximately 10 seconds to allow that
-     * application to acquire further wake locks in which to complete its work.</p>
+     * added to the system's temporary power exemption list for approximately 10 seconds to allow
+     * that application to acquire further wake locks in which to complete its work.</p>
      *
      * <p>These alarms can significantly impact the power use
      * of the device when idle (and thus cause significant battery blame to the app scheduling
diff --git a/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java b/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
index 6d23635..876d73a 100644
--- a/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
+++ b/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
@@ -67,8 +67,8 @@
  * Class to keep track of the information related to "force app standby", which includes:
  * - OP_RUN_ANY_IN_BACKGROUND for each package
  * - UID foreground/active state
- * - User+system power save whitelist
- * - Temporary power save whitelist
+ * - User+system power save exemption list
+ * - Temporary power save exemption list
  * - Global "force all apps standby" mode enforced by battery saver.
  *
  * Test: atest com.android.server.AppStateTrackerTest
@@ -110,25 +110,25 @@
     final SparseBooleanArray mForegroundUids = new SparseBooleanArray();
 
     /**
-     * System except-idle + user whitelist in the device idle controller.
+     * System except-idle + user exemption list in the device idle controller.
      */
     @GuardedBy("mLock")
-    private int[] mPowerWhitelistedAllAppIds = new int[0];
+    private int[] mPowerExemptAllAppIds = new int[0];
 
     /**
-     * User whitelisted apps in the device idle controller.
+     * User exempted apps in the device idle controller.
      */
     @GuardedBy("mLock")
-    private int[] mPowerWhitelistedUserAppIds = new int[0];
+    private int[] mPowerExemptUserAppIds = new int[0];
 
     @GuardedBy("mLock")
-    private int[] mTempWhitelistedAppIds = mPowerWhitelistedAllAppIds;
+    private int[] mTempExemptAppIds = mPowerExemptAllAppIds;
 
     /**
      * Per-user packages that are in the EXEMPT bucket.
      */
     @GuardedBy("mLock")
-    private final SparseSetArray<String> mExemptedPackages = new SparseSetArray<>();
+    private final SparseSetArray<String> mExemptBucketPackages = new SparseSetArray<>();
 
     @GuardedBy("mLock")
     final ArraySet<Listener> mListeners = new ArraySet<>();
@@ -177,10 +177,10 @@
         int UID_FG_STATE_CHANGED = 0;
         int UID_ACTIVE_STATE_CHANGED = 1;
         int RUN_ANY_CHANGED = 2;
-        int ALL_UNWHITELISTED = 3;
-        int ALL_WHITELIST_CHANGED = 4;
-        int TEMP_WHITELIST_CHANGED = 5;
-        int EXEMPT_CHANGED = 6;
+        int ALL_UNEXEMPTED = 3;
+        int ALL_EXEMPTION_LIST_CHANGED = 4;
+        int TEMP_EXEMPTION_LIST_CHANGED = 5;
+        int EXEMPT_BUCKET_CHANGED = 6;
         int FORCE_ALL_CHANGED = 7;
         int FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED = 8;
 
@@ -192,10 +192,10 @@
             "UID_FG_STATE_CHANGED",
             "UID_ACTIVE_STATE_CHANGED",
             "RUN_ANY_CHANGED",
-            "ALL_UNWHITELISTED",
-            "ALL_WHITELIST_CHANGED",
-            "TEMP_WHITELIST_CHANGED",
-            "EXEMPT_CHANGED",
+            "ALL_UNEXEMPTED",
+            "ALL_EXEMPTION_LIST_CHANGED",
+            "TEMP_EXEMPTION_LIST_CHANGED",
+            "EXEMPT_BUCKET_CHANGED",
             "FORCE_ALL_CHANGED",
             "FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED",
 
@@ -308,38 +308,39 @@
         }
 
         /**
-         * This is called when an app-id(s) is removed from the power save whitelist.
+         * This is called when an app-id(s) is removed from the power save allow-list.
          */
-        private void onPowerSaveUnwhitelisted(AppStateTrackerImpl sender) {
+        private void onPowerSaveUnexempted(AppStateTrackerImpl sender) {
             updateAllJobs();
             unblockAllUnrestrictedAlarms();
         }
 
         /**
-         * This is called when the power save whitelist changes, excluding the
-         * {@link #onPowerSaveUnwhitelisted} case.
+         * This is called when the power save exemption list changes, excluding the
+         * {@link #onPowerSaveUnexempted} case.
          */
-        private void onPowerSaveWhitelistedChanged(AppStateTrackerImpl sender) {
+        private void onPowerSaveExemptionListChanged(AppStateTrackerImpl sender) {
             updateAllJobs();
         }
 
         /**
-         * This is called when the temp whitelist changes.
+         * This is called when the temp exemption list changes.
          */
-        private void onTempPowerSaveWhitelistChanged(AppStateTrackerImpl sender) {
+        private void onTempPowerSaveExemptionListChanged(AppStateTrackerImpl sender) {
 
             // TODO This case happens rather frequently; consider optimizing and update jobs
             // only for affected app-ids.
 
             updateAllJobs();
 
-            // Note when an app is just put in the temp whitelist, we do *not* drain pending alarms.
+            // Note when an app is just put in the temp exemption list, we do *not* drain pending
+            // alarms.
         }
 
         /**
          * This is called when the EXEMPT bucket is updated.
          */
-        private void onExemptChanged(AppStateTrackerImpl sender) {
+        private void onExemptBucketChanged(AppStateTrackerImpl sender) {
             // This doesn't happen very often, so just re-evaluate all jobs / alarms.
             updateAllJobs();
             unblockAllUnrestrictedAlarms();
@@ -709,8 +710,8 @@
                     && !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
                 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
                 final String pkgName = intent.getData().getSchemeSpecificPart();
-                if (mExemptedPackages.remove(userId, pkgName)) {
-                    mHandler.notifyExemptChanged();
+                if (mExemptBucketPackages.remove(userId, pkgName)) {
+                    mHandler.notifyExemptBucketChanged();
                 }
             }
         }
@@ -727,12 +728,12 @@
             synchronized (mLock) {
                 final boolean changed;
                 if (bucket == UsageStatsManager.STANDBY_BUCKET_EXEMPTED) {
-                    changed = mExemptedPackages.add(userId, packageName);
+                    changed = mExemptBucketPackages.add(userId, packageName);
                 } else {
-                    changed = mExemptedPackages.remove(userId, packageName);
+                    changed = mExemptBucketPackages.remove(userId, packageName);
                 }
                 if (changed) {
-                    mHandler.notifyExemptChanged();
+                    mHandler.notifyExemptBucketChanged();
                 }
             }
         }
@@ -748,13 +749,13 @@
         private static final int MSG_UID_ACTIVE_STATE_CHANGED = 0;
         private static final int MSG_UID_FG_STATE_CHANGED = 1;
         private static final int MSG_RUN_ANY_CHANGED = 3;
-        private static final int MSG_ALL_UNWHITELISTED = 4;
-        private static final int MSG_ALL_WHITELIST_CHANGED = 5;
-        private static final int MSG_TEMP_WHITELIST_CHANGED = 6;
+        private static final int MSG_ALL_UNEXEMPTED = 4;
+        private static final int MSG_ALL_EXEMPTION_LIST_CHANGED = 5;
+        private static final int MSG_TEMP_EXEMPTION_LIST_CHANGED = 6;
         private static final int MSG_FORCE_ALL_CHANGED = 7;
         private static final int MSG_USER_REMOVED = 8;
         private static final int MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED = 9;
-        private static final int MSG_EXEMPT_CHANGED = 10;
+        private static final int MSG_EXEMPT_BUCKET_CHANGED = 10;
 
         private static final int MSG_ON_UID_STATE_CHANGED = 11;
         private static final int MSG_ON_UID_ACTIVE = 12;
@@ -777,19 +778,19 @@
             obtainMessage(MSG_RUN_ANY_CHANGED, uid, 0, packageName).sendToTarget();
         }
 
-        public void notifyAllUnwhitelisted() {
-            removeMessages(MSG_ALL_UNWHITELISTED);
-            obtainMessage(MSG_ALL_UNWHITELISTED).sendToTarget();
+        public void notifyAllUnexempted() {
+            removeMessages(MSG_ALL_UNEXEMPTED);
+            obtainMessage(MSG_ALL_UNEXEMPTED).sendToTarget();
         }
 
-        public void notifyAllWhitelistChanged() {
-            removeMessages(MSG_ALL_WHITELIST_CHANGED);
-            obtainMessage(MSG_ALL_WHITELIST_CHANGED).sendToTarget();
+        public void notifyAllExemptionListChanged() {
+            removeMessages(MSG_ALL_EXEMPTION_LIST_CHANGED);
+            obtainMessage(MSG_ALL_EXEMPTION_LIST_CHANGED).sendToTarget();
         }
 
-        public void notifyTempWhitelistChanged() {
-            removeMessages(MSG_TEMP_WHITELIST_CHANGED);
-            obtainMessage(MSG_TEMP_WHITELIST_CHANGED).sendToTarget();
+        public void notifyTempExemptionListChanged() {
+            removeMessages(MSG_TEMP_EXEMPTION_LIST_CHANGED);
+            obtainMessage(MSG_TEMP_EXEMPTION_LIST_CHANGED).sendToTarget();
         }
 
         public void notifyForceAllAppsStandbyChanged() {
@@ -802,9 +803,9 @@
             obtainMessage(MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED).sendToTarget();
         }
 
-        public void notifyExemptChanged() {
-            removeMessages(MSG_EXEMPT_CHANGED);
-            obtainMessage(MSG_EXEMPT_CHANGED).sendToTarget();
+        public void notifyExemptBucketChanged() {
+            removeMessages(MSG_EXEMPT_BUCKET_CHANGED);
+            obtainMessage(MSG_EXEMPT_BUCKET_CHANGED).sendToTarget();
         }
 
         public void doUserRemoved(int userId) {
@@ -866,32 +867,32 @@
                     mStatLogger.logDurationStat(Stats.RUN_ANY_CHANGED, start);
                     return;
 
-                case MSG_ALL_UNWHITELISTED:
+                case MSG_ALL_UNEXEMPTED:
                     for (Listener l : cloneListeners()) {
-                        l.onPowerSaveUnwhitelisted(sender);
+                        l.onPowerSaveUnexempted(sender);
                     }
-                    mStatLogger.logDurationStat(Stats.ALL_UNWHITELISTED, start);
+                    mStatLogger.logDurationStat(Stats.ALL_UNEXEMPTED, start);
                     return;
 
-                case MSG_ALL_WHITELIST_CHANGED:
+                case MSG_ALL_EXEMPTION_LIST_CHANGED:
                     for (Listener l : cloneListeners()) {
-                        l.onPowerSaveWhitelistedChanged(sender);
+                        l.onPowerSaveExemptionListChanged(sender);
                     }
-                    mStatLogger.logDurationStat(Stats.ALL_WHITELIST_CHANGED, start);
+                    mStatLogger.logDurationStat(Stats.ALL_EXEMPTION_LIST_CHANGED, start);
                     return;
 
-                case MSG_TEMP_WHITELIST_CHANGED:
+                case MSG_TEMP_EXEMPTION_LIST_CHANGED:
                     for (Listener l : cloneListeners()) {
-                        l.onTempPowerSaveWhitelistChanged(sender);
+                        l.onTempPowerSaveExemptionListChanged(sender);
                     }
-                    mStatLogger.logDurationStat(Stats.TEMP_WHITELIST_CHANGED, start);
+                    mStatLogger.logDurationStat(Stats.TEMP_EXEMPTION_LIST_CHANGED, start);
                     return;
 
-                case MSG_EXEMPT_CHANGED:
+                case MSG_EXEMPT_BUCKET_CHANGED:
                     for (Listener l : cloneListeners()) {
-                        l.onExemptChanged(sender);
+                        l.onExemptBucketChanged(sender);
                     }
-                    mStatLogger.logDurationStat(Stats.EXEMPT_CHANGED, start);
+                    mStatLogger.logDurationStat(Stats.EXEMPT_BUCKET_CHANGED, start);
                     return;
 
                 case MSG_FORCE_ALL_CHANGED:
@@ -1004,7 +1005,7 @@
             }
             cleanUpArrayForUser(mActiveUids, removedUserId);
             cleanUpArrayForUser(mForegroundUids, removedUserId);
-            mExemptedPackages.remove(removedUserId);
+            mExemptBucketPackages.remove(removedUserId);
         }
     }
 
@@ -1020,39 +1021,39 @@
     }
 
     /**
-     * Called by device idle controller to update the power save whitelists.
+     * Called by device idle controller to update the power save exemption lists.
      */
-    public void setPowerSaveWhitelistAppIds(
-            int[] powerSaveWhitelistExceptIdleAppIdArray,
-            int[] powerSaveWhitelistUserAppIdArray,
-            int[] tempWhitelistAppIdArray) {
+    public void setPowerSaveExemptionListAppIds(
+            int[] powerSaveExemptionListExceptIdleAppIdArray,
+            int[] powerSaveExemptionListUserAppIdArray,
+            int[] tempExemptionListAppIdArray) {
         synchronized (mLock) {
-            final int[] previousWhitelist = mPowerWhitelistedAllAppIds;
-            final int[] previousTempWhitelist = mTempWhitelistedAppIds;
+            final int[] previousExemptionList = mPowerExemptAllAppIds;
+            final int[] previousTempExemptionList = mTempExemptAppIds;
 
-            mPowerWhitelistedAllAppIds = powerSaveWhitelistExceptIdleAppIdArray;
-            mTempWhitelistedAppIds = tempWhitelistAppIdArray;
-            mPowerWhitelistedUserAppIds = powerSaveWhitelistUserAppIdArray;
+            mPowerExemptAllAppIds = powerSaveExemptionListExceptIdleAppIdArray;
+            mTempExemptAppIds = tempExemptionListAppIdArray;
+            mPowerExemptUserAppIds = powerSaveExemptionListUserAppIdArray;
 
-            if (isAnyAppIdUnwhitelisted(previousWhitelist, mPowerWhitelistedAllAppIds)) {
-                mHandler.notifyAllUnwhitelisted();
-            } else if (!Arrays.equals(previousWhitelist, mPowerWhitelistedAllAppIds)) {
-                mHandler.notifyAllWhitelistChanged();
+            if (isAnyAppIdUnexempt(previousExemptionList, mPowerExemptAllAppIds)) {
+                mHandler.notifyAllUnexempted();
+            } else if (!Arrays.equals(previousExemptionList, mPowerExemptAllAppIds)) {
+                mHandler.notifyAllExemptionListChanged();
             }
 
-            if (!Arrays.equals(previousTempWhitelist, mTempWhitelistedAppIds)) {
-                mHandler.notifyTempWhitelistChanged();
+            if (!Arrays.equals(previousTempExemptionList, mTempExemptAppIds)) {
+                mHandler.notifyTempExemptionListChanged();
             }
 
         }
     }
 
     /**
-     * @retunr true if a sorted app-id array {@code prevArray} has at least one element
+     * @return true if a sorted app-id array {@code prevArray} has at least one element
      * that's not in a sorted app-id array {@code newArray}.
      */
     @VisibleForTesting
-    static boolean isAnyAppIdUnwhitelisted(int[] prevArray, int[] newArray) {
+    static boolean isAnyAppIdUnexempt(int[] prevArray, int[] newArray) {
         int i1 = 0;
         int i2 = 0;
         boolean prevFinished;
@@ -1100,7 +1101,7 @@
      */
     public boolean areAlarmsRestricted(int uid, @NonNull String packageName,
             boolean isExemptOnBatterySaver) {
-        return isRestricted(uid, packageName, /*useTempWhitelistToo=*/ false,
+        return isRestricted(uid, packageName, /*useTempExemptionListToo=*/ false,
                 isExemptOnBatterySaver);
     }
 
@@ -1109,7 +1110,7 @@
      */
     public boolean areJobsRestricted(int uid, @NonNull String packageName,
             boolean hasForegroundExemption) {
-        return isRestricted(uid, packageName, /*useTempWhitelistToo=*/ true,
+        return isRestricted(uid, packageName, /*useTempExemptionListToo=*/ true,
                 hasForegroundExemption);
     }
 
@@ -1127,17 +1128,16 @@
      * @return whether force-app-standby is effective for a UID package-name.
      */
     private boolean isRestricted(int uid, @NonNull String packageName,
-            boolean useTempWhitelistToo, boolean exemptOnBatterySaver) {
+            boolean useTempExemptionListToo, boolean exemptOnBatterySaver) {
         if (isUidActive(uid)) {
             return false;
         }
         synchronized (mLock) {
-            // Whitelisted?
             final int appId = UserHandle.getAppId(uid);
-            if (ArrayUtils.contains(mPowerWhitelistedAllAppIds, appId)) {
+            if (ArrayUtils.contains(mPowerExemptAllAppIds, appId)) {
                 return false;
             }
-            if (useTempWhitelistToo && ArrayUtils.contains(mTempWhitelistedAppIds, appId)) {
+            if (useTempExemptionListToo && ArrayUtils.contains(mTempExemptAppIds, appId)) {
                 return false;
             }
             if (mForcedAppStandbyEnabled && isRunAnyRestrictedLocked(uid, packageName)) {
@@ -1148,7 +1148,7 @@
             }
             final int userId = UserHandle.getUserId(uid);
             if (mAppStandbyInternal.isAppIdleEnabled() && !mAppStandbyInternal.isInParole()
-                    && mExemptedPackages.contains(userId, packageName)) {
+                    && mExemptBucketPackages.contains(userId, packageName)) {
                 return false;
             }
             return mForceAllAppsStandby;
@@ -1225,34 +1225,34 @@
     }
 
     /**
-     * @return whether a UID is in the user / system defined power-save whitelist or not.
+     * @return whether a UID is in the user / system defined power-save exemption list or not.
      *
      * Note clients normally shouldn't need to access it. It's only for dumpsys.
      */
-    public boolean isUidPowerSaveWhitelisted(int uid) {
+    public boolean isUidPowerSaveExempt(int uid) {
         synchronized (mLock) {
-            return ArrayUtils.contains(mPowerWhitelistedAllAppIds, UserHandle.getAppId(uid));
+            return ArrayUtils.contains(mPowerExemptAllAppIds, UserHandle.getAppId(uid));
         }
     }
 
     /**
      * @param uid the uid to check for
-     * @return whether a UID is in the user defined power-save whitelist or not.
+     * @return whether a UID is in the user defined power-save exemption list or not.
      */
-    public boolean isUidPowerSaveUserWhitelisted(int uid) {
+    public boolean isUidPowerSaveUserExempt(int uid) {
         synchronized (mLock) {
-            return ArrayUtils.contains(mPowerWhitelistedUserAppIds, UserHandle.getAppId(uid));
+            return ArrayUtils.contains(mPowerExemptUserAppIds, UserHandle.getAppId(uid));
         }
     }
 
     /**
-     * @return whether a UID is in the temp power-save whitelist or not.
+     * @return whether a UID is in the temp power-save exemption list or not.
      *
      * Note clients normally shouldn't need to access it. It's only for dumpsys.
      */
-    public boolean isUidTempPowerSaveWhitelisted(int uid) {
+    public boolean isUidTempPowerSaveExempt(int uid) {
         synchronized (mLock) {
-            return ArrayUtils.contains(mTempWhitelistedAppIds, UserHandle.getAppId(uid));
+            return ArrayUtils.contains(mTempExemptAppIds, UserHandle.getAppId(uid));
         }
     }
 
@@ -1290,25 +1290,25 @@
             pw.print("Foreground uids: ");
             dumpUids(pw, mForegroundUids);
 
-            pw.print("Except-idle + user whitelist appids: ");
-            pw.println(Arrays.toString(mPowerWhitelistedAllAppIds));
+            pw.print("Except-idle + user exemption list appids: ");
+            pw.println(Arrays.toString(mPowerExemptAllAppIds));
 
-            pw.print("User whitelist appids: ");
-            pw.println(Arrays.toString(mPowerWhitelistedUserAppIds));
+            pw.print("User exemption list appids: ");
+            pw.println(Arrays.toString(mPowerExemptUserAppIds));
 
-            pw.print("Temp whitelist appids: ");
-            pw.println(Arrays.toString(mTempWhitelistedAppIds));
+            pw.print("Temp exemption list appids: ");
+            pw.println(Arrays.toString(mTempExemptAppIds));
 
-            pw.println("Exempted packages:");
+            pw.println("Exempted bucket packages:");
             pw.increaseIndent();
-            for (int i = 0; i < mExemptedPackages.size(); i++) {
+            for (int i = 0; i < mExemptBucketPackages.size(); i++) {
                 pw.print("User ");
-                pw.print(mExemptedPackages.keyAt(i));
+                pw.print(mExemptBucketPackages.keyAt(i));
                 pw.println();
 
                 pw.increaseIndent();
-                for (int j = 0; j < mExemptedPackages.sizeAt(i); j++) {
-                    pw.print(mExemptedPackages.valueAt(i, j));
+                for (int j = 0; j < mExemptBucketPackages.sizeAt(i); j++) {
+                    pw.print(mExemptBucketPackages.valueAt(i, j));
                     pw.println();
                 }
                 pw.decreaseIndent();
@@ -1372,24 +1372,24 @@
                 }
             }
 
-            for (int appId : mPowerWhitelistedAllAppIds) {
-                proto.write(AppStateTrackerProto.POWER_SAVE_WHITELIST_APP_IDS, appId);
+            for (int appId : mPowerExemptAllAppIds) {
+                proto.write(AppStateTrackerProto.POWER_SAVE_EXEMPT_APP_IDS, appId);
             }
 
-            for (int appId : mPowerWhitelistedUserAppIds) {
-                proto.write(AppStateTrackerProto.POWER_SAVE_USER_WHITELIST_APP_IDS, appId);
+            for (int appId : mPowerExemptUserAppIds) {
+                proto.write(AppStateTrackerProto.POWER_SAVE_USER_EXEMPT_APP_IDS, appId);
             }
 
-            for (int appId : mTempWhitelistedAppIds) {
-                proto.write(AppStateTrackerProto.TEMP_POWER_SAVE_WHITELIST_APP_IDS, appId);
+            for (int appId : mTempExemptAppIds) {
+                proto.write(AppStateTrackerProto.TEMP_POWER_SAVE_EXEMPT_APP_IDS, appId);
             }
 
-            for (int i = 0; i < mExemptedPackages.size(); i++) {
-                for (int j = 0; j < mExemptedPackages.sizeAt(i); j++) {
-                    final long token2 = proto.start(AppStateTrackerProto.EXEMPTED_PACKAGES);
+            for (int i = 0; i < mExemptBucketPackages.size(); i++) {
+                for (int j = 0; j < mExemptBucketPackages.sizeAt(i); j++) {
+                    final long token2 = proto.start(AppStateTrackerProto.EXEMPTED_BUCKET_PACKAGES);
 
-                    proto.write(ExemptedPackage.USER_ID, mExemptedPackages.keyAt(i));
-                    proto.write(ExemptedPackage.PACKAGE_NAME, mExemptedPackages.valueAt(i, j));
+                    proto.write(ExemptedPackage.USER_ID, mExemptBucketPackages.keyAt(i));
+                    proto.write(ExemptedPackage.PACKAGE_NAME, mExemptBucketPackages.valueAt(i, j));
 
                     proto.end(token2);
                 }
diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
index b1bafee..6c3398f 100644
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
@@ -3715,7 +3715,7 @@
     }
 
     private void passWhiteListsToForceAppStandbyTrackerLocked() {
-        mAppStateTracker.setPowerSaveWhitelistAppIds(
+        mAppStateTracker.setPowerSaveExemptionListAppIds(
                 mPowerSaveWhitelistExceptIdleAppIdArray,
                 mPowerSaveWhitelistUserAppIdArray,
                 mTempWhitelistAppIdArray);
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index 6529503..4194fd0 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -2089,7 +2089,7 @@
             } else if (workSource == null && (callingUid < Process.FIRST_APPLICATION_UID
                     || UserHandle.isSameApp(callingUid, mSystemUiUid)
                     || ((mAppStateTracker != null)
-                        && mAppStateTracker.isUidPowerSaveUserWhitelisted(callingUid)))) {
+                        && mAppStateTracker.isUidPowerSaveUserExempt(callingUid)))) {
                 flags |= AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
                 flags &= ~AlarmManager.FLAG_ALLOW_WHILE_IDLE;
             }
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index 4db4adc..3234b27 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -89,6 +89,7 @@
 import com.android.server.AppStateTrackerImpl;
 import com.android.server.DeviceIdleInternal;
 import com.android.server.LocalServices;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.job.JobSchedulerServiceDumpProto.ActiveJob;
 import com.android.server.job.JobSchedulerServiceDumpProto.PendingJob;
 import com.android.server.job.controllers.BackgroundJobsController;
@@ -975,24 +976,24 @@
     }
 
     @Override
-    public void onStartUser(int userHandle) {
+    public void onUserStarting(@NonNull TargetUser user) {
         synchronized (mLock) {
-            mStartedUsers = ArrayUtils.appendInt(mStartedUsers, userHandle);
+            mStartedUsers = ArrayUtils.appendInt(mStartedUsers, user.getUserIdentifier());
         }
         // Let's kick any outstanding jobs for this user.
         mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
     }
 
     @Override
-    public void onUnlockUser(int userHandle) {
+    public void onUserUnlocking(@NonNull TargetUser user) {
         // Let's kick any outstanding jobs for this user.
         mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
     }
 
     @Override
-    public void onStopUser(int userHandle) {
+    public void onUserStopping(@NonNull TargetUser user) {
         synchronized (mLock) {
-            mStartedUsers = ArrayUtils.removeInt(mStartedUsers, userHandle);
+            mStartedUsers = ArrayUtils.removeInt(mStartedUsers, user.getUserIdentifier());
         }
     }
 
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java
index b632435..44c8fcf 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java
@@ -91,9 +91,9 @@
             pw.print(" from ");
             UserHandle.formatUid(pw, uid);
             pw.print(mAppStateTracker.isUidActive(uid) ? " active" : " idle");
-            if (mAppStateTracker.isUidPowerSaveWhitelisted(uid) ||
-                    mAppStateTracker.isUidTempPowerSaveWhitelisted(uid)) {
-                pw.print(", whitelisted");
+            if (mAppStateTracker.isUidPowerSaveExempt(uid)
+                    || mAppStateTracker.isUidTempPowerSaveExempt(uid)) {
+                pw.print(", exempted");
             }
             pw.print(": ");
             pw.print(sourcePkg);
@@ -132,8 +132,8 @@
 
             proto.write(TrackedJob.IS_IN_FOREGROUND, mAppStateTracker.isUidActive(sourceUid));
             proto.write(TrackedJob.IS_WHITELISTED,
-                    mAppStateTracker.isUidPowerSaveWhitelisted(sourceUid) ||
-                    mAppStateTracker.isUidTempPowerSaveWhitelisted(sourceUid));
+                    mAppStateTracker.isUidPowerSaveExempt(sourceUid)
+                            || mAppStateTracker.isUidTempPowerSaveExempt(sourceUid));
 
             proto.write(TrackedJob.CAN_RUN_ANY_IN_BACKGROUND,
                     mAppStateTracker.isRunAnyInBackgroundAppOpsAllowed(sourceUid, sourcePkg));
diff --git a/api/module-lib-current.txt b/api/module-lib-current.txt
index 696e029..3f3b8ea 100644
--- a/api/module-lib-current.txt
+++ b/api/module-lib-current.txt
@@ -31,6 +31,14 @@
 
 }
 
+package android.media {
+
+  public class AudioManager {
+    field public static final int FLAG_FROM_KEY = 4096; // 0x1000
+  }
+
+}
+
 package android.net {
 
   public final class TetheringConstants {
diff --git a/cmds/idmap2/idmap2d/aidl/android/os/OverlayablePolicy.aidl b/cmds/idmap2/idmap2d/aidl/android/os/OverlayablePolicy.aidl
index 02b27a8..403d8c5 100644
--- a/cmds/idmap2/idmap2d/aidl/android/os/OverlayablePolicy.aidl
+++ b/cmds/idmap2/idmap2d/aidl/android/os/OverlayablePolicy.aidl
@@ -29,4 +29,5 @@
   const int ODM_PARTITION = 0x00000020;
   const int OEM_PARTITION = 0x00000040;
   const int ACTOR_SIGNATURE = 0x00000080;
+  const int CONFIG_SIGNATURE = 0x0000100;
 }
diff --git a/cmds/idmap2/libidmap2/ResourceMapping.cpp b/cmds/idmap2/libidmap2/ResourceMapping.cpp
index 34589a1..fd8b4eb 100644
--- a/cmds/idmap2/libidmap2/ResourceMapping.cpp
+++ b/cmds/idmap2/libidmap2/ResourceMapping.cpp
@@ -61,10 +61,13 @@
                               const ResourceId& target_resource) {
   static constexpr const PolicyBitmask sDefaultPolicies =
       PolicyFlags::ODM_PARTITION | PolicyFlags::OEM_PARTITION | PolicyFlags::SYSTEM_PARTITION |
-      PolicyFlags::VENDOR_PARTITION | PolicyFlags::PRODUCT_PARTITION | PolicyFlags::SIGNATURE;
+      PolicyFlags::VENDOR_PARTITION | PolicyFlags::PRODUCT_PARTITION | PolicyFlags::SIGNATURE |
+      PolicyFlags::CONFIG_SIGNATURE;
 
   // If the resource does not have an overlayable definition, allow the resource to be overlaid if
-  // the overlay is preinstalled or signed with the same signature as the target.
+  // the overlay is preinstalled, signed with the same signature as the target or signed with the
+  // same signature as reference package defined in SystemConfig under 'overlay-config-signature'
+  // tag.
   if (!target_package.DefinesOverlayable()) {
     return (sDefaultPolicies & fulfilled_policies) != 0
                ? Result<Unit>({})
diff --git a/cmds/idmap2/libidmap2_policies/include/idmap2/Policies.h b/cmds/idmap2/libidmap2_policies/include/idmap2/Policies.h
index f7987b0..cdce451 100644
--- a/cmds/idmap2/libidmap2_policies/include/idmap2/Policies.h
+++ b/cmds/idmap2/libidmap2_policies/include/idmap2/Policies.h
@@ -38,16 +38,18 @@
 constexpr const char* kPolicyOem = "oem";
 constexpr const char* kPolicyProduct = "product";
 constexpr const char* kPolicyPublic = "public";
+constexpr const char* kPolicyConfigSignature = "config_signature";
 constexpr const char* kPolicySignature = "signature";
 constexpr const char* kPolicySystem = "system";
 constexpr const char* kPolicyVendor = "vendor";
 
-inline static const std::array<std::pair<StringPiece, PolicyFlags>, 8> kPolicyStringToFlag = {
+inline static const std::array<std::pair<StringPiece, PolicyFlags>, 9> kPolicyStringToFlag = {
     std::pair{kPolicyActor, PolicyFlags::ACTOR_SIGNATURE},
     {kPolicyOdm, PolicyFlags::ODM_PARTITION},
     {kPolicyOem, PolicyFlags::OEM_PARTITION},
     {kPolicyProduct, PolicyFlags::PRODUCT_PARTITION},
     {kPolicyPublic, PolicyFlags::PUBLIC},
+    {kPolicyConfigSignature, PolicyFlags::CONFIG_SIGNATURE},
     {kPolicySignature, PolicyFlags::SIGNATURE},
     {kPolicySystem, PolicyFlags::SYSTEM_PARTITION},
     {kPolicyVendor, PolicyFlags::VENDOR_PARTITION},
diff --git a/cmds/idmap2/tests/R.h b/cmds/idmap2/tests/R.h
index 4f2ee1c..854b57f 100644
--- a/cmds/idmap2/tests/R.h
+++ b/cmds/idmap2/tests/R.h
@@ -43,16 +43,17 @@
     constexpr ResourceId not_overlayable = 0x7f020003;
     constexpr ResourceId other = 0x7f020004;
     constexpr ResourceId policy_actor = 0x7f020005;
-    constexpr ResourceId policy_odm = 0x7f020006;
-    constexpr ResourceId policy_oem = 0x7f020007;
-    constexpr ResourceId policy_product = 0x7f020008;
-    constexpr ResourceId policy_public = 0x7f020009;
-    constexpr ResourceId policy_signature = 0x7f02000a;
-    constexpr ResourceId policy_system = 0x7f02000b;
-    constexpr ResourceId policy_system_vendor = 0x7f02000c;
-    constexpr ResourceId str1 = 0x7f02000d;
-    constexpr ResourceId str3 = 0x7f02000f;
-    constexpr ResourceId str4 = 0x7f020010;
+    constexpr ResourceId policy_config_signature = 0x7f020006;
+    constexpr ResourceId policy_odm = 0x7f020007;
+    constexpr ResourceId policy_oem = 0x7f020008;
+    constexpr ResourceId policy_product = 0x7f020009;
+    constexpr ResourceId policy_public = 0x7f02000a;
+    constexpr ResourceId policy_signature = 0x7f02000b;
+    constexpr ResourceId policy_system = 0x7f02000c;
+    constexpr ResourceId policy_system_vendor = 0x7f02000d;
+    constexpr ResourceId str1 = 0x7f02000e;
+    constexpr ResourceId str3 = 0x7f020010;
+    constexpr ResourceId str4 = 0x7f020011;
 
     namespace literal {  // NOLINT(runtime/indentation_namespace)
       inline const std::string str1 = hexify(R::target::string::str1);
@@ -94,13 +95,14 @@
   constexpr ResourceId not_overlayable = 0x7f010000;
   constexpr ResourceId other = 0x7f010001;
   constexpr ResourceId policy_actor = 0x7f010002;
-  constexpr ResourceId policy_odm = 0x7f010003;
-  constexpr ResourceId policy_oem = 0x7f010004;
-  constexpr ResourceId policy_product = 0x7f010005;
-  constexpr ResourceId policy_public = 0x7f010006;
-  constexpr ResourceId policy_signature = 0x7f010007;
-  constexpr ResourceId policy_system = 0x7f010008;
-  constexpr ResourceId policy_system_vendor = 0x7f010009;
+  constexpr ResourceId policy_config_signature = 0x7f010003;
+  constexpr ResourceId policy_odm = 0x7f010004;
+  constexpr ResourceId policy_oem = 0x7f010005;
+  constexpr ResourceId policy_product = 0x7f010006;
+  constexpr ResourceId policy_public = 0x7f010007;
+  constexpr ResourceId policy_signature = 0x7f010008;
+  constexpr ResourceId policy_system = 0x7f010009;
+  constexpr ResourceId policy_system_vendor = 0x7f01000a;
 }  // namespace R::system_overlay_invalid::string
 // clang-format on
 
diff --git a/cmds/idmap2/tests/ResourceMappingTests.cpp b/cmds/idmap2/tests/ResourceMappingTests.cpp
index de039f4..3ec6ac2 100644
--- a/cmds/idmap2/tests/ResourceMappingTests.cpp
+++ b/cmds/idmap2/tests/ResourceMappingTests.cpp
@@ -237,7 +237,7 @@
 
   ASSERT_TRUE(resources) << resources.GetErrorMessage();
   auto& res = *resources;
-  ASSERT_EQ(res.GetTargetToOverlayMap().size(), 10U);
+  ASSERT_EQ(res.GetTargetToOverlayMap().size(), 11U);
   ASSERT_RESULT(MappingExists(res, R::target::string::not_overlayable, Res_value::TYPE_REFERENCE,
                               R::system_overlay_invalid::string::not_overlayable,
                               false /* rewrite */));
@@ -256,6 +256,10 @@
   ASSERT_RESULT(MappingExists(res, R::target::string::policy_public, Res_value::TYPE_REFERENCE,
                               R::system_overlay_invalid::string::policy_public,
                               false /* rewrite */));
+  ASSERT_RESULT(MappingExists(res, R::target::string::policy_config_signature,
+                              Res_value::TYPE_REFERENCE,
+                              R::system_overlay_invalid::string::policy_config_signature,
+                              false /* rewrite */));
   ASSERT_RESULT(MappingExists(res, R::target::string::policy_signature, Res_value::TYPE_REFERENCE,
                               R::system_overlay_invalid::string::policy_signature,
                               false /* rewrite */));
@@ -298,8 +302,9 @@
   ASSERT_EQ(resources->GetTargetToOverlayMap().size(), 0U);
 }
 
-// Overlays that are pre-installed or are signed with the same signature as the target can overlay
-// packages that have not defined overlayable resources.
+// Overlays that are pre-installed or are signed with the same signature as the target  or are signed
+// with the same signature as the reference package can overlay packages that have not defined
+// overlayable resources.
 TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPolicies) {
   auto CheckEntries = [&](const PolicyBitmask& fulfilled_policies) -> void {
     auto resources = TestGetResourceMapping("/target/target-no-overlayable.apk",
@@ -309,7 +314,7 @@
 
     ASSERT_TRUE(resources) << resources.GetErrorMessage();
     auto& res = *resources;
-    ASSERT_EQ(resources->GetTargetToOverlayMap().size(), 10U);
+    ASSERT_EQ(resources->GetTargetToOverlayMap().size(), 11U);
     ASSERT_RESULT(MappingExists(res, R::target::string::not_overlayable, Res_value::TYPE_REFERENCE,
                                 R::system_overlay_invalid::string::not_overlayable,
                                 false /* rewrite */));
@@ -330,6 +335,10 @@
     ASSERT_RESULT(MappingExists(res, R::target::string::policy_public, Res_value::TYPE_REFERENCE,
                                 R::system_overlay_invalid::string::policy_public,
                                 false /* rewrite */));
+    ASSERT_RESULT(MappingExists(res, R::target::string::policy_config_signature,
+                                Res_value::TYPE_REFERENCE,
+                                R::system_overlay_invalid::string::policy_config_signature,
+                                false /* rewrite */));
     ASSERT_RESULT(MappingExists(res, R::target::string::policy_signature, Res_value::TYPE_REFERENCE,
                                 R::system_overlay_invalid::string::policy_signature,
                                 false /* rewrite */));
@@ -342,6 +351,7 @@
   };
 
   CheckEntries(PolicyFlags::SIGNATURE);
+  CheckEntries(PolicyFlags::CONFIG_SIGNATURE);
   CheckEntries(PolicyFlags::PRODUCT_PARTITION);
   CheckEntries(PolicyFlags::SYSTEM_PARTITION);
   CheckEntries(PolicyFlags::VENDOR_PARTITION);
diff --git a/cmds/idmap2/tests/TestConstants.h b/cmds/idmap2/tests/TestConstants.h
index 74ea18f..9641f6b5 100644
--- a/cmds/idmap2/tests/TestConstants.h
+++ b/cmds/idmap2/tests/TestConstants.h
@@ -19,11 +19,11 @@
 
 namespace android::idmap2::TestConstants {
 
-constexpr const auto TARGET_CRC = 0x41c60c8c;
-constexpr const auto TARGET_CRC_STRING = "41c60c8c";
+constexpr const auto TARGET_CRC =  0x7c2d4719;
+constexpr const auto TARGET_CRC_STRING = "7c2d4719";
 
-constexpr const auto OVERLAY_CRC = 0xc054fb26;
-constexpr const auto OVERLAY_CRC_STRING = "c054fb26";
+constexpr const auto OVERLAY_CRC = 0x5afff726;
+constexpr const auto OVERLAY_CRC_STRING = "5afff726";
 
 }  // namespace android::idmap2::TestConstants
 
diff --git a/cmds/idmap2/tests/data/overlay/overlay-no-name-static.apk b/cmds/idmap2/tests/data/overlay/overlay-no-name-static.apk
index 7c25985..dab25b1 100644
--- a/cmds/idmap2/tests/data/overlay/overlay-no-name-static.apk
+++ b/cmds/idmap2/tests/data/overlay/overlay-no-name-static.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/overlay/overlay-no-name.apk b/cmds/idmap2/tests/data/overlay/overlay-no-name.apk
index c75f3e1..c8b95c2 100644
--- a/cmds/idmap2/tests/data/overlay/overlay-no-name.apk
+++ b/cmds/idmap2/tests/data/overlay/overlay-no-name.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/overlay/overlay-shared.apk b/cmds/idmap2/tests/data/overlay/overlay-shared.apk
index 93dcc82..0a8b737 100644
--- a/cmds/idmap2/tests/data/overlay/overlay-shared.apk
+++ b/cmds/idmap2/tests/data/overlay/overlay-shared.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/overlay/overlay-static-1.apk b/cmds/idmap2/tests/data/overlay/overlay-static-1.apk
index 5b8a6e4..fd41182 100644
--- a/cmds/idmap2/tests/data/overlay/overlay-static-1.apk
+++ b/cmds/idmap2/tests/data/overlay/overlay-static-1.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/overlay/overlay-static-2.apk b/cmds/idmap2/tests/data/overlay/overlay-static-2.apk
index 698a1fd..b24765f 100644
--- a/cmds/idmap2/tests/data/overlay/overlay-static-2.apk
+++ b/cmds/idmap2/tests/data/overlay/overlay-static-2.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/overlay/overlay.apk b/cmds/idmap2/tests/data/overlay/overlay.apk
index 1db303f..870575e 100644
--- a/cmds/idmap2/tests/data/overlay/overlay.apk
+++ b/cmds/idmap2/tests/data/overlay/overlay.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk b/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk
index 51e19de..e0fd204 100644
--- a/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk
+++ b/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/system-overlay-invalid/res/values/values.xml b/cmds/idmap2/tests/data/system-overlay-invalid/res/values/values.xml
index 7119d82..ebaf49c 100644
--- a/cmds/idmap2/tests/data/system-overlay-invalid/res/values/values.xml
+++ b/cmds/idmap2/tests/data/system-overlay-invalid/res/values/values.xml
@@ -26,6 +26,7 @@
     <string name="policy_odm">policy_odm</string>
     <string name="policy_oem">policy_oem</string>
     <string name="policy_actor">policy_actor</string>
+    <string name="policy_config_signature">policy_config_signature</string>
 
     <!-- Requests to overlay a resource that is not declared as overlayable. -->
     <string name="not_overlayable">not_overlayable</string>
diff --git a/cmds/idmap2/tests/data/system-overlay-invalid/system-overlay-invalid.apk b/cmds/idmap2/tests/data/system-overlay-invalid/system-overlay-invalid.apk
index bd99098..a63daf8 100644
--- a/cmds/idmap2/tests/data/system-overlay-invalid/system-overlay-invalid.apk
+++ b/cmds/idmap2/tests/data/system-overlay-invalid/system-overlay-invalid.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/system-overlay/system-overlay.apk b/cmds/idmap2/tests/data/system-overlay/system-overlay.apk
index a0fba43..90d2803 100644
--- a/cmds/idmap2/tests/data/system-overlay/system-overlay.apk
+++ b/cmds/idmap2/tests/data/system-overlay/system-overlay.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/target/res/values/overlayable.xml b/cmds/idmap2/tests/data/target/res/values/overlayable.xml
index ad4cd48..57e6c43 100644
--- a/cmds/idmap2/tests/data/target/res/values/overlayable.xml
+++ b/cmds/idmap2/tests/data/target/res/values/overlayable.xml
@@ -45,6 +45,10 @@
         <item type="string" name="policy_actor" />
     </policy>
 
+    <policy type="config_signature">
+        <item type="string" name="policy_config_signature"/>
+    </policy>
+
     <!-- Resources publicly overlayable -->
     <policy type="public">
         <item type="string" name="policy_public" />
diff --git a/cmds/idmap2/tests/data/target/res/values/values.xml b/cmds/idmap2/tests/data/target/res/values/values.xml
index 5230e25..00909a9 100644
--- a/cmds/idmap2/tests/data/target/res/values/values.xml
+++ b/cmds/idmap2/tests/data/target/res/values/values.xml
@@ -37,6 +37,7 @@
     <string name="policy_system">policy_system</string>
     <string name="policy_system_vendor">policy_system_vendor</string>
     <string name="policy_actor">policy_actor</string>
+    <string name="policy_config_signature">policy_config_signature</string>
 
     <string name="other">other</string>
 </resources>
diff --git a/cmds/idmap2/tests/data/target/target-no-overlayable.apk b/cmds/idmap2/tests/data/target/target-no-overlayable.apk
index 58504a7..cc3491d 100644
--- a/cmds/idmap2/tests/data/target/target-no-overlayable.apk
+++ b/cmds/idmap2/tests/data/target/target-no-overlayable.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/target/target.apk b/cmds/idmap2/tests/data/target/target.apk
index c80e5eb..4a58c5e 100644
--- a/cmds/idmap2/tests/data/target/target.apk
+++ b/cmds/idmap2/tests/data/target/target.apk
Binary files differ
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index b7f23a6..6327490 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -526,19 +526,34 @@
     OnConfigUpdatedLocked(timestampNs, key, config);
 }
 
-void StatsLogProcessor::OnConfigUpdatedLocked(
-        const int64_t timestampNs, const ConfigKey& key, const StatsdConfig& config) {
+void StatsLogProcessor::OnConfigUpdatedLocked(const int64_t timestampNs, const ConfigKey& key,
+                                              const StatsdConfig& config, bool modularUpdate) {
     VLOG("Updated configuration for key %s", key.ToString().c_str());
-    sp<MetricsManager> newMetricsManager =
-            new MetricsManager(key, config, mTimeBaseNs, timestampNs, mUidMap, mPullerManager,
-                               mAnomalyAlarmMonitor, mPeriodicAlarmMonitor);
-    if (newMetricsManager->isConfigValid()) {
-        newMetricsManager->init();
-        mUidMap->OnConfigUpdated(key);
-        newMetricsManager->refreshTtl(timestampNs);
-        mMetricsManagers[key] = newMetricsManager;
-        VLOG("StatsdConfig valid");
+    // Create new config if this is not a modular update or if this is a new config.
+    const auto& it = mMetricsManagers.find(key);
+    bool configValid = false;
+    if (!modularUpdate || it == mMetricsManagers.end()) {
+        sp<MetricsManager> newMetricsManager =
+                new MetricsManager(key, config, mTimeBaseNs, timestampNs, mUidMap, mPullerManager,
+                                   mAnomalyAlarmMonitor, mPeriodicAlarmMonitor);
+        configValid = newMetricsManager->isConfigValid();
+        if (configValid) {
+            newMetricsManager->init();
+            mUidMap->OnConfigUpdated(key);
+            newMetricsManager->refreshTtl(timestampNs);
+            mMetricsManagers[key] = newMetricsManager;
+            VLOG("StatsdConfig valid");
+        }
     } else {
+        // Preserve the existing MetricsManager, update necessary components and metadata in place.
+        configValid = it->second->updateConfig(timestampNs, config);
+        if (configValid) {
+            // TODO(b/162323476): refresh TTL, ensure init() is handled properly.
+            mUidMap->OnConfigUpdated(key);
+
+        }
+    }
+    if (!configValid) {
         // If there is any error in the config, don't use it.
         // Remove any existing config with the same key.
         ALOGE("StatsdConfig NOT valid");
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index 2384ed8..383dbd9 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -187,8 +187,8 @@
 
     void resetIfConfigTtlExpiredLocked(const int64_t timestampNs);
 
-    void OnConfigUpdatedLocked(
-        const int64_t currentTimestampNs, const ConfigKey& key, const StatsdConfig& config);
+    void OnConfigUpdatedLocked(const int64_t currentTimestampNs, const ConfigKey& key,
+                               const StatsdConfig& config, bool modularUpdate = false);
 
     void GetActiveConfigsLocked(const int uid, vector<int64_t>& outActiveConfigs);
 
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index 60de1a2..189d811 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -195,6 +195,10 @@
     VLOG("~MetricsManager()");
 }
 
+bool MetricsManager::updateConfig(const int64_t currentTimeNs, const StatsdConfig& config) {
+    return mConfigValid;
+}
+
 void MetricsManager::initLogSourceWhiteList() {
     std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
     mAllowedLogSources.clear();
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index ad30a88..042de29 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -46,6 +46,8 @@
 
     virtual ~MetricsManager();
 
+    bool updateConfig(const int64_t currentTimeNs, const StatsdConfig& config);
+
     // Return whether the configuration is valid.
     bool isConfigValid() const;
 
diff --git a/cmds/statsd/src/packages/PackageInfoListener.h b/cmds/statsd/src/packages/PackageInfoListener.h
index 6c50a8c..1bc84c5 100644
--- a/cmds/statsd/src/packages/PackageInfoListener.h
+++ b/cmds/statsd/src/packages/PackageInfoListener.h
@@ -17,6 +17,8 @@
 #ifndef STATSD_PACKAGE_INFO_LISTENER_H
 #define STATSD_PACKAGE_INFO_LISTENER_H
 
+#include <utils/RefBase.h>
+
 #include <string>
 
 namespace android {
diff --git a/cmds/statsd/src/packages/UidMap.h b/cmds/statsd/src/packages/UidMap.h
index 22250ae..622321b 100644
--- a/cmds/statsd/src/packages/UidMap.h
+++ b/cmds/statsd/src/packages/UidMap.h
@@ -17,7 +17,6 @@
 #pragma once
 
 #include "config/ConfigKey.h"
-#include "config/ConfigListener.h"
 #include "packages/PackageInfoListener.h"
 #include "stats_util.h"
 
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 4a982dd..2be9282 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -35,6 +35,7 @@
 import android.annotation.StyleRes;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
+import android.annotation.UiContext;
 import android.app.VoiceInteractor.Request;
 import android.app.admin.DevicePolicyManager;
 import android.app.assist.AssistContent;
@@ -726,6 +727,7 @@
  * upload, independent of whether the original activity is paused, stopped,
  * or finished.
  */
+@UiContext
 public class Activity extends ContextThemeWrapper
         implements LayoutInflater.Factory2,
         Window.Callback, KeyEvent.Callback,
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index f474389..7fe567b 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -457,7 +457,7 @@
     public abstract int broadcastIntent(Intent intent,
             IIntentReceiver resultTo,
             String[] requiredPermissions, boolean serialized,
-            int userId, int[] appIdWhitelist);
+            int userId, int[] appIdAllowList);
 
     /**
      * Add uid to the ActivityManagerService PendingStartActivityUids list.
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index 5e05506..9833ed6 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -24,6 +24,7 @@
 import android.annotation.Nullable;
 import android.annotation.StringRes;
 import android.annotation.StyleRes;
+import android.annotation.UiContext;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
 import android.content.Context;
@@ -101,6 +102,7 @@
     private final WindowManager mWindowManager;
 
     @UnsupportedAppUsage
+    @UiContext
     final Context mContext;
     @UnsupportedAppUsage
     final Window mWindow;
@@ -158,7 +160,7 @@
      * @param context the context in which the dialog should run
      * @see android.R.styleable#Theme_dialogTheme
      */
-    public Dialog(@NonNull Context context) {
+    public Dialog(@UiContext @NonNull Context context) {
         this(context, 0, true);
     }
 
@@ -177,11 +179,12 @@
      * @param themeResId a style resource describing the theme to use for the
      *              window, or {@code 0} to use the default dialog theme
      */
-    public Dialog(@NonNull Context context, @StyleRes int themeResId) {
+    public Dialog(@UiContext @NonNull Context context, @StyleRes int themeResId) {
         this(context, themeResId, true);
     }
 
-    Dialog(@NonNull Context context, @StyleRes int themeResId, boolean createContextThemeWrapper) {
+    Dialog(@UiContext @NonNull Context context, @StyleRes int themeResId,
+            boolean createContextThemeWrapper) {
         if (createContextThemeWrapper) {
             if (themeResId == Resources.ID_NULL) {
                 final TypedValue outValue = new TypedValue();
@@ -222,7 +225,7 @@
         mCancelMessage = cancelCallback;
     }
 
-    protected Dialog(@NonNull Context context, boolean cancelable,
+    protected Dialog(@UiContext @NonNull Context context, boolean cancelable,
             @Nullable OnCancelListener cancelListener) {
         this(context);
         mCancelable = cancelable;
@@ -234,7 +237,9 @@
      * 
      * @return Context The Context used by the Dialog.
      */
-    public final @NonNull Context getContext() {
+    @UiContext
+    @NonNull
+    public final Context getContext() {
         return mContext;
     }
 
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index c5d343d..0a80ccc 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -26,6 +26,7 @@
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.TestApi;
+import android.annotation.UiContext;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -213,7 +214,6 @@
     private static final Object sSync = new Object[0];
     @UnsupportedAppUsage
     private static Globals sGlobals;
-
     private final Context mContext;
     private final boolean mWcgEnabled;
     private final ColorManagementProxy mCmProxy;
@@ -539,7 +539,8 @@
         }
     }
 
-    /*package*/ WallpaperManager(IWallpaperManager service, Context context, Handler handler) {
+    /*package*/ WallpaperManager(IWallpaperManager service, @UiContext Context context,
+            Handler handler) {
         mContext = context;
         if (service != null) {
             initGlobals(service, context.getMainLooper());
diff --git a/core/java/android/app/WindowContext.java b/core/java/android/app/WindowContext.java
index cb416c9..5f72bac 100644
--- a/core/java/android/app/WindowContext.java
+++ b/core/java/android/app/WindowContext.java
@@ -20,6 +20,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UiContext;
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.os.Bundle;
@@ -42,6 +43,7 @@
  * @see Context#createWindowContext(int, Bundle)
  * @hide
  */
+@UiContext
 public class WindowContext extends ContextWrapper {
     private final WindowManagerImpl mWindowManager;
     private final IWindowManager mWms;
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
index 8a6cc95..1345e66 100644
--- a/core/java/android/app/usage/UsageStatsManager.java
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -109,7 +109,7 @@
 
 
     /**
-     * The app is whitelisted for some reason and the bucket cannot be changed.
+     * The app is exempted for some reason and the bucket cannot be changed.
      * {@hide}
      */
     @SystemApi
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index fa3df1d..fd60560 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -1033,6 +1033,18 @@
     }
 
     /**
+     * Returns the anonymized hardware address of this BluetoothDevice. The first three octets
+     * will be suppressed for anonymization.
+     * <p> For example, "XX:XX:XX:AA:BB:CC".
+     *
+     * @return Anonymized bluetooth hardware address as string
+     * @hide
+     */
+    public String getAnonymizedAddress() {
+        return "XX:XX:XX" + getAddress().substring(8);
+    }
+
+    /**
      * Get the friendly Bluetooth name of the remote device.
      *
      * <p>The local adapter will automatically retrieve remote names when
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 2385712..16cdf23 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -21,6 +21,7 @@
 import android.annotation.CheckResult;
 import android.annotation.ColorInt;
 import android.annotation.ColorRes;
+import android.annotation.DisplayContext;
 import android.annotation.DrawableRes;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -33,6 +34,7 @@
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
+import android.annotation.UiContext;
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.IApplicationThread;
@@ -3750,6 +3752,7 @@
      * @see #getSystemService(String)
      * @see android.view.WindowManager
      */
+    @UiContext
     public static final String WINDOW_SERVICE = "window";
 
     /**
@@ -3760,6 +3763,7 @@
      * @see #getSystemService(String)
      * @see android.view.LayoutInflater
      */
+    @UiContext
     public static final String LAYOUT_INFLATER_SERVICE = "layout_inflater";
 
     /**
@@ -3932,6 +3936,7 @@
      *
      * @see #getSystemService(String)
      */
+    @UiContext
     public static final String WALLPAPER_SERVICE = "wallpaper";
 
     /**
@@ -5789,6 +5794,7 @@
      *
      * @return A {@link Context} for the display.
      */
+    @DisplayContext
     public abstract Context createDisplayContext(@NonNull Display display);
 
     /**
@@ -5853,7 +5859,9 @@
      * the current number of window contexts without adding any view by
      * {@link WindowManager#addView} <b>exceeds five</b>.
      */
-    public @NonNull Context createWindowContext(@WindowType int type, @Nullable Bundle options)  {
+    @UiContext
+    @NonNull
+    public Context createWindowContext(@WindowType int type, @Nullable Bundle options)  {
         throw new RuntimeException("Not implemented. Must override in a subclass.");
     }
 
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index c5a11abe..7250801 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -32,6 +32,7 @@
 import android.annotation.MainThread;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UiContext;
 import android.app.ActivityManager;
 import android.app.Dialog;
 import android.compat.annotation.UnsupportedAppUsage;
@@ -258,6 +259,7 @@
  * @attr ref android.R.styleable#InputMethodService_imeExtractEnterAnimation
  * @attr ref android.R.styleable#InputMethodService_imeExtractExitAnimation
  */
+@UiContext
 public class InputMethodService extends AbstractInputMethodService {
     static final String TAG = "InputMethodService";
     static final boolean DEBUG = false;
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index 1539b6e..a6b869d 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -570,7 +570,7 @@
         final ContentResolver contentResolver = context.getContentResolver();
         final List<String> angleAllowlist =
                 getGlobalSettingsString(contentResolver, bundle,
-                    Settings.Global.GLOBAL_SETTINGS_ANGLE_WHITELIST);
+                    Settings.Global.GLOBAL_SETTINGS_ANGLE_ALLOWLIST);
 
         if (DEBUG) Log.v(TAG, "ANGLE allowlist: " + angleAllowlist);
 
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
index 0ec4fb8..40c291f 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -16,6 +16,6 @@
 per-file PowerManagerInternal.java = michaelwr@google.com, santoscordon@google.com
 
 # Zygote
-per-file ZygoteProcess.java = chriswailes@google.com, ngeoffray@google.com, sehr@google.com, narayan@google.com, maco@google.com
+per-file ZygoteProcess.java = calin@google.com, chriswailes@google.com, maco@google.com, narayan@google.com, ngeoffray@google.com
 
 per-file GraphicsEnvironment.java = chrisforbes@google.com, cnorthrop@google.com, lpy@google.com, timvp@google.com, zzyiwei@google.com
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index 39038f5..ffede09 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -251,11 +251,11 @@
     private final Object mLock = new Object();
 
     /**
-     * List of exemptions to the API blacklist. These are prefix matches on the runtime format
+     * List of exemptions to the API deny list. These are prefix matches on the runtime format
      * symbol signature. Any matching symbol is treated by the runtime as being on the light grey
      * list.
      */
-    private List<String> mApiBlacklistExemptions = Collections.emptyList();
+    private List<String> mApiDenylistExemptions = Collections.emptyList();
 
     /**
      * Proportion of hidden API accesses that should be logged to the event log; 0 - 0x10000.
@@ -562,7 +562,7 @@
         "--preload-package",
         "--preload-app",
         "--start-child-zygote",
-        "--set-api-blacklist-exemptions",
+        "--set-api-denylist-exemptions",
         "--hidden-api-log-sampling-rate",
         "--hidden-api-statslog-sampling-rate",
         "--invoke-with"
@@ -922,20 +922,20 @@
     }
 
     /**
-     * Push hidden API blacklisting exemptions into the zygote process(es).
+     * Push hidden API deny-listing exemptions into the zygote process(es).
      *
      * <p>The list of exemptions will take affect for all new processes forked from the zygote after
      * this call.
      *
      * @param exemptions List of hidden API exemption prefixes. Any matching members are treated as
-     *        whitelisted/public APIs (i.e. allowed, no logging of usage).
+     *        allowed/public APIs (i.e. allowed, no logging of usage).
      */
-    public boolean setApiBlacklistExemptions(List<String> exemptions) {
+    public boolean setApiDenylistExemptions(List<String> exemptions) {
         synchronized (mLock) {
-            mApiBlacklistExemptions = exemptions;
-            boolean ok = maybeSetApiBlacklistExemptions(primaryZygoteState, true);
+            mApiDenylistExemptions = exemptions;
+            boolean ok = maybeSetApiDenylistExemptions(primaryZygoteState, true);
             if (ok) {
-                ok = maybeSetApiBlacklistExemptions(secondaryZygoteState, true);
+                ok = maybeSetApiDenylistExemptions(secondaryZygoteState, true);
             }
             return ok;
         }
@@ -972,32 +972,32 @@
     }
 
     @GuardedBy("mLock")
-    private boolean maybeSetApiBlacklistExemptions(ZygoteState state, boolean sendIfEmpty) {
+    private boolean maybeSetApiDenylistExemptions(ZygoteState state, boolean sendIfEmpty) {
         if (state == null || state.isClosed()) {
-            Slog.e(LOG_TAG, "Can't set API blacklist exemptions: no zygote connection");
+            Slog.e(LOG_TAG, "Can't set API denylist exemptions: no zygote connection");
             return false;
-        } else if (!sendIfEmpty && mApiBlacklistExemptions.isEmpty()) {
+        } else if (!sendIfEmpty && mApiDenylistExemptions.isEmpty()) {
             return true;
         }
 
         try {
-            state.mZygoteOutputWriter.write(Integer.toString(mApiBlacklistExemptions.size() + 1));
+            state.mZygoteOutputWriter.write(Integer.toString(mApiDenylistExemptions.size() + 1));
             state.mZygoteOutputWriter.newLine();
-            state.mZygoteOutputWriter.write("--set-api-blacklist-exemptions");
+            state.mZygoteOutputWriter.write("--set-api-denylist-exemptions");
             state.mZygoteOutputWriter.newLine();
-            for (int i = 0; i < mApiBlacklistExemptions.size(); ++i) {
-                state.mZygoteOutputWriter.write(mApiBlacklistExemptions.get(i));
+            for (int i = 0; i < mApiDenylistExemptions.size(); ++i) {
+                state.mZygoteOutputWriter.write(mApiDenylistExemptions.get(i));
                 state.mZygoteOutputWriter.newLine();
             }
             state.mZygoteOutputWriter.flush();
             int status = state.mZygoteInputStream.readInt();
             if (status != 0) {
-                Slog.e(LOG_TAG, "Failed to set API blacklist exemptions; status " + status);
+                Slog.e(LOG_TAG, "Failed to set API denylist exemptions; status " + status);
             }
             return true;
         } catch (IOException ioe) {
-            Slog.e(LOG_TAG, "Failed to set API blacklist exemptions", ioe);
-            mApiBlacklistExemptions = Collections.emptyList();
+            Slog.e(LOG_TAG, "Failed to set API denylist exemptions", ioe);
+            mApiDenylistExemptions = Collections.emptyList();
             return false;
         }
     }
@@ -1054,7 +1054,7 @@
             primaryZygoteState =
                     ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress);
 
-            maybeSetApiBlacklistExemptions(primaryZygoteState, false);
+            maybeSetApiDenylistExemptions(primaryZygoteState, false);
             maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
         }
     }
@@ -1069,7 +1069,7 @@
                     ZygoteState.connect(mZygoteSecondarySocketAddress,
                             mUsapPoolSecondarySocketAddress);
 
-            maybeSetApiBlacklistExemptions(secondaryZygoteState, false);
+            maybeSetApiDenylistExemptions(secondaryZygoteState, false);
             maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState);
         }
     }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index dc1a0ca..5acc11a8 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -12328,8 +12328,8 @@
          * List of package names that should check ANGLE rules
          * @hide
          */
-        public static final String GLOBAL_SETTINGS_ANGLE_WHITELIST =
-                "angle_whitelist";
+        public static final String GLOBAL_SETTINGS_ANGLE_ALLOWLIST =
+                "angle_allowlist";
 
         /**
          * Show the "ANGLE In Use" dialog box to the user when ANGLE is the OpenGL driver.
diff --git a/core/java/android/util/proto/ProtoInputStream.java b/core/java/android/util/proto/ProtoInputStream.java
index cbe3734..aa70d07 100644
--- a/core/java/android/util/proto/ProtoInputStream.java
+++ b/core/java/android/util/proto/ProtoInputStream.java
@@ -96,7 +96,7 @@
     private byte mState = 0;
 
     /**
-     * Keeps track of the currently read nested Objects, for end object sanity checking and debug
+     * Keeps track of the currently read nested Objects, for end object checking and debug
      */
     private ArrayList<Long> mExpectedObjectTokenStack = null;
 
@@ -513,7 +513,7 @@
                     (int) fieldId, getOffset() + messageSize));
         }
 
-        // Sanity check
+        // Validation check
         if (mDepth > 0
                 && getOffsetFromToken(mExpectedObjectTokenStack.get(mDepth))
                 > getOffsetFromToken(mExpectedObjectTokenStack.get(mDepth - 1))) {
@@ -536,7 +536,7 @@
      * @param token - token
      */
     public void end(long token) {
-        // Sanity check to make sure user is keeping track of their embedded messages
+        // Make sure user is keeping track of their embedded messages
         if (mExpectedObjectTokenStack.get(mDepth) != token) {
             throw new ProtoParseException(
                     "end token " + token + " does not match current message token "
diff --git a/core/java/android/util/proto/ProtoOutputStream.java b/core/java/android/util/proto/ProtoOutputStream.java
index 5fcd38e..afca4ab 100644
--- a/core/java/android/util/proto/ProtoOutputStream.java
+++ b/core/java/android/util/proto/ProtoOutputStream.java
@@ -59,10 +59,10 @@
  * cache the size, and then write the size-prefixed buffers.
  *
  * We are trying to avoid too much generated code here, but this class still
- * needs to have a somewhat sane API.  We can't have the multiple passes be
- * done by the calling code.  In addition, we want to avoid the memory high
- * water mark of duplicating all of the values into the traditional in-memory
- * Message objects. We need to find another way.
+ * needs to have API.  We can't have the multiple passes be done by the
+ * calling code.  In addition, we want to avoid the memory high water mark
+ * of duplicating all of the values into the traditional in-memory Message
+ * objects. We need to find another way.
  *
  * So what we do here is to let the calling code write the data into a
  * byte[] (actually a collection of them wrapped in the EncodedBuffer class),
diff --git a/core/java/android/view/GestureDetector.java b/core/java/android/view/GestureDetector.java
index 55c527b..8a72218 100644
--- a/core/java/android/view/GestureDetector.java
+++ b/core/java/android/view/GestureDetector.java
@@ -25,6 +25,7 @@
 import static com.android.internal.util.FrameworkStatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SINGLE_TAP;
 import static com.android.internal.util.FrameworkStatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__UNKNOWN_CLASSIFICATION;
 
+import android.annotation.UiContext;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.Build;
@@ -393,7 +394,7 @@
      *
      * @throws NullPointerException if {@code listener} is null.
      */
-    public GestureDetector(Context context, OnGestureListener listener) {
+    public GestureDetector(@UiContext Context context, OnGestureListener listener) {
         this(context, listener, null);
     }
 
@@ -412,7 +413,8 @@
      *
      * @throws NullPointerException if {@code listener} is null.
      */
-    public GestureDetector(Context context, OnGestureListener listener, Handler handler) {
+    public GestureDetector(@UiContext Context context, OnGestureListener listener,
+            Handler handler) {
         if (handler != null) {
             mHandler = new GestureHandler(handler);
         } else {
@@ -442,12 +444,12 @@
      *
      * @throws NullPointerException if {@code listener} is null.
      */
-    public GestureDetector(Context context, OnGestureListener listener, Handler handler,
+    public GestureDetector(@UiContext Context context, OnGestureListener listener, Handler handler,
             boolean unused) {
         this(context, listener, handler);
     }
 
-    private void init(Context context) {
+    private void init(@UiContext Context context) {
         if (mListener == null) {
             throw new NullPointerException("OnGestureListener must not be null");
         }
diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java
index 1afe11e..b925b49 100644
--- a/core/java/android/view/LayoutInflater.java
+++ b/core/java/android/view/LayoutInflater.java
@@ -21,6 +21,7 @@
 import android.annotation.Nullable;
 import android.annotation.SystemService;
 import android.annotation.TestApi;
+import android.annotation.UiContext;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
@@ -94,6 +95,7 @@
      * {@hide}
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UiContext
     protected final Context mContext;
 
     // these are optional, set by the caller
@@ -277,7 +279,7 @@
     /**
      * Obtains the LayoutInflater from the given context.
      */
-    public static LayoutInflater from(Context context) {
+    public static LayoutInflater from(@UiContext Context context) {
         LayoutInflater LayoutInflater =
                 (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         if (LayoutInflater == null) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index ef4bc91..0818abe 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -43,6 +43,7 @@
 import android.annotation.Size;
 import android.annotation.StyleRes;
 import android.annotation.TestApi;
+import android.annotation.UiContext;
 import android.annotation.UiThread;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.AutofillOptions;
@@ -4909,6 +4910,7 @@
      */
     @ViewDebug.ExportedProperty(deepExport = true)
     @UnsupportedAppUsage
+    @UiContext
     protected Context mContext;
 
     @UnsupportedAppUsage
@@ -15070,6 +15072,7 @@
      * @return The view's Context.
      */
     @ViewDebug.CapturedViewProperty
+    @UiContext
     public final Context getContext() {
         return mContext;
     }
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index ffeeb80..ccf1fb0 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -20,6 +20,7 @@
 
 import android.annotation.FloatRange;
 import android.annotation.TestApi;
+import android.annotation.UiContext;
 import android.app.Activity;
 import android.app.AppGlobals;
 import android.compat.annotation.UnsupportedAppUsage;
@@ -391,7 +392,7 @@
      * @see #get(android.content.Context)
      * @see android.util.DisplayMetrics
      */
-    private ViewConfiguration(Context context) {
+    private ViewConfiguration(@UiContext Context context) {
         mConstructedWithContext = true;
         final Resources res = context.getResources();
         final DisplayMetrics metrics = res.getDisplayMetrics();
@@ -498,7 +499,8 @@
      *                be {@link Activity} or other {@link Context} created with
      *                {@link Context#createWindowContext(int, Bundle)}.
      */
-    public static ViewConfiguration get(Context context) {
+
+    public static ViewConfiguration get(@UiContext Context context) {
         if (!context.isUiContext() && vmIncorrectContextUseEnabled()) {
             final String errorMessage = "Tried to access UI constants from a non-visual Context:"
                     + context;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 2a2d1e6..64ddb2f 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -64,6 +64,7 @@
 import android.annotation.AnyThread;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UiContext;
 import android.app.ActivityManager;
 import android.app.ActivityThread;
 import android.app.ResourcesManager;
@@ -349,6 +350,7 @@
     @GuardedBy("mWindowCallbacks")
     final ArrayList<WindowCallbacks> mWindowCallbacks = new ArrayList<>();
     @UnsupportedAppUsage
+    @UiContext
     public final Context mContext;
 
     @UnsupportedAppUsage
@@ -719,11 +721,11 @@
                 false /* useSfChoreographer */);
     }
 
-    public ViewRootImpl(Context context, Display display, IWindowSession session) {
+    public ViewRootImpl(@UiContext Context context, Display display, IWindowSession session) {
         this(context, display, session, false /* useSfChoreographer */);
     }
 
-    public ViewRootImpl(Context context, Display display, IWindowSession session,
+    public ViewRootImpl(@UiContext Context context, Display display, IWindowSession session,
             boolean useSfChoreographer) {
         mContext = context;
         mWindowSession = session;
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 446e7aa..1dbf37a 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -27,6 +27,7 @@
 import android.annotation.StyleRes;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
+import android.annotation.UiContext;
 import android.app.WindowConfiguration;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
@@ -280,6 +281,7 @@
     public static final int DECOR_CAPTION_SHADE_DARK = 2;
 
     @UnsupportedAppUsage
+    @UiContext
     private final Context mContext;
 
     @UnsupportedAppUsage
@@ -722,7 +724,7 @@
     }
 
 
-    public Window(Context context) {
+    public Window(@UiContext Context context) {
         mContext = context;
         mFeatures = mLocalFeatures = getDefaultFeatures(context);
     }
@@ -733,6 +735,7 @@
      *
      * @return Context The Context that was supplied to the constructor.
      */
+    @UiContext
     public final Context getContext() {
         return mContext;
     }
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index cf4315f..7923ff0 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -347,6 +347,7 @@
             TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE,
             TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION,
             TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER,
+            TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION
     })
     @Retention(RetentionPolicy.SOURCE)
     @interface TransitionFlags {}
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index b4561c5..27fbfb6 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -25,6 +25,7 @@
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
 
 import android.annotation.NonNull;
+import android.annotation.UiContext;
 import android.app.ResourcesManager;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
@@ -69,6 +70,7 @@
 public final class WindowManagerImpl implements WindowManager {
     @UnsupportedAppUsage
     private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
+    @UiContext
     @VisibleForTesting
     public final Context mContext;
     private final Window mParentWindow;
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 793d940..f6671d8 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -22,6 +22,7 @@
 import static com.android.internal.inputmethod.StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION;
 import static com.android.internal.inputmethod.StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION;
 
+import android.annotation.DisplayContext;
 import android.annotation.DrawableRes;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -1193,7 +1194,7 @@
      * @hide
      */
     @NonNull
-    public static InputMethodManager forContext(Context context) {
+    public static InputMethodManager forContext(@DisplayContext Context context) {
         final int displayId = context.getDisplayId();
         // For better backward compatibility, we always use Looper.getMainLooper() for the default
         // display case.
diff --git a/core/java/com/android/internal/os/ChildZygoteInit.java b/core/java/com/android/internal/os/ChildZygoteInit.java
index 1f816c1..749ff84 100644
--- a/core/java/com/android/internal/os/ChildZygoteInit.java
+++ b/core/java/com/android/internal/os/ChildZygoteInit.java
@@ -116,7 +116,7 @@
         try {
             server.registerServerSocketAtAbstractName(socketName);
 
-            // Add the abstract socket to the FD whitelist so that the native zygote code
+            // Add the abstract socket to the FD allow list so that the native zygote code
             // can properly detach it after forking.
             Zygote.nativeAllowFileAcrossFork("ABSTRACT/" + socketName);
 
diff --git a/core/java/com/android/internal/os/OWNERS b/core/java/com/android/internal/os/OWNERS
index 9283105..afc9432 100644
--- a/core/java/com/android/internal/os/OWNERS
+++ b/core/java/com/android/internal/os/OWNERS
@@ -1 +1 @@
-per-file ZygoteArguments.java,ZygoteConnection.java,ZygoteInit.java,Zygote.java,ZygoteServer.java = chriswailes@google.com, ngeoffray@google.com, sehr@google.com, narayan@google.com, maco@google.com
+per-file ZygoteArguments.java,ZygoteConnection.java,ZygoteInit.java,Zygote.java,ZygoteServer.java = calin@google.com, chriswailes@google.com, maco@google.com, narayan@google.com, ngeoffray@google.com
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 2989a5e..1ca9250 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -816,9 +816,9 @@
             throw new IllegalArgumentException(USAP_ERROR_PREFIX + "--preload-app");
         } else if (args.mStartChildZygote) {
             throw new IllegalArgumentException(USAP_ERROR_PREFIX + "--start-child-zygote");
-        } else if (args.mApiBlacklistExemptions != null) {
+        } else if (args.mApiDenylistExemptions != null) {
             throw new IllegalArgumentException(
-                USAP_ERROR_PREFIX + "--set-api-blacklist-exemptions");
+                    USAP_ERROR_PREFIX + "--set-api-denylist-exemptions");
         } else if (args.mHiddenApiAccessLogSampleRate != -1) {
             throw new IllegalArgumentException(
                     USAP_ERROR_PREFIX + "--hidden-api-log-sampling-rate=");
diff --git a/core/java/com/android/internal/os/ZygoteArguments.java b/core/java/com/android/internal/os/ZygoteArguments.java
index 94c1f71..22082d0 100644
--- a/core/java/com/android/internal/os/ZygoteArguments.java
+++ b/core/java/com/android/internal/os/ZygoteArguments.java
@@ -192,10 +192,10 @@
     boolean mBootCompleted;
 
     /**
-     * Exemptions from API blacklisting. These are sent to the pre-forked zygote at boot time, or
-     * when they change, via --set-api-blacklist-exemptions.
+     * Exemptions from API deny-listing. These are sent to the pre-forked zygote at boot time, or
+     * when they change, via --set-api-denylist-exemptions.
      */
-    String[] mApiBlacklistExemptions;
+    String[] mApiDenylistExemptions;
 
     /**
      * Sampling rate for logging hidden API accesses to the event log. This is sent to the
@@ -416,10 +416,10 @@
                 expectRuntimeArgs = false;
             } else if (arg.equals("--start-child-zygote")) {
                 mStartChildZygote = true;
-            } else if (arg.equals("--set-api-blacklist-exemptions")) {
+            } else if (arg.equals("--set-api-denylist-exemptions")) {
                 // consume all remaining args; this is a stand-alone command, never included
                 // with the regular fork command.
-                mApiBlacklistExemptions = Arrays.copyOfRange(args, curArg + 1, args.length);
+                mApiDenylistExemptions = Arrays.copyOfRange(args, curArg + 1, args.length);
                 curArg = args.length;
                 expectRuntimeArgs = false;
             } else if (arg.startsWith("--hidden-api-log-sampling-rate=")) {
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index ec1b05a..5a576ebb 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -185,8 +185,8 @@
             return null;
         }
 
-        if (parsedArgs.mApiBlacklistExemptions != null) {
-            return handleApiBlacklistExemptions(zygoteServer, parsedArgs.mApiBlacklistExemptions);
+        if (parsedArgs.mApiDenylistExemptions != null) {
+            return handleApiDenylistExemptions(zygoteServer, parsedArgs.mApiDenylistExemptions);
         }
 
         if (parsedArgs.mHiddenApiAccessLogSampleRate != -1
@@ -367,11 +367,11 @@
     }
 
     /**
-     * Makes the necessary changes to implement a new API blacklist exemption policy, and then
+     * Makes the necessary changes to implement a new API deny list exemption policy, and then
      * responds to the system server, letting it know that the task has been completed.
      *
      * This necessitates a change to the internal state of the Zygote.  As such, if the USAP
-     * pool is enabled all existing USAPs have an incorrect API blacklist exemption list.  To
+     * pool is enabled all existing USAPs have an incorrect API deny list exemption list.  To
      * properly handle this request the pool must be emptied and refilled.  This process can return
      * a Runnable object that must be returned to ZygoteServer.runSelectLoop to be invoked.
      *
@@ -380,9 +380,9 @@
      * @return A Runnable object representing a new app in any USAPs spawned from here; the
      *         zygote process will always receive a null value from this function.
      */
-    private Runnable handleApiBlacklistExemptions(ZygoteServer zygoteServer, String[] exemptions) {
+    private Runnable handleApiDenylistExemptions(ZygoteServer zygoteServer, String[] exemptions) {
         return stateChangeWithUsapPoolReset(zygoteServer,
-                () -> ZygoteInit.setApiBlacklistExemptions(exemptions));
+                () -> ZygoteInit.setApiDenylistExemptions(exemptions));
     }
 
     private Runnable handleUsapPoolStatusChange(ZygoteServer zygoteServer, boolean newStatus) {
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 5fd9333..32e7fdc 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -583,7 +583,10 @@
         VMRuntime.registerAppInfo(profilePath, codePaths);
     }
 
-    public static void setApiBlacklistExemptions(String[] exemptions) {
+    /**
+     * Sets the list of classes/methods for the hidden API
+     */
+    public static void setApiDenylistExemptions(String[] exemptions) {
         VMRuntime.getRuntime().setHiddenApiExemptions(exemptions);
     }
 
diff --git a/core/java/com/android/internal/os/ZygoteServer.java b/core/java/com/android/internal/os/ZygoteServer.java
index a0b50df..bb17337 100644
--- a/core/java/com/android/internal/os/ZygoteServer.java
+++ b/core/java/com/android/internal/os/ZygoteServer.java
@@ -451,7 +451,7 @@
              * For reasons of correctness the USAP pool pipe and event FDs
              * must be processed before the session and server sockets.  This
              * is to ensure that the USAP pool accounting information is
-             * accurate when handling other requests like API blacklist
+             * accurate when handling other requests like API deny list
              * exemptions.
              */
 
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 0a3fe09..053b06f 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -35,6 +35,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UiContext;
 import android.app.ActivityManager;
 import android.app.KeyguardManager;
 import android.app.SearchManager;
@@ -342,7 +343,7 @@
     static final RotationWatcher sRotationWatcher = new RotationWatcher();
 
     @UnsupportedAppUsage
-    public PhoneWindow(Context context) {
+    public PhoneWindow(@UiContext Context context) {
         super(context);
         mLayoutInflater = LayoutInflater.from(context);
         mRenderShadowsInCompositor = Settings.Global.getInt(context.getContentResolver(),
@@ -352,7 +353,7 @@
     /**
      * Constructor for main window of an activity.
      */
-    public PhoneWindow(Context context, Window preservedWindow,
+    public PhoneWindow(@UiContext Context context, Window preservedWindow,
             ActivityConfigCallback activityConfigCallback) {
         this(context);
         // Only main activity windows use decor context, all the other windows depend on whatever
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index c6a1153..6b754ca 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -19,6 +19,7 @@
 import static com.android.internal.util.ArrayUtils.appendInt;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.content.ComponentName;
 import android.content.pm.FeatureInfo;
@@ -245,6 +246,14 @@
      */
     private Map<String, Map<String, String>> mNamedActors = null;
 
+    // Package name of the package pre-installed on a read-only
+    // partition that is used to verify if an overlay package fulfills
+    // the 'config_signature' policy by comparing their signatures:
+    // if the overlay package is signed with the same certificate as
+    // the package declared in 'config-signature' tag, then the
+    // overlay package fulfills the 'config_signature' policy.
+    private String mOverlayConfigSignaturePackage;
+
     public static SystemConfig getInstance() {
         if (!isSystemProcess()) {
             Slog.wtf(TAG, "SystemConfig is being accessed by a process other than "
@@ -432,6 +441,12 @@
         return mNamedActors != null ? mNamedActors : Collections.emptyMap();
     }
 
+    @Nullable
+    public String getOverlayConfigSignaturePackage() {
+        return TextUtils.isEmpty(mOverlayConfigSignaturePackage)
+                ? null : mOverlayConfigSignaturePackage;
+    }
+
     /**
      * Only use for testing. Do NOT use in production code.
      * @param readPermissions false to create an empty SystemConfig; true to read the permissions.
@@ -1137,6 +1152,27 @@
                         }
                         XmlUtils.skipCurrentTag(parser);
                     } break;
+                    case "overlay-config-signature": {
+                        if (allowAll) {
+                            String pkgName = parser.getAttributeValue(null, "package");
+                            if (pkgName == null) {
+                                Slog.w(TAG, "<" + name + "> without package in " + permFile
+                                        + " at " + parser.getPositionDescription());
+                            } else {
+                                if (TextUtils.isEmpty(mOverlayConfigSignaturePackage)) {
+                                    mOverlayConfigSignaturePackage = pkgName.intern();
+                                } else {
+                                    throw new IllegalStateException("Reference signature package "
+                                                  + "defined as both "
+                                                  + mOverlayConfigSignaturePackage
+                                                  + " and " + pkgName);
+                                }
+                            }
+                        } else {
+                            logNotAllowedInPartition(name, permFile, parser);
+                        }
+                        XmlUtils.skipCurrentTag(parser);
+                    } break;
                     case "rollback-whitelisted-app": {
                         String pkgname = parser.getAttributeValue(null, "package");
                         if (pkgname == null) {
diff --git a/core/jni/OWNERS b/core/jni/OWNERS
index d7d8621..7d80993 100644
--- a/core/jni/OWNERS
+++ b/core/jni/OWNERS
@@ -17,4 +17,4 @@
 per-file android_view_PointerIcon.* = michaelwr@google.com, svv@google.com
 
 # Zygote
-per-file com_android_internal_os_Zygote.*,fd_utils.* = chriswailes@google.com, ngeoffray@google.com, sehr@google.com, narayan@google.com, maco@google.com
+per-file com_android_internal_os_Zygote.*,fd_utils.* = calin@google.com, chriswailes@google.com, maco@google.com, narayan@google.com, ngeoffray@google.com
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 22bb210..1f62544 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -974,7 +974,7 @@
         if (jHandle == NULL) {
             return (jint)AUDIO_JAVA_ERROR;
         }
-        // create dummy port and port config objects with just the correct handle
+        // create placeholder port and port config objects with just the correct handle
         // and configuration data. The actual AudioPortConfig objects will be
         // constructed by java code with correct class type (device, mix etc...)
         // and reference to AudioPort instance in this client
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index e56809f..8d4c4e5 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -93,13 +93,13 @@
 
 static void android_net_utils_detachBPFFilter(JNIEnv *env, jobject clazz, jobject javaFd)
 {
-    int dummy = 0;
+    int optval_ignored = 0;
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
-    if (setsockopt(fd, SOL_SOCKET, SO_DETACH_FILTER, &dummy, sizeof(dummy)) != 0) {
+    if (setsockopt(fd, SOL_SOCKET, SO_DETACH_FILTER, &optval_ignored, sizeof(optval_ignored)) !=
+        0) {
         jniThrowExceptionFmt(env, "java/net/SocketException",
                 "setsockopt(SO_DETACH_FILTER): %s", strerror(errno));
     }
-
 }
 
 static jboolean android_net_utils_bindProcessToNetwork(JNIEnv *env, jobject thiz, jint netId)
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index d6e8531..ef0eeec 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -920,7 +920,7 @@
 {
     jclass clazz = env->FindClass("android/os/Debug$MemoryInfo");
 
-    // Sanity check the number of other statistics expected in Java matches here.
+    // Check the number of other statistics expected in Java matches here.
     jfieldID numOtherStats_field = env->GetStaticFieldID(clazz, "NUM_OTHER_STATS", "I");
     jint numOtherStats = env->GetStaticIntField(clazz, numOtherStats_field);
     jfieldID numDvkStats_field = env->GetStaticFieldID(clazz, "NUM_DVK_STATS", "I");
diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp
index 2000ecb..7cfe3bc 100644
--- a/core/jni/android_os_Parcel.cpp
+++ b/core/jni/android_os_Parcel.cpp
@@ -330,7 +330,7 @@
     if (parcel != NULL) {
         int32_t len = parcel->readInt32();
 
-        // sanity check the stored length against the true data size
+        // Validate the stored length against the true data size
         if (len >= 0 && len <= (int32_t)parcel->dataAvail()) {
             ret = env->NewByteArray(len);
 
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 885b0a3..e118038 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -962,7 +962,7 @@
 
 static void android_os_Binder_restoreCallingIdentity(JNIEnv* env, jobject clazz, jlong token)
 {
-    // XXX temporary sanity check to debug crashes.
+    // XXX temporary validation check to debug crashes.
     int uid = (int)(token>>32);
     if (uid > 0 && uid < 999) {
         // In Android currently there are no uids in this range.
diff --git a/core/jni/android_view_InputQueue.cpp b/core/jni/android_view_InputQueue.cpp
index 24c3ff8..70a9be7 100644
--- a/core/jni/android_view_InputQueue.cpp
+++ b/core/jni/android_view_InputQueue.cpp
@@ -176,8 +176,8 @@
     Mutex::Autolock _l(mLock);
     mPendingEvents.push(event);
     if (mPendingEvents.size() == 1) {
-        char dummy = 0;
-        int res = TEMP_FAILURE_RETRY(write(mDispatchWriteFd, &dummy, sizeof(dummy)));
+        char payload = '\0';
+        int res = TEMP_FAILURE_RETRY(write(mDispatchWriteFd, &payload, sizeof(payload)));
         if (res < 0 && errno != EAGAIN) {
             ALOGW("Failed writing to dispatch fd: %s", strerror(errno));
         }
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index fe540bb..e4a142b 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -449,7 +449,7 @@
         // Game Driver - List of Apps that are allowed to use Game Driver
         optional SettingProto game_driver_allowlist = 12;
         // ANGLE - List of Apps that can check ANGLE rules
-        optional SettingProto angle_whitelist = 13;
+        optional SettingProto angle_allowlist = 13;
         // Game Driver - List of denylists, each denylist is a denylist for
         // a specific Game Driver version
         optional SettingProto game_driver_denylists = 14;
diff --git a/core/proto/android/server/alarm/alarmmanagerservice.proto b/core/proto/android/server/alarm/alarmmanagerservice.proto
index b74991d..e1240245 100644
--- a/core/proto/android/server/alarm/alarmmanagerservice.proto
+++ b/core/proto/android/server/alarm/alarmmanagerservice.proto
@@ -59,9 +59,10 @@
     // Time since the last wakeup was set.
     optional int64 time_since_last_wakeup_set_ms = 15;
     optional int64 time_change_event_count = 16;
-    // The current set of user whitelisted apps for device idle mode, meaning
+    // The current set of user exempted apps for device idle mode, meaning
     // these are allowed to freely schedule alarms. These are app IDs, not UIDs.
-    repeated int32 device_idle_user_whitelist_app_ids = 17;
+    // This field is currently unused.
+    repeated int32 device_idle_user_exempt_app_ids = 17;
 
     repeated AlarmClockMetadataProto next_alarm_clock_metadata = 18;
 
diff --git a/core/proto/android/server/appstatetracker.proto b/core/proto/android/server/appstatetracker.proto
index 51e8845..f5583d4 100644
--- a/core/proto/android/server/appstatetracker.proto
+++ b/core/proto/android/server/appstatetracker.proto
@@ -41,14 +41,14 @@
     // UIDs currently in the foreground.
     repeated int32 foreground_uids = 11;
 
-    // App ids that are in power-save whitelist.
-    repeated int32 power_save_whitelist_app_ids = 3;
+    // App ids that are in power-save exemption list.
+    repeated int32 power_save_exempt_app_ids = 3;
 
-    // App ids that are in power-save user whitelist.
-    repeated int32 power_save_user_whitelist_app_ids = 12;
+    // App ids that are in power-save user exemption list.
+    repeated int32 power_save_user_exempt_app_ids = 12;
 
-    // App ids that are in temporary power-save whitelist.
-    repeated int32 temp_power_save_whitelist_app_ids = 4;
+    // App ids that are in temporary power-save exemption list.
+    repeated int32 temp_power_save_exempt_app_ids = 4;
 
     message RunAnyInBackgroundRestrictedPackages {
         option (.android.msg_privacy).dest = DEST_AUTOMATIC;
@@ -79,5 +79,5 @@
     }
 
     // Packages that are in the EXEMPT bucket.
-    repeated ExemptedPackage exempted_packages = 10;
+    repeated ExemptedPackage exempted_bucket_packages = 10;
 }
diff --git a/core/tests/coretests/apks/install/res/values/strings.xml b/core/tests/coretests/apks/install/res/values/strings.xml
index 3b8b3b1..984152f 100644
--- a/core/tests/coretests/apks/install/res/values/strings.xml
+++ b/core/tests/coretests/apks/install/res/values/strings.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 
-<!-- Just need this dummy file to have something to build. -->
+<!-- Just need this placeholder file to have something to build. -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string name="dummy">dummy</string>
+  <string name="placeholder">placeholder</string>
 </resources>
diff --git a/core/tests/coretests/apks/install_bad_dex/res/values/strings.xml b/core/tests/coretests/apks/install_bad_dex/res/values/strings.xml
index 3b8b3b1..984152f 100644
--- a/core/tests/coretests/apks/install_bad_dex/res/values/strings.xml
+++ b/core/tests/coretests/apks/install_bad_dex/res/values/strings.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 
-<!-- Just need this dummy file to have something to build. -->
+<!-- Just need this placeholder file to have something to build. -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string name="dummy">dummy</string>
+  <string name="placeholder">placeholder</string>
 </resources>
diff --git a/core/tests/coretests/apks/install_decl_perm/res/values/strings.xml b/core/tests/coretests/apks/install_decl_perm/res/values/strings.xml
index 3b8b3b1..984152f 100644
--- a/core/tests/coretests/apks/install_decl_perm/res/values/strings.xml
+++ b/core/tests/coretests/apks/install_decl_perm/res/values/strings.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 
-<!-- Just need this dummy file to have something to build. -->
+<!-- Just need this placeholder file to have something to build. -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string name="dummy">dummy</string>
+  <string name="placeholder">placeholder</string>
 </resources>
diff --git a/core/tests/coretests/apks/install_loc_auto/res/values/strings.xml b/core/tests/coretests/apks/install_loc_auto/res/values/strings.xml
index 3b8b3b1..984152f 100644
--- a/core/tests/coretests/apks/install_loc_auto/res/values/strings.xml
+++ b/core/tests/coretests/apks/install_loc_auto/res/values/strings.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 
-<!-- Just need this dummy file to have something to build. -->
+<!-- Just need this placeholder file to have something to build. -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string name="dummy">dummy</string>
+  <string name="placeholder">placeholder</string>
 </resources>
diff --git a/core/tests/coretests/apks/install_loc_internal/res/values/strings.xml b/core/tests/coretests/apks/install_loc_internal/res/values/strings.xml
index 3b8b3b1..984152f 100644
--- a/core/tests/coretests/apks/install_loc_internal/res/values/strings.xml
+++ b/core/tests/coretests/apks/install_loc_internal/res/values/strings.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 
-<!-- Just need this dummy file to have something to build. -->
+<!-- Just need this placeholder file to have something to build. -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string name="dummy">dummy</string>
+  <string name="placeholder">placeholder</string>
 </resources>
diff --git a/core/tests/coretests/apks/install_loc_sdcard/res/values/strings.xml b/core/tests/coretests/apks/install_loc_sdcard/res/values/strings.xml
index 3b8b3b1..984152f 100644
--- a/core/tests/coretests/apks/install_loc_sdcard/res/values/strings.xml
+++ b/core/tests/coretests/apks/install_loc_sdcard/res/values/strings.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 
-<!-- Just need this dummy file to have something to build. -->
+<!-- Just need this placeholder file to have something to build. -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string name="dummy">dummy</string>
+  <string name="placeholder">placeholder</string>
 </resources>
diff --git a/core/tests/coretests/apks/install_loc_unspecified/res/values/strings.xml b/core/tests/coretests/apks/install_loc_unspecified/res/values/strings.xml
index 3b8b3b1..984152f 100644
--- a/core/tests/coretests/apks/install_loc_unspecified/res/values/strings.xml
+++ b/core/tests/coretests/apks/install_loc_unspecified/res/values/strings.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 
-<!-- Just need this dummy file to have something to build. -->
+<!-- Just need this placeholder file to have something to build. -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string name="dummy">dummy</string>
+  <string name="placeholder">placeholder</string>
 </resources>
diff --git a/core/tests/coretests/apks/install_use_perm_good/res/values/strings.xml b/core/tests/coretests/apks/install_use_perm_good/res/values/strings.xml
index 3b8b3b1..984152f 100644
--- a/core/tests/coretests/apks/install_use_perm_good/res/values/strings.xml
+++ b/core/tests/coretests/apks/install_use_perm_good/res/values/strings.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 
-<!-- Just need this dummy file to have something to build. -->
+<!-- Just need this placeholder file to have something to build. -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string name="dummy">dummy</string>
+  <string name="placeholder">placeholder</string>
 </resources>
diff --git a/core/tests/coretests/apks/install_uses_feature/res/values/strings.xml b/core/tests/coretests/apks/install_uses_feature/res/values/strings.xml
index 3b8b3b1..984152f 100644
--- a/core/tests/coretests/apks/install_uses_feature/res/values/strings.xml
+++ b/core/tests/coretests/apks/install_uses_feature/res/values/strings.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 
-<!-- Just need this dummy file to have something to build. -->
+<!-- Just need this placeholder file to have something to build. -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string name="dummy">dummy</string>
+  <string name="placeholder">placeholder</string>
 </resources>
diff --git a/core/tests/coretests/apks/install_verifier_bad/res/values/strings.xml b/core/tests/coretests/apks/install_verifier_bad/res/values/strings.xml
index 3b8b3b1..984152f 100644
--- a/core/tests/coretests/apks/install_verifier_bad/res/values/strings.xml
+++ b/core/tests/coretests/apks/install_verifier_bad/res/values/strings.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 
-<!-- Just need this dummy file to have something to build. -->
+<!-- Just need this placeholder file to have something to build. -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string name="dummy">dummy</string>
+  <string name="placeholder">placeholder</string>
 </resources>
diff --git a/core/tests/coretests/apks/install_verifier_good/res/values/strings.xml b/core/tests/coretests/apks/install_verifier_good/res/values/strings.xml
index 3b8b3b1..984152f 100644
--- a/core/tests/coretests/apks/install_verifier_good/res/values/strings.xml
+++ b/core/tests/coretests/apks/install_verifier_good/res/values/strings.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 
-<!-- Just need this dummy file to have something to build. -->
+<!-- Just need this placeholder file to have something to build. -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string name="dummy">dummy</string>
+  <string name="placeholder">placeholder</string>
 </resources>
diff --git a/core/tests/coretests/apks/keyset/res/values/strings.xml b/core/tests/coretests/apks/keyset/res/values/strings.xml
index ff99ffa..d811ec2 100644
--- a/core/tests/coretests/apks/keyset/res/values/strings.xml
+++ b/core/tests/coretests/apks/keyset/res/values/strings.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 
-<!-- Just need this dummy file to have something to build. -->
+<!-- Just need this placeholder file to have something to build. -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string name="dummy">dummy</string>
+  <string name="placeholder">placeholder</string>
   <string name="keyset_perm_desc">keyset_perm_description</string>
   <string name="keyset_perm_label">keyset_perm_label</string>
 </resources>
diff --git a/core/tests/coretests/apks/version/res/values/strings.xml b/core/tests/coretests/apks/version/res/values/strings.xml
index 3b8b3b1..984152f 100644
--- a/core/tests/coretests/apks/version/res/values/strings.xml
+++ b/core/tests/coretests/apks/version/res/values/strings.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 
-<!-- Just need this dummy file to have something to build. -->
+<!-- Just need this placeholder file to have something to build. -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string name="dummy">dummy</string>
+  <string name="placeholder">placeholder</string>
 </resources>
diff --git a/core/tests/coretests/apks/version_nosys/res/values/strings.xml b/core/tests/coretests/apks/version_nosys/res/values/strings.xml
index 3b8b3b1..984152f 100644
--- a/core/tests/coretests/apks/version_nosys/res/values/strings.xml
+++ b/core/tests/coretests/apks/version_nosys/res/values/strings.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 
-<!-- Just need this dummy file to have something to build. -->
+<!-- Just need this placeholder file to have something to build. -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string name="dummy">dummy</string>
+  <string name="placeholder">placeholder</string>
 </resources>
diff --git a/data/keyboards/Vendor_2dc8_Product_6101.kl b/data/keyboards/Vendor_2dc8_Product_6101.kl
new file mode 100644
index 0000000..ec9f558
--- /dev/null
+++ b/data/keyboards/Vendor_2dc8_Product_6101.kl
@@ -0,0 +1,55 @@
+# Copyright (C) 2020 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.
+
+#
+# 8BitDo - SN30 Pro gamepad in Android (D-Input) mode
+#
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+# Button labeled as "A" but should really produce keycode "B"
+key 304      BUTTON_B
+# Button labeled as "B" but should really produce keycode "A"
+key 305      BUTTON_A
+# Button labeled as "X" but should really produce keycode "Y"
+key 307      BUTTON_Y
+# Button labeled as "Y" but should really produce keycode "X"
+key 308      BUTTON_X
+
+key 310      BUTTON_L1
+key 312      BUTTON_L2
+key 311      BUTTON_R1
+key 313      BUTTON_R2
+
+# Button "Start" does not emit event when gamepad is in Android mode
+# Button "Home"
+key 306      BUTTON_MODE
+key 314      BUTTON_SELECT
+key 315      BUTTON_START
+
+key 317      BUTTON_THUMBL
+key 318      BUTTON_THUMBR
+
+# Left Analog Stick
+axis 0x00    X
+axis 0x01    Y
+
+# Right Analog Stick
+axis 0x02    Z
+axis 0x05    RZ
+
+# Dpad
+axis 0x10    HAT_X
+axis 0x11    HAT_Y
+
diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h
index e351a46..e10a7f3 100644
--- a/libs/androidfw/include/androidfw/ResourceTypes.h
+++ b/libs/androidfw/include/androidfw/ResourceTypes.h
@@ -1717,6 +1717,10 @@
     // The overlay must be signed with the same signature as the actor declared for the target
     // resource
     ACTOR_SIGNATURE = 0x00000080,
+
+    // The overlay must be signed with the same signature as the reference package declared
+    // in the SystemConfig
+    CONFIG_SIGNATURE = 0x00000100,
   };
 
   using PolicyBitmask = uint32_t;
diff --git a/libs/hwui/apex/jni_runtime.cpp b/libs/hwui/apex/jni_runtime.cpp
index b933813..12e2e81 100644
--- a/libs/hwui/apex/jni_runtime.cpp
+++ b/libs/hwui/apex/jni_runtime.cpp
@@ -16,14 +16,14 @@
 
 #include "android/graphics/jni_runtime.h"
 
-#include <android/log.h>
-#include <nativehelper/JNIHelp.h>
-#include <sys/cdefs.h>
-
 #include <EGL/egl.h>
 #include <GraphicsJNI.h>
 #include <Properties.h>
 #include <SkGraphics.h>
+#include <android/log.h>
+#include <nativehelper/JNIHelp.h>
+#include <sys/cdefs.h>
+#include <vulkan/vulkan.h>
 
 #undef LOG_TAG
 #define LOG_TAG "AndroidGraphicsJNI"
@@ -172,6 +172,11 @@
 
 void zygote_preload_graphics() {
     if (Properties::peekRenderPipelineType() == RenderPipelineType::SkiaGL) {
+        // Preload GL driver if HWUI renders with GL backend.
         eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    } else {
+        // Preload Vulkan driver if HWUI renders with Vulkan backend.
+        uint32_t apiVersion;
+        vkEnumerateInstanceVersion(&apiVersion);
     }
-}
\ No newline at end of file
+}
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index bea6121..565fb61 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -162,7 +162,6 @@
 }
 
 void RenderThread::initThreadLocals() {
-    HardwareBitmapUploader::initialize();
     setupFrameInterval();
     initializeChoreographer();
     mEglManager = new EglManager();
@@ -391,12 +390,10 @@
     if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
         std::thread eglInitThread([]() { eglGetDisplay(EGL_DEFAULT_DISPLAY); });
         eglInitThread.detach();
+    } else {
+        requireVkContext();
     }
-    // TODO: uncomment only after http://b/135536511 is fixed.
-    // else {
-    //    uint32_t apiVersion;
-    //    vkEnumerateInstanceVersion(&apiVersion);
-    //}
+    HardwareBitmapUploader::initialize();
 }
 
 } /* namespace renderthread */
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 928fb62..4c03fd1 100755
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -564,6 +564,7 @@
      * request is from a hardware key press. (e.g. {@link MediaController}).
      * @hide
      */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final int FLAG_FROM_KEY = 1 << 12;
 
     // The iterator of TreeMap#entrySet() returns the entries in ascending key order.
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java
index 87c3bb9..5dc6f75 100644
--- a/media/java/android/media/ImageReader.java
+++ b/media/java/android/media/ImageReader.java
@@ -198,7 +198,10 @@
      *   {@link HardwareBuffer#USAGE_GPU_SAMPLED_IMAGE}, or combined</td>
      * </tr>
      * </table>
-     * Using other combinations may result in {@link IllegalArgumentException}.
+     * Using other combinations may result in {@link IllegalArgumentException}. Additionally,
+     * specifying {@link HardwareBuffer#USAGE_CPU_WRITE_RARELY} or
+     * {@link HardwareBuffer#USAGE_CPU_WRITE_OFTEN} and writing to the ImageReader's buffers
+     * might break assumptions made by some producers, and should be used with caution.
      * </p>
      * <p>
      * If the {@link ImageReader} is used as an output target for a {@link
@@ -255,6 +258,7 @@
         mWidth = width;
         mHeight = height;
         mFormat = format;
+        mUsage = usage;
         mMaxImages = maxImages;
 
         if (width < 1 || height < 1) {
@@ -768,6 +772,7 @@
     private final int mWidth;
     private final int mHeight;
     private final int mFormat;
+    private final long mUsage;
     private final int mMaxImages;
     private final int mNumPlanes;
     private final Surface mSurface;
@@ -909,7 +914,8 @@
             throwISEIfImageIsInvalid();
 
             if (mPlanes == null) {
-                mPlanes = nativeCreatePlanes(ImageReader.this.mNumPlanes, ImageReader.this.mFormat);
+                mPlanes = nativeCreatePlanes(ImageReader.this.mNumPlanes, ImageReader.this.mFormat,
+                        ImageReader.this.mUsage);
             }
             // Shallow copy is fine.
             return mPlanes.clone();
@@ -1038,7 +1044,7 @@
         private AtomicBoolean mIsDetached = new AtomicBoolean(false);
 
         private synchronized native SurfacePlane[] nativeCreatePlanes(int numPlanes,
-                int readerFormat);
+                int readerFormat, long readerUsage);
         private synchronized native int nativeGetWidth();
         private synchronized native int nativeGetHeight();
         private synchronized native int nativeGetFormat(int readerFormat);
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp
index 0a02156..bd2a0eaa7 100644
--- a/media/jni/android_media_ImageReader.cpp
+++ b/media/jni/android_media_ImageReader.cpp
@@ -675,7 +675,8 @@
     return android_view_Surface_createFromIGraphicBufferProducer(env, gbp);
 }
 
-static void Image_getLockedImage(JNIEnv* env, jobject thiz, LockedImage *image) {
+static void Image_getLockedImage(JNIEnv* env, jobject thiz, LockedImage *image,
+        uint64_t ndkReaderUsage) {
     ALOGV("%s", __FUNCTION__);
     BufferItem* buffer = Image_getBufferItem(env, thiz);
     if (buffer == NULL) {
@@ -684,8 +685,16 @@
         return;
     }
 
-    status_t res = lockImageFromBuffer(buffer,
-            GRALLOC_USAGE_SW_READ_OFTEN, buffer->mFence->dup(), image);
+    uint32_t lockUsage;
+    if ((ndkReaderUsage & (AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY
+            | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN)) != 0) {
+        lockUsage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
+    } else {
+        lockUsage = GRALLOC_USAGE_SW_READ_OFTEN;
+    }
+
+    status_t res = lockImageFromBuffer(buffer, lockUsage, buffer->mFence->dup(), image);
+
     if (res != OK) {
         jniThrowExceptionFmt(env, "java/lang/RuntimeException",
                 "lock buffer failed for format 0x%x",
@@ -721,7 +730,7 @@
 }
 
 static jobjectArray Image_createSurfacePlanes(JNIEnv* env, jobject thiz,
-        int numPlanes, int readerFormat)
+        int numPlanes, int readerFormat, uint64_t ndkReaderUsage)
 {
     ALOGV("%s: create SurfacePlane array with size %d", __FUNCTION__, numPlanes);
     int rowStride = 0;
@@ -754,7 +763,7 @@
     }
 
     LockedImage lockedImg = LockedImage();
-    Image_getLockedImage(env, thiz, &lockedImg);
+    Image_getLockedImage(env, thiz, &lockedImg, ndkReaderUsage);
     if (env->ExceptionCheck()) {
         return NULL;
     }
@@ -839,7 +848,7 @@
 };
 
 static const JNINativeMethod gImageMethods[] = {
-    {"nativeCreatePlanes",      "(II)[Landroid/media/ImageReader$SurfaceImage$SurfacePlane;",
+    {"nativeCreatePlanes",      "(IIJ)[Landroid/media/ImageReader$SurfaceImage$SurfacePlane;",
                                                              (void*)Image_createSurfacePlanes },
     {"nativeGetWidth",          "()I",                       (void*)Image_getWidth },
     {"nativeGetHeight",         "()I",                       (void*)Image_getHeight },
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 033a32f..55aac09 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -590,7 +590,7 @@
     ALOGV("getSyncSettings: %d %d %f %f",
             scp.sync.mSource, scp.sync.mAudioAdjustMode, scp.sync.mTolerance, scp.frameRate);
 
-    // sanity check params
+    // check params
     if (scp.sync.mSource >= AVSYNC_SOURCE_MAX
             || scp.sync.mAudioAdjustMode >= AVSYNC_AUDIO_ADJUST_MODE_MAX
             || scp.sync.mTolerance < 0.f
diff --git a/media/jni/android_media_MediaSync.cpp b/media/jni/android_media_MediaSync.cpp
index f752008..d1ce30a 100644
--- a/media/jni/android_media_MediaSync.cpp
+++ b/media/jni/android_media_MediaSync.cpp
@@ -451,7 +451,7 @@
     ALOGV("getSyncParams: %d %d %f %f",
             scs.sync.mSource, scs.sync.mAudioAdjustMode, scs.sync.mTolerance, scs.frameRate);
 
-    // sanity check params
+    // check params
     if (scs.sync.mSource >= AVSYNC_SOURCE_MAX
             || scs.sync.mAudioAdjustMode >= AVSYNC_AUDIO_ADJUST_MODE_MAX
             || scs.sync.mTolerance < 0.f
diff --git a/media/mca/filterfw/java/android/filterfw/core/FilterFunction.java b/media/mca/filterfw/java/android/filterfw/core/FilterFunction.java
index ce81a18..ab9ae8a 100644
--- a/media/mca/filterfw/java/android/filterfw/core/FilterFunction.java
+++ b/media/mca/filterfw/java/android/filterfw/core/FilterFunction.java
@@ -43,7 +43,7 @@
     public Frame execute(KeyValueMap inputMap) {
         int filterOutCount = mFilter.getNumberOfOutputs();
 
-        // Sanity checks
+        // Validation checks
         if (filterOutCount > 1) {
             throw new RuntimeException("Calling execute on filter " + mFilter + " with multiple "
                 + "outputs! Use executeMulti() instead!");
diff --git a/media/mca/filterfw/jni/jni_native_program.cpp b/media/mca/filterfw/jni/jni_native_program.cpp
index 1424607..cd4f718 100644
--- a/media/mca/filterfw/jni/jni_native_program.cpp
+++ b/media/mca/filterfw/jni/jni_native_program.cpp
@@ -134,7 +134,7 @@
                                                                     jobject output) {
   NativeProgram* program = ConvertFromJava<NativeProgram>(env, thiz);
 
-  // Sanity checks
+  // Validation checks
   if (!program || !inputs) {
     return JNI_FALSE;
   }
diff --git a/non-updatable-api/module-lib-current.txt b/non-updatable-api/module-lib-current.txt
index 45ff6d3..3c0b955 100644
--- a/non-updatable-api/module-lib-current.txt
+++ b/non-updatable-api/module-lib-current.txt
@@ -31,6 +31,14 @@
 
 }
 
+package android.media {
+
+  public class AudioManager {
+    field public static final int FLAG_FROM_KEY = 4096; // 0x1000
+  }
+
+}
+
 package android.os {
 
   public class Binder implements android.os.IBinder {
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediator.java b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediator.java
index aea6914..7db2823 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediator.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediator.java
@@ -16,12 +16,12 @@
 
 package com.android.systemui.car.userswitcher;
 
-import android.app.ActivityManager;
 import android.car.Car;
 import android.car.user.CarUserManager;
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.car.CarDeviceProvisionedController;
 import com.android.systemui.car.CarServiceProvider;
 import com.android.systemui.car.window.OverlayViewMediator;
 
@@ -36,13 +36,16 @@
     private static final String TAG = "UserSwitchTransitionViewMediator";
 
     private final CarServiceProvider mCarServiceProvider;
+    private final CarDeviceProvisionedController mCarDeviceProvisionedController;
     private final UserSwitchTransitionViewController mUserSwitchTransitionViewController;
 
     @Inject
     public UserSwitchTransitionViewMediator(
             CarServiceProvider carServiceProvider,
+            CarDeviceProvisionedController carDeviceProvisionedController,
             UserSwitchTransitionViewController userSwitchTransitionViewController) {
         mCarServiceProvider = carServiceProvider;
+        mCarDeviceProvisionedController = carDeviceProvisionedController;
         mUserSwitchTransitionViewController = userSwitchTransitionViewController;
     }
 
@@ -74,7 +77,7 @@
     @VisibleForTesting
     void handleUserLifecycleEvent(CarUserManager.UserLifecycleEvent event) {
         if (event.getEventType() == CarUserManager.USER_LIFECYCLE_EVENT_TYPE_STARTING
-                && ActivityManager.getCurrentUser() == event.getUserId()) {
+                && mCarDeviceProvisionedController.getCurrentUser() == event.getUserId()) {
             mUserSwitchTransitionViewController.handleShow(event.getUserId());
         }
 
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppListenerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppListenerTest.java
index 20576e9..67f222b 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppListenerTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppListenerTest.java
@@ -220,7 +220,7 @@
 
         verify(mSideLoadedAppStateController, never()).onUnsafeTaskCreatedOnDisplay(any());
         verify(mSideLoadedAppStateController).onSafeTaskDisplayedOnDisplay(display1);
-        verify(mSideLoadedAppStateController, never()).onUnsafeTaskDisplayedOnDisplay(display2);
+        verify(mSideLoadedAppStateController).onUnsafeTaskDisplayedOnDisplay(display2);
         verify(mSideLoadedAppStateController).onSafeTaskDisplayedOnDisplay(display3);
         verify(mSideLoadedAppStateController, never()).onUnsafeTaskDisplayedOnDisplay(display1);
         verify(mSideLoadedAppStateController).onUnsafeTaskDisplayedOnDisplay(display2);
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediatorTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediatorTest.java
index de6feb6..7aeffce 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediatorTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediatorTest.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.car.userswitcher;
 
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -24,6 +25,8 @@
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.car.CarDeviceProvisionedController;
 import com.android.systemui.car.CarServiceProvider;
 import com.android.systemui.car.CarSystemUiTest;
 
@@ -37,13 +40,15 @@
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 @SmallTest
-public class UserSwitchTransitionViewMediatorTest {
+public class UserSwitchTransitionViewMediatorTest extends SysuiTestCase {
     private static final int TEST_USER = 100;
 
     private UserSwitchTransitionViewMediator mUserSwitchTransitionViewMediator;
     @Mock
     private CarServiceProvider mCarServiceProvider;
     @Mock
+    private CarDeviceProvisionedController mCarDeviceProvisionedController;
+    @Mock
     private UserSwitchTransitionViewController mUserSwitchTransitionViewController;
     @Mock
     private CarUserManager.UserLifecycleEvent mUserLifecycleEvent;
@@ -53,21 +58,35 @@
         MockitoAnnotations.initMocks(this);
 
         mUserSwitchTransitionViewMediator = new UserSwitchTransitionViewMediator(
-                mCarServiceProvider, mUserSwitchTransitionViewController);
-
+                mCarServiceProvider, mCarDeviceProvisionedController,
+                mUserSwitchTransitionViewController);
+        when(mCarDeviceProvisionedController.getCurrentUser()).thenReturn(TEST_USER);
     }
 
     @Test
-    public void onUserLifecycleEvent_userStarting_callsHandleShow() {
+    public void onUserLifecycleEvent_userStarting_isCurrentUser_callsHandleShow() {
         when(mUserLifecycleEvent.getEventType()).thenReturn(
                 CarUserManager.USER_LIFECYCLE_EVENT_TYPE_STARTING);
         when(mUserLifecycleEvent.getUserId()).thenReturn(TEST_USER);
+
         mUserSwitchTransitionViewMediator.handleUserLifecycleEvent(mUserLifecycleEvent);
 
         verify(mUserSwitchTransitionViewController).handleShow(TEST_USER);
     }
 
     @Test
+    public void onUserLifecycleEvent_userStarting_isNotCurrentUser_doesNotCallHandleShow() {
+        when(mUserLifecycleEvent.getEventType()).thenReturn(
+                CarUserManager.USER_LIFECYCLE_EVENT_TYPE_STARTING);
+        when(mUserLifecycleEvent.getUserId()).thenReturn(TEST_USER);
+        when(mCarDeviceProvisionedController.getCurrentUser()).thenReturn(TEST_USER + 1);
+
+        mUserSwitchTransitionViewMediator.handleUserLifecycleEvent(mUserLifecycleEvent);
+
+        verify(mUserSwitchTransitionViewController, never()).handleShow(TEST_USER);
+    }
+
+    @Test
     public void onUserLifecycleEvent_userSwitching_callsHandleHide() {
         when(mUserLifecycleEvent.getEventType()).thenReturn(
                 CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index df0137d..fa06e14 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -761,8 +761,8 @@
                 Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_VALUES,
                 GlobalSettingsProto.Gpu.ANGLE_GL_DRIVER_SELECTION_VALUES);
         dumpSetting(s, p,
-                Settings.Global.GLOBAL_SETTINGS_ANGLE_WHITELIST,
-                GlobalSettingsProto.Gpu.ANGLE_WHITELIST);
+                Settings.Global.GLOBAL_SETTINGS_ANGLE_ALLOWLIST,
+                GlobalSettingsProto.Gpu.ANGLE_ALLOWLIST);
         dumpSetting(s, p,
                 Settings.Global.GLOBAL_SETTINGS_SHOW_ANGLE_IN_USE_DIALOG_BOX,
                 GlobalSettingsProto.Gpu.SHOW_ANGLE_IN_USE_DIALOG);
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index f538e89..4bb8f45 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -503,7 +503,7 @@
                     Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_ALL_ANGLE,
                     Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_PKGS,
                     Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_VALUES,
-                    Settings.Global.GLOBAL_SETTINGS_ANGLE_WHITELIST,
+                    Settings.Global.GLOBAL_SETTINGS_ANGLE_ALLOWLIST,
                     Settings.Global.GAME_DRIVER_ALL_APPS,
                     Settings.Global.GAME_DRIVER_OPT_IN_APPS,
                     Settings.Global.GAME_DRIVER_PRERELEASE_OPT_IN_APPS,
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index e26aa55..318a987 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -458,15 +458,6 @@
         mPointerView.setBackground(mPointerDrawable);
     }
 
-    /**
-     * Hides the IME if it's showing. This is currently done by dispatching a back press to the AV.
-     */
-    void hideImeIfVisible() {
-        if (mKeyboardVisible) {
-            performBackPressIfNeeded();
-        }
-    }
-
     @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index ea12c95..b3fbfd6 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -1081,11 +1081,10 @@
                     final Bubble bubble = mBubbleData.getSelectedBubble();
                     if (bubble != null && mBubbleData.hasBubbleInStackWithKey(bubble.getKey())) {
                         final Intent intent = bubble.getSettingsIntent(mContext);
-                        collapseStack(() -> {
-                            mContext.startActivityAsUser(intent, bubble.getUser());
-                            logBubbleEvent(bubble,
-                                    SysUiStatsLog.BUBBLE_UICHANGED__ACTION__HEADER_GO_TO_SETTINGS);
-                        });
+                        mBubbleData.setExpanded(false);
+                        mContext.startActivityAsUser(intent, bubble.getUser());
+                        logBubbleEvent(bubble,
+                                SysUiStatsLog.BUBBLE_UICHANGED__ACTION__HEADER_GO_TO_SETTINGS);
                     }
                 });
 
@@ -1769,36 +1768,6 @@
         }
     }
 
-    /**
-     * Dismiss the stack of bubbles.
-     *
-     * @deprecated
-     */
-    @Deprecated
-    void stackDismissed(int reason) {
-        if (DEBUG_BUBBLE_STACK_VIEW) {
-            Log.d(TAG, "stackDismissed: reason=" + reason);
-        }
-        mBubbleData.dismissAll(reason);
-        logBubbleEvent(null /* no bubble associated with bubble stack dismiss */,
-                SysUiStatsLog.BUBBLE_UICHANGED__ACTION__STACK_DISMISSED);
-    }
-
-    /**
-     * @deprecated use {@link #setExpanded(boolean)} and
-     * {@link BubbleData#setSelectedBubble(Bubble)}
-     */
-    @Deprecated
-    @MainThread
-    void collapseStack(Runnable endRunnable) {
-        if (DEBUG_BUBBLE_STACK_VIEW) {
-            Log.d(TAG, "collapseStack(endRunnable)");
-        }
-        mBubbleData.setExpanded(false);
-        // TODO - use the runnable at end of animation
-        endRunnable.run();
-    }
-
     void showExpandedViewContents(int displayId) {
         if (mExpandedBubble != null
                 && mExpandedBubble.getExpandedView() != null
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
index b773856..95ba759 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
@@ -64,6 +64,8 @@
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     private final HighPriorityProvider mHighPriorityProvider;
 
+    private boolean mHideSilentNotificationsOnLockscreen;
+
     @Inject
     public KeyguardCoordinator(
             Context context,
@@ -86,6 +88,8 @@
 
     @Override
     public void attach(NotifPipeline pipeline) {
+        readShowSilentNotificationSetting();
+
         setupInvalidateNotifListCallbacks();
         pipeline.addFinalizeFilter(mNotifFilter);
     }
@@ -147,7 +151,7 @@
             return false;
         }
         if (NotificationUtils.useNewInterruptionModel(mContext)
-                && hideSilentNotificationsOnLockscreen()) {
+                && mHideSilentNotificationsOnLockscreen) {
             return mHighPriorityProvider.isHighPriority(entry);
         } else {
             return entry.getRepresentativeEntry() != null
@@ -155,11 +159,6 @@
         }
     }
 
-    private boolean hideSilentNotificationsOnLockscreen() {
-        return Settings.Secure.getInt(mContext.getContentResolver(),
-                Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 1) == 0;
-    }
-
     private void setupInvalidateNotifListCallbacks() {
         // register onKeyguardShowing callback
         mKeyguardStateController.addCallback(mKeyguardCallback);
@@ -169,6 +168,11 @@
         final ContentObserver settingsObserver = new ContentObserver(mMainHandler) {
             @Override
             public void onChange(boolean selfChange, Uri uri) {
+                if (uri.equals(Settings.Secure.getUriFor(
+                        Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS))) {
+                    readShowSilentNotificationSetting();
+                }
+
                 if (mKeyguardStateController.isShowing()) {
                     invalidateListFromFilter("Settings " + uri + " changed");
                 }
@@ -192,6 +196,12 @@
                 false,
                 settingsObserver);
 
+        mContext.getContentResolver().registerContentObserver(
+                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS),
+                false,
+                settingsObserver,
+                UserHandle.USER_ALL);
+
         // register (maybe) public mode changed callbacks:
         mStatusBarStateController.addCallback(mStatusBarStateListener);
         mBroadcastDispatcher.registerReceiver(new BroadcastReceiver() {
@@ -208,6 +218,14 @@
         mNotifFilter.invalidateList();
     }
 
+    private void readShowSilentNotificationSetting() {
+        mHideSilentNotificationsOnLockscreen =
+                Settings.Secure.getInt(
+                        mContext.getContentResolver(),
+                        Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS,
+                        1) == 0;
+    }
+
     private final KeyguardStateController.Callback mKeyguardCallback =
             new KeyguardStateController.Callback() {
         @Override
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java
index b229e9f..3562205 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java
@@ -16,11 +16,13 @@
 
 package com.android.server.appwidget;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
 
 import com.android.server.AppWidgetBackupBridge;
-import com.android.server.FgThread;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 
 /**
  * SystemService that publishes an IAppWidgetService.
@@ -49,12 +51,12 @@
     }
 
     @Override
-    public void onStopUser(int userHandle) {
-        mImpl.onUserStopped(userHandle);
+    public void onUserStopping(@NonNull TargetUser user) {
+        mImpl.onUserStopped(user.getUserIdentifier());
     }
 
     @Override
-    public void onSwitchUser(int userHandle) {
-        mImpl.reloadWidgetsMaskedStateForGroup(userHandle);
+    public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
+        mImpl.reloadWidgetsMaskedStateForGroup(to.getUserIdentifier());
     }
 }
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 089861b..663fd62 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -84,6 +84,7 @@
 import com.android.internal.util.SyncResultReceiver;
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.autofill.ui.AutoFillUI;
 import com.android.server.infra.AbstractMasterSystemService;
 import com.android.server.infra.FrameworkResourcesServiceNameResolver;
@@ -363,7 +364,7 @@
     }
 
     @Override // from SystemService
-    public void onSwitchUser(int userHandle) {
+    public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
         if (sDebug) Slog.d(TAG, "Hiding UI when user switched");
         mUi.hideAll(null);
     }
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index c839ce94..12e6e10 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -19,6 +19,7 @@
 import static java.util.Collections.emptySet;
 
 import android.Manifest;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
@@ -60,6 +61,7 @@
 import com.android.internal.util.DumpUtils;
 import com.android.server.SystemConfig;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.backup.utils.RandomAccessFileUtils;
 
 import java.io.File;
@@ -1605,13 +1607,13 @@
         }
 
         @Override
-        public void onUnlockUser(int userId) {
-            sInstance.onUnlockUser(userId);
+        public void onUserUnlocking(@NonNull TargetUser user) {
+            sInstance.onUnlockUser(user.getUserIdentifier());
         }
 
         @Override
-        public void onStopUser(int userId) {
-            sInstance.onStopUser(userId);
+        public void onUserStopping(@NonNull TargetUser user) {
+            sInstance.onStopUser(user.getUserIdentifier());
         }
 
         @VisibleForTesting
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 6d8f9a3..eb38f51 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -28,6 +28,7 @@
 import static java.util.concurrent.TimeUnit.MINUTES;
 
 import android.annotation.CheckResult;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.AppOpsManager;
 import android.app.PendingIntent;
@@ -84,6 +85,7 @@
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.wm.ActivityTaskManagerInternal;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -189,7 +191,8 @@
     }
 
     @Override
-    public void onUnlockUser(int userHandle) {
+    public void onUserUnlocking(@NonNull TargetUser user) {
+        int userHandle = user.getUserIdentifier();
         Set<Association> associations = readAllAssociations(userHandle);
         if (associations == null || associations.isEmpty()) {
             return;
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index b241bd1..ad1986a6 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -69,6 +69,7 @@
     public static final int PACKAGE_WIFI = 13;
     public static final int PACKAGE_COMPANION = 14;
     public static final int PACKAGE_RETAIL_DEMO = 15;
+    public static final int PACKAGE_OVERLAY_CONFIG_SIGNATURE = 16;
 
     @IntDef(flag = true, prefix = "RESOLVE_", value = {
             RESOLVE_NON_BROWSER_ONLY,
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 2e4d44c..f372c6f 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -96,6 +96,8 @@
 
     private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
     private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
+    private static final String BLUETOOTH_PRIVILEGED =
+            android.Manifest.permission.BLUETOOTH_PRIVILEGED;
 
     private static final String SECURE_SETTINGS_BLUETOOTH_ADDR_VALID = "bluetooth_addr_valid";
     private static final String SECURE_SETTINGS_BLUETOOTH_ADDRESS = "bluetooth_address";
@@ -306,6 +308,9 @@
             };
 
     public boolean onFactoryReset() {
+        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
+                "Need BLUETOOTH_PRIVILEGED permission");
+
         // Wait for stable state if bluetooth is temporary state.
         int state = getState();
         if (state == BluetoothAdapter.STATE_BLE_TURNING_ON
diff --git a/services/core/java/com/android/server/BluetoothService.java b/services/core/java/com/android/server/BluetoothService.java
index 0bcd937..1a1eecd 100644
--- a/services/core/java/com/android/server/BluetoothService.java
+++ b/services/core/java/com/android/server/BluetoothService.java
@@ -16,10 +16,14 @@
 
 package com.android.server;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.bluetooth.BluetoothAdapter;
 import android.content.Context;
 import android.os.UserManager;
 
+import com.android.server.SystemService.TargetUser;
+
 class BluetoothService extends SystemService {
     private BluetoothManagerService mBluetoothManagerService;
     private boolean mInitialized = false;
@@ -52,16 +56,16 @@
     }
 
     @Override
-    public void onSwitchUser(int userHandle) {
+    public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
         if (!mInitialized) {
             initialize();
         } else {
-            mBluetoothManagerService.handleOnSwitchUser(userHandle);
+            mBluetoothManagerService.handleOnSwitchUser(to.getUserIdentifier());
         }
     }
 
     @Override
-    public void onUnlockUser(int userHandle) {
-        mBluetoothManagerService.handleOnUnlockUser(userHandle);
+    public void onUserUnlocking(@NonNull TargetUser user) {
+        mBluetoothManagerService.handleOnUnlockUser(user.getUserIdentifier());
     }
 }
diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java
index 3148a62..a3bcbbe 100644
--- a/services/core/java/com/android/server/PinnerService.java
+++ b/services/core/java/com/android/server/PinnerService.java
@@ -20,6 +20,7 @@
 import static android.app.ActivityManager.UID_OBSERVER_GONE;
 
 import android.annotation.IntDef;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
@@ -60,6 +61,7 @@
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.function.pooled.PooledLambda;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.wm.ActivityTaskManagerInternal;
 
 import dalvik.system.DexFile;
@@ -236,16 +238,18 @@
      * individual apps. Make sure that user's preference is pinned into memory.
      */
     @Override
-    public void onSwitchUser(int userHandle) {
-        if (!mUserManager.isManagedProfile(userHandle)) {
-            sendPinAppsMessage(userHandle);
+    public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
+        int userId = to.getUserIdentifier();
+        if (!mUserManager.isManagedProfile(userId)) {
+            sendPinAppsMessage(userId);
         }
     }
 
     @Override
-    public void onUnlockUser(int userHandle) {
-        if (!mUserManager.isManagedProfile(userHandle)) {
-            sendPinAppsMessage(userHandle);
+    public void onUserUnlocking(@NonNull TargetUser user) {
+        int userId = user.getUserIdentifier();
+        if (!mUserManager.isManagedProfile(userId)) {
+            sendPinAppsMessage(userId);
         }
     }
 
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 1520dd3..eca6036 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -55,6 +55,7 @@
 import static org.xmlpull.v1.XmlPullParser.START_TAG;
 
 import android.Manifest;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
@@ -152,6 +153,7 @@
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Preconditions;
 import com.android.internal.widget.LockPatternUtils;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.pm.Installer;
 import com.android.server.storage.AppFuseBridge;
 import com.android.server.storage.StorageSessionController;
@@ -259,23 +261,23 @@
         }
 
         @Override
-        public void onSwitchUser(int userHandle) {
-            mStorageManagerService.mCurrentUserId = userHandle;
+        public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
+            mStorageManagerService.mCurrentUserId = to.getUserIdentifier();
         }
 
         @Override
-        public void onUnlockUser(int userHandle) {
-            mStorageManagerService.onUnlockUser(userHandle);
+        public void onUserUnlocking(@NonNull TargetUser user) {
+            mStorageManagerService.onUnlockUser(user.getUserIdentifier());
         }
 
         @Override
-        public void onCleanupUser(int userHandle) {
-            mStorageManagerService.onCleanupUser(userHandle);
+        public void onUserStopped(@NonNull TargetUser user) {
+            mStorageManagerService.onCleanupUser(user.getUserIdentifier());
         }
 
         @Override
-        public void onStopUser(int userHandle) {
-            mStorageManagerService.onStopUser(userHandle);
+        public void onUserStopping(@NonNull TargetUser user) {
+            mStorageManagerService.onStopUser(user.getUserIdentifier());
         }
 
         @Override
diff --git a/services/core/java/com/android/server/SystemService.java b/services/core/java/com/android/server/SystemService.java
index 45d53a1..1496e92 100644
--- a/services/core/java/com/android/server/SystemService.java
+++ b/services/core/java/com/android/server/SystemService.java
@@ -23,7 +23,6 @@
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.annotation.SystemApi.Client;
-import android.annotation.UserIdInt;
 import android.app.ActivityThread;
 import android.content.Context;
 import android.content.pm.UserInfo;
@@ -263,26 +262,6 @@
     }
 
     /**
-     * @deprecated subclasses should extend {@link #onUserStarting(TargetUser)} instead
-     * (which by default calls this method).
-     *
-     * @hide
-     */
-    @Deprecated
-    public void onStartUser(@UserIdInt int userId) {}
-
-    /**
-     * @deprecated subclasses should extend {@link #onUserStarting(TargetUser)} instead
-     * (which by default calls this method).
-     *
-     * @hide
-     */
-    @Deprecated
-    public void onStartUser(@NonNull UserInfo userInfo) {
-        onStartUser(userInfo.id);
-    }
-
-    /**
      * Called when a new user is starting, for system services to initialize any per-user
      * state they maintain for running users.
      *
@@ -292,27 +271,6 @@
      * @param user target user
      */
     public void onUserStarting(@NonNull TargetUser user) {
-        onStartUser(user.getUserInfo());
-    }
-
-    /**
-     * @deprecated subclasses should extend {@link #onUserUnlocking(TargetUser)} instead (which by
-     * default calls this method).
-     *
-     * @hide
-     */
-    @Deprecated
-    public void onUnlockUser(@UserIdInt int userId) {}
-
-    /**
-     * @deprecated subclasses should extend {@link #onUserUnlocking(TargetUser)} instead (which by
-     * default calls this method).
-     *
-     * @hide
-     */
-    @Deprecated
-    public void onUnlockUser(@NonNull UserInfo userInfo) {
-        onUnlockUser(userInfo.id);
     }
 
     /**
@@ -333,7 +291,6 @@
      * @param user target user
      */
     public void onUserUnlocking(@NonNull TargetUser user) {
-        onUnlockUser(user.getUserInfo());
     }
 
     /**
@@ -348,26 +305,6 @@
     }
 
     /**
-     * @deprecated subclasses should extend {@link #onUserSwitching(TargetUser, TargetUser)} instead
-     * (which by default calls this method).
-     *
-     * @hide
-     */
-    @Deprecated
-    public void onSwitchUser(@UserIdInt int toUserId) {}
-
-    /**
-     * @deprecated subclasses should extend {@link #onUserSwitching(TargetUser, TargetUser)} instead
-     * (which by default calls this method).
-     *
-     * @hide
-     */
-    @Deprecated
-    public void onSwitchUser(@Nullable UserInfo from, @NonNull UserInfo to) {
-        onSwitchUser(to.id);
-    }
-
-    /**
      * Called when switching to a different foreground user, for system services that have
      * special behavior for whichever user is currently in the foreground.  This is called
      * before any application processes are aware of the new user.
@@ -382,28 +319,6 @@
      * @param to the user switching to
      */
     public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
-        onSwitchUser((from == null ? null : from.getUserInfo()), to.getUserInfo());
-    }
-
-    /**
-     * @deprecated subclasses should extend {@link #onUserStopping(TargetUser)} instead
-     * (which by default calls this method).
-     *
-     * @hide
-     */
-    @Deprecated
-    public void onStopUser(@UserIdInt int userId) {}
-
-    /**
-     * @deprecated subclasses should extend {@link #onUserStopping(TargetUser)} instead
-     * (which by default calls this method).
-     *
-     * @hide
-     */
-    @Deprecated
-    public void onStopUser(@NonNull UserInfo user) {
-        onStopUser(user.id);
-
     }
 
     /**
@@ -420,27 +335,6 @@
      * @param user target user
      */
     public void onUserStopping(@NonNull TargetUser user) {
-        onStopUser(user.getUserInfo());
-    }
-
-    /**
-     * @deprecated subclasses should extend {@link #onUserStopped(TargetUser)} instead (which by
-     * default calls this method).
-     *
-     * @hide
-     */
-    @Deprecated
-    public void onCleanupUser(@UserIdInt int userId) {}
-
-    /**
-     * @deprecated subclasses should extend {@link #onUserStopped(TargetUser)} instead (which by
-     * default calls this method).
-     *
-     * @hide
-     */
-    @Deprecated
-    public void onCleanupUser(@NonNull UserInfo user) {
-        onCleanupUser(user.id);
     }
 
     /**
@@ -454,7 +348,6 @@
      * @param user target user
      */
     public void onUserStopped(@NonNull TargetUser user) {
-        onCleanupUser(user.getUserInfo());
     }
 
     /**
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 915189c..df9dee89 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -16,7 +16,15 @@
 
 package com.android.server;
 
+import static android.app.UiModeManager.DEFAULT_PRIORITY;
+import static android.app.UiModeManager.MODE_NIGHT_AUTO;
+import static android.app.UiModeManager.MODE_NIGHT_CUSTOM;
+import static android.app.UiModeManager.MODE_NIGHT_YES;
+import static android.os.UserHandle.USER_SYSTEM;
+import static android.util.TimeUtils.isTimeBetween;
+
 import android.annotation.IntRange;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.Activity;
 import android.app.ActivityManager;
@@ -64,6 +72,7 @@
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.util.DumpUtils;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.twilight.TwilightListener;
 import com.android.server.twilight.TwilightManager;
 import com.android.server.twilight.TwilightState;
@@ -81,13 +90,6 @@
 import java.util.Map;
 import java.util.Set;
 
-import static android.app.UiModeManager.DEFAULT_PRIORITY;
-import static android.app.UiModeManager.MODE_NIGHT_AUTO;
-import static android.app.UiModeManager.MODE_NIGHT_CUSTOM;
-import static android.app.UiModeManager.MODE_NIGHT_YES;
-import static android.os.UserHandle.USER_SYSTEM;
-import static android.util.TimeUtils.isTimeBetween;
-
 final class UiModeManagerService extends SystemService {
     private static final String TAG = UiModeManager.class.getSimpleName();
     private static final boolean LOG = false;
@@ -322,8 +324,7 @@
     }
 
     @Override
-    public void onSwitchUser(int userHandle) {
-        super.onSwitchUser(userHandle);
+    public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
         getContext().getContentResolver().unregisterContentObserver(mSetupWizardObserver);
         verifySetupWizardCompleted();
     }
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 7dc0b3a..35e88eb 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -106,6 +106,7 @@
 import com.android.server.LocalServices;
 import com.android.server.ServiceThread;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 
 import com.google.android.collect.Lists;
 import com.google.android.collect.Sets;
@@ -161,14 +162,14 @@
         }
 
         @Override
-        public void onUnlockUser(int userHandle) {
-            mService.onUnlockUser(userHandle);
+        public void onUserUnlocking(@NonNull TargetUser user) {
+            mService.onUnlockUser(user.getUserIdentifier());
         }
 
         @Override
-        public void onStopUser(int userHandle) {
-            Slog.i(TAG, "onStopUser " + userHandle);
-            mService.purgeUserData(userHandle);
+        public void onUserStopping(@NonNull TargetUser user) {
+            Slog.i(TAG, "onStopUser " + user);
+            mService.purgeUserData(user.getUserIdentifier());
         }
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 2f7d105..c187772 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -341,6 +341,7 @@
 import com.android.server.ServiceThread;
 import com.android.server.SystemConfig;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.SystemServiceManager;
 import com.android.server.ThreadPriorityBooster;
 import com.android.server.UserspaceRebootLogger;
@@ -2333,8 +2334,8 @@
         }
 
         @Override
-        public void onCleanupUser(int userId) {
-            mService.mBatteryStatsService.onCleanupUser(userId);
+        public void onUserStopped(@NonNull TargetUser user) {
+            mService.mBatteryStatsService.onCleanupUser(user.getUserIdentifier());
         }
 
         public ActivityManagerService getService() {
@@ -2443,7 +2444,7 @@
                             ? Collections.emptyList()
                             : Arrays.asList(exemptions.split(","));
                 }
-                if (!ZYGOTE_PROCESS.setApiBlacklistExemptions(mExemptions)) {
+                if (!ZYGOTE_PROCESS.setApiDenylistExemptions(mExemptions)) {
                   Slog.e(TAG, "Failed to set API blacklist exemptions!");
                   // leave mExemptionsStr as is, so we don't try to send the same list again.
                   mExemptions = Collections.emptyList();
@@ -14286,7 +14287,7 @@
     }
 
     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
-            int callingUid, int[] users, int[] broadcastWhitelist) {
+            int callingUid, int[] users, int[] broadcastAllowList) {
         // TODO: come back and remove this assumption to triage all broadcasts
         int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
 
@@ -14362,12 +14363,12 @@
         } catch (RemoteException ex) {
             // pm is in same process, this will never happen.
         }
-        if (receivers != null && broadcastWhitelist != null) {
+        if (receivers != null && broadcastAllowList != null) {
             for (int i = receivers.size() - 1; i >= 0; i--) {
                 final int receiverAppId = UserHandle.getAppId(
                         receivers.get(i).activityInfo.applicationInfo.uid);
                 if (receiverAppId >= Process.FIRST_APPLICATION_UID
-                        && Arrays.binarySearch(broadcastWhitelist, receiverAppId) < 0) {
+                        && Arrays.binarySearch(broadcastAllowList, receiverAppId) < 0) {
                     receivers.remove(i);
                 }
             }
@@ -14477,7 +14478,7 @@
             boolean ordered, boolean sticky, int callingPid, int callingUid, int realCallingUid,
             int realCallingPid, int userId, boolean allowBackgroundActivityStarts,
             @Nullable IBinder backgroundActivityStartsToken,
-            @Nullable int[] broadcastWhitelist) {
+            @Nullable int[] broadcastAllowList) {
         intent = new Intent(intent);
 
         final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
@@ -14486,10 +14487,10 @@
             intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
         }
 
-        if (userId == UserHandle.USER_ALL && broadcastWhitelist != null) {
-                Slog.e(TAG, "broadcastWhitelist only applies when sending to individual users. "
+        if (userId == UserHandle.USER_ALL && broadcastAllowList != null) {
+                Slog.e(TAG, "broadcastAllowList only applies when sending to individual users. "
                         + "Assuming restrictive whitelist.");
-                broadcastWhitelist = new int[]{};
+                broadcastAllowList = new int[]{};
         }
 
         // By default broadcasts do not go to stopped apps.
@@ -14981,7 +14982,7 @@
         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
                  == 0) {
             receivers = collectReceiverComponents(
-                    intent, resolvedType, callingUid, users, broadcastWhitelist);
+                    intent, resolvedType, callingUid, users, broadcastAllowList);
         }
         if (intent.getComponent() == null) {
             if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
@@ -15011,13 +15012,13 @@
 
         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
                 + " replacePending=" + replacePending);
-        if (registeredReceivers != null && broadcastWhitelist != null) {
+        if (registeredReceivers != null && broadcastAllowList != null) {
             // if a uid whitelist was provided, remove anything in the application space that wasn't
             // in it.
             for (int i = registeredReceivers.size() - 1; i >= 0; i--) {
                 final int owningAppId = UserHandle.getAppId(registeredReceivers.get(i).owningUid);
                 if (owningAppId >= Process.FIRST_APPLICATION_UID
-                        && Arrays.binarySearch(broadcastWhitelist, owningAppId) < 0) {
+                        && Arrays.binarySearch(broadcastAllowList, owningAppId) < 0) {
                     registeredReceivers.remove(i);
                 }
             }
@@ -17996,7 +17997,7 @@
         public int broadcastIntent(Intent intent,
                 IIntentReceiver resultTo,
                 String[] requiredPermissions,
-                boolean serialized, int userId, int[] appIdWhitelist) {
+                boolean serialized, int userId, int[] appIdAllowList) {
             synchronized (ActivityManagerService.this) {
                 intent = verifyBroadcastLocked(intent);
 
@@ -18011,7 +18012,7 @@
                             null /*options*/, serialized, false /*sticky*/, callingPid, callingUid,
                             callingUid, callingPid, userId, false /*allowBackgroundStarts*/,
                             null /*tokenNeededForBackgroundActivityStarts*/,
-                            appIdWhitelist);
+                            appIdAllowList);
                 } finally {
                     Binder.restoreCallingIdentity(origId);
                 }
diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java
index 00b33c4..8970ec4 100644
--- a/services/core/java/com/android/server/am/CoreSettingsObserver.java
+++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java
@@ -92,7 +92,7 @@
         sGlobalSettingToTypeMap.put(
                 Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_VALUES, String.class);
         sGlobalSettingToTypeMap.put(
-                Settings.Global.GLOBAL_SETTINGS_ANGLE_WHITELIST, String.class);
+                Settings.Global.GLOBAL_SETTINGS_ANGLE_ALLOWLIST, String.class);
         sGlobalSettingToTypeMap.put(
                 Settings.Global.GLOBAL_SETTINGS_SHOW_ANGLE_IN_USE_DIALOG_BOX, String.class);
         sGlobalSettingToTypeMap.put(Settings.Global.ENABLE_GPU_DEBUG_LAYERS, int.class);
diff --git a/services/core/java/com/android/server/appbinding/AppBindingService.java b/services/core/java/com/android/server/appbinding/AppBindingService.java
index 7e63e72..5db6dc7 100644
--- a/services/core/java/com/android/server/appbinding/AppBindingService.java
+++ b/services/core/java/com/android/server/appbinding/AppBindingService.java
@@ -45,6 +45,7 @@
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.DumpUtils;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.am.PersistentConnection;
 import com.android.server.appbinding.finders.AppServiceFinder;
 import com.android.server.appbinding.finders.CarrierMessagingClientServiceFinder;
@@ -125,18 +126,18 @@
         }
 
         @Override
-        public void onStartUser(int userHandle) {
-            mService.onStartUser(userHandle);
+        public void onUserStarting(@NonNull TargetUser user) {
+            mService.onStartUser(user.getUserIdentifier());
         }
 
         @Override
-        public void onUnlockUser(int userId) {
-            mService.onUnlockUser(userId);
+        public void onUserUnlocking(@NonNull TargetUser user) {
+            mService.onUnlockUser(user.getUserIdentifier());
         }
 
         @Override
-        public void onStopUser(int userHandle) {
-            mService.onStopUser(userHandle);
+        public void onUserStopping(@NonNull TargetUser user) {
+            mService.onStopUser(user.getUserIdentifier());
         }
     }
 
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 2d77d6f..32be03f 100755
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -5855,11 +5855,13 @@
                             caller);
                 }
                 // fire changed intents for all streams
-                mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, index);
-                mVolumeChanged.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex);
-                mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS,
-                        mStreamVolumeAlias[mStreamType]);
-                sendBroadcastToAll(mVolumeChanged);
+                if (index != oldIndex) {
+                    mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, index);
+                    mVolumeChanged.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex);
+                    mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS,
+                            mStreamVolumeAlias[mStreamType]);
+                    sendBroadcastToAll(mVolumeChanged);
+                }
             }
             return changed;
         }
@@ -7497,6 +7499,7 @@
         pw.print("  mIsSingleVolume="); pw.println(mIsSingleVolume);
         pw.print("  mUseFixedVolume="); pw.println(mUseFixedVolume);
         pw.print("  mFixedVolumeDevices="); pw.println(dumpDeviceTypes(mFixedVolumeDevices));
+        pw.print("  mFullVolumeDevices="); pw.println(dumpDeviceTypes(mFullVolumeDevices));
         pw.print("  mExtVolumeController="); pw.println(mExtVolumeController);
         pw.print("  mHdmiCecSink="); pw.println(mHdmiCecSink);
         pw.print("  mHdmiAudioSystemClient="); pw.println(mHdmiAudioSystemClient);
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index b4c41b2..5e8f1ef 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -632,21 +632,28 @@
         return result;
     }
 
+    // Return `(null)` if given BluetoothDevice is null. Otherwise, return the anonymized address.
+    private String getAnonymizedAddress(BluetoothDevice btDevice) {
+        return btDevice == null ? "(null)" : btDevice.getAnonymizedAddress();
+    }
+
     // @GuardedBy("AudioDeviceBroker.mSetModeLock")
     //@GuardedBy("AudioDeviceBroker.mDeviceStateLock")
     @GuardedBy("BtHelper.this")
     private void setBtScoActiveDevice(BluetoothDevice btDevice) {
-        Log.i(TAG, "setBtScoActiveDevice: " + mBluetoothHeadsetDevice + " -> " + btDevice);
+        Log.i(TAG, "setBtScoActiveDevice: " + getAnonymizedAddress(mBluetoothHeadsetDevice)
+                + " -> " + getAnonymizedAddress(btDevice));
         final BluetoothDevice previousActiveDevice = mBluetoothHeadsetDevice;
         if (Objects.equals(btDevice, previousActiveDevice)) {
             return;
         }
         if (!handleBtScoActiveDeviceChange(previousActiveDevice, false)) {
             Log.w(TAG, "setBtScoActiveDevice() failed to remove previous device "
-                    + previousActiveDevice);
+                    + getAnonymizedAddress(previousActiveDevice));
         }
         if (!handleBtScoActiveDeviceChange(btDevice, true)) {
-            Log.e(TAG, "setBtScoActiveDevice() failed to add new device " + btDevice);
+            Log.e(TAG, "setBtScoActiveDevice() failed to add new device "
+                    + getAnonymizedAddress(btDevice));
             // set mBluetoothHeadsetDevice to null when failing to add new device
             btDevice = null;
         }
@@ -826,7 +833,8 @@
                                 mBluetoothHeadsetDevice, mScoAudioMode)) {
                             mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
                         } else {
-                            Log.w(TAG, "requestScoState: connect to " + mBluetoothHeadsetDevice
+                            Log.w(TAG, "requestScoState: connect to "
+                                    + getAnonymizedAddress(mBluetoothHeadsetDevice)
                                     + " failed, mScoAudioMode=" + mScoAudioMode);
                             broadcastScoConnectionState(
                                     AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java
index 61c99b8..88867fc 100644
--- a/services/core/java/com/android/server/camera/CameraServiceProxy.java
+++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java
@@ -15,6 +15,8 @@
  */
 package com.android.server.camera;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -43,6 +45,7 @@
 import com.android.server.LocalServices;
 import com.android.server.ServiceThread;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.wm.WindowManagerInternal;
 
 import java.util.ArrayList;
@@ -252,20 +255,20 @@
     }
 
     @Override
-    public void onStartUser(int userHandle) {
+    public void onUserStarting(@NonNull TargetUser user) {
         synchronized(mLock) {
             if (mEnabledCameraUsers == null) {
                 // Initialize cameraserver, or update cameraserver if we are recovering
                 // from a crash.
-                switchUserLocked(userHandle);
+                switchUserLocked(user.getUserIdentifier());
             }
         }
     }
 
     @Override
-    public void onSwitchUser(int userHandle) {
+    public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
         synchronized(mLock) {
-            switchUserLocked(userHandle);
+            switchUserLocked(to.getUserIdentifier());
         }
     }
 
diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java
index ed3a223..a0bc7d8 100644
--- a/services/core/java/com/android/server/clipboard/ClipboardService.java
+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java
@@ -19,6 +19,7 @@
 import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
 
 import android.Manifest;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.app.ActivityManagerInternal;
@@ -59,6 +60,7 @@
 
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.contentcapture.ContentCaptureManagerInternal;
 import com.android.server.uri.UriGrantsManagerInternal;
 import com.android.server.wm.WindowManagerInternal;
@@ -218,9 +220,9 @@
     }
 
     @Override
-    public void onCleanupUser(int userId) {
+    public void onUserStopped(@NonNull TargetUser user) {
         synchronized (mClipboards) {
-            mClipboards.remove(userId);
+            mClipboards.remove(user.getUserIdentifier());
         }
     }
 
diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
index f8774b1..7202f0f 100644
--- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java
+++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
@@ -171,8 +171,8 @@
             mAllApps.add(UserHandle.getAppId(uid));
 
             final boolean isNetwork = hasPermission(CHANGE_NETWORK_STATE, uid);
-            final boolean hasRestrictedPermission =
-                    hasRestrictedNetworkPermission(app.applicationInfo);
+            final boolean hasRestrictedPermission = hasRestrictedNetworkPermission(uid)
+                    || isCarryoverPackage(app.applicationInfo);
 
             if (isNetwork || hasRestrictedPermission) {
                 Boolean permission = mApps.get(uid);
@@ -200,7 +200,7 @@
         for (int i = 0; i < systemPermission.size(); i++) {
             ArraySet<String> perms = systemPermission.valueAt(i);
             int uid = systemPermission.keyAt(i);
-            int netdPermission = 0;
+            int netdPermission = PERMISSION_NONE;
             // Get the uids of native services that have UPDATE_DEVICE_STATS or INTERNET permission.
             if (perms != null) {
                 netdPermission |= perms.contains(UPDATE_DEVICE_STATS)
@@ -225,20 +225,21 @@
     }
 
     @VisibleForTesting
-    boolean hasRestrictedNetworkPermission(@Nullable final ApplicationInfo appInfo) {
-        if (appInfo == null)  return false;
-        // TODO : remove this check in the future(b/162295056). All apps should just
-        // request the appropriate permission for their use case since android Q.
-        if ((appInfo.targetSdkVersion < VERSION_Q && isVendorApp(appInfo))
+    // TODO : remove this check in the future(b/162295056). All apps should just request the
+    // appropriate permission for their use case since android Q.
+    boolean isCarryoverPackage(@Nullable final ApplicationInfo appInfo) {
+        if (appInfo == null) return false;
+        return (appInfo.targetSdkVersion < VERSION_Q && isVendorApp(appInfo))
                 // Backward compatibility for b/114245686, on devices that launched before Q daemons
                 // and apps running as the system UID are exempted from this check.
-                || (appInfo.uid == SYSTEM_UID && mDeps.getDeviceFirstSdkInt() < VERSION_Q)) {
-            return true;
-        }
+                || (appInfo.uid == SYSTEM_UID && mDeps.getDeviceFirstSdkInt() < VERSION_Q);
+    }
 
-        return hasPermission(PERMISSION_MAINLINE_NETWORK_STACK, appInfo.uid)
-                || hasPermission(NETWORK_STACK, appInfo.uid)
-                || hasPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, appInfo.uid);
+    @VisibleForTesting
+    boolean hasRestrictedNetworkPermission(final int uid) {
+        return hasPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, uid)
+                || hasPermission(PERMISSION_MAINLINE_NETWORK_STACK, uid)
+                || hasPermission(NETWORK_STACK, uid);
     }
 
     /** Returns whether the given uid has using background network permission. */
@@ -328,8 +329,8 @@
         try {
             final PackageInfo app = mPackageManager.getPackageInfo(name, GET_PERMISSIONS);
             final boolean isNetwork = hasPermission(CHANGE_NETWORK_STATE, uid);
-            final boolean hasRestrictedPermission =
-                    hasRestrictedNetworkPermission(app.applicationInfo);
+            final boolean hasRestrictedPermission = hasRestrictedNetworkPermission(uid)
+                    || isCarryoverPackage(app.applicationInfo);
             if (isNetwork || hasRestrictedPermission) {
                 currentPermission = hasRestrictedPermission;
             }
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 9a910bf..1294e90 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -20,6 +20,7 @@
 
 import android.Manifest;
 import android.accounts.Account;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.app.ActivityManager;
@@ -75,6 +76,7 @@
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.pm.permission.PermissionManagerServiceInternal;
 
 import java.io.FileDescriptor;
@@ -124,26 +126,25 @@
             mService.onBootPhase(phase);
         }
 
-
         @Override
-        public void onStartUser(int userHandle) {
-            mService.onStartUser(userHandle);
+        public void onUserStarting(@NonNull TargetUser user) {
+            mService.onStartUser(user.getUserIdentifier());
         }
 
         @Override
-        public void onUnlockUser(int userHandle) {
-            mService.onUnlockUser(userHandle);
+        public void onUserUnlocking(@NonNull TargetUser user) {
+            mService.onUnlockUser(user.getUserIdentifier());
         }
 
         @Override
-        public void onStopUser(int userHandle) {
-            mService.onStopUser(userHandle);
+        public void onUserStopping(@NonNull TargetUser user) {
+            mService.onStopUser(user.getUserIdentifier());
         }
 
         @Override
-        public void onCleanupUser(int userHandle) {
+        public void onUserStopped(@NonNull TargetUser user) {
             synchronized (mService.mCache) {
-                mService.mCache.remove(userHandle);
+                mService.mCache.remove(user.getUserIdentifier());
             }
         }
     }
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index a00c22a..0979ad6 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -104,6 +104,7 @@
 import com.android.server.DisplayThread;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.UiThread;
 import com.android.server.wm.SurfaceAnimationThread;
 import com.android.server.wm.WindowManagerInternal;
@@ -417,7 +418,8 @@
     }
 
     @Override
-    public void onSwitchUser(@UserIdInt int newUserId) {
+    public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
+        final int newUserId = to.getUserIdentifier();
         final int userSerial = getUserManager().getUserSerialNumber(newUserId);
         synchronized (mSyncRoot) {
             if (mCurrentUserId != newUserId) {
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 fa4ba38..92a3ccf 100644
--- a/services/core/java/com/android/server/display/color/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/color/ColorDisplayService.java
@@ -77,6 +77,7 @@
 import com.android.server.DisplayThread;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.twilight.TwilightListener;
 import com.android.server.twilight.TwilightManager;
 import com.android.server.twilight.TwilightState;
@@ -206,30 +207,24 @@
     }
 
     @Override
-    public void onStartUser(int userHandle) {
-        super.onStartUser(userHandle);
-
+    public void onUserStarting(@NonNull TargetUser user) {
         if (mCurrentUser == UserHandle.USER_NULL) {
             final Message message = mHandler.obtainMessage(MSG_USER_CHANGED);
-            message.arg1 = userHandle;
+            message.arg1 = user.getUserIdentifier();
             mHandler.sendMessage(message);
         }
     }
 
     @Override
-    public void onSwitchUser(int userHandle) {
-        super.onSwitchUser(userHandle);
-
+    public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
         final Message message = mHandler.obtainMessage(MSG_USER_CHANGED);
-        message.arg1 = userHandle;
+        message.arg1 = to.getUserIdentifier();
         mHandler.sendMessage(message);
     }
 
     @Override
-    public void onStopUser(int userHandle) {
-        super.onStopUser(userHandle);
-
-        if (mCurrentUser == userHandle) {
+    public void onUserStopping(@NonNull TargetUser user) {
+        if (mCurrentUser == user.getUserIdentifier()) {
             final Message message = mHandler.obtainMessage(MSG_USER_CHANGED);
             message.arg1 = UserHandle.USER_NULL;
             mHandler.sendMessage(message);
diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
index 2672f84..7bbcdaa 100644
--- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
+++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
@@ -43,6 +43,7 @@
 import com.android.internal.os.BackgroundThread;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
@@ -299,16 +300,16 @@
     }
 
     @Override // from SystemService
-    public void onUnlockUser(int userId) {
+    public void onUserUnlocking(@NonNull TargetUser user) {
         synchronized (mLock) {
-            updateCachedServiceLocked(userId);
+            updateCachedServiceLocked(user.getUserIdentifier());
         }
     }
 
     @Override // from SystemService
-    public void onCleanupUser(int userId) {
+    public void onUserStopped(@NonNull TargetUser user) {
         synchronized (mLock) {
-            removeCachedServiceLocked(userId);
+            removeCachedServiceLocked(user.getUserIdentifier());
         }
     }
 
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 254285d..3cd70fe 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -159,6 +159,7 @@
 import com.android.server.EventLogTags;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.inputmethod.InputMethodManagerInternal.InputMethodListListener;
 import com.android.server.inputmethod.InputMethodSubtypeSwitchingController.ImeSubtypeListItem;
 import com.android.server.inputmethod.InputMethodUtils.InputMethodSettings;
@@ -1596,10 +1597,11 @@
         }
 
         @Override
-        public void onSwitchUser(@UserIdInt int userHandle) {
+        public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
             // Called on ActivityManager thread.
             synchronized (mService.mMethodMap) {
-                mService.scheduleSwitchUserTaskLocked(userHandle, null /* clientToBeReset */);
+                mService.scheduleSwitchUserTaskLocked(to.getUserIdentifier(),
+                        /* clientToBeReset= */ null);
             }
         }
 
@@ -1615,10 +1617,10 @@
         }
 
         @Override
-        public void onUnlockUser(final @UserIdInt int userHandle) {
+        public void onUserUnlocking(@NonNull TargetUser user) {
             // Called on ActivityManager thread.
             mService.mHandler.sendMessage(mService.mHandler.obtainMessage(MSG_SYSTEM_UNLOCK_USER,
-                    userHandle /* arg1 */, 0 /* arg2 */));
+                    /* arg1= */ user.getUserIdentifier(), /* arg2= */ 0));
         }
     }
 
diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
index 2516e28..937514c 100644
--- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
@@ -94,6 +94,7 @@
 import com.android.internal.view.InputBindResult;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.wm.WindowManagerInternal;
 
 import java.io.FileDescriptor;
@@ -249,23 +250,26 @@
 
         @MainThread
         @Override
-        public void onStartUser(@UserIdInt int userId) {
+        public void onUserStarting(@NonNull TargetUser user) {
             mOnWorkerThreadCallback.getHandler().sendMessage(PooledLambda.obtainMessage(
-                    OnWorkerThreadCallback::onStartUser, mOnWorkerThreadCallback, userId));
+                    OnWorkerThreadCallback::onStartUser, mOnWorkerThreadCallback,
+                    user.getUserIdentifier()));
         }
 
         @MainThread
         @Override
-        public void onUnlockUser(@UserIdInt int userId) {
+        public void onUserUnlocking(@NonNull TargetUser user) {
             mOnWorkerThreadCallback.getHandler().sendMessage(PooledLambda.obtainMessage(
-                    OnWorkerThreadCallback::onUnlockUser, mOnWorkerThreadCallback, userId));
+                    OnWorkerThreadCallback::onUnlockUser, mOnWorkerThreadCallback,
+                    user.getUserIdentifier()));
         }
 
         @MainThread
         @Override
-        public void onStopUser(@UserIdInt int userId) {
+        public void onUserStopping(@NonNull TargetUser user) {
             mOnWorkerThreadCallback.getHandler().sendMessage(PooledLambda.obtainMessage(
-                    OnWorkerThreadCallback::onStopUser, mOnWorkerThreadCallback, userId));
+                    OnWorkerThreadCallback::onStopUser, mOnWorkerThreadCallback,
+                    user.getUserIdentifier()));
         }
     }
 
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index e568848..f1b89c7 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -123,6 +123,7 @@
 import com.android.server.LocalServices;
 import com.android.server.ServiceThread;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.locksettings.LockSettingsStorage.CredentialHash;
 import com.android.server.locksettings.LockSettingsStorage.PersistentData;
 import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationResult;
@@ -275,18 +276,18 @@
         }
 
         @Override
-        public void onStartUser(int userHandle) {
-            mLockSettingsService.onStartUser(userHandle);
+        public void onUserStarting(@NonNull TargetUser user) {
+            mLockSettingsService.onStartUser(user.getUserIdentifier());
         }
 
         @Override
-        public void onUnlockUser(int userHandle) {
-            mLockSettingsService.onUnlockUser(userHandle);
+        public void onUserUnlocking(@NonNull TargetUser user) {
+            mLockSettingsService.onUnlockUser(user.getUserIdentifier());
         }
 
         @Override
-        public void onCleanupUser(int userHandle) {
-            mLockSettingsService.onCleanupUser(userHandle);
+        public void onUserStopped(@NonNull TargetUser user) {
+            mLockSettingsService.onCleanupUser(user.getUserIdentifier());
         }
     }
 
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 9f6c18d..e2f70e3 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -25,6 +25,8 @@
 import static com.android.server.media.MediaKeyDispatcher.isSingleTapOverridden;
 import static com.android.server.media.MediaKeyDispatcher.isTripleTapOverridden;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.KeyguardManager;
 import android.app.NotificationManager;
@@ -85,6 +87,7 @@
 import com.android.internal.util.DumpUtils;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.Watchdog;
 import com.android.server.Watchdog.Monitor;
 
@@ -333,19 +336,21 @@
     }
 
     @Override
-    public void onStartUser(int userId) {
-        if (DEBUG) Log.d(TAG, "onStartUser: " + userId);
+    public void onUserStarting(@NonNull TargetUser user) {
+        if (DEBUG) Log.d(TAG, "onStartUser: " + user);
         updateUser();
     }
 
     @Override
-    public void onSwitchUser(int userId) {
-        if (DEBUG) Log.d(TAG, "onSwitchUser: " + userId);
+    public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
+        if (DEBUG) Log.d(TAG, "onSwitchUser: " + to);
         updateUser();
     }
 
     @Override
-    public void onCleanupUser(int userId) {
+    public void onUserStopped(@NonNull TargetUser targetUser) {
+        int userId = targetUser.getUserIdentifier();
+
         if (DEBUG) Log.d(TAG, "onCleanupUser: " + userId);
         synchronized (mLock) {
             FullUserRecord user = getFullUserRecordLocked(userId);
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
index 1a749b3..94776f8 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -17,6 +17,8 @@
 package com.android.server.media.projection;
 
 import android.Manifest;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.ActivityManagerInternal;
 import android.app.AppOpsManager;
 import android.app.IProcessObserver;
@@ -48,6 +50,7 @@
 import com.android.internal.util.DumpUtils;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.Watchdog;
 
 import java.io.FileDescriptor;
@@ -122,8 +125,8 @@
     }
 
     @Override
-    public void onSwitchUser(int userId) {
-        mMediaRouter.rebindAsUser(userId);
+    public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
+        mMediaRouter.rebindAsUser(to.getUserIdentifier());
         synchronized (mLock) {
             if (mProjectionGrant != null) {
                 mProjectionGrant.stop();
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index eefff2fb..d71c33e 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -261,6 +261,7 @@
 import com.android.server.IoThread;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.UiThread;
 import com.android.server.lights.LightsManager;
 import com.android.server.lights.LogicalLight;
@@ -322,7 +323,7 @@
     static final boolean DEBUG_INTERRUPTIVENESS = SystemProperties.getBoolean(
             "debug.notification.interruptiveness", false);
 
-    static final int MAX_PACKAGE_NOTIFICATIONS = 25;
+    static final int MAX_PACKAGE_NOTIFICATIONS = 50;
     static final float DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE = 5f;
 
     // message codes
@@ -2351,11 +2352,11 @@
     }
 
     @Override
-    public void onUnlockUser(@NonNull UserInfo userInfo) {
+    public void onUserUnlocking(@NonNull TargetUser user) {
         mHandler.post(() -> {
             Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "notifHistoryUnlockUser");
             try {
-                mHistoryManager.onUserUnlocked(userInfo.id);
+                mHistoryManager.onUserUnlocked(user.getUserIdentifier());
             } finally {
                 Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
             }
@@ -2363,11 +2364,11 @@
     }
 
     @Override
-    public void onStopUser(@NonNull UserInfo userInfo) {
+    public void onUserStopping(@NonNull TargetUser user) {
         mHandler.post(() -> {
             Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "notifHistoryStopUser");
             try {
-                mHistoryManager.onUserStopped(userInfo.id);
+                mHistoryManager.onUserStopped(user.getUserIdentifier());
             } finally {
                 Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
             }
diff --git a/services/core/java/com/android/server/om/IdmapManager.java b/services/core/java/com/android/server/om/IdmapManager.java
index d6b1b27..cb6e960 100644
--- a/services/core/java/com/android/server/om/IdmapManager.java
+++ b/services/core/java/com/android/server/om/IdmapManager.java
@@ -27,6 +27,7 @@
 import android.os.Build.VERSION_CODES;
 import android.os.OverlayablePolicy;
 import android.os.SystemProperties;
+import android.text.TextUtils;
 import android.util.Slog;
 
 import java.io.IOException;
@@ -53,11 +54,20 @@
     }
 
     private final IdmapDaemon mIdmapDaemon;
-    private final OverlayableInfoCallback mOverlayableCallback;
+    private final PackageManagerHelper mPackageManager;
 
-    IdmapManager(final IdmapDaemon idmapDaemon, final OverlayableInfoCallback verifyCallback) {
-        mOverlayableCallback = verifyCallback;
+    /**
+     * Package name of the reference package defined in 'config-signature' tag of
+     * SystemConfig or empty String if tag not defined. This package is vetted on scan by
+     * PackageManagerService that it's a system package and is used to check if overlay matches
+     * its signature in order to fulfill the config_signature policy.
+     */
+    private final String mConfigSignaturePackage;
+
+    IdmapManager(final IdmapDaemon idmapDaemon, final PackageManagerHelper packageManager) {
+        mPackageManager = packageManager;
         mIdmapDaemon = idmapDaemon;
+        mConfigSignaturePackage = packageManager.getConfigSignaturePackage();
     }
 
     /**
@@ -139,7 +149,7 @@
         int fulfilledPolicies = OverlayablePolicy.PUBLIC;
 
         // Overlay matches target signature
-        if (mOverlayableCallback.signaturesMatching(targetPackage.packageName,
+        if (mPackageManager.signaturesMatching(targetPackage.packageName,
                 overlayPackage.packageName, userId)) {
             fulfilledPolicies |= OverlayablePolicy.SIGNATURE;
         }
@@ -149,6 +159,16 @@
             fulfilledPolicies |= OverlayablePolicy.ACTOR_SIGNATURE;
         }
 
+        // If SystemConfig defines 'config-signature' package, given that
+        // this package is vetted by OverlayManagerService that it's a
+        // preinstalled package, check if overlay matches its signature.
+        if (!TextUtils.isEmpty(mConfigSignaturePackage)
+                && mPackageManager.signaturesMatching(mConfigSignaturePackage,
+                                                           overlayPackage.packageName,
+                                                           userId)) {
+            fulfilledPolicies |= OverlayablePolicy.CONFIG_SIGNATURE;
+        }
+
         // Vendor partition (/vendor)
         if (ai.isVendor()) {
             return fulfilledPolicies | OverlayablePolicy.VENDOR_PARTITION;
@@ -183,12 +203,12 @@
         String targetOverlayableName = overlayPackage.targetOverlayableName;
         if (targetOverlayableName != null) {
             try {
-                OverlayableInfo overlayableInfo = mOverlayableCallback.getOverlayableForTarget(
+                OverlayableInfo overlayableInfo = mPackageManager.getOverlayableForTarget(
                         targetPackage.packageName, targetOverlayableName, userId);
                 if (overlayableInfo != null && overlayableInfo.actor != null) {
                     String actorPackageName = OverlayActorEnforcer.getPackageNameForActor(
-                            overlayableInfo.actor, mOverlayableCallback.getNamedActors()).first;
-                    if (mOverlayableCallback.signaturesMatching(actorPackageName,
+                            overlayableInfo.actor, mPackageManager.getNamedActors()).first;
+                    if (mPackageManager.signaturesMatching(actorPackageName,
                             overlayPackage.packageName, userId)) {
                         return true;
                     }
diff --git a/services/core/java/com/android/server/om/OverlayActorEnforcer.java b/services/core/java/com/android/server/om/OverlayActorEnforcer.java
index 2bc3499..8c03c6c 100644
--- a/services/core/java/com/android/server/om/OverlayActorEnforcer.java
+++ b/services/core/java/com/android/server/om/OverlayActorEnforcer.java
@@ -45,7 +45,7 @@
     // By default, the reason is not logged to prevent leaks of why it failed
     private static final boolean DEBUG_REASON = false;
 
-    private final OverlayableInfoCallback mOverlayableCallback;
+    private final PackageManagerHelper mPackageManager;
 
     /**
      * @return nullable actor result with {@link ActorState} failure status
@@ -79,8 +79,8 @@
         return Pair.create(packageName, ActorState.ALLOWED);
     }
 
-    public OverlayActorEnforcer(@NonNull OverlayableInfoCallback overlayableCallback) {
-        mOverlayableCallback = overlayableCallback;
+    public OverlayActorEnforcer(@NonNull PackageManagerHelper packageManager) {
+        mPackageManager = packageManager;
     }
 
     void enforceActor(@NonNull OverlayInfo overlayInfo, @NonNull String methodName,
@@ -110,7 +110,7 @@
                 return ActorState.ALLOWED;
         }
 
-        String[] callingPackageNames = mOverlayableCallback.getPackagesForUid(callingUid);
+        String[] callingPackageNames = mPackageManager.getPackagesForUid(callingUid);
         if (ArrayUtils.isEmpty(callingPackageNames)) {
             return ActorState.NO_PACKAGES_FOR_UID;
         }
@@ -125,12 +125,12 @@
 
         if (TextUtils.isEmpty(targetOverlayableName)) {
             try {
-                if (mOverlayableCallback.doesTargetDefineOverlayable(targetPackageName, userId)) {
+                if (mPackageManager.doesTargetDefineOverlayable(targetPackageName, userId)) {
                     return ActorState.MISSING_TARGET_OVERLAYABLE_NAME;
                 } else {
                     // If there's no overlayable defined, fallback to the legacy permission check
                     try {
-                        mOverlayableCallback.enforcePermission(
+                        mPackageManager.enforcePermission(
                                 android.Manifest.permission.CHANGE_OVERLAY_PACKAGES, methodName);
 
                         // If the previous method didn't throw, check passed
@@ -146,7 +146,7 @@
 
         OverlayableInfo targetOverlayable;
         try {
-            targetOverlayable = mOverlayableCallback.getOverlayableForTarget(targetPackageName,
+            targetOverlayable = mPackageManager.getOverlayableForTarget(targetPackageName,
                     targetOverlayableName, userId);
         } catch (IOException e) {
             return ActorState.UNABLE_TO_GET_TARGET;
@@ -160,7 +160,7 @@
         if (TextUtils.isEmpty(actor)) {
             // If there's no actor defined, fallback to the legacy permission check
             try {
-                mOverlayableCallback.enforcePermission(
+                mPackageManager.enforcePermission(
                         android.Manifest.permission.CHANGE_OVERLAY_PACKAGES, methodName);
 
                 // If the previous method didn't throw, check passed
@@ -170,7 +170,7 @@
             }
         }
 
-        Map<String, Map<String, String>> namedActors = mOverlayableCallback.getNamedActors();
+        Map<String, Map<String, String>> namedActors = mPackageManager.getNamedActors();
         Pair<String, ActorState> actorUriPair = getPackageNameForActor(actor, namedActors);
         ActorState actorUriState = actorUriPair.second;
         if (actorUriState != ActorState.ALLOWED) {
@@ -178,7 +178,7 @@
         }
 
         String packageName = actorUriPair.first;
-        PackageInfo packageInfo = mOverlayableCallback.getPackageInfo(packageName, userId);
+        PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName, userId);
         if (packageInfo == null) {
             return ActorState.MISSING_APP_INFO;
         }
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 3968153..a4debc1 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -31,6 +31,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.IActivityManager;
 import android.content.BroadcastReceiver;
@@ -68,6 +69,7 @@
 import com.android.server.LocalServices;
 import com.android.server.SystemConfig;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.pm.UserManagerService;
 
 import libcore.util.EmptyArray;
@@ -303,7 +305,11 @@
     }
 
     @Override
-    public void onSwitchUser(final int newUserId) {
+    public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
+        onSwitchUser(to.getUserIdentifier());
+    }
+
+    private void onSwitchUser(@UserIdInt int newUserId) {
         try {
             traceBegin(TRACE_TAG_RRO, "OMS#onSwitchUser " + newUserId);
             // ensure overlays in the settings are up-to-date, and propagate
@@ -1053,8 +1059,7 @@
         }
     }
 
-    private static final class PackageManagerHelperImpl implements PackageManagerHelper,
-            OverlayableInfoCallback {
+    private static final class PackageManagerHelperImpl implements PackageManagerHelper  {
 
         private final Context mContext;
         private final IPackageManager mPackageManager;
@@ -1127,6 +1132,14 @@
             return overlays;
         }
 
+        @Override
+        public String getConfigSignaturePackage() {
+            final String[] pkgs = mPackageManagerInternal.getKnownPackageNames(
+                    PackageManagerInternal.PACKAGE_OVERLAY_CONFIG_SIGNATURE,
+                    UserHandle.USER_SYSTEM);
+            return (pkgs.length == 0) ? null : pkgs[0];
+        }
+
         @Nullable
         @Override
         public OverlayableInfo getOverlayableForTarget(@NonNull String packageName,
diff --git a/services/core/java/com/android/server/om/OverlayableInfoCallback.java b/services/core/java/com/android/server/om/OverlayableInfoCallback.java
deleted file mode 100644
index 5066ecd..0000000
--- a/services/core/java/com/android/server/om/OverlayableInfoCallback.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2020 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.om;
-
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.om.OverlayableInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-
-import com.android.server.pm.PackageManagerServiceUtils;
-
-import java.io.IOException;
-import java.util.Map;
-
-/**
- * Delegate to the system for querying information about overlayables and packages.
- */
-public interface OverlayableInfoCallback {
-
-    /**
-     * Read from the APK and AndroidManifest of a package to return the overlayable defined for
-     * a given name.
-     *
-     * @throws IOException if the target can't be read
-     */
-    @Nullable
-    OverlayableInfo getOverlayableForTarget(@NonNull String packageName,
-            @NonNull String targetOverlayableName, int userId)
-            throws IOException;
-
-    /**
-     * @see PackageManager#getPackagesForUid(int)
-     */
-    @Nullable
-    String[] getPackagesForUid(int uid);
-
-    /**
-     * @param userId user to filter package visibility by
-     * @see PackageManager#getPackageInfo(String, int)
-     */
-    @Nullable
-    PackageInfo getPackageInfo(@NonNull String packageName, int userId);
-
-    /**
-     * @return map of system pre-defined, uniquely named actors; keys are namespace,
-     * value maps actor name to package name
-     */
-    @NonNull
-    Map<String, Map<String, String>> getNamedActors();
-
-    /**
-     * @return true if the target package has declared an overlayable
-     */
-    boolean doesTargetDefineOverlayable(String targetPackageName, int userId) throws IOException;
-
-    /**
-     * @throws SecurityException containing message if the caller doesn't have the given
-     *                           permission
-     */
-    void enforcePermission(String permission, String message) throws SecurityException;
-
-    /**
-     * @return true if {@link PackageManagerServiceUtils#compareSignatures} run on both packages
-     *     in the system returns {@link PackageManager#SIGNATURE_MATCH}
-     */
-    boolean signaturesMatching(@NonNull String pkgName1, @NonNull String pkgName2, int userId);
-}
diff --git a/services/core/java/com/android/server/om/PackageManagerHelper.java b/services/core/java/com/android/server/om/PackageManagerHelper.java
index ec9c5e6..b1a8b4e 100644
--- a/services/core/java/com/android/server/om/PackageManagerHelper.java
+++ b/services/core/java/com/android/server/om/PackageManagerHelper.java
@@ -17,11 +17,17 @@
 package com.android.server.om;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.om.OverlayableInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
 
+import com.android.server.pm.PackageManagerServiceUtils;
+
+import java.io.IOException;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Delegate for {@link PackageManager} and {@link PackageManagerInternal} functionality,
@@ -30,7 +36,65 @@
  * @hide
  */
 interface PackageManagerHelper {
-    PackageInfo getPackageInfo(@NonNull String packageName, int userId);
-    boolean signaturesMatching(@NonNull String pkgName1, @NonNull String pkgName2, int userId);
+    /**
+     * @return true if the target package has declared an overlayable
+     */
+    boolean doesTargetDefineOverlayable(String targetPackageName, int userId) throws IOException;
+
+    /**
+     * @throws SecurityException containing message if the caller doesn't have the given
+     *                           permission
+     */
+    void enforcePermission(String permission, String message) throws SecurityException;
+
+    /**
+     * Returns the package name of the reference package defined in 'overlay-config-signature' tag
+     * of SystemConfig. This package is vetted on scan by PackageManagerService that it's a system
+     * package and is used to check if overlay matches its signature in order to fulfill the
+     * config_signature policy.
+     */
+    @Nullable
+    String getConfigSignaturePackage();
+
+    /**
+     * @return map of system pre-defined, uniquely named actors; keys are namespace,
+     * value maps actor name to package name
+     */
+    @NonNull
+    Map<String, Map<String, String>> getNamedActors();
+
+    /**
+     * @see PackageManagerInternal#getOverlayPackages(int)
+     */
     List<PackageInfo> getOverlayPackages(int userId);
+
+    /**
+     * Read from the APK and AndroidManifest of a package to return the overlayable defined for
+     * a given name.
+     *
+     * @throws IOException if the target can't be read
+     */
+    @Nullable
+    OverlayableInfo getOverlayableForTarget(@NonNull String packageName,
+            @NonNull String targetOverlayableName, int userId)
+            throws IOException;
+
+    /**
+     * @see PackageManager#getPackagesForUid(int)
+     */
+    @Nullable
+    String[] getPackagesForUid(int uid);
+
+    /**
+     * @param userId user to filter package visibility by
+     * @see PackageManager#getPackageInfo(String, int)
+     */
+    @Nullable
+    PackageInfo getPackageInfo(@NonNull String packageName, int userId);
+
+    /**
+     * @return true if {@link PackageManagerServiceUtils#compareSignatures} run on both packages
+     *     in the system returns {@link PackageManager#SIGNATURE_MATCH}
+     */
+    boolean signaturesMatching(@NonNull String pkgName1, @NonNull String pkgName2, int userId);
 }
diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java
index c3c2e5e..92c0c6a 100644
--- a/services/core/java/com/android/server/pm/AppsFilter.java
+++ b/services/core/java/com/android/server/pm/AppsFilter.java
@@ -137,11 +137,11 @@
     @VisibleForTesting(visibility = PRIVATE)
     AppsFilter(StateProvider stateProvider,
             FeatureConfig featureConfig,
-            String[] forceQueryableWhitelist,
+            String[] forceQueryableList,
             boolean systemAppsQueryable,
             @Nullable OverlayReferenceMapper.Provider overlayProvider) {
         mFeatureConfig = featureConfig;
-        mForceQueryableByDevicePackageNames = forceQueryableWhitelist;
+        mForceQueryableByDevicePackageNames = forceQueryableList;
         mSystemAppsQueryable = systemAppsQueryable;
         mOverlayReferenceMapper = new OverlayReferenceMapper(true /*deferRebuild*/,
                 overlayProvider);
@@ -746,11 +746,11 @@
      * @param users            the set of users that should be evaluated for this calculation
      * @param existingSettings the set of all package settings that currently exist on device
      * @return a SparseArray mapping userIds to a sorted int array of appIds that may view the
-     * provided setting or null if the app is visible to all and no whitelist should be
+     * provided setting or null if the app is visible to all and no allow list should be
      * applied.
      */
     @Nullable
-    public SparseArray<int[]> getVisibilityWhitelist(PackageSetting setting, int[] users,
+    public SparseArray<int[]> getVisibilityAllowList(PackageSetting setting, int[] users,
             ArrayMap<String, PackageSetting> existingSettings) {
         if (mForceQueryable.contains(setting.appId)) {
             return null;
@@ -761,14 +761,14 @@
             final int userId = users[u];
             int[] appIds = new int[existingSettings.size()];
             int[] buffer = null;
-            int whitelistSize = 0;
+            int allowListSize = 0;
             for (int i = existingSettings.size() - 1; i >= 0; i--) {
                 final PackageSetting existingSetting = existingSettings.valueAt(i);
                 final int existingAppId = existingSetting.appId;
                 if (existingAppId < Process.FIRST_APPLICATION_UID) {
                     continue;
                 }
-                final int loc = Arrays.binarySearch(appIds, 0, whitelistSize, existingAppId);
+                final int loc = Arrays.binarySearch(appIds, 0, allowListSize, existingAppId);
                 if (loc >= 0) {
                     continue;
                 }
@@ -778,13 +778,13 @@
                         buffer = new int[appIds.length];
                     }
                     final int insert = ~loc;
-                    System.arraycopy(appIds, insert, buffer, 0, whitelistSize - insert);
+                    System.arraycopy(appIds, insert, buffer, 0, allowListSize - insert);
                     appIds[insert] = existingAppId;
-                    System.arraycopy(buffer, 0, appIds, insert + 1, whitelistSize - insert);
-                    whitelistSize++;
+                    System.arraycopy(buffer, 0, appIds, insert + 1, allowListSize - insert);
+                    allowListSize++;
                 }
             }
-            result.put(userId, Arrays.copyOf(appIds, whitelistSize));
+            result.put(userId, Arrays.copyOf(appIds, allowListSize));
         }
         return result;
     }
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 1dabfdb..7765f18 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -3400,7 +3400,7 @@
     private void destroyInternal() {
         synchronized (mLock) {
             mSealed = true;
-            if (!params.isStaged || isStagedAndInTerminalState()) {
+            if (!params.isStaged) {
                 mDestroyed = true;
             }
             // Force shut down all bridges
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index b39efbc..a726c8d 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -120,6 +120,7 @@
 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
 import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
+import static com.android.server.pm.PackageManagerServiceUtils.comparePackageSignatures;
 import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures;
 import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists;
 import static com.android.server.pm.PackageManagerServiceUtils.decompressFile;
@@ -1128,6 +1129,7 @@
         public @Nullable String storageManagerPackage;
         public @Nullable String defaultTextClassifierPackage;
         public @Nullable String systemTextClassifierPackage;
+        public @Nullable String overlayConfigSignaturePackage;
         public ViewCompiler viewCompiler;
         public @Nullable String wellbeingPackage;
         public @Nullable String retailDemoPackage;
@@ -1660,6 +1662,7 @@
     final @Nullable String mServicesExtensionPackageName;
     final @Nullable String mSharedSystemSharedLibraryPackageName;
     final @Nullable String mRetailDemoPackage;
+    final @Nullable String mOverlayConfigSignaturePackage;
 
     private final PackageUsage mPackageUsage = new PackageUsage();
     private final CompilerStats mCompilerStats = new CompilerStats();
@@ -2213,17 +2216,17 @@
                 }
                 extras.putInt(PackageInstaller.EXTRA_DATA_LOADER_TYPE, dataLoaderType);
                 // Send to all running apps.
-                final SparseArray<int[]> newBroadcastWhitelist;
+                final SparseArray<int[]> newBroadcastAllowList;
 
                 synchronized (mLock) {
-                    newBroadcastWhitelist = mAppsFilter.getVisibilityWhitelist(
+                    newBroadcastAllowList = mAppsFilter.getVisibilityAllowList(
                             getPackageSettingInternal(res.name, Process.SYSTEM_UID),
                             updateUserIds, mSettings.mPackages);
                 }
                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
                         extras, 0 /*flags*/,
                         null /*targetPackage*/, null /*finishedReceiver*/,
-                        updateUserIds, instantUserIds, newBroadcastWhitelist);
+                        updateUserIds, instantUserIds, newBroadcastAllowList);
                 if (installerPackageName != null) {
                     // Send to the installer, even if it's not running.
                     sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
@@ -2255,7 +2258,7 @@
                     sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
                             packageName, extras, 0 /*flags*/,
                             null /*targetPackage*/, null /*finishedReceiver*/,
-                            updateUserIds, instantUserIds, res.removedInfo.broadcastWhitelist);
+                            updateUserIds, instantUserIds, res.removedInfo.broadcastAllowList);
                     if (installerPackageName != null) {
                         sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
                                 extras, 0 /*flags*/,
@@ -2817,6 +2820,7 @@
         mIncidentReportApproverPackage = testParams.incidentReportApproverPackage;
         mServicesExtensionPackageName = testParams.servicesExtensionPackageName;
         mSharedSystemSharedLibraryPackageName = testParams.sharedSystemSharedLibraryPackageName;
+        mOverlayConfigSignaturePackage = testParams.overlayConfigSignaturePackage;
 
         mResolveComponentName = testParams.resolveComponentName;
         mPackages.putAll(testParams.packages);
@@ -3382,6 +3386,7 @@
             mAppPredictionServicePackage = getAppPredictionServicePackageName();
             mIncidentReportApproverPackage = getIncidentReportApproverPackageName();
             mRetailDemoPackage = getRetailDemoPackageName();
+            mOverlayConfigSignaturePackage = getOverlayConfigSignaturePackageName();
 
             // Now that we know all of the shared libraries, update all clients to have
             // the correct library paths.
@@ -4208,13 +4213,9 @@
         Iterator<ResolveInfo> iter = matches.iterator();
         while (iter.hasNext()) {
             final ResolveInfo rInfo = iter.next();
-            final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
-            if (ps != null) {
-                final PermissionsState permissionsState = ps.getPermissionsState();
-                if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)
-                        || Build.IS_ENG) {
-                    continue;
-                }
+            if (checkPermission(Manifest.permission.INSTALL_PACKAGES,
+                    rInfo.activityInfo.packageName, 0) == PERMISSION_GRANTED || Build.IS_ENG) {
+                continue;
             }
             iter.remove();
         }
@@ -8594,10 +8595,9 @@
     private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
             String[] permissions, boolean[] tmp, int flags, int userId) {
         int numMatch = 0;
-        final PermissionsState permissionsState = ps.getPermissionsState();
         for (int i=0; i<permissions.length; i++) {
             final String permission = permissions[i];
-            if (permissionsState.hasPermission(permission, userId)) {
+            if (checkPermission(permission, ps.name, userId) == PERMISSION_GRANTED) {
                 tmp[i] = true;
                 numMatch++;
             } else {
@@ -12122,12 +12122,8 @@
                 if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
                     // Exempt SharedUsers signed with the platform key.
                     PackageSetting platformPkgSetting = mSettings.mPackages.get("android");
-                    if ((platformPkgSetting.signatures.mSigningDetails
-                            != PackageParser.SigningDetails.UNKNOWN)
-                            && (compareSignatures(
-                                    platformPkgSetting.signatures.mSigningDetails.signatures,
-                            pkg.getSigningDetails().signatures)
-                                            != PackageManager.SIGNATURE_MATCH)) {
+                    if (!comparePackageSignatures(platformPkgSetting,
+                            pkg.getSigningDetails().signatures)) {
                         throw new PackageManagerException("Apps that share a user with a " +
                                 "privileged app must themselves be marked as privileged. " +
                                 pkg.getPackageName() + " shares privileged user " +
@@ -12174,12 +12170,8 @@
                     if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.Q) {
                         final PackageSetting platformPkgSetting =
                                 mSettings.getPackageLPr("android");
-                        if ((platformPkgSetting.signatures.mSigningDetails
-                                    != PackageParser.SigningDetails.UNKNOWN)
-                                && (compareSignatures(
-                                        platformPkgSetting.signatures.mSigningDetails.signatures,
-                                pkg.getSigningDetails().signatures)
-                                    != PackageManager.SIGNATURE_MATCH)) {
+                        if (!comparePackageSignatures(platformPkgSetting,
+                                pkg.getSigningDetails().signatures)) {
                             throw new PackageManagerException("Overlay "
                                     + pkg.getPackageName()
                                     + " must target Q or later, "
@@ -12188,24 +12180,35 @@
                     }
 
                     // A non-preloaded overlay package, without <overlay android:targetName>, will
-                    // only be used if it is signed with the same certificate as its target. If the
-                    // target is already installed, check this here to augment the last line of
-                    // defence which is OMS.
+                    // only be used if it is signed with the same certificate as its target OR if
+                    // it is signed with the same certificate as a reference package declared
+                    // in 'config-signature' tag of SystemConfig.
+                    // If the target is already installed or 'config-signature' tag in SystemConfig
+                    // is set, check this here to augment the last line of defence which is OMS.
                     if (pkg.getOverlayTargetName() == null) {
                         final PackageSetting targetPkgSetting =
                                 mSettings.getPackageLPr(pkg.getOverlayTarget());
                         if (targetPkgSetting != null) {
-                            if ((targetPkgSetting.signatures.mSigningDetails
-                                        != PackageParser.SigningDetails.UNKNOWN)
-                                    && (compareSignatures(
-                                            targetPkgSetting.signatures.mSigningDetails.signatures,
-                                    pkg.getSigningDetails().signatures)
-                                        != PackageManager.SIGNATURE_MATCH)) {
-                                throw new PackageManagerException("Overlay "
-                                        + pkg.getPackageName() + " and target "
-                                        + pkg.getOverlayTarget() + " signed with"
-                                        + " different certificates, and the overlay lacks"
-                                        + " <overlay android:targetName>");
+                            if (!comparePackageSignatures(targetPkgSetting,
+                                    pkg.getSigningDetails().signatures)) {
+                                // check reference signature
+                                if (mOverlayConfigSignaturePackage == null) {
+                                    throw new PackageManagerException("Overlay "
+                                            + pkg.getPackageName() + " and target "
+                                            + pkg.getOverlayTarget() + " signed with"
+                                            + " different certificates, and the overlay lacks"
+                                            + " <overlay android:targetName>");
+                                }
+                                final PackageSetting refPkgSetting =
+                                        mSettings.getPackageLPr(mOverlayConfigSignaturePackage);
+                                if (!comparePackageSignatures(refPkgSetting,
+                                        pkg.getSigningDetails().signatures)) {
+                                    throw new PackageManagerException("Overlay "
+                                            + pkg.getPackageName() + " signed with a different "
+                                            + "certificate than both the reference package and "
+                                            + "target " + pkg.getOverlayTarget() + ", and the "
+                                            + "overlay lacks <overlay android:targetName>");
+                                }
                             }
                         }
                     }
@@ -12675,7 +12678,7 @@
     public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
             final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
             final int[] userIds, int[] instantUserIds,
-            @Nullable SparseArray<int[]> broadcastWhitelist) {
+            @Nullable SparseArray<int[]> broadcastAllowList) {
         mHandler.post(() -> {
             try {
                 final IActivityManager am = ActivityManager.getService();
@@ -12687,7 +12690,7 @@
                     resolvedUserIds = userIds;
                 }
                 doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
-                        resolvedUserIds, false, broadcastWhitelist);
+                        resolvedUserIds, false, broadcastAllowList);
                 if (instantUserIds != null && instantUserIds != EMPTY_INT_ARRAY) {
                     doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
                             instantUserIds, true, null);
@@ -12760,7 +12763,7 @@
      */
     private void doSendBroadcast(IActivityManager am, String action, String pkg, Bundle extras,
             int flags, String targetPkg, IIntentReceiver finishedReceiver,
-            int[] userIds, boolean isInstantApp, @Nullable SparseArray<int[]> broadcastWhitelist) {
+            int[] userIds, boolean isInstantApp, @Nullable SparseArray<int[]> broadcastAllowList) {
         for (int id : userIds) {
             final Intent intent = new Intent(action,
                     pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
@@ -12790,7 +12793,7 @@
             mInjector.getActivityManagerInternal().broadcastIntent(
                     intent, finishedReceiver, requiredPermissions,
                     finishedReceiver != null, id,
-                    broadcastWhitelist == null ? null : broadcastWhitelist.get(id));
+                    broadcastAllowList == null ? null : broadcastAllowList.get(id));
         }
     }
 
@@ -12930,7 +12933,7 @@
 
         sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
                 packageName, extras, 0, null, null, userIds, instantUserIds,
-                mAppsFilter.getVisibilityWhitelist(
+                mAppsFilter.getVisibilityAllowList(
                         getPackageSettingInternal(packageName, Process.SYSTEM_UID),
                         userIds, mSettings.mPackages));
         if (sendBootCompleted && !ArrayUtils.isEmpty(userIds)) {
@@ -16763,7 +16766,7 @@
                 reconciledPkg.pkgSetting.firstInstallTime = deletedPkgSetting.firstInstallTime;
                 reconciledPkg.pkgSetting.lastUpdateTime = System.currentTimeMillis();
 
-                res.removedInfo.broadcastWhitelist = mAppsFilter.getVisibilityWhitelist(
+                res.removedInfo.broadcastAllowList = mAppsFilter.getVisibilityAllowList(
                                 reconciledPkg.pkgSetting, request.mAllUsers, mSettings.mPackages);
                 if (reconciledPkg.prepareResult.system) {
                     // Remove existing system package
@@ -18693,7 +18696,7 @@
         boolean isStaticSharedLib;
         // a two dimensional array mapping userId to the set of appIds that can receive notice
         // of package changes
-        SparseArray<int[]> broadcastWhitelist;
+        SparseArray<int[]> broadcastAllowList;
         // Clean up resources deleted packages.
         InstallArgs args = null;
 
@@ -18716,9 +18719,9 @@
             extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
             extras.putBoolean(Intent.EXTRA_REPLACING, true);
             packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage, extras,
-                    0, null /*targetPackage*/, null, null, null, broadcastWhitelist);
+                    0, null /*targetPackage*/, null, null, null, broadcastAllowList);
             packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage,
-                    extras, 0, null /*targetPackage*/, null, null, null, broadcastWhitelist);
+                    extras, 0, null /*targetPackage*/, null, null, null, broadcastAllowList);
             packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, null, 0,
                     removedPackage, null, null, null, null /* broadcastWhitelist */);
             if (installerPackageName != null) {
@@ -18750,7 +18753,7 @@
             if (removedPackage != null) {
                 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
                     removedPackage, extras, 0, null /*targetPackage*/, null,
-                    broadcastUsers, instantUserIds, broadcastWhitelist);
+                    broadcastUsers, instantUserIds, broadcastAllowList);
                 if (installerPackageName != null) {
                     packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
                             removedPackage, extras, 0 /*flags*/,
@@ -18759,7 +18762,7 @@
                 if (dataRemoved && !isRemovedPackageSystemUpdate) {
                     packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
                             removedPackage, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, null,
-                            null, broadcastUsers, instantUserIds, broadcastWhitelist);
+                            null, broadcastUsers, instantUserIds, broadcastAllowList);
                     packageSender.notifyPackageRemoved(removedPackage, removedUid);
                 }
             }
@@ -18772,7 +18775,7 @@
 
                 packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
                         null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
-                        null, null, broadcastUsers, instantUserIds, broadcastWhitelist);
+                        null, null, broadcastUsers, instantUserIds, broadcastAllowList);
             }
         }
 
@@ -19271,6 +19274,13 @@
         final int flags = action.flags;
         final boolean systemApp = isSystemApp(ps);
 
+        // We need to get the permission state before package state is (potentially) destroyed.
+        final SparseBooleanArray hadSuspendAppsPermission = new SparseBooleanArray();
+        for (int userId : allUserHandles) {
+            hadSuspendAppsPermission.put(userId, checkPermission(Manifest.permission.SUSPEND_APPS,
+                    packageName, userId) == PERMISSION_GRANTED);
+        }
+
         final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
 
         if ((!systemApp || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)
@@ -19337,8 +19347,7 @@
             affectedUserIds = resolveUserIds(userId);
         }
         for (final int affectedUserId : affectedUserIds) {
-            if (ps.getPermissionsState().hasPermission(Manifest.permission.SUSPEND_APPS,
-                    affectedUserId)) {
+            if (hadSuspendAppsPermission.get(affectedUserId)) {
                 unsuspendForSuspendingPackage(packageName, affectedUserId);
                 removeAllDistractingPackageRestrictions(affectedUserId);
             }
@@ -20805,6 +20814,11 @@
         return ensureSystemPackageName(contentCaptureServiceComponentName.getPackageName());
     }
 
+    public String getOverlayConfigSignaturePackageName() {
+        return ensureSystemPackageName(SystemConfig.getInstance()
+                .getOverlayConfigSignaturePackage());
+    }
+
     @Nullable
     private String getRetailDemoPackageName() {
         final String predefinedPkgName = mContext.getString(R.string.config_retailDemoPackage);
@@ -21111,8 +21125,8 @@
                 pkgSetting.setEnabled(newState, userId, callingPackage);
                 if ((newState == COMPONENT_ENABLED_STATE_DISABLED_USER
                         || newState == COMPONENT_ENABLED_STATE_DISABLED)
-                        && pkgSetting.getPermissionsState().hasPermission(
-                                Manifest.permission.SUSPEND_APPS, userId)) {
+                        && checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId)
+                        == PERMISSION_GRANTED) {
                     // This app should not generally be allowed to get disabled by the UI, but if it
                     // ever does, we don't want to end up with some of the user's apps permanently
                     // suspended.
@@ -21264,17 +21278,17 @@
         final boolean isInstantApp = isInstantApp(packageName, userId);
         final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
         final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
-        final SparseArray<int[]> broadcastWhitelist;
+        final SparseArray<int[]> broadcastAllowList;
         synchronized (mLock) {
             PackageSetting setting = getPackageSettingInternal(packageName, Process.SYSTEM_UID);
             if (setting == null) {
                 return;
             }
-            broadcastWhitelist = isInstantApp ? null : mAppsFilter.getVisibilityWhitelist(setting,
+            broadcastAllowList = isInstantApp ? null : mAppsFilter.getVisibilityAllowList(setting,
                     userIds, mSettings.mPackages);
         }
         sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
-                userIds, instantUserIds, broadcastWhitelist);
+                userIds, instantUserIds, broadcastAllowList);
     }
 
     @Override
@@ -24320,6 +24334,8 @@
                     return TextUtils.isEmpty(mRetailDemoPackage)
                             ? ArrayUtils.emptyArray(String.class)
                             : new String[] {mRetailDemoPackage};
+                case PackageManagerInternal.PACKAGE_OVERLAY_CONFIG_SIGNATURE:
+                    return filterOnlySystemPackages(getOverlayConfigSignaturePackageName());
                 default:
                     return ArrayUtils.emptyArray(String.class);
             }
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index 03f4708..de0e4b5 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -488,6 +488,18 @@
     }
 
     /**
+     * Returns true if the signature set of the package is identical to the specified signature
+     * set or if the signing details of the package are unknown.
+     */
+    public static boolean comparePackageSignatures(PackageSetting pkgSetting,
+            Signature[] signatures) {
+        return pkgSetting.signatures.mSigningDetails
+                == PackageParser.SigningDetails.UNKNOWN
+                || compareSignatures(pkgSetting.signatures.mSigningDetails.signatures, signatures)
+                == PackageManager.SIGNATURE_MATCH;
+    }
+
+    /**
      * Used for backward compatibility to make sure any packages with
      * certificate chains get upgraded to the new style. {@code existingSigs}
      * will be in the old format (since they were stored on disk from before the
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index f16b5b4..89ed3c7 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -108,6 +108,7 @@
 import com.android.internal.util.StatLogger;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.pm.ShortcutUser.PackageWithUser;
 import com.android.server.uri.UriGrantsManagerInternal;
 
@@ -614,13 +615,13 @@
         }
 
         @Override
-        public void onStopUser(int userHandle) {
-            mService.handleStopUser(userHandle);
+        public void onUserStopping(@NonNull TargetUser user) {
+            mService.handleStopUser(user.getUserIdentifier());
         }
 
         @Override
-        public void onUnlockUser(int userId) {
-            mService.handleUnlockUser(userId);
+        public void onUserUnlocking(@NonNull TargetUser user) {
+            mService.handleUnlockUser(user.getUserIdentifier());
         }
     }
 
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index b0d3d53..8f11fd5 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -110,6 +110,7 @@
 import com.android.server.LocalServices;
 import com.android.server.LockGuard;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.am.UserState;
 import com.android.server.storage.DeviceStorageMonitorInternal;
 import com.android.server.utils.TimingsTraceAndSlog;
@@ -553,9 +554,9 @@
         }
 
         @Override
-        public void onStartUser(@UserIdInt int userId) {
+        public void onUserStarting(@NonNull TargetUser targetUser) {
             synchronized (mUms.mUsersLock) {
-                final UserData user = mUms.getUserDataLU(userId);
+                final UserData user = mUms.getUserDataLU(targetUser.getUserIdentifier());
                 if (user != null) {
                     user.startRealtime = SystemClock.elapsedRealtime();
                 }
@@ -563,9 +564,9 @@
         }
 
         @Override
-        public void onUnlockUser(@UserIdInt int userId) {
+        public void onUserUnlocking(@NonNull TargetUser targetUser) {
             synchronized (mUms.mUsersLock) {
-                final UserData user = mUms.getUserDataLU(userId);
+                final UserData user = mUms.getUserDataLU(targetUser.getUserIdentifier());
                 if (user != null) {
                     user.unlockRealtime = SystemClock.elapsedRealtime();
                 }
@@ -573,9 +574,9 @@
         }
 
         @Override
-        public void onStopUser(@UserIdInt int userId) {
+        public void onUserStopping(@NonNull TargetUser targetUser) {
             synchronized (mUms.mUsersLock) {
-                final UserData user = mUms.getUserDataLU(userId);
+                final UserData user = mUms.getUserDataLU(targetUser.getUserIdentifier());
                 if (user != null) {
                     user.startRealtime = 0;
                     user.unlockRealtime = 0;
diff --git a/services/core/java/com/android/server/pm/dex/OWNERS b/services/core/java/com/android/server/pm/dex/OWNERS
index fcc1f6c..5a4431e 100644
--- a/services/core/java/com/android/server/pm/dex/OWNERS
+++ b/services/core/java/com/android/server/pm/dex/OWNERS
@@ -1,4 +1,2 @@
-agampe@google.com
 calin@google.com
 ngeoffray@google.com
-sehr@google.com
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java
index 37f088b..4d48a2e 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyService.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java
@@ -67,6 +67,7 @@
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.pm.parsing.pkg.AndroidPackage;
 import com.android.server.pm.permission.PermissionManagerServiceInternal;
 import com.android.server.policy.PermissionPolicyInternal.OnInitializedCallback;
@@ -347,7 +348,11 @@
     }
 
     @Override
-    public void onStartUser(@UserIdInt int userId) {
+    public void onUserStarting(@NonNull TargetUser user) {
+        onStartUser(user.getUserIdentifier());
+    }
+
+    private void onStartUser(@UserIdInt int userId) {
         if (DEBUG) Slog.i(LOG_TAG, "onStartUser(" + userId + ")");
 
         if (isStarted(userId)) {
@@ -373,11 +378,11 @@
     }
 
     @Override
-    public void onStopUser(@UserIdInt int userId) {
-        if (DEBUG) Slog.i(LOG_TAG, "onStopUser(" + userId + ")");
+    public void onUserStopping(@NonNull TargetUser user) {
+        if (DEBUG) Slog.i(LOG_TAG, "onStopUser(" + user + ")");
 
         synchronized (mLock) {
-            mIsStarted.delete(userId);
+            mIsStarted.delete(user.getUserIdentifier());
         }
     }
 
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index a2b46a0..f9a49c9 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -493,9 +493,6 @@
     private boolean mProximityPositive;
 
     // Screen brightness setting limits.
-    private float mScreenBrightnessSettingMinimum;
-    private float mScreenBrightnessSettingMaximum;
-    private float mScreenBrightnessSettingDefault;
     public final float mScreenBrightnessMinimum;
     public final float mScreenBrightnessMaximum;
     public final float mScreenBrightnessDefault;
@@ -1030,14 +1027,6 @@
             mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class);
             mAttentionDetector.systemReady(mContext);
 
-            PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
-            mScreenBrightnessSettingMinimum = pm.getBrightnessConstraint(
-                    PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM);
-            mScreenBrightnessSettingMaximum = pm.getBrightnessConstraint(
-                    PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM);
-            mScreenBrightnessSettingDefault = pm.getBrightnessConstraint(
-                    PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT);
-
             SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper());
 
             // The notifier runs on the system server's main looper so as not to interfere
@@ -2818,7 +2807,7 @@
                 // Keep the brightness steady during boot. This requires the
                 // bootloader brightness and the default brightness to be identical.
                 autoBrightness = false;
-                screenBrightnessOverride = mScreenBrightnessSettingDefault;
+                screenBrightnessOverride = mScreenBrightnessDefault;
             } else if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) {
                 autoBrightness = false;
                 screenBrightnessOverride = mScreenBrightnessOverrideFromWindowManager;
@@ -3869,9 +3858,9 @@
             pw.println("  mDrawWakeLockOverrideFromSidekick=" + mDrawWakeLockOverrideFromSidekick);
             pw.println("  mDozeScreenBrightnessOverrideFromDreamManager="
                     + mDozeScreenBrightnessOverrideFromDreamManager);
-            pw.println("  mScreenBrightnessSettingMinimumFloat=" + mScreenBrightnessSettingMinimum);
-            pw.println("  mScreenBrightnessSettingMaximumFloat=" + mScreenBrightnessSettingMaximum);
-            pw.println("  mScreenBrightnessSettingDefaultFloat=" + mScreenBrightnessSettingDefault);
+            pw.println("  mScreenBrightnessMinimum=" + mScreenBrightnessMinimum);
+            pw.println("  mScreenBrightnessMaximum=" + mScreenBrightnessMaximum);
+            pw.println("  mScreenBrightnessDefault=" + mScreenBrightnessDefault);
             pw.println("  mDoubleTapWakeEnabled=" + mDoubleTapWakeEnabled);
             pw.println("  mIsVrModeEnabled=" + mIsVrModeEnabled);
             pw.println("  mForegroundProfile=" + mForegroundProfile);
@@ -4228,15 +4217,15 @@
             proto.write(
                     PowerServiceSettingsAndConfigurationDumpProto.ScreenBrightnessSettingLimitsProto
                             .SETTING_MINIMUM_FLOAT,
-                    mScreenBrightnessSettingMinimum);
+                    mScreenBrightnessMinimum);
             proto.write(
                     PowerServiceSettingsAndConfigurationDumpProto.ScreenBrightnessSettingLimitsProto
                             .SETTING_MAXIMUM_FLOAT,
-                    mScreenBrightnessSettingMaximum);
+                    mScreenBrightnessMaximum);
             proto.write(
                     PowerServiceSettingsAndConfigurationDumpProto.ScreenBrightnessSettingLimitsProto
                             .SETTING_DEFAULT_FLOAT,
-                    mScreenBrightnessSettingDefault);
+                    mScreenBrightnessDefault);
             proto.end(screenBrightnessSettingLimitsToken);
 
             proto.write(
diff --git a/services/core/java/com/android/server/role/RoleManagerService.java b/services/core/java/com/android/server/role/RoleManagerService.java
index 392792d..a291cef 100644
--- a/services/core/java/com/android/server/role/RoleManagerService.java
+++ b/services/core/java/com/android/server/role/RoleManagerService.java
@@ -34,14 +34,11 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.PermissionChecker;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.Signature;
-import android.database.CursorWindow;
 import android.os.Binder;
-import android.os.Bundle;
 import android.os.Handler;
 import android.os.RemoteCallback;
 import android.os.RemoteCallbackList;
@@ -74,6 +71,7 @@
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.pm.permission.PermissionManagerServiceInternal;
 
 import java.io.ByteArrayOutputStream;
@@ -217,8 +215,8 @@
     }
 
     @Override
-    public void onStartUser(@UserIdInt int userId) {
-        maybeGrantDefaultRolesSync(userId);
+    public void onUserStarting(@NonNull TargetUser user) {
+        maybeGrantDefaultRolesSync(user.getUserIdentifier());
     }
 
     @MainThread
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerService.java b/services/core/java/com/android/server/rollback/RollbackManagerService.java
index ce1156b..04a5ca5 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerService.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerService.java
@@ -16,10 +16,12 @@
 
 package com.android.server.rollback;
 
+import android.annotation.NonNull;
 import android.content.Context;
 
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 
 /**
  * Service that manages APK level rollbacks. Publishes
@@ -43,8 +45,8 @@
     }
 
     @Override
-    public void onUserUnlocking(TargetUser user) {
-        mService.onUnlockUser(user.getUserHandle().getIdentifier());
+    public void onUserUnlocking(@NonNull TargetUser user) {
+        mService.onUnlockUser(user.getUserIdentifier());
     }
 
     @Override
diff --git a/services/core/java/com/android/server/search/SearchManagerService.java b/services/core/java/com/android/server/search/SearchManagerService.java
index fea68d3..7091c47 100644
--- a/services/core/java/com/android/server/search/SearchManagerService.java
+++ b/services/core/java/com/android/server/search/SearchManagerService.java
@@ -16,9 +16,7 @@
 
 package com.android.server.search;
 
-import android.app.ActivityManager;
-import android.app.ActivityTaskManager;
-import android.app.IActivityTaskManager;
+import android.annotation.NonNull;
 import android.app.ISearchManager;
 import android.app.SearchManager;
 import android.app.SearchableInfo;
@@ -26,18 +24,14 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
-import android.content.res.Configuration;
 import android.database.ContentObserver;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
-import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
-import android.service.voice.VoiceInteractionService;
 import android.util.Log;
 import android.util.SparseArray;
 
@@ -48,6 +42,7 @@
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.statusbar.StatusBarManagerInternal;
 
 import java.io.FileDescriptor;
@@ -76,18 +71,13 @@
         }
 
         @Override
-        public void onUnlockUser(final int userId) {
-            mService.mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    mService.onUnlockUser(userId);
-                }
-            });
+        public void onUserUnlocking(@NonNull TargetUser user) {
+            mService.mHandler.post(() -> mService.onUnlockUser(user.getUserIdentifier()));
         }
 
         @Override
-        public void onCleanupUser(int userHandle) {
-            mService.onCleanupUser(userHandle);
+        public void onUserStopped(@NonNull TargetUser user) {
+            mService.onCleanupUser(user.getUserIdentifier());
         }
     }
 
diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java
index 7c8c494..4349ca4 100644
--- a/services/core/java/com/android/server/slice/SliceManagerService.java
+++ b/services/core/java/com/android/server/slice/SliceManagerService.java
@@ -26,6 +26,7 @@
 import static android.os.Process.SYSTEM_UID;
 
 import android.Manifest.permission;
+import android.annotation.NonNull;
 import android.app.AppOpsManager;
 import android.app.slice.ISliceManager;
 import android.app.slice.SliceSpec;
@@ -59,10 +60,10 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.AssistUtils;
-import com.android.internal.util.Preconditions;
 import com.android.server.LocalServices;
 import com.android.server.ServiceThread;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -615,13 +616,13 @@
         }
 
         @Override
-        public void onUnlockUser(int userHandle) {
-            mService.onUnlockUser(userHandle);
+        public void onUserUnlocking(@NonNull TargetUser user) {
+            mService.onUnlockUser(user.getUserIdentifier());
         }
 
         @Override
-        public void onStopUser(int userHandle) {
-            mService.onStopUser(userHandle);
+        public void onUserStopping(@NonNull TargetUser user) {
+            mService.onStopUser(user.getUserIdentifier());
         }
     }
 
diff --git a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
index 1707d95..363e86d 100644
--- a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
+++ b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
@@ -66,6 +66,7 @@
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Preconditions;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -118,14 +119,14 @@
         }
 
         @Override
-        public void onStartUser(int userId) {
-            processAnyPendingWork(userId);
+        public void onUserStarting(@NonNull TargetUser user) {
+            processAnyPendingWork(user.getUserIdentifier());
         }
 
         @Override
-        public void onUnlockUser(int userId) {
+        public void onUserUnlocking(@NonNull TargetUser user) {
             // Rebind if we failed earlier due to locked encrypted user
-            processAnyPendingWork(userId);
+            processAnyPendingWork(user.getUserIdentifier());
         }
 
         private void processAnyPendingWork(int userId) {
@@ -135,7 +136,9 @@
         }
 
         @Override
-        public void onStopUser(int userId) {
+        public void onUserStopping(@NonNull TargetUser user) {
+            int userId = user.getUserIdentifier();
+
             synchronized (mManagerService.mLock) {
                 UserState userState = mManagerService.peekUserStateLocked(userId);
                 if (userState != null) {
diff --git a/services/core/java/com/android/server/textservices/TextServicesManagerService.java b/services/core/java/com/android/server/textservices/TextServicesManagerService.java
index e0bac93..f39067b 100644
--- a/services/core/java/com/android/server/textservices/TextServicesManagerService.java
+++ b/services/core/java/com/android/server/textservices/TextServicesManagerService.java
@@ -58,6 +58,7 @@
 import com.android.internal.util.DumpUtils;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -287,21 +288,21 @@
         }
 
         @Override
-        public void onStopUser(@UserIdInt int userHandle) {
+        public void onUserStopping(@NonNull TargetUser user) {
             if (DBG) {
-                Slog.d(TAG, "onStopUser userId: " + userHandle);
+                Slog.d(TAG, "onStopUser user: " + user);
             }
-            mService.onStopUser(userHandle);
+            mService.onStopUser(user.getUserIdentifier());
         }
 
         @Override
-        public void onUnlockUser(@UserIdInt int userHandle) {
+        public void onUserUnlocking(@NonNull TargetUser user) {
             if(DBG) {
-                Slog.d(TAG, "onUnlockUser userId: " + userHandle);
+                Slog.d(TAG, "onUnlockUser userId: " + user);
             }
             // Called on the system server's main looper thread.
             // TODO: Dispatch this to a worker thread as needed.
-            mService.onUnlockUser(userHandle);
+            mService.onUnlockUser(user.getUserIdentifier());
         }
     }
 
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index fd3c1f9..6adff0d 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -17,6 +17,8 @@
 package com.android.server.trust;
 
 import android.Manifest;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.AlarmManager;
@@ -71,6 +73,7 @@
 import com.android.internal.util.DumpUtils;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -1042,28 +1045,28 @@
     // User lifecycle
 
     @Override
-    public void onStartUser(int userId) {
-        mHandler.obtainMessage(MSG_START_USER, userId, 0, null).sendToTarget();
+    public void onUserStarting(@NonNull TargetUser user) {
+        mHandler.obtainMessage(MSG_START_USER, user.getUserIdentifier(), 0, null).sendToTarget();
     }
 
     @Override
-    public void onCleanupUser(int userId) {
-        mHandler.obtainMessage(MSG_CLEANUP_USER, userId, 0, null).sendToTarget();
+    public void onUserStopped(@NonNull TargetUser user) {
+        mHandler.obtainMessage(MSG_CLEANUP_USER, user.getUserIdentifier(), 0, null).sendToTarget();
     }
 
     @Override
-    public void onSwitchUser(int userId) {
-        mHandler.obtainMessage(MSG_SWITCH_USER, userId, 0, null).sendToTarget();
+    public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
+        mHandler.obtainMessage(MSG_SWITCH_USER, to.getUserIdentifier(), 0, null).sendToTarget();
     }
 
     @Override
-    public void onUnlockUser(int userId) {
-        mHandler.obtainMessage(MSG_UNLOCK_USER, userId, 0, null).sendToTarget();
+    public void onUserUnlocking(@NonNull TargetUser user) {
+        mHandler.obtainMessage(MSG_UNLOCK_USER, user.getUserIdentifier(), 0, null).sendToTarget();
     }
 
     @Override
-    public void onStopUser(@UserIdInt int userId) {
-        mHandler.obtainMessage(MSG_STOP_USER, userId, 0, null).sendToTarget();
+    public void onUserStopping(@NonNull TargetUser user) {
+        mHandler.obtainMessage(MSG_STOP_USER, user.getUserIdentifier(), 0, null).sendToTarget();
     }
 
     // Plumbing
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 323ac7b..b3ec849 100755
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -20,6 +20,7 @@
 import static android.media.tv.TvInputManager.INPUT_STATE_CONNECTED;
 import static android.media.tv.TvInputManager.INPUT_STATE_CONNECTED_STANDBY;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.content.BroadcastReceiver;
@@ -83,6 +84,7 @@
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.IoThread;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 
 import java.io.File;
 import java.io.FileDescriptor;
@@ -165,10 +167,10 @@
     }
 
     @Override
-    public void onUnlockUser(int userHandle) {
-        if (DEBUG) Slog.d(TAG, "onUnlockUser(userHandle=" + userHandle + ")");
+    public void onUserUnlocking(@NonNull TargetUser user) {
+        if (DEBUG) Slog.d(TAG, "onUnlockUser(user=" + user + ")");
         synchronized (mLock) {
-            if (mCurrentUserId != userHandle) {
+            if (mCurrentUserId != user.getUserIdentifier()) {
                 return;
             }
             buildTvInputListLocked(mCurrentUserId, null);
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index 45689ce..ae873e2 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -19,6 +19,7 @@
 
 import android.Manifest;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
 import android.app.AppOpsManager;
@@ -65,6 +66,7 @@
 import com.android.server.LocalServices;
 import com.android.server.SystemConfig;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.utils.ManagedApplicationService;
 import com.android.server.utils.ManagedApplicationService.BinderChecker;
 import com.android.server.utils.ManagedApplicationService.LogEvent;
@@ -817,14 +819,14 @@
     }
 
     @Override
-    public void onStartUser(int userHandle) {
+    public void onUserStarting(@NonNull TargetUser user) {
         synchronized (mLock) {
             mComponentObserver.onUsersChanged();
         }
     }
 
     @Override
-    public void onSwitchUser(int userHandle) {
+    public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
         FgThread.getHandler().post(() -> {
             synchronized (mLock) {
                 mComponentObserver.onUsersChanged();
@@ -834,7 +836,7 @@
     }
 
     @Override
-    public void onStopUser(int userHandle) {
+    public void onUserStopping(@NonNull TargetUser user) {
         synchronized (mLock) {
             mComponentObserver.onUsersChanged();
         }
@@ -842,7 +844,7 @@
     }
 
     @Override
-    public void onCleanupUser(int userHandle) {
+    public void onUserStopped(@NonNull TargetUser user) {
         synchronized (mLock) {
             mComponentObserver.onUsersChanged();
         }
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 90f87b1..2f695c6 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -105,6 +105,7 @@
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.utils.TimingsTraceAndSlog;
 import com.android.server.wm.WindowManagerInternal;
 
@@ -166,9 +167,9 @@
         }
 
         @Override
-        public void onUnlockUser(int userHandle) {
+        public void onUserUnlocking(@NonNull TargetUser user) {
             if (mService != null) {
-                mService.onUnlockUser(userHandle);
+                mService.onUnlockUser(user.getUserIdentifier());
             }
         }
     }
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 024ef87..b72ff2d 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -2865,7 +2865,7 @@
 
         if (hasProcess()) {
             if (removeFromApp) {
-                app.removeActivity(this);
+                app.removeActivity(this, true /* keepAssociation */);
                 if (!app.hasActivities()) {
                     mAtmService.clearHeavyWeightProcessIfEquals(app);
                     // Update any services we are bound to that might care about whether
@@ -2914,7 +2914,7 @@
                 setState(DESTROYED,
                         "destroyActivityLocked. not finishing or skipping destroy");
                 if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during destroy for activity " + this);
-                app = null;
+                detachFromProcess();
             }
         } else {
             // Remove this record from the history.
@@ -2963,13 +2963,20 @@
         }
         setState(DESTROYED, "removeFromHistory");
         if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during remove for activity " + this);
-        app = null;
+        detachFromProcess();
         removeAppTokenFromDisplay();
 
         cleanUpActivityServices();
         removeUriPermissionsLocked();
     }
 
+    void detachFromProcess() {
+        if (app != null) {
+            app.removeActivity(this, false /* keepAssociation */);
+        }
+        app = null;
+    }
+
     void makeFinishingLocked() {
         if (finishing) {
             return;
@@ -3019,7 +3026,7 @@
         if (setState) {
             setState(DESTROYED, "cleanUp");
             if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during cleanUp for activity " + this);
-            app = null;
+            detachFromProcess();
         }
 
         // Inform supervisor the activity has been removed.
@@ -3160,6 +3167,64 @@
         mServiceConnectionsHolder = null;
     }
 
+    /**
+     * Detach this activity from process and clear the references to it. If the activity is
+     * finishing or has no saved state or crashed many times, it will also be removed from history.
+     */
+    void handleAppDied() {
+        final boolean remove;
+        if ((mRelaunchReason == RELAUNCH_REASON_WINDOWING_MODE_RESIZE
+                || mRelaunchReason == RELAUNCH_REASON_FREE_RESIZE)
+                && launchCount < 3 && !finishing) {
+            // If the process crashed during a resize, always try to relaunch it, unless it has
+            // failed more than twice. Skip activities that's already finishing cleanly by itself.
+            remove = false;
+        } else if ((!mHaveState && !stateNotNeeded
+                && !isState(ActivityState.RESTARTING_PROCESS)) || finishing) {
+            // Don't currently have state for the activity, or it is finishing -- always remove it.
+            remove = true;
+        } else if (!mVisibleRequested && launchCount > 2
+                && lastLaunchTime > (SystemClock.uptimeMillis() - 60000)) {
+            // We have launched this activity too many times since it was able to run, so give up
+            // and remove it. (Note if the activity is visible, we don't remove the record. We leave
+            // the dead window on the screen but the process will not be restarted unless user
+            // explicitly tap on it.)
+            remove = true;
+        } else {
+            // The process may be gone, but the activity lives on!
+            remove = false;
+        }
+        if (remove) {
+            if (ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE || DEBUG_CLEANUP) {
+                Slog.i(TAG_ADD_REMOVE, "Removing activity " + this
+                        + " hasSavedState=" + mHaveState + " stateNotNeeded=" + stateNotNeeded
+                        + " finishing=" + finishing + " state=" + mState
+                        + " callers=" + Debug.getCallers(5));
+            }
+            if (!finishing || (app != null && app.isRemoved())) {
+                Slog.w(TAG, "Force removing " + this + ": app died, no saved state");
+                EventLogTags.writeWmFinishActivity(mUserId, System.identityHashCode(this),
+                        task != null ? task.mTaskId : -1, shortComponentName,
+                        "proc died without state saved");
+            }
+        } else {
+            // We have the current state for this activity, so it can be restarted later
+            // when needed.
+            if (DEBUG_APP) {
+                Slog.v(TAG_APP, "Keeping entry during removeHistory for activity " + this);
+            }
+            // Set nowVisible to previous visible state. If the app was visible while it died, we
+            // leave the dead window on screen so it's basically visible. This is needed when user
+            // later tap on the dead window, we need to stop other apps when user transfers focus
+            // to the restarted activity.
+            nowVisible = mVisibleRequested;
+        }
+        cleanUp(true /* cleanServices */, true /* setState */);
+        if (remove) {
+            removeFromHistory("appDied");
+        }
+    }
+
     @Override
     void removeImmediately() {
         onRemovedFromDisplay();
@@ -4114,6 +4179,12 @@
             // Now that the app is going invisible, we can remove it. It will be restarted
             // if made visible again.
             removeDeadWindows();
+            // If this activity is about to finish/stopped and now becomes invisible, remove it
+            // from the unknownApp list in case the activity does not want to draw anything, which
+            // keep the user waiting for the next transition to start.
+            if (finishing || isState(STOPPED)) {
+                displayContent.mUnknownAppVisibilityController.appRemovedOrHidden(this);
+            }
         } else {
             if (!appTransition.isTransitionSet()
                     && appTransition.isReady()) {
@@ -7561,6 +7632,11 @@
     }
 
     @Override
+    boolean canCustomizeAppTransition() {
+        return true;
+    }
+
+    @Override
     public String toString() {
         if (stringName != null) {
             return stringName + " t" + (task == null ? INVALID_TASK_ID : task.mTaskId) +
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index 04b1edc..ed1ea35 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -891,7 +891,7 @@
                 // This is the first time we failed -- restart process and
                 // retry.
                 r.launchFailed = true;
-                proc.removeActivity(r);
+                proc.removeActivity(r, true /* keepAssociation */);
                 throw e;
             }
         } finally {
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index c4af3e2..5534b8c 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -254,6 +254,7 @@
 import com.android.server.AttributeCache;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.SystemServiceManager;
 import com.android.server.UiThread;
 import com.android.server.Watchdog;
@@ -1027,16 +1028,17 @@
         }
 
         @Override
-        public void onUnlockUser(int userId) {
+        public void onUserUnlocking(@NonNull TargetUser user) {
             synchronized (mService.getGlobalLock()) {
-                mService.mStackSupervisor.onUserUnlocked(userId);
+                mService.mStackSupervisor.onUserUnlocked(user.getUserIdentifier());
             }
         }
 
         @Override
-        public void onCleanupUser(int userId) {
+        public void onUserStopped(@NonNull TargetUser user) {
             synchronized (mService.getGlobalLock()) {
-                mService.mStackSupervisor.mLaunchParamsPersister.onCleanupUser(userId);
+                mService.mStackSupervisor.mLaunchParamsPersister
+                        .onCleanupUser(user.getUserIdentifier());
             }
         }
 
@@ -6789,11 +6791,14 @@
         public void handleAppDied(WindowProcessController wpc, boolean restarting,
                 Runnable finishInstrumentationCallback) {
             synchronized (mGlobalLockWithoutBoost) {
-                // Remove this application's activities from active lists.
-                boolean hasVisibleActivities = mRootWindowContainer.handleAppDied(wpc);
-
-                wpc.clearRecentTasks();
-                wpc.clearActivities();
+                mStackSupervisor.beginDeferResume();
+                final boolean hasVisibleActivities;
+                try {
+                    // Remove this application's activities from active lists.
+                    hasVisibleActivities = wpc.handleAppDied();
+                } finally {
+                    mStackSupervisor.endDeferResume();
+                }
 
                 if (wpc.isInstrumenting()) {
                     finishInstrumentationCallback.run();
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 3abc54f..11a468b 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -203,6 +203,7 @@
     private static final int NEXT_TRANSIT_TYPE_REMOTE = 10;
 
     private int mNextAppTransitionType = NEXT_TRANSIT_TYPE_NONE;
+    private boolean mNextAppTransitionOverrideRequested;
 
     // These are the possible states for the enter/exit activities during a thumbnail transition
     private static final int THUMBNAIL_TRANSITION_ENTER_SCALE_UP = 0;
@@ -337,6 +338,11 @@
         mNextAppTransitionFlags |= flags;
         setLastAppTransition(TRANSIT_UNSET, null, null, null);
         updateBooster();
+        if (isTransitionSet()) {
+            removeAppTransitionTimeoutCallbacks();
+            mHandler.postDelayed(mHandleAppTransitionTimeoutRunnable,
+                    APP_TRANSITION_TIMEOUT_MS);
+        }
     }
 
     void setLastAppTransition(int transit, ActivityRecord openingApp, ActivityRecord closingApp,
@@ -454,6 +460,7 @@
 
     void clear() {
         mNextAppTransitionType = NEXT_TRANSIT_TYPE_NONE;
+        mNextAppTransitionOverrideRequested = false;
         mNextAppTransitionPackage = null;
         mNextAppTransitionAnimationsSpecs.clear();
         mRemoteAnimationController = null;
@@ -1574,6 +1581,7 @@
      */
     boolean canSkipFirstFrame() {
         return mNextAppTransitionType != NEXT_TRANSIT_TYPE_CUSTOM
+                && !mNextAppTransitionOverrideRequested
                 && mNextAppTransitionType != NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE
                 && mNextAppTransitionType != NEXT_TRANSIT_TYPE_CLIP_REVEAL
                 && mNextAppTransition != TRANSIT_KEYGUARD_GOING_AWAY;
@@ -1608,6 +1616,11 @@
             int orientation, Rect frame, Rect displayFrame, Rect insets,
             @Nullable Rect surfaceInsets, @Nullable Rect stableInsets, boolean isVoiceInteraction,
             boolean freeform, WindowContainer container) {
+
+        if (mNextAppTransitionOverrideRequested && container.canCustomizeAppTransition()) {
+            mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM;
+        }
+
         Animation a;
         if (isKeyguardGoingAwayTransit(transit) && enter) {
             a = loadKeyguardExitAnimation(transit);
@@ -1648,7 +1661,6 @@
                     "applyAnimation: anim=%s nextAppTransition=ANIM_CUSTOM transit=%s "
                             + "isEntrance=%b Callers=%s",
                     a, appTransitionToString(transit), enter, Debug.getCallers(3));
-            setAppTransitionFinishedCallbackIfNeeded(a);
         } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE) {
             a = loadAnimationRes(mNextAppTransitionPackage, mNextAppTransitionInPlace);
             ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
@@ -1775,6 +1787,7 @@
                     a, animAttr, appTransitionToString(transit), enter,
                     Debug.getCallers(3));
         }
+        setAppTransitionFinishedCallbackIfNeeded(a);
         return a;
     }
 
@@ -1816,7 +1829,7 @@
             IRemoteCallback startedCallback, IRemoteCallback endedCallback) {
         if (canOverridePendingAppTransition()) {
             clear();
-            mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM;
+            mNextAppTransitionOverrideRequested = true;
             mNextAppTransitionPackage = packageName;
             mNextAppTransitionEnter = enterAnim;
             mNextAppTransitionExit = exitAnim;
@@ -2134,15 +2147,16 @@
             pw.print(prefix); pw.print("mNextAppTransitionType=");
                     pw.println(transitTypeToString());
         }
+        if (mNextAppTransitionOverrideRequested
+                || mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) {
+            pw.print(prefix); pw.print("mNextAppTransitionPackage=");
+            pw.println(mNextAppTransitionPackage);
+            pw.print(prefix); pw.print("mNextAppTransitionEnter=0x");
+            pw.print(Integer.toHexString(mNextAppTransitionEnter));
+            pw.print(" mNextAppTransitionExit=0x");
+            pw.println(Integer.toHexString(mNextAppTransitionExit));
+        }
         switch (mNextAppTransitionType) {
-            case NEXT_TRANSIT_TYPE_CUSTOM:
-                pw.print(prefix); pw.print("mNextAppTransitionPackage=");
-                        pw.println(mNextAppTransitionPackage);
-                pw.print(prefix); pw.print("mNextAppTransitionEnter=0x");
-                        pw.print(Integer.toHexString(mNextAppTransitionEnter));
-                        pw.print(" mNextAppTransitionExit=0x");
-                        pw.println(Integer.toHexString(mNextAppTransitionExit));
-                break;
             case NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE:
                 pw.print(prefix); pw.print("mNextAppTransitionPackage=");
                         pw.println(mNextAppTransitionPackage);
@@ -2229,12 +2243,7 @@
                 setAppTransition(transit, flags);
             }
         }
-        boolean prepared = prepare();
-        if (isTransitionSet()) {
-            removeAppTransitionTimeoutCallbacks();
-            mHandler.postDelayed(mHandleAppTransitionTimeoutRunnable, APP_TRANSITION_TIMEOUT_MS);
-        }
-        return prepared;
+        return prepare();
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 06dec7c..526ec08 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -2751,7 +2751,7 @@
         if (r.app != app) return;
         Slog.w(TAG, "  Force finishing activity "
                 + r.intent.getComponent().flattenToShortString());
-        r.app = null;
+        r.detachFromProcess();
         r.getDisplay().mDisplayContent.prepareAppTransition(
                 TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */);
         r.destroyIfPossible("handleAppCrashed");
@@ -3104,22 +3104,6 @@
         return null;
     }
 
-    boolean handleAppDied(WindowProcessController app) {
-        if (app.isRemoved()) {
-            // The package of the died process should be force-stopped, so make its activities as
-            // finishing to prevent the process from being started again if the next top (or being
-            // visible) activity also resides in the same process.
-            app.makeFinishingForProcessRemoved();
-        }
-        return reduceOnAllTaskDisplayAreas((taskDisplayArea, result) -> {
-            for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
-                final Task stack = taskDisplayArea.getStackAt(sNdx);
-                result |= stack.handleAppDied(app);
-            }
-            return result;
-        }, false /* initValue */);
-    }
-
     void closeSystemDialogActivities(String reason) {
         forAllActivities((r) -> {
             if ((r.info.flags & ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 897b680..f362005 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -86,8 +86,6 @@
 import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList;
 import static com.android.server.wm.ActivityStackSupervisor.printThisActivity;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_APP;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PAUSE;
@@ -115,8 +113,6 @@
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.ActivityTaskManagerService.H.FIRST_ACTIVITY_STACK_MSG;
-import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE;
-import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
 import static com.android.server.wm.IdentifierProto.HASH_CODE;
 import static com.android.server.wm.IdentifierProto.TITLE;
 import static com.android.server.wm.IdentifierProto.USER_ID;
@@ -746,111 +742,6 @@
         }
     }
 
-    // TODO: Can we just loop through WindowProcessController#mActivities instead of doing this?
-    private final RemoveHistoryRecordsForApp mRemoveHistoryRecordsForApp =
-            new RemoveHistoryRecordsForApp();
-    private class RemoveHistoryRecordsForApp {
-        private boolean mHasVisibleActivities;
-        private boolean mIsProcessRemoved;
-        private WindowProcessController mApp;
-        private ArrayList<ActivityRecord> mToRemove = new ArrayList<>();
-
-        boolean process(WindowProcessController app) {
-            mToRemove.clear();
-            mHasVisibleActivities = false;
-            mApp = app;
-            mIsProcessRemoved = app.isRemoved();
-
-            final PooledConsumer c = PooledLambda.obtainConsumer(
-                    RemoveHistoryRecordsForApp::addActivityToRemove, this,
-                    PooledLambda.__(ActivityRecord.class));
-            forAllActivities(c);
-            c.recycle();
-
-            while (!mToRemove.isEmpty()) {
-                processActivity(mToRemove.remove(0));
-            }
-
-            mApp = null;
-            return mHasVisibleActivities;
-        }
-
-        private void addActivityToRemove(ActivityRecord r) {
-            if (r.app == mApp) {
-                mToRemove.add(r);
-            }
-        }
-
-        private void processActivity(ActivityRecord r) {
-            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, "Record " + r + ": app=" + r.app);
-
-            if (r.app != mApp) {
-                return;
-            }
-            if (r.isVisible() || r.mVisibleRequested) {
-                // While an activity launches a new activity, it's possible that the old
-                // activity is already requested to be hidden (mVisibleRequested=false), but
-                // this visibility is not yet committed, so isVisible()=true.
-                mHasVisibleActivities = true;
-            }
-            final boolean remove;
-            if ((r.mRelaunchReason == RELAUNCH_REASON_WINDOWING_MODE_RESIZE
-                    || r.mRelaunchReason == RELAUNCH_REASON_FREE_RESIZE)
-                    && r.launchCount < 3 && !r.finishing) {
-                // If the process crashed during a resize, always try to relaunch it, unless
-                // it has failed more than twice. Skip activities that's already finishing
-                // cleanly by itself.
-                remove = false;
-            } else if ((!r.hasSavedState() && !r.stateNotNeeded
-                    && !r.isState(ActivityState.RESTARTING_PROCESS)) || r.finishing) {
-                // Don't currently have state for the activity, or
-                // it is finishing -- always remove it.
-                remove = true;
-            } else if (!r.mVisibleRequested && r.launchCount > 2
-                    && r.lastLaunchTime > (SystemClock.uptimeMillis() - 60000)) {
-                // We have launched this activity too many times since it was
-                // able to run, so give up and remove it.
-                // (Note if the activity is visible, we don't remove the record.
-                // We leave the dead window on the screen but the process will
-                // not be restarted unless user explicitly tap on it.)
-                remove = true;
-            } else {
-                // The process may be gone, but the activity lives on!
-                remove = false;
-            }
-            if (remove) {
-                if (DEBUG_ADD_REMOVE || DEBUG_CLEANUP) Slog.i(TAG_ADD_REMOVE,
-                        "Removing activity " + r + " from stack "
-                                + ": hasSavedState=" + r.hasSavedState()
-                                + " stateNotNeeded=" + r.stateNotNeeded
-                                + " finishing=" + r.finishing
-                                + " state=" + r.getState() + " callers=" + Debug.getCallers(5));
-                if (!r.finishing || mIsProcessRemoved) {
-                    Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
-                    EventLogTags.writeWmFinishActivity(r.mUserId,
-                            System.identityHashCode(r), r.getTask().mTaskId,
-                            r.shortComponentName, "proc died without state saved");
-                }
-            } else {
-                // We have the current state for this activity, so
-                // it can be restarted later when needed.
-                if (DEBUG_ALL) Slog.v(TAG, "Keeping entry, setting app to null");
-                if (DEBUG_APP) Slog.v(TAG_APP,
-                        "Clearing app during removeHistory for activity " + r);
-                r.app = null;
-                // Set nowVisible to previous visible state. If the app was visible while
-                // it died, we leave the dead window on screen so it's basically visible.
-                // This is needed when user later tap on the dead window, we need to stop
-                // other apps when user transfers focus to the restarted activity.
-                r.nowVisible = r.mVisibleRequested;
-            }
-            r.cleanUp(true /* cleanServices */, true /* setState */);
-            if (remove) {
-                r.removeFromHistory("appDied");
-            }
-        }
-    }
-
     private final FindRootHelper mFindRootHelper = new FindRootHelper();
     private class FindRootHelper {
         private ActivityRecord mRoot;
@@ -7167,9 +7058,8 @@
     /**
      * Reset local parameters because an app's activity died.
      * @param app The app of the activity that died.
-     * @return result from removeHistoryRecordsForAppLocked.
      */
-    boolean handleAppDied(WindowProcessController app) {
+    void handleAppDied(WindowProcessController app) {
         if (mPausingActivity != null && mPausingActivity.app == app) {
             if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG_PAUSE,
                     "App died while pausing: " + mPausingActivity);
@@ -7179,9 +7069,6 @@
             mLastPausedActivity = null;
             mLastNoHistoryActivity = null;
         }
-
-        mStackSupervisor.removeHistoryRecords(app);
-        return mRemoveHistoryRecordsForApp.process(app);
     }
 
     boolean dump(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient,
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index a3a4e40..e24d185 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -857,6 +857,14 @@
     }
 
     /**
+     * @return {@code true} when an application can override an app transition animation on this
+     * container.
+     */
+    boolean canCustomizeAppTransition() {
+        return !WindowManagerService.sDisableCustomTaskAnimationProperty;
+    }
+
+    /**
      * @return {@code true} when this container or its related containers are running an
      * animation, {@code false} otherwise.
      *
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 9acaa9e..ede92f0 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -395,6 +395,21 @@
     // trying to apply a new one.
     private static final boolean ALWAYS_KEEP_CURRENT = true;
 
+    /**
+     * Restrict ability of activities overriding transition animation in a way such that
+     * an activity can do it only when the transition happens within a same task.
+     *
+     * @see android.app.Activity#overridePendingTransition(int, int)
+     */
+    private static final String DISABLE_CUSTOM_TASK_ANIMATION_PROPERTY =
+            "persist.wm.disable_custom_task_animation";
+
+    /**
+     * @see #DISABLE_CUSTOM_TASK_ANIMATION_PROPERTY
+     */
+    static boolean sDisableCustomTaskAnimationProperty =
+            SystemProperties.getBoolean(DISABLE_CUSTOM_TASK_ANIMATION_PROPERTY, false);
+
     private static final String DISABLE_TRIPLE_BUFFERING_PROPERTY =
             "ro.sf.disable_triple_buffer";
 
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 6ba8769..df59c56 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -177,8 +177,10 @@
     // Whether this process has ever started a service with the BIND_INPUT_METHOD permission.
     private volatile boolean mHasImeService;
 
-    // all activities running in the process
+    /** All activities running in the process (exclude destroying). */
     private final ArrayList<ActivityRecord> mActivities = new ArrayList<>();
+    /** The activities will be removed but still belong to this process. */
+    private ArrayList<ActivityRecord> mInactiveActivities;
     // any tasks this process had run root activities in
     private final ArrayList<Task> mRecentTasks = new ArrayList<>();
     // The most recent top-most activity that was resumed in the process for pre-Q app.
@@ -635,21 +637,39 @@
             return;
         }
         mActivities.add(r);
+        if (mInactiveActivities != null) {
+            mInactiveActivities.remove(r);
+        }
         updateActivityConfigurationListener();
     }
 
-    void removeActivity(ActivityRecord r) {
+    /**
+     * Indicates that the given activity is no longer active in this process.
+     *
+     * @param r The running activity to be removed.
+     * @param keepAssociation {@code true} if the activity still belongs to this process but will
+     *                        be removed soon, e.g. destroying. From the perspective of process
+     *                        priority, the process is not important if it only contains activities
+     *                        that are being destroyed. But the association is still needed to
+     *                        ensure all activities are reachable from this process.
+     */
+    void removeActivity(ActivityRecord r, boolean keepAssociation) {
+        if (keepAssociation) {
+            if (mInactiveActivities == null) {
+                mInactiveActivities = new ArrayList<>();
+                mInactiveActivities.add(r);
+            } else if (!mInactiveActivities.contains(r)) {
+                mInactiveActivities.add(r);
+            }
+        } else if (mInactiveActivities != null) {
+            mInactiveActivities.remove(r);
+        }
         mActivities.remove(r);
         updateActivityConfigurationListener();
     }
 
-    void makeFinishingForProcessRemoved() {
-        for (int i = mActivities.size() - 1; i >= 0; --i) {
-            mActivities.get(i).makeFinishingLocked();
-        }
-    }
-
     void clearActivities() {
+        mInactiveActivities = null;
         mActivities.clear();
         updateActivityConfigurationListener();
     }
@@ -1142,6 +1162,47 @@
         mAtm.mH.sendMessage(m);
     }
 
+    /**
+     * Clean up the activities belonging to this process.
+     *
+     * @return {@code true} if the process has any visible activity.
+     */
+    boolean handleAppDied() {
+        mAtm.mStackSupervisor.removeHistoryRecords(this);
+
+        final boolean isRemoved = isRemoved();
+        boolean hasVisibleActivities = false;
+        if (mInactiveActivities != null && !mInactiveActivities.isEmpty()) {
+            // Make sure that all activities in this process are handled.
+            mActivities.addAll(mInactiveActivities);
+        }
+        for (int i = mActivities.size() - 1; i >= 0; i--) {
+            final ActivityRecord r = mActivities.get(i);
+            if (r.mVisibleRequested || r.isVisible()) {
+                // While an activity launches a new activity, it's possible that the old activity
+                // is already requested to be hidden (mVisibleRequested=false), but this visibility
+                // is not yet committed, so isVisible()=true.
+                hasVisibleActivities = true;
+            }
+            if (isRemoved) {
+                // The package of the died process should be force-stopped, so make its activities
+                // as finishing to prevent the process from being started again if the next top (or
+                // being visible) activity also resides in the same process.
+                r.makeFinishingLocked();
+            }
+
+            final Task rootTask = r.getRootTask();
+            if (rootTask != null) {
+                rootTask.handleAppDied(this);
+            }
+            r.handleAppDied();
+        }
+        clearRecentTasks();
+        clearActivities();
+
+        return hasVisibleActivities;
+    }
+
     void registerDisplayConfigurationListener(DisplayContent displayContent) {
         if (displayContent == null) {
             return;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 7ec819f..9a2bef8 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -290,6 +290,7 @@
 import com.android.server.PersistentDataBlockManagerInternal;
 import com.android.server.SystemServerInitThreadPool;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.devicepolicy.DevicePolicyManagerService.ActiveAdmin.TrustAgentInfo;
 import com.android.server.inputmethod.InputMethodManagerInternal;
 import com.android.server.net.NetworkPolicyManagerInternal;
@@ -775,18 +776,18 @@
         }
 
         @Override
-        public void onStartUser(int userHandle) {
-            mService.handleStartUser(userHandle);
+        public void onUserStarting(@NonNull TargetUser user) {
+            mService.handleStartUser(user.getUserIdentifier());
         }
 
         @Override
-        public void onUnlockUser(int userHandle) {
-            mService.handleUnlockUser(userHandle);
+        public void onUserUnlocking(@NonNull TargetUser user) {
+            mService.handleUnlockUser(user.getUserIdentifier());
         }
 
         @Override
-        public void onStopUser(int userHandle) {
-            mService.handleStopUser(userHandle);
+        public void onUserStopping(@NonNull TargetUser user) {
+            mService.handleStopUser(user.getUserIdentifier());
         }
     }
 
diff --git a/services/midi/java/com/android/server/midi/MidiService.java b/services/midi/java/com/android/server/midi/MidiService.java
index 51478b3..2cfdf3f 100644
--- a/services/midi/java/com/android/server/midi/MidiService.java
+++ b/services/midi/java/com/android/server/midi/MidiService.java
@@ -16,6 +16,7 @@
 
 package com.android.server.midi;
 
+import android.annotation.NonNull;
 import android.bluetooth.BluetoothDevice;
 import android.content.ComponentName;
 import android.content.Context;
@@ -47,8 +48,8 @@
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.IndentingPrintWriter;
-import com.android.internal.util.XmlUtils;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 
 import org.xmlpull.v1.XmlPullParser;
 
@@ -75,8 +76,8 @@
         }
 
         @Override
-        public void onUnlockUser(int userHandle) {
-            if (userHandle == UserHandle.USER_SYSTEM) {
+        public void onUserUnlocking(@NonNull TargetUser user) {
+            if (user.getUserIdentifier()  == UserHandle.USER_SYSTEM) {
                 mMidiService.onUnlockUser();
             }
         }
diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java
index d064f7e..1cdcbd8 100644
--- a/services/print/java/com/android/server/print/PrintManagerService.java
+++ b/services/print/java/com/android/server/print/PrintManagerService.java
@@ -72,6 +72,7 @@
 import com.android.internal.util.dump.DualDumpOutputStream;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -101,13 +102,13 @@
     }
 
     @Override
-    public void onUnlockUser(int userHandle) {
-        mPrintManagerImpl.handleUserUnlocked(userHandle);
+    public void onUserUnlocking(@NonNull TargetUser user) {
+        mPrintManagerImpl.handleUserUnlocked(user.getUserIdentifier());
     }
 
     @Override
-    public void onStopUser(int userHandle) {
-        mPrintManagerImpl.handleUserStopped(userHandle);
+    public void onUserStopping(@NonNull TargetUser user) {
+        mPrintManagerImpl.handleUserStopped(user.getUserIdentifier());
     }
 
     class PrintManagerImpl extends IPrintManager.Stub {
diff --git a/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceRoboTest.java b/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceRoboTest.java
index 4a73efe..cd9b6ac 100644
--- a/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceRoboTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceRoboTest.java
@@ -38,7 +38,6 @@
 
 import android.annotation.UserIdInt;
 import android.app.Application;
-import android.app.backup.BackupManager;
 import android.app.backup.BackupManager.OperationType;
 import android.app.backup.IBackupManagerMonitor;
 import android.app.backup.IBackupObserver;
@@ -46,6 +45,7 @@
 import android.app.backup.ISelectBackupTransportCallback;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.UserInfo;
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
@@ -54,6 +54,7 @@
 import android.platform.test.annotations.Presubmit;
 import android.util.SparseArray;
 
+import com.android.server.SystemService.TargetUser;
 import com.android.server.backup.testing.TransportData;
 import com.android.server.testing.shadows.ShadowApplicationPackageManager;
 import com.android.server.testing.shadows.ShadowBinder;
@@ -1601,7 +1602,7 @@
         BackupManagerService.Lifecycle lifecycle =
                 new BackupManagerService.Lifecycle(mContext, backupManagerService);
 
-        lifecycle.onUnlockUser(UserHandle.USER_SYSTEM);
+        lifecycle.onUserUnlocking(new TargetUser(new UserInfo(UserHandle.USER_SYSTEM, null, 0)));
 
         verify(backupManagerService).onUnlockUser(UserHandle.USER_SYSTEM);
     }
@@ -1613,7 +1614,7 @@
         BackupManagerService.Lifecycle lifecycle =
                 new BackupManagerService.Lifecycle(mContext, backupManagerService);
 
-        lifecycle.onStopUser(UserHandle.USER_SYSTEM);
+        lifecycle.onUserStopping(new TargetUser(new UserInfo(UserHandle.USER_SYSTEM, null, 0)));
 
         verify(backupManagerService).onStopUser(UserHandle.USER_SYSTEM);
     }
diff --git a/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java b/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
index 8ccaedd..2f5e883 100644
--- a/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
@@ -247,7 +247,7 @@
                 .thenAnswer(inv -> getPowerSaveState());
         when(mMockAppOpsManager.getPackagesForOps(
                 any(int[].class)
-                )).thenAnswer(mGetPackagesForOps);
+        )).thenAnswer(mGetPackagesForOps);
 
         mMockContentResolver = new MockContentResolver();
         when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver);
@@ -447,7 +447,7 @@
         areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS);
         areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
 
-        // Clear the app ops and update the whitelist.
+        // Clear the app ops and update the exemption list.
         setAppOps(UID_1, PACKAGE_1, false);
         setAppOps(UID_10_2, PACKAGE_2, false);
 
@@ -462,7 +462,8 @@
         areRestricted(instance, UID_10_3, PACKAGE_3, JOBS_AND_ALARMS);
         areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
 
-        instance.setPowerSaveWhitelistAppIds(new int[] {UID_1}, new int[] {}, new int[] {UID_2});
+        instance.setPowerSaveExemptionListAppIds(new int[] {UID_1}, new int[] {},
+                new int[] {UID_2});
 
         areRestricted(instance, UID_1, PACKAGE_1, NONE);
         areRestricted(instance, UID_10_1, PACKAGE_1, NONE);
@@ -487,24 +488,25 @@
         areRestricted(instance, UID_10_3, PACKAGE_3, JOBS_AND_ALARMS);
         areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
 
-        assertTrue(instance.isUidPowerSaveWhitelisted(UID_1));
-        assertTrue(instance.isUidPowerSaveWhitelisted(UID_10_1));
-        assertFalse(instance.isUidPowerSaveWhitelisted(UID_2));
-        assertFalse(instance.isUidPowerSaveWhitelisted(UID_10_2));
+        assertTrue(instance.isUidPowerSaveExempt(UID_1));
+        assertTrue(instance.isUidPowerSaveExempt(UID_10_1));
+        assertFalse(instance.isUidPowerSaveExempt(UID_2));
+        assertFalse(instance.isUidPowerSaveExempt(UID_10_2));
 
-        assertFalse(instance.isUidTempPowerSaveWhitelisted(UID_1));
-        assertFalse(instance.isUidTempPowerSaveWhitelisted(UID_10_1));
-        assertTrue(instance.isUidTempPowerSaveWhitelisted(UID_2));
-        assertTrue(instance.isUidTempPowerSaveWhitelisted(UID_10_2));
+        assertFalse(instance.isUidTempPowerSaveExempt(UID_1));
+        assertFalse(instance.isUidTempPowerSaveExempt(UID_10_1));
+        assertTrue(instance.isUidTempPowerSaveExempt(UID_2));
+        assertTrue(instance.isUidTempPowerSaveExempt(UID_10_2));
     }
 
     @Test
-    public void testPowerSaveUserWhitelist() throws Exception {
+    public void testPowerSaveUserExemptionList() throws Exception {
         final AppStateTrackerTestable instance = newInstance();
-        instance.setPowerSaveWhitelistAppIds(new int[] {}, new int[] {UID_1, UID_2}, new int[] {});
-        assertTrue(instance.isUidPowerSaveUserWhitelisted(UID_1));
-        assertTrue(instance.isUidPowerSaveUserWhitelisted(UID_2));
-        assertFalse(instance.isUidPowerSaveUserWhitelisted(UID_3));
+        instance.setPowerSaveExemptionListAppIds(new int[] {}, new int[] {UID_1, UID_2},
+                new int[] {});
+        assertTrue(instance.isUidPowerSaveUserExempt(UID_1));
+        assertTrue(instance.isUidPowerSaveUserExempt(UID_2));
+        assertFalse(instance.isUidPowerSaveUserExempt(UID_3));
     }
 
     @Test
@@ -909,9 +911,10 @@
         reset(l);
 
         // -------------------------------------------------------------------------
-        // Tests with system/user/temp whitelist.
+        // Tests with system/user/temp exemption list.
 
-        instance.setPowerSaveWhitelistAppIds(new int[] {UID_1, UID_2}, new int[] {}, new int[] {});
+        instance.setPowerSaveExemptionListAppIds(new int[] {UID_1, UID_2}, new int[] {},
+                new int[] {});
 
         waitUntilMainHandlerDrain();
         verify(l, times(1)).updateAllJobs();
@@ -923,7 +926,7 @@
         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
         reset(l);
 
-        instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, new int[] {});
+        instance.setPowerSaveExemptionListAppIds(new int[] {UID_2}, new int[] {}, new int[] {});
 
         waitUntilMainHandlerDrain();
         verify(l, times(1)).updateAllJobs();
@@ -935,8 +938,8 @@
         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
         reset(l);
 
-        // Update temp whitelist.
-        instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {},
+        // Update temp exemption list.
+        instance.setPowerSaveExemptionListAppIds(new int[] {UID_2}, new int[] {},
                 new int[] {UID_1, UID_3});
 
         waitUntilMainHandlerDrain();
@@ -949,7 +952,8 @@
         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
         reset(l);
 
-        instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, new int[] {UID_3});
+        instance.setPowerSaveExemptionListAppIds(new int[] {UID_2}, new int[] {},
+                new int[] {UID_3});
 
         waitUntilMainHandlerDrain();
         verify(l, times(1)).updateAllJobs();
@@ -975,10 +979,11 @@
         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
         reset(l);
 
-        instance.setPowerSaveWhitelistAppIds(new int[] {UID_1, UID_2}, new int[] {}, new int[] {});
+        instance.setPowerSaveExemptionListAppIds(new int[] {UID_1, UID_2}, new int[] {},
+                new int[] {});
 
         waitUntilMainHandlerDrain();
-        // Called once for updating all whitelist and once for updating temp whitelist
+        // Called once for updating all exemption list and once for updating temp exemption list
         verify(l, times(2)).updateAllJobs();
         verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
         verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
@@ -988,7 +993,7 @@
         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
         reset(l);
 
-        instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, new int[] {});
+        instance.setPowerSaveExemptionListAppIds(new int[] {UID_2}, new int[] {}, new int[] {});
 
         waitUntilMainHandlerDrain();
         verify(l, times(1)).updateAllJobs();
@@ -1000,8 +1005,8 @@
         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
         reset(l);
 
-        // Update temp whitelist.
-        instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {},
+        // Update temp exemption list.
+        instance.setPowerSaveExemptionListAppIds(new int[] {UID_2}, new int[] {},
                 new int[] {UID_1, UID_3});
 
         waitUntilMainHandlerDrain();
@@ -1014,7 +1019,8 @@
         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
         reset(l);
 
-        instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, new int[] {UID_3});
+        instance.setPowerSaveExemptionListAppIds(new int[] {UID_2}, new int[] {},
+                new int[] {UID_3});
 
         waitUntilMainHandlerDrain();
         verify(l, times(1)).updateAllJobs();
@@ -1254,7 +1260,7 @@
                 .mapToInt(Integer::intValue).toArray();
     }
 
-    static boolean isAnyAppIdUnwhitelistedSlow(int[] prevArray, int[] newArray) {
+    static boolean isAnyAppIdUnexemptSlow(int[] prevArray, int[] newArray) {
         Arrays.sort(newArray); // Just in case...
         for (int p : prevArray) {
             if (Arrays.binarySearch(newArray, p) < 0) {
@@ -1264,31 +1270,31 @@
         return false;
     }
 
-    private void checkAnyAppIdUnwhitelisted(int[] prevArray, int[] newArray, boolean expected) {
+    private void checkAnyAppIdUnexempt(int[] prevArray, int[] newArray, boolean expected) {
         assertEquals("Input: " + Arrays.toString(prevArray) + " " + Arrays.toString(newArray),
-                expected, AppStateTrackerImpl.isAnyAppIdUnwhitelisted(prevArray, newArray));
+                expected, AppStateTrackerImpl.isAnyAppIdUnexempt(prevArray, newArray));
 
-        // Also test isAnyAppIdUnwhitelistedSlow.
+        // Also test isAnyAppIdUnexempt.
         assertEquals("Input: " + Arrays.toString(prevArray) + " " + Arrays.toString(newArray),
-                expected, isAnyAppIdUnwhitelistedSlow(prevArray, newArray));
+                expected, isAnyAppIdUnexemptSlow(prevArray, newArray));
     }
 
     @Test
-    public void isAnyAppIdUnwhitelisted() {
-        checkAnyAppIdUnwhitelisted(array(), array(), false);
+    public void isAnyAppIdUnexempt() {
+        checkAnyAppIdUnexempt(array(), array(), false);
 
-        checkAnyAppIdUnwhitelisted(array(1), array(), true);
-        checkAnyAppIdUnwhitelisted(array(1), array(1), false);
-        checkAnyAppIdUnwhitelisted(array(1), array(0, 1), false);
-        checkAnyAppIdUnwhitelisted(array(1), array(0, 1, 2), false);
-        checkAnyAppIdUnwhitelisted(array(1), array(0, 1, 2), false);
+        checkAnyAppIdUnexempt(array(1), array(), true);
+        checkAnyAppIdUnexempt(array(1), array(1), false);
+        checkAnyAppIdUnexempt(array(1), array(0, 1), false);
+        checkAnyAppIdUnexempt(array(1), array(0, 1, 2), false);
+        checkAnyAppIdUnexempt(array(1), array(0, 1, 2), false);
 
-        checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(), true);
-        checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(1, 2), true);
-        checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(1, 2, 10), false);
-        checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(2, 10), true);
-        checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(0, 1, 2, 4, 3, 10), false);
-        checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(0, 0, 1, 2, 10), false);
+        checkAnyAppIdUnexempt(array(1, 2, 10), array(), true);
+        checkAnyAppIdUnexempt(array(1, 2, 10), array(1, 2), true);
+        checkAnyAppIdUnexempt(array(1, 2, 10), array(1, 2, 10), false);
+        checkAnyAppIdUnexempt(array(1, 2, 10), array(2, 10), true);
+        checkAnyAppIdUnexempt(array(1, 2, 10), array(0, 1, 2, 4, 3, 10), false);
+        checkAnyAppIdUnexempt(array(1, 2, 10), array(0, 0, 1, 2, 10), false);
 
         // Random test
         int trueCount = 0;
@@ -1297,8 +1303,8 @@
             final int[] array1 = makeRandomArray();
             final int[] array2 = makeRandomArray();
 
-            final boolean expected = isAnyAppIdUnwhitelistedSlow(array1, array2);
-            final boolean actual = AppStateTrackerImpl.isAnyAppIdUnwhitelisted(array1, array2);
+            final boolean expected = isAnyAppIdUnexemptSlow(array1, array2);
+            final boolean actual = AppStateTrackerImpl.isAnyAppIdUnexempt(array1, array2);
 
             assertEquals("Input: " + Arrays.toString(array1) + " " + Arrays.toString(array2),
                     expected, actual);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
index 9b2f2b6..960a7ab 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
@@ -275,7 +275,6 @@
     }
 
     @Test
-    @Ignore("b/120845532")
     public void handleSetSystemAudioModeOn_audioSystemBroadcast() {
         mHdmiControlService.setSystemAudioActivated(false);
         assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isFalse();
@@ -287,7 +286,6 @@
     }
 
     @Test
-    @Ignore("b/120845532")
     public void handleSetSystemAudioModeOff_audioSystemToPlayback() {
         mHdmiCecLocalDevicePlayback.mService.setSystemAudioActivated(true);
         assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isTrue();
@@ -301,8 +299,7 @@
     }
 
     @Test
-    @Ignore("b/120845532")
-    public void handleSystemAudioModeStatusOn_DirectltToLocalDeviceFromAudioSystem() {
+    public void handleSystemAudioModeStatusOn_DirectlyToLocalDeviceFromAudioSystem() {
         mHdmiControlService.setSystemAudioActivated(false);
         assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isFalse();
         HdmiCecMessage message =
diff --git a/services/tests/servicestests/src/com/android/server/om/OverlayActorEnforcerTests.kt b/services/tests/servicestests/src/com/android/server/om/OverlayActorEnforcerTests.kt
index e08eea2..0839273 100644
--- a/services/tests/servicestests/src/com/android/server/om/OverlayActorEnforcerTests.kt
+++ b/services/tests/servicestests/src/com/android/server/om/OverlayActorEnforcerTests.kt
@@ -160,7 +160,7 @@
         private val hasPermission: Boolean = false,
         private val overlayableInfo: OverlayableInfo? = null,
         private vararg val packageNames: String = arrayOf("com.test.actor.one")
-    ) : OverlayableInfoCallback {
+    ) : PackageManagerHelper {
 
         override fun getNamedActors() = if (isActor) {
             mapOf(NAMESPACE to mapOf(ACTOR_NAME to ACTOR_PKG_NAME))
@@ -195,6 +195,14 @@
             }
         }
 
+        override fun getConfigSignaturePackage(): String {
+            throw UnsupportedOperationException()
+        }
+
+        override fun getOverlayPackages(userId: Int): MutableList<PackageInfo> {
+            throw UnsupportedOperationException()
+        }
+
         override fun signaturesMatching(pkgName1: String, pkgName2: String, userId: Int): Boolean {
             throw UnsupportedOperationException()
         }
diff --git a/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplRebootTests.java b/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplRebootTests.java
index b7692f9..e281f2b 100644
--- a/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplRebootTests.java
+++ b/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplRebootTests.java
@@ -44,9 +44,9 @@
     @Test
     public void testUpdateOverlaysForUser() {
         final OverlayManagerServiceImpl impl = getImpl();
-        addSystemPackage(target(TARGET), USER);
-        addSystemPackage(target("some.other.target"), USER);;
-        addSystemPackage(overlay(OVERLAY, TARGET), USER);
+        addPackage(target(TARGET), USER);
+        addPackage(target("some.other.target"), USER);
+        addPackage(overlay(OVERLAY, TARGET), USER);
 
         // do nothing, expect no change
         final List<String> a = impl.updateOverlaysForUser(USER);
@@ -54,7 +54,7 @@
         assertTrue(a.contains(TARGET));
 
         // upgrade overlay, keep target
-        addSystemPackage(overlay(OVERLAY, TARGET), USER);
+        addPackage(overlay(OVERLAY, TARGET), USER);
 
         final List<String> b = impl.updateOverlaysForUser(USER);
         assertEquals(1, b.size());
@@ -66,7 +66,7 @@
         assertTrue(c.contains(TARGET));
 
         // upgrade overlay, switch to new target
-        addSystemPackage(overlay(OVERLAY, "some.other.target"), USER);
+        addPackage(overlay(OVERLAY, "some.other.target"), USER);
         final List<String> d = impl.updateOverlaysForUser(USER);
         assertEquals(2, d.size());
         assertTrue(d.containsAll(Arrays.asList(TARGET, "some.other.target")));
diff --git a/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTests.java b/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTests.java
index f4c5506..c1d862a 100644
--- a/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTests.java
+++ b/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTests.java
@@ -19,6 +19,7 @@
 import static android.content.om.OverlayInfo.STATE_DISABLED;
 import static android.content.om.OverlayInfo.STATE_ENABLED;
 import static android.content.om.OverlayInfo.STATE_MISSING_TARGET;
+import static android.os.OverlayablePolicy.CONFIG_SIGNATURE;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -49,6 +50,10 @@
     private static final String OVERLAY3 = OVERLAY + "3";
     private static final int USER3 = USER2 + 1;
 
+    private static final String CONFIG_SIGNATURE_REFERENCE_PKG = "com.dummy.ref";
+    private static final String CERT_CONFIG_OK = "config_certificate_ok";
+    private static final String CERT_CONFIG_NOK = "config_certificate_nok";
+
     @Test
     public void testGetOverlayInfo() {
         installNewPackage(overlay(OVERLAY, TARGET), USER);
@@ -204,4 +209,87 @@
         impl.setEnabled(OVERLAY, true, USER);
         assertEquals(0, listener.count);
     }
+
+    @Test
+    public void testConfigSignaturePolicyOk() {
+        setConfigSignaturePackageName(CONFIG_SIGNATURE_REFERENCE_PKG);
+        reinitializeImpl();
+
+        addPackage(target(CONFIG_SIGNATURE_REFERENCE_PKG).setCertificate(CERT_CONFIG_OK), USER);
+        installNewPackage(target(TARGET), USER);
+        installNewPackage(overlay(OVERLAY, TARGET).setCertificate(CERT_CONFIG_OK), USER);
+
+        final DummyIdmapDaemon idmapd = getIdmapd();
+        final DummyDeviceState state = getState();
+        String overlayPath = state.select(OVERLAY, USER).apkPath;
+        assertTrue(idmapd.idmapExists(overlayPath, USER));
+
+        DummyIdmapDaemon.IdmapHeader idmap = idmapd.getIdmap(overlayPath);
+        assertTrue((CONFIG_SIGNATURE & idmap.policies) == CONFIG_SIGNATURE);
+    }
+
+    @Test
+    public void testConfigSignaturePolicyCertNok() {
+        setConfigSignaturePackageName(CONFIG_SIGNATURE_REFERENCE_PKG);
+        reinitializeImpl();
+
+        addPackage(target(CONFIG_SIGNATURE_REFERENCE_PKG).setCertificate(CERT_CONFIG_OK), USER);
+        installNewPackage(target(TARGET), USER);
+        installNewPackage(overlay(OVERLAY, TARGET).setCertificate(CERT_CONFIG_NOK), USER);
+
+        final DummyIdmapDaemon idmapd = getIdmapd();
+        final DummyDeviceState state = getState();
+        String overlayPath = state.select(OVERLAY, USER).apkPath;
+        assertTrue(idmapd.idmapExists(overlayPath, USER));
+
+        DummyIdmapDaemon.IdmapHeader idmap = idmapd.getIdmap(overlayPath);
+        assertTrue((CONFIG_SIGNATURE & idmap.policies) == 0);
+    }
+
+    @Test
+    public void testConfigSignaturePolicyNoConfig() {
+        addPackage(target(CONFIG_SIGNATURE_REFERENCE_PKG).setCertificate(CERT_CONFIG_OK), USER);
+        installNewPackage(target(TARGET), USER);
+        installNewPackage(overlay(OVERLAY, TARGET).setCertificate(CERT_CONFIG_NOK), USER);
+
+        final DummyIdmapDaemon idmapd = getIdmapd();
+        final DummyDeviceState state = getState();
+        String overlayPath = state.select(OVERLAY, USER).apkPath;
+        assertTrue(idmapd.idmapExists(overlayPath, USER));
+
+        DummyIdmapDaemon.IdmapHeader idmap = idmapd.getIdmap(overlayPath);
+        assertTrue((CONFIG_SIGNATURE & idmap.policies) == 0);
+    }
+
+    @Test
+    public void testConfigSignaturePolicyNoRefPkg() {
+        installNewPackage(target(TARGET), USER);
+        installNewPackage(overlay(OVERLAY, TARGET).setCertificate(CERT_CONFIG_NOK), USER);
+
+        final DummyIdmapDaemon idmapd = getIdmapd();
+        final DummyDeviceState state = getState();
+        String overlayPath = state.select(OVERLAY, USER).apkPath;
+        assertTrue(idmapd.idmapExists(overlayPath, USER));
+
+        DummyIdmapDaemon.IdmapHeader idmap = idmapd.getIdmap(overlayPath);
+        assertTrue((CONFIG_SIGNATURE & idmap.policies) == 0);
+    }
+
+    @Test
+    public void testConfigSignaturePolicyRefPkgNotSystem() {
+        setConfigSignaturePackageName(CONFIG_SIGNATURE_REFERENCE_PKG);
+        reinitializeImpl();
+
+        addPackage(app(CONFIG_SIGNATURE_REFERENCE_PKG).setCertificate(CERT_CONFIG_OK), USER);
+        installNewPackage(target(TARGET), USER);
+        installNewPackage(overlay(OVERLAY, TARGET).setCertificate(CERT_CONFIG_NOK), USER);
+
+        final DummyIdmapDaemon idmapd = getIdmapd();
+        final DummyDeviceState state = getState();
+        String overlayPath = state.select(OVERLAY, USER).apkPath;
+        assertTrue(idmapd.idmapExists(overlayPath, USER));
+
+        DummyIdmapDaemon.IdmapHeader idmap = idmapd.getIdmap(overlayPath);
+        assertTrue((CONFIG_SIGNATURE & idmap.policies) == 0);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTestsBase.java b/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTestsBase.java
index 733310b..2faf29f 100644
--- a/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTestsBase.java
@@ -27,6 +27,7 @@
 import android.content.om.OverlayableInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
+import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 
@@ -52,6 +53,7 @@
     private DummyPackageManagerHelper mPackageManager;
     private DummyIdmapDaemon mIdmapDaemon;
     private OverlayConfig mOverlayConfig;
+    private String mConfigSignaturePackageName;
 
     @Before
     public void setUp() {
@@ -83,6 +85,18 @@
         return mListener;
     }
 
+    DummyIdmapDaemon getIdmapd() {
+        return mIdmapDaemon;
+    }
+
+    DummyDeviceState getState() {
+        return mState;
+    }
+
+    void setConfigSignaturePackageName(String packageName) {
+        mConfigSignaturePackageName = packageName;
+    }
+
     void assertState(@State int expected, final String overlayPackageName, int userId) {
         final OverlayInfo info = mImpl.getOverlayInfo(overlayPackageName, userId);
         if (info == null) {
@@ -102,9 +116,14 @@
         assertEquals(expected, actual);
     }
 
+    DummyDeviceState.PackageBuilder app(String packageName) {
+        return new DummyDeviceState.PackageBuilder(packageName, null /* targetPackageName */,
+                null /* targetOverlayableName */, "data");
+    }
+
     DummyDeviceState.PackageBuilder target(String packageName) {
         return new DummyDeviceState.PackageBuilder(packageName, null /* targetPackageName */,
-                null /* targetOverlayableName */);
+                null /* targetOverlayableName */, "");
     }
 
     DummyDeviceState.PackageBuilder overlay(String packageName, String targetPackageName) {
@@ -114,10 +133,10 @@
     DummyDeviceState.PackageBuilder overlay(String packageName, String targetPackageName,
             String targetOverlayableName) {
         return new DummyDeviceState.PackageBuilder(packageName, targetPackageName,
-                targetOverlayableName);
+                targetOverlayableName, "");
     }
 
-    void addSystemPackage(DummyDeviceState.PackageBuilder pkg, int userId) {
+    void addPackage(DummyDeviceState.PackageBuilder pkg, int userId) {
         mState.add(pkg, userId);
     }
 
@@ -242,15 +261,17 @@
             private String packageName;
             private String targetPackage;
             private String certificate = "[default]";
+            private String partition;
             private int version = 0;
             private ArrayList<String> overlayableNames = new ArrayList<>();
             private String targetOverlayableName;
 
             private PackageBuilder(String packageName, String targetPackage,
-                    String targetOverlayableName) {
+                    String targetOverlayableName, String partition) {
                 this.packageName = packageName;
                 this.targetPackage = targetPackage;
                 this.targetOverlayableName = targetOverlayableName;
+                this.partition = partition;
             }
 
             PackageBuilder setCertificate(String certificate) {
@@ -269,9 +290,19 @@
             }
 
             Package build() {
-                final String apkPath = String.format("%s/%s/base.apk",
-                        targetPackage == null ? "/system/app/:" : "/vendor/overlay/:",
-                        packageName);
+                String path = "";
+                if (TextUtils.isEmpty(partition)) {
+                    if (targetPackage == null) {
+                        path = "/system/app";
+                    } else {
+                        path = "/vendor/overlay";
+                    }
+                } else {
+                    String type = targetPackage == null ? "app" : "overlay";
+                    path = String.format("%s/%s", partition, type);
+                }
+
+                final String apkPath = String.format("%s/%s/base.apk", path, packageName);
                 final Package newPackage = new Package(packageName, targetPackage,
                         targetOverlayableName, version, apkPath, certificate);
                 newPackage.overlayableNames.addAll(overlayableNames);
@@ -302,8 +333,7 @@
         }
     }
 
-    static final class DummyPackageManagerHelper implements PackageManagerHelper,
-            OverlayableInfoCallback {
+    final class DummyPackageManagerHelper implements PackageManagerHelper {
         private final DummyDeviceState mState;
 
         private DummyPackageManagerHelper(DummyDeviceState state) {
@@ -343,6 +373,11 @@
                     .collect(Collectors.toList());
         }
 
+        @Override
+        public @NonNull String getConfigSignaturePackage() {
+            return mConfigSignaturePackageName;
+        }
+
         @Nullable
         @Override
         public OverlayableInfo getOverlayableForTarget(@NonNull String packageName,
diff --git a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
index 2d9c6ce..f991dff 100644
--- a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
@@ -19,7 +19,6 @@
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.contains;
-import static org.hamcrest.Matchers.empty;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
@@ -70,8 +69,6 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.function.IntFunction;
-import java.util.stream.Collectors;
 
 @Presubmit
 @RunWith(JUnit4.class)
@@ -805,24 +802,24 @@
                 queriesProviderAppId);
 
         final SparseArray<int[]> systemFilter =
-                appsFilter.getVisibilityWhitelist(system, USER_ARRAY, mExisting);
+                appsFilter.getVisibilityAllowList(system, USER_ARRAY, mExisting);
         assertThat(toList(systemFilter.get(SYSTEM_USER)),
                 contains(seesNothingAppId, hasProviderAppId, queriesProviderAppId));
 
         final SparseArray<int[]> seesNothingFilter =
-                appsFilter.getVisibilityWhitelist(seesNothing, USER_ARRAY, mExisting);
+                appsFilter.getVisibilityAllowList(seesNothing, USER_ARRAY, mExisting);
         assertThat(toList(seesNothingFilter.get(SYSTEM_USER)),
                 contains(seesNothingAppId));
         assertThat(toList(seesNothingFilter.get(SECONDARY_USER)),
                 contains(seesNothingAppId));
 
         final SparseArray<int[]> hasProviderFilter =
-                appsFilter.getVisibilityWhitelist(hasProvider, USER_ARRAY, mExisting);
+                appsFilter.getVisibilityAllowList(hasProvider, USER_ARRAY, mExisting);
         assertThat(toList(hasProviderFilter.get(SYSTEM_USER)),
                 contains(hasProviderAppId, queriesProviderAppId));
 
         SparseArray<int[]> queriesProviderFilter =
-                appsFilter.getVisibilityWhitelist(queriesProvider, USER_ARRAY, mExisting);
+                appsFilter.getVisibilityAllowList(queriesProvider, USER_ARRAY, mExisting);
         assertThat(toList(queriesProviderFilter.get(SYSTEM_USER)),
                 contains(queriesProviderAppId));
 
@@ -831,7 +828,7 @@
 
         // ensure implicit access is included in the filter
         queriesProviderFilter =
-                appsFilter.getVisibilityWhitelist(queriesProvider, USER_ARRAY, mExisting);
+                appsFilter.getVisibilityAllowList(queriesProvider, USER_ARRAY, mExisting);
         assertThat(toList(queriesProviderFilter.get(SYSTEM_USER)),
                 contains(hasProviderAppId, queriesProviderAppId));
     }
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 70006b4..980772b 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -166,6 +166,7 @@
 import com.android.server.DeviceIdleInternal;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.UiServiceTestCase;
 import com.android.server.lights.LightsManager;
 import com.android.server.lights.LogicalLight;
@@ -6454,7 +6455,7 @@
     public void testOnUnlockUser() {
         UserInfo ui = new UserInfo();
         ui.id = 10;
-        mService.onUnlockUser(ui);
+        mService.onUserUnlocking(new TargetUser(ui));
         waitForIdle();
 
         verify(mHistoryManager, timeout(MAX_POST_DELAY).times(1)).onUserUnlocked(ui.id);
@@ -6464,7 +6465,7 @@
     public void testOnStopUser() {
         UserInfo ui = new UserInfo();
         ui.id = 10;
-        mService.onStopUser(ui);
+        mService.onUserStopping(new TargetUser(ui));
         waitForIdle();
 
         verify(mHistoryManager, timeout(MAX_POST_DELAY).times(1)).onUserStopped(ui.id);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index e45ced6..2f02073 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -1327,12 +1327,15 @@
     public void testRemoveFromHistory() {
         final Task stack = mActivity.getRootTask();
         final Task task = mActivity.getTask();
+        final WindowProcessController wpc = mActivity.app;
+        assertTrue(wpc.hasActivities());
 
         mActivity.removeFromHistory("test");
 
         assertEquals(DESTROYED, mActivity.getState());
         assertNull(mActivity.app);
         assertNull(mActivity.getTask());
+        assertFalse(wpc.hasActivities());
         assertEquals(0, task.getChildCount());
         assertEquals(task.getRootTask(), task);
         assertEquals(0, stack.getChildCount());
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
index 775df74..dfdf686 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
@@ -1072,7 +1072,7 @@
 
         assertEquals(2, mTask.getChildCount());
 
-        mRootWindowContainer.handleAppDied(secondActivity.app);
+        secondActivity.app.handleAppDied();
 
         assertFalse(mTask.hasChild());
         assertFalse(mStack.hasChild());
@@ -1086,7 +1086,7 @@
         activity.launchCount = 1;
         activity.setSavedState(null /* savedState */);
 
-        mRootWindowContainer.handleAppDied(activity.app);
+        activity.app.handleAppDied();
 
         assertEquals(1, mTask.getChildCount());
         assertEquals(1, mStack.getChildCount());
@@ -1100,7 +1100,7 @@
         activity.launchCount = 3;
         activity.setSavedState(null /* savedState */);
 
-        mRootWindowContainer.handleAppDied(activity.app);
+        activity.app.handleAppDied();
 
         assertFalse(mTask.hasChild());
         assertFalse(mStack.hasChild());
@@ -1114,7 +1114,7 @@
         activity.launchCount = 1;
         activity.setSavedState(null /* savedState */);
 
-        mRootWindowContainer.handleAppDied(activity.app);
+        activity.app.handleAppDied();
 
         assertEquals(1, mTask.getChildCount());
         assertEquals(1, mStack.getChildCount());
@@ -1128,7 +1128,7 @@
         activity.launchCount = 3;
         activity.setSavedState(null /* savedState */);
 
-        mRootWindowContainer.handleAppDied(activity.app);
+        activity.app.handleAppDied();
 
         assertFalse(mTask.hasChild());
         assertFalse(mStack.hasChild());
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 2e4c9ea..d9d07d9b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -175,23 +175,30 @@
     @Test
     public void testForceStopPackage() {
         final Task task = new ActivityTestsBase.StackBuilder(mWm.mRoot).build();
-        final ActivityRecord activity1 = task.getTopMostActivity();
-        final ActivityRecord activity2 =
-                new ActivityTestsBase.ActivityBuilder(mWm.mAtmService).setStack(task).build();
-        final WindowProcessController wpc = activity1.app;
+        final ActivityRecord activity = task.getTopMostActivity();
+        final WindowProcessController wpc = activity.app;
+        final ActivityRecord[] activities = {
+                activity,
+                new ActivityTestsBase.ActivityBuilder(mWm.mAtmService)
+                        .setStack(task).setUseProcess(wpc).build(),
+                new ActivityTestsBase.ActivityBuilder(mWm.mAtmService)
+                        .setStack(task).setUseProcess(wpc).build()
+        };
+        activities[0].detachFromProcess();
+        activities[1].finishing = true;
+        activities[1].destroyImmediately(true /* removeFromApp */, "test");
         spyOn(wpc);
-        activity1.app = null;
-        activity2.setProcess(wpc);
         doReturn(true).when(wpc).isRemoved();
 
         mWm.mAtmService.mInternal.onForceStopPackage(wpc.mInfo.packageName, true /* doit */,
                 false /* evenPersistent */, wpc.mUserId);
         // The activity without process should be removed.
-        assertEquals(1, task.getChildCount());
+        assertEquals(2, task.getChildCount());
 
-        mWm.mRoot.handleAppDied(wpc);
-        // The activity with process should be removed because WindowProcessController#isRemoved.
+        wpc.handleAppDied();
+        // The activities with process should be removed because WindowProcessController#isRemoved.
         assertFalse(task.hasChild());
+        assertFalse(wpc.hasActivities());
     }
 }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
index e8a4e90..75ed928 100644
--- a/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
@@ -79,6 +79,16 @@
     }
 
     @Test
+    public void testRemoveFinishingInvisibleActivityFromUnknown() {
+        final ActivityRecord activity = WindowTestUtils.createTestActivityRecord(mDisplayContent);
+        mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(activity);
+        activity.finishing = true;
+        activity.mVisibleRequested = true;
+        activity.setVisibility(false, false);
+        assertTrue(mDisplayContent.mUnknownAppVisibilityController.allResolved());
+    }
+
+    @Test
     public void testAppRemoved() {
         final ActivityRecord activity = WindowTestUtils.createTestActivityRecord(mDisplayContent);
         mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(activity);
diff --git a/services/usage/java/com/android/server/usage/AppTimeLimitController.java b/services/usage/java/com/android/server/usage/AppTimeLimitController.java
index 6861ad1..4986d18 100644
--- a/services/usage/java/com/android/server/usage/AppTimeLimitController.java
+++ b/services/usage/java/com/android/server/usage/AppTimeLimitController.java
@@ -307,7 +307,7 @@
                 }
             } else {
                 if (mActives > mObserved.length) {
-                    // Try to get to a sane state and log the issue
+                    // Try to get to a valid state and log the issue
                     mActives = mObserved.length;
                     final UserData user = mUserRef.get();
                     if (user == null) return;
@@ -334,7 +334,7 @@
                 cancelCheckTimeoutLocked(this);
             } else {
                 if (mActives < 0) {
-                    // Try to get to a sane state and log the issue
+                    // Try to get to a valid state and log the issue
                     mActives = 0;
                     final UserData user = mUserRef.get();
                     if (user == null) return;
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 9b18ec6..2fd6c42 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -92,6 +92,7 @@
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;
 
 import java.io.BufferedReader;
@@ -291,27 +292,26 @@
     }
 
     @Override
-    public void onStartUser(UserInfo userInfo) {
+    public void onUserStarting(@NonNull TargetUser user) {
         // Create an entry in the user state map to indicate that the user has been started but
         // not necessarily unlocked. This will ensure that reported events are flushed to disk
         // event if the user is never unlocked (following the logic in #flushToDiskLocked)
-        mUserState.put(userInfo.id, null);
-        super.onStartUser(userInfo);
+        mUserState.put(user.getUserIdentifier(), null);
     }
 
     @Override
-    public void onUnlockUser(@NonNull UserInfo userInfo) {
-        mHandler.obtainMessage(MSG_UNLOCKED_USER, userInfo.id, 0).sendToTarget();
-        super.onUnlockUser(userInfo);
+    public void onUserUnlocking(@NonNull TargetUser user) {
+        mHandler.obtainMessage(MSG_UNLOCKED_USER, user.getUserIdentifier(), 0).sendToTarget();
     }
 
     @Override
-    public void onStopUser(@NonNull UserInfo userInfo) {
+    public void onUserStopping(@NonNull TargetUser user) {
+        final UserInfo userInfo = user.getUserInfo();
+
         synchronized (mLock) {
             // User was started but never unlocked so no need to report a user stopped event
             if (!mUserUnlockedStates.get(userInfo.id)) {
                 persistPendingEventsLocked(userInfo.id);
-                super.onStopUser(userInfo);
                 return;
             }
 
@@ -326,7 +326,6 @@
             mUserUnlockedStates.put(userInfo.id, false);
             mUserState.put(userInfo.id, null); // release the service (mainly for GC)
         }
-        super.onStopUser(userInfo);
     }
 
     private void onUserUnlocked(int userId) {
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
index 534fe03..ee564a9 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
@@ -221,14 +221,6 @@
         }
     }
 
-    @Override
-    public void onStartUser(int userHandle) {
-    }
-
-    @Override
-    public void onSwitchUser(int userHandle) {
-    }
-
     private synchronized void initSoundTriggerHelper() {
         if (mSoundTriggerHelper == null) {
             mSoundTriggerHelper = new SoundTriggerHelper(mContext);
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 9621f68..0f898f8 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -189,10 +189,10 @@
     }
 
     @Override
-    public void onSwitchUser(@NonNull UserInfo from, @NonNull UserInfo to) {
+    public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
         if (DEBUG_USER) Slog.d(TAG, "onSwitchUser(" + from + " > " + to + ")");
 
-        mServiceStub.switchUser(to.id);
+        mServiceStub.switchUser(to.getUserIdentifier());
     }
 
     class LocalService extends VoiceInteractionManagerInternal {
diff --git a/tests/BootImageProfileTest/OWNERS b/tests/BootImageProfileTest/OWNERS
index 657b3f2..7ee0d9a 100644
--- a/tests/BootImageProfileTest/OWNERS
+++ b/tests/BootImageProfileTest/OWNERS
@@ -1,4 +1,4 @@
-mathieuc@google.com
 calin@google.com
+mathieuc@google.com
+ngeoffray@google.com
 yawanng@google.com
-sehr@google.com
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.kt
index eaf4d87..abe7dbc 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.kt
@@ -92,7 +92,7 @@
         app2: IAppHelper?,
         extraInfo: String
     ): String {
-        var testTag = "${testName}__$${app.launcherName}"
+        var testTag = "${testName}__${app.launcherName}"
         if (app2 != null) {
             testTag += "-${app2.launcherName}"
         }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
index 31d1fd3..2e4d390 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
@@ -81,11 +81,11 @@
                 }
 
                 layersTrace {
-                    navBarLayerIsAlwaysVisible()
-                    statusBarLayerIsAlwaysVisible()
-                    noUncoveredRegions(rotation)
-                    navBarLayerRotatesAndScales(rotation)
-                    statusBarLayerRotatesScales(rotation)
+                    navBarLayerIsAlwaysVisible(bugId = 140855415)
+                    statusBarLayerIsAlwaysVisible(bugId = 140855415)
+                    noUncoveredRegions(rotation, Surface.ROTATION_0, allStates = false)
+                    navBarLayerRotatesAndScales(rotation, Surface.ROTATION_0)
+                    statusBarLayerRotatesScales(rotation, Surface.ROTATION_0)
                     imeLayerBecomesInvisible(bugId = 141458352)
                     imeAppLayerBecomesInvisible(testApp, bugId = 153739621)
                 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
index b643ec2..1c0da4f 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
@@ -89,9 +89,9 @@
                 }
 
                 layersTrace {
-                    navBarLayerIsAlwaysVisible()
-                    statusBarLayerIsAlwaysVisible()
-                    noUncoveredRegions(rotation)
+                    navBarLayerIsAlwaysVisible(bugId = 140855415)
+                    statusBarLayerIsAlwaysVisible(bugId = 140855415)
+                    noUncoveredRegions(rotation, Surface.ROTATION_0, allStates = false)
                     navBarLayerRotatesAndScales(rotation, Surface.ROTATION_0)
                     statusBarLayerRotatesScales(rotation, Surface.ROTATION_0)
                     imeLayerBecomesInvisible(bugId = 153739621)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
index af751dc..62337e9 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
@@ -71,18 +71,18 @@
                 windowManagerTrace {
                     navBarWindowIsAlwaysVisible()
                     statusBarWindowIsAlwaysVisible()
-                    appWindowReplacesLauncherAsTopWindow(bugId = 141361128)
+                    appWindowReplacesLauncherAsTopWindow()
                     wallpaperWindowBecomesInvisible()
                 }
 
                 layersTrace {
-                    noUncoveredRegions(rotation, bugId = 141361128)
                     // During testing the launcher is always in portrait mode
+                    noUncoveredRegions(Surface.ROTATION_0, rotation, bugId = 141361128)
                     navBarLayerRotatesAndScales(Surface.ROTATION_0, rotation)
                     statusBarLayerRotatesScales(Surface.ROTATION_0, rotation)
-                    navBarLayerIsAlwaysVisible(bugId = 141361128)
-                    statusBarLayerIsAlwaysVisible(bugId = 141361128)
-                    wallpaperLayerBecomesInvisible(bugId = 141361128)
+                    navBarLayerIsAlwaysVisible()
+                    statusBarLayerIsAlwaysVisible(enabled = false)
+                    wallpaperLayerBecomesInvisible()
                 }
 
                 eventLog {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTestBase.kt
index 3cec077..7d70812 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTestBase.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTestBase.kt
@@ -44,10 +44,9 @@
         enabled: Boolean = bugId == 0
     ) {
         all("appWindowReplacesLauncherAsTopWindow", enabled, bugId) {
-            this.showsAppWindowOnTop(
-                    "Launcher")
+            this.showsAppWindowOnTop("Launcher")
                     .then()
-                    .showsAppWindowOnTop(testApp.getPackage())
+                    .showsAppWindowOnTop("Snapshot", testApp.getPackage())
         }
     }
 
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
index d359574..9a8e37b 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
@@ -79,18 +79,18 @@
                 windowManagerTrace {
                     navBarWindowIsAlwaysVisible()
                     statusBarWindowIsAlwaysVisible()
-                    appWindowReplacesLauncherAsTopWindow(bugId = 141361128)
+                    appWindowReplacesLauncherAsTopWindow()
                     wallpaperWindowBecomesInvisible(enabled = false)
                 }
 
                 layersTrace {
-                    noUncoveredRegions(rotation, bugId = 141361128)
                     // During testing the launcher is always in portrait mode
+                    noUncoveredRegions(Surface.ROTATION_0, rotation, bugId = 141361128)
                     navBarLayerRotatesAndScales(Surface.ROTATION_0, rotation)
                     statusBarLayerRotatesScales(Surface.ROTATION_0, rotation)
-                    navBarLayerIsAlwaysVisible(bugId = 141361128)
-                    statusBarLayerIsAlwaysVisible(bugId = 141361128)
-                    wallpaperLayerBecomesInvisible(bugId = 141361128)
+                    navBarLayerIsAlwaysVisible()
+                    statusBarLayerIsAlwaysVisible(enabled = false)
+                    wallpaperLayerBecomesInvisible()
                 }
 
                 eventLog {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/EnterPipTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/EnterPipTest.kt
new file mode 100644
index 0000000..4acd975
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/EnterPipTest.kt
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2020 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.wm.flicker.pip
+
+import android.view.Surface
+import androidx.test.filters.FlakyTest
+import androidx.test.filters.LargeTest
+import com.android.server.wm.flicker.dsl.flicker
+import com.android.server.wm.flicker.helpers.closePipWindow
+import com.android.server.wm.flicker.helpers.expandPipWindow
+import com.android.server.wm.flicker.helpers.hasPipWindow
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test Pip launch.
+ * To run this test: `atest FlickerTests:PipToAppTest`
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@FlakyTest(bugId = 152738416)
+class EnterPipTest(
+    rotationName: String,
+    rotation: Int
+) : PipTestBase(rotationName, rotation) {
+    @Test
+    fun test() {
+        flicker(instrumentation) {
+            withTag { buildTestTag("enterPip", testApp, rotation) }
+            repeat { 1 }
+            setup {
+                test {
+                    device.wakeUpAndGoToHomeScreen()
+                }
+                eachRun {
+                    device.pressHome()
+                    testApp.open()
+                    this.setRotation(rotation)
+                }
+            }
+            teardown {
+                eachRun {
+                    if (device.hasPipWindow()) {
+                        device.closePipWindow()
+                    }
+                    testApp.exit()
+                    this.setRotation(Surface.ROTATION_0)
+                }
+                test {
+                    if (device.hasPipWindow()) {
+                        device.closePipWindow()
+                    }
+                }
+            }
+            transitions {
+                testApp.clickEnterPipButton(device)
+                device.expandPipWindow()
+            }
+            assertions {
+                windowManagerTrace {
+                    navBarWindowIsAlwaysVisible()
+                    statusBarWindowIsAlwaysVisible()
+                    all("pipWindowBecomesVisible") {
+                        this.showsAppWindow(testApp.`package`)
+                                .then()
+                                .showsAppWindow(sPipWindowTitle)
+                    }
+                }
+
+                layersTrace {
+                    navBarLayerIsAlwaysVisible()
+                    statusBarLayerIsAlwaysVisible()
+                    noUncoveredRegions(rotation, Surface.ROTATION_0, allStates = false)
+                    navBarLayerRotatesAndScales(rotation, Surface.ROTATION_0)
+                    statusBarLayerRotatesScales(rotation, Surface.ROTATION_0)
+
+                    all("pipLayerBecomesVisible") {
+                        this.showsLayer(testApp.launcherName)
+                                .then()
+                                .showsLayer(sPipWindowTitle)
+                    }
+                }
+            }
+        }
+    }
+
+    companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): Collection<Array<Any>> {
+            val supportedRotations = intArrayOf(Surface.ROTATION_0)
+            return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) }
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipTestBase.kt
index 4afabd4..691db7fb 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipTestBase.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipTestBase.kt
@@ -16,9 +16,7 @@
 
 package com.android.server.wm.flicker.pip
 
-import com.android.server.wm.flicker.dsl.LayersAssertion
 import com.android.server.wm.flicker.NonRotationTestBase
-import com.android.server.wm.flicker.dsl.WmAssertion
 import com.android.server.wm.flicker.helpers.PipAppHelper
 
 abstract class PipTestBase(
@@ -27,24 +25,6 @@
 ) : NonRotationTestBase(rotationName, rotation) {
     protected val testApp = PipAppHelper(instrumentation)
 
-    protected fun WmAssertion.pipWindowBecomesVisible() {
-        all("pipWindowBecomesVisible") {
-            this.skipUntilFirstAssertion()
-                    .showsAppWindowOnTop(sPipWindowTitle)
-                    .then()
-                    .hidesAppWindow(sPipWindowTitle)
-        }
-    }
-
-    protected fun LayersAssertion.pipLayerBecomesVisible() {
-        all("pipLayerBecomesVisible") {
-            this.skipUntilFirstAssertion()
-                    .showsLayer(sPipWindowTitle)
-                    .then()
-                    .hidesLayer(sPipWindowTitle)
-        }
-    }
-
     companion object {
         const val sPipWindowTitle = "PipMenuActivity"
     }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToAppTest.kt
index c8a0e7d..04c2f59 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToAppTest.kt
@@ -56,35 +56,42 @@
             withTag { buildTestTag("exitPipModeToApp", testApp, rotation) }
             repeat { 1 }
             setup {
-                eachRun {
+                test {
                     device.wakeUpAndGoToHomeScreen()
+                    device.pressHome()
+                    testApp.open()
+                }
+                eachRun {
+                    this.setRotation(rotation)
+                    testApp.clickEnterPipButton(device)
+                    device.hasPipWindow()
                 }
             }
             teardown {
                 eachRun {
-                    testApp.exit()
                     this.setRotation(Surface.ROTATION_0)
                 }
                 test {
                     if (device.hasPipWindow()) {
                         device.closePipWindow()
                     }
+                    testApp.exit()
                 }
             }
             transitions {
-                device.pressHome()
-                this.setRotation(rotation)
-                testApp.open()
-                testApp.clickEnterPipButton(device)
                 device.expandPipWindow()
                 device.waitForIdle()
-                testApp.exit()
             }
             assertions {
                 windowManagerTrace {
                     navBarWindowIsAlwaysVisible()
                     statusBarWindowIsAlwaysVisible()
-                    pipWindowBecomesVisible()
+
+                    all("appReplacesPipWindow") {
+                        this.showsAppWindow(sPipWindowTitle)
+                                .then()
+                                .showsAppWindowOnTop(testApp.launcherName)
+                    }
                 }
 
                 layersTrace {
@@ -93,7 +100,12 @@
                     noUncoveredRegions(rotation)
                     navBarLayerRotatesAndScales(rotation)
                     statusBarLayerRotatesScales(rotation)
-                    pipLayerBecomesVisible()
+
+                    all("appReplacesPipLayer") {
+                        this.showsLayer(sPipWindowTitle)
+                                .then()
+                                .showsLayer(testApp.launcherName)
+                    }
                 }
 
                 eventLog {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToHomeTest.kt
index 7e9880c..b6074cd 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToHomeTest.kt
@@ -55,52 +55,59 @@
             withTag { buildTestTag("exitPipModeToApp", testApp, rotation) }
             repeat { 1 }
             setup {
-                eachRun {
+                test {
                     device.wakeUpAndGoToHomeScreen()
                     device.pressHome()
-                    this.setRotation(rotation)
+                }
+                eachRun {
                     testApp.open()
+                    this.setRotation(rotation)
+                    testApp.clickEnterPipButton(device)
+                    device.hasPipWindow()
                 }
             }
             teardown {
                 eachRun {
-                    testApp.exit()
                     this.setRotation(Surface.ROTATION_0)
+                    if (device.hasPipWindow()) {
+                        device.closePipWindow()
+                    }
                 }
                 test {
                     if (device.hasPipWindow()) {
                         device.closePipWindow()
                     }
+                    testApp.exit()
                 }
             }
             transitions {
-                testApp.clickEnterPipButton(device)
                 testApp.closePipWindow(device)
-                device.waitForIdle()
-                testApp.exit()
             }
             assertions {
                 windowManagerTrace {
                     navBarWindowIsAlwaysVisible()
                     statusBarWindowIsAlwaysVisible()
-                    pipWindowBecomesVisible()
 
-                    all {
-                        this.showsAppWindowOnTop(sPipWindowTitle)
-                                .and()
-                                .showsBelowAppWindow("Wallpaper")
+                    all("pipWindowBecomesInvisible") {
+                        this.showsAppWindow(sPipWindowTitle)
                                 .then()
-                                .showsAboveAppWindow("Wallpaper")
+                                .hidesAppWindow(sPipWindowTitle)
                     }
                 }
 
                 layersTrace {
                     navBarLayerIsAlwaysVisible()
                     statusBarLayerIsAlwaysVisible()
-                    noUncoveredRegions(rotation)
+                    // The final state is the launcher, so always in portrait mode
+                    noUncoveredRegions(rotation, Surface.ROTATION_0, allStates = false)
                     navBarLayerRotatesAndScales(rotation)
                     statusBarLayerRotatesScales(rotation)
-                    pipLayerBecomesVisible()
+
+                    all("pipLayerBecomesInvisible") {
+                        this.showsLayer(sPipWindowTitle)
+                                .then()
+                                .hidesLayer(sPipWindowTitle)
+                    }
                 }
 
                 eventLog {
@@ -109,4 +116,13 @@
             }
         }
     }
+
+    companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): Collection<Array<Any>> {
+            val supportedRotations = intArrayOf(Surface.ROTATION_0)
+            return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) }
+        }
+    }
 }
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
index a7aae8c..5e75e4a 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
@@ -62,25 +62,29 @@
             }
             repeat { 1 }
             setup {
-                eachRun {
+                test {
                     device.wakeUpAndGoToHomeScreen()
                     testApp.open()
+                }
+                eachRun {
                     this.setRotation(beginRotation)
                 }
             }
             teardown {
                 eachRun {
-                    testApp.exit()
                     this.setRotation(Surface.ROTATION_0)
                 }
+                test {
+                    testApp.exit()
+                }
             }
             transitions {
                 this.setRotation(endRotation)
             }
             assertions {
                 windowManagerTrace {
-                    navBarWindowIsAlwaysVisible(bugId = 140855415)
-                    statusBarWindowIsAlwaysVisible(bugId = 140855415)
+                    navBarWindowIsAlwaysVisible()
+                    statusBarWindowIsAlwaysVisible()
                 }
 
                 layersTrace {
@@ -103,21 +107,12 @@
                         this.hasVisibleRegion(testApp.getPackage(), endingPos)
                     }
 
-                    all("screenshotLayerBecomesInvisible", enabled = false) {
+                    all("screenshotLayerBecomesInvisible") {
                         this.showsLayer(testApp.getPackage())
                                 .then()
-                                .replaceVisibleLayer(
-                                        testApp.getPackage(),
-                                        SCREENSHOT_LAYER)
-                                .then()
-                                .showsLayer(testApp.getPackage())
-                                .and()
                                 .showsLayer(SCREENSHOT_LAYER)
                                 .then()
-                                .replaceVisibleLayer(
-                                        SCREENSHOT_LAYER,
-                                        testApp.getPackage()
-                                )
+                                showsLayer(testApp.getPackage())
                     }
                 }
 
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt
index a4ec3b1..e078f26 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt
@@ -16,7 +16,6 @@
 
 package com.android.server.wm.flicker.splitscreen
 
-import android.os.SystemClock
 import android.view.Surface
 import androidx.test.filters.LargeTest
 import com.android.server.wm.flicker.NonRotationTestBase
@@ -24,6 +23,7 @@
 import com.android.server.wm.flicker.dsl.flicker
 import com.android.server.wm.flicker.focusChanges
 import com.android.server.wm.flicker.helpers.exitSplitScreen
+import com.android.server.wm.flicker.helpers.isInSplitScreen
 import com.android.server.wm.flicker.helpers.launchSplitScreen
 import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
 import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
@@ -59,16 +59,21 @@
             withTag { buildTestTag("appToSplitScreen", testApp, rotation) }
             repeat { 1 }
             setup {
-                eachRun {
+                test {
                     device.wakeUpAndGoToHomeScreen()
-                    this.setRotation(rotation)
+                }
+                eachRun {
                     testApp.open()
-                    SystemClock.sleep(500)
+                    this.setRotation(rotation)
                 }
             }
             teardown {
                 eachRun {
-                    device.exitSplitScreen()
+                    if (device.isInSplitScreen()) {
+                        device.exitSplitScreen()
+                    }
+                }
+                test {
                     testApp.exit()
                 }
             }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt
index 3ae3967..e2d7839 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt
@@ -17,9 +17,8 @@
 package com.android.server.wm.flicker.splitscreen
 
 import android.view.Surface
-import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
-import com.android.server.wm.flicker.FlickerTestBase
+import com.android.server.wm.flicker.NonRotationTestBase
 import com.android.server.wm.flicker.StandardAppHelper
 import com.android.server.wm.flicker.dsl.flicker
 import com.android.server.wm.flicker.focusDoesNotChange
@@ -38,16 +37,19 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
 
 /**
  * Test open app to split screen.
  * To run this test: `atest FlickerTests:SplitScreenToLauncherTest`
  */
 @LargeTest
-@RunWith(AndroidJUnit4::class)
+@RunWith(Parameterized::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class SplitScreenToLauncherTest : FlickerTestBase() {
-    private val rotation: Int = Surface.ROTATION_0
+class SplitScreenToLauncherTest(
+    rotationName: String,
+    rotation: Int
+) : NonRotationTestBase(rotationName, rotation) {
     @Test
     fun test() {
         val testApp = StandardAppHelper(instrumentation,
@@ -57,8 +59,10 @@
             withTag { buildTestTag("splitScreenToLauncher", testApp, rotation) }
             repeat { 1 }
             setup {
-                eachRun {
+                test {
                     device.wakeUpAndGoToHomeScreen()
+                }
+                eachRun {
                     testApp.open()
                     this.setRotation(rotation)
                     device.launchSplitScreen()
@@ -111,4 +115,14 @@
             }
         }
     }
+
+    companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): Collection<Array<Any>> {
+            // b/161435597 causes the test not to work on 90 degrees
+            val supportedRotations = intArrayOf(Surface.ROTATION_0)
+            return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) }
+        }
+    }
 }
diff --git a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
index eb0a867..a384687 100644
--- a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
@@ -28,6 +28,7 @@
 import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_VENDOR;
 import static android.content.pm.PackageManager.GET_PERMISSIONS;
 import static android.content.pm.PackageManager.MATCH_ANY_USER;
+import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
 import static android.os.Process.SYSTEM_UID;
 
 import static com.android.server.connectivity.PermissionMonitor.NETWORK;
@@ -138,17 +139,10 @@
         verify(mMockPmi).getPackageList(mPermissionMonitor);
     }
 
-    /**
-     * Remove all permissions from the uid then build new package info and setup permissions to uid
-     * for checking restricted network permission.
-     */
-    private boolean hasRestrictedNetworkPermission(String partition, int targetSdkVersion, int uid,
-            String... permissions) {
+    private boolean wouldBeCarryoverPackage(String partition, int targetSdkVersion, int uid) {
         final PackageInfo packageInfo = buildPackageInfo(partition, uid, MOCK_USER1);
         packageInfo.applicationInfo.targetSdkVersion = targetSdkVersion;
-        removeAllPermissions(uid);
-        addPermissions(uid, permissions);
-        return mPermissionMonitor.hasRestrictedNetworkPermission(packageInfo.applicationInfo);
+        return mPermissionMonitor.isCarryoverPackage(packageInfo.applicationInfo);
     }
 
     private static PackageInfo packageInfoWithPartition(String partition) {
@@ -228,61 +222,57 @@
         assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo));
     }
 
+    /**
+     * Remove all permissions from the uid then setup permissions to uid for checking restricted
+     * network permission.
+     */
+    private void assertRestrictedNetworkPermission(boolean hasPermission, int uid,
+            String... permissions) {
+        removeAllPermissions(uid);
+        addPermissions(uid, permissions);
+        assertEquals(hasPermission, mPermissionMonitor.hasRestrictedNetworkPermission(uid));
+    }
+
     @Test
     public void testHasRestrictedNetworkPermission() {
-        assertFalse(hasRestrictedNetworkPermission(PARTITION_SYSTEM, VERSION_P, MOCK_UID1));
-        assertFalse(hasRestrictedNetworkPermission(
-                PARTITION_SYSTEM, VERSION_P, MOCK_UID1, CHANGE_NETWORK_STATE));
-        assertTrue(hasRestrictedNetworkPermission(
-                PARTITION_SYSTEM, VERSION_P, MOCK_UID1, NETWORK_STACK));
-        assertFalse(hasRestrictedNetworkPermission(
-                PARTITION_SYSTEM, VERSION_P, MOCK_UID1, CONNECTIVITY_INTERNAL));
-        assertTrue(hasRestrictedNetworkPermission(
-                PARTITION_SYSTEM, VERSION_P, MOCK_UID1, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
-        assertFalse(hasRestrictedNetworkPermission(
-                PARTITION_SYSTEM, VERSION_P, MOCK_UID1, CHANGE_WIFI_STATE));
+        assertRestrictedNetworkPermission(false, MOCK_UID1);
+        assertRestrictedNetworkPermission(false, MOCK_UID1, CHANGE_NETWORK_STATE);
+        assertRestrictedNetworkPermission(true, MOCK_UID1, NETWORK_STACK);
+        assertRestrictedNetworkPermission(false, MOCK_UID1, CONNECTIVITY_INTERNAL);
+        assertRestrictedNetworkPermission(true, MOCK_UID1, CONNECTIVITY_USE_RESTRICTED_NETWORKS);
+        assertRestrictedNetworkPermission(false, MOCK_UID1, CHANGE_WIFI_STATE);
+        assertRestrictedNetworkPermission(true, MOCK_UID1, PERMISSION_MAINLINE_NETWORK_STACK);
 
-        assertFalse(hasRestrictedNetworkPermission(PARTITION_SYSTEM, VERSION_Q, MOCK_UID1));
-        assertFalse(hasRestrictedNetworkPermission(
-                PARTITION_SYSTEM, VERSION_Q, MOCK_UID1, CONNECTIVITY_INTERNAL));
+        assertFalse(mPermissionMonitor.hasRestrictedNetworkPermission(MOCK_UID2));
+        assertFalse(mPermissionMonitor.hasRestrictedNetworkPermission(SYSTEM_UID));
     }
 
     @Test
-    public void testHasRestrictedNetworkPermissionSystemUid() {
+    public void testIsCarryoverPackage() {
         doReturn(VERSION_P).when(mDeps).getDeviceFirstSdkInt();
-        assertTrue(hasRestrictedNetworkPermission(PARTITION_SYSTEM, VERSION_P, SYSTEM_UID));
-        assertTrue(hasRestrictedNetworkPermission(
-                PARTITION_SYSTEM, VERSION_P, SYSTEM_UID, CONNECTIVITY_INTERNAL));
-        assertTrue(hasRestrictedNetworkPermission(
-                PARTITION_SYSTEM, VERSION_P, SYSTEM_UID, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
+        assertTrue(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_P, SYSTEM_UID));
+        assertTrue(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_P, SYSTEM_UID));
+        assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_P, MOCK_UID1));
+        assertTrue(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_P, MOCK_UID1));
+        assertTrue(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID));
+        assertTrue(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_Q, SYSTEM_UID));
+        assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_Q, MOCK_UID1));
+        assertFalse(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_Q, MOCK_UID1));
 
         doReturn(VERSION_Q).when(mDeps).getDeviceFirstSdkInt();
-        assertFalse(hasRestrictedNetworkPermission(PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID));
-        assertFalse(hasRestrictedNetworkPermission(
-                PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID, CONNECTIVITY_INTERNAL));
-        assertTrue(hasRestrictedNetworkPermission(
-                PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
-    }
+        assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_P, SYSTEM_UID));
+        assertTrue(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_P, SYSTEM_UID));
+        assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_P, MOCK_UID1));
+        assertTrue(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_P, MOCK_UID1));
+        assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID));
+        assertFalse(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_Q, SYSTEM_UID));
+        assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_Q, MOCK_UID1));
+        assertFalse(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_Q, MOCK_UID1));
 
-    @Test
-    public void testHasRestrictedNetworkPermissionVendorApp() {
-        assertTrue(hasRestrictedNetworkPermission(PARTITION_VENDOR, VERSION_P, MOCK_UID1));
-        assertTrue(hasRestrictedNetworkPermission(
-                PARTITION_VENDOR, VERSION_P, MOCK_UID1, CHANGE_NETWORK_STATE));
-        assertTrue(hasRestrictedNetworkPermission(
-                PARTITION_VENDOR, VERSION_P, MOCK_UID1, NETWORK_STACK));
-        assertTrue(hasRestrictedNetworkPermission(
-                PARTITION_VENDOR, VERSION_P, MOCK_UID1, CONNECTIVITY_INTERNAL));
-        assertTrue(hasRestrictedNetworkPermission(
-                PARTITION_VENDOR, VERSION_P, MOCK_UID1, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
-        assertTrue(hasRestrictedNetworkPermission(
-                PARTITION_VENDOR, VERSION_P, MOCK_UID1, CHANGE_WIFI_STATE));
-
-        assertFalse(hasRestrictedNetworkPermission(PARTITION_VENDOR, VERSION_Q, MOCK_UID1));
-        assertFalse(hasRestrictedNetworkPermission(
-                PARTITION_VENDOR, VERSION_Q, MOCK_UID1, CONNECTIVITY_INTERNAL));
-        assertFalse(hasRestrictedNetworkPermission(
-                PARTITION_VENDOR, VERSION_Q, MOCK_UID1, CHANGE_NETWORK_STATE));
+        assertFalse(wouldBeCarryoverPackage(PARTITION_OEM, VERSION_Q, SYSTEM_UID));
+        assertFalse(wouldBeCarryoverPackage(PARTITION_PRODUCT, VERSION_Q, SYSTEM_UID));
+        assertFalse(wouldBeCarryoverPackage(PARTITION_OEM, VERSION_Q, MOCK_UID1));
+        assertFalse(wouldBeCarryoverPackage(PARTITION_PRODUCT, VERSION_Q, MOCK_UID1));
     }
 
     private void assertBackgroundPermission(boolean hasPermission, String name, int uid,
@@ -296,19 +286,23 @@
 
     @Test
     public void testHasUseBackgroundNetworksPermission() throws Exception {
+        assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID1));
+        assertBackgroundPermission(false, "mock1", MOCK_UID1);
+        assertBackgroundPermission(false, "mock2", MOCK_UID1, CONNECTIVITY_INTERNAL);
+        assertBackgroundPermission(true, "mock3", MOCK_UID1, NETWORK_STACK);
+
+        assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID2));
+        assertBackgroundPermission(false, "mock4", MOCK_UID2);
+        assertBackgroundPermission(true, "mock5", MOCK_UID2,
+                CONNECTIVITY_USE_RESTRICTED_NETWORKS);
+
         doReturn(VERSION_Q).when(mDeps).getDeviceFirstSdkInt();
         assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(SYSTEM_UID));
         assertBackgroundPermission(false, "system1", SYSTEM_UID);
-        assertBackgroundPermission(false, "system2", SYSTEM_UID, CONNECTIVITY_INTERNAL);
-        assertBackgroundPermission(true, "system3", SYSTEM_UID, CHANGE_NETWORK_STATE);
-
-        assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID1));
-        assertBackgroundPermission(false, "mock1", MOCK_UID1);
-        assertBackgroundPermission(true, "mock2", MOCK_UID1, CONNECTIVITY_USE_RESTRICTED_NETWORKS);
-
-        assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID2));
-        assertBackgroundPermission(false, "mock3", MOCK_UID2, CONNECTIVITY_INTERNAL);
-        assertBackgroundPermission(true, "mock4", MOCK_UID2, NETWORK_STACK);
+        assertBackgroundPermission(true, "system2", SYSTEM_UID, CHANGE_NETWORK_STATE);
+        doReturn(VERSION_P).when(mDeps).getDeviceFirstSdkInt();
+        removeAllPermissions(SYSTEM_UID);
+        assertBackgroundPermission(true, "system3", SYSTEM_UID);
     }
 
     private class NetdMonitor {
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 931a14b..3d9be59 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -342,7 +342,7 @@
     }
   }
 
-  // Sanity check to make sure we processed all the nodes.
+  // Validity check to make sure we processed all the nodes.
   CHECK(node_stack.size() == 1u);
   CHECK(node_stack.back() == &root);
 
diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp
index 469128b..7dfc983 100644
--- a/tools/aapt2/ResourceUtils.cpp
+++ b/tools/aapt2/ResourceUtils.cpp
@@ -740,7 +740,7 @@
   if (type == ResourceType::kId) {
     if (res_value.dataType != android::Res_value::TYPE_REFERENCE &&
         res_value.dataType != android::Res_value::TYPE_DYNAMIC_REFERENCE) {
-      // plain "id" resources are actually encoded as dummy values (aapt1 uses an empty string,
+      // plain "id" resources are actually encoded as unused values (aapt1 uses an empty string,
       // while aapt2 uses a false boolean).
       return util::make_unique<Id>();
     }
diff --git a/tools/aapt2/Resources.proto b/tools/aapt2/Resources.proto
index ab9ce66..b1e1a77 100644
--- a/tools/aapt2/Resources.proto
+++ b/tools/aapt2/Resources.proto
@@ -168,6 +168,7 @@
     ODM = 6;
     OEM = 7;
     ACTOR = 8;
+    CONFIG_SIGNATURE = 9;
   }
 
   // The location of the <item> declaration in source.
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index fb7f6d7..f9c54f6 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -1401,7 +1401,7 @@
     return MergeExportedSymbols(compiled_file.source, compiled_file.exported_symbols);
   }
 
-  // Takes a path to load as a ZIP file and merges the files within into the master ResourceTable.
+  // Takes a path to load as a ZIP file and merges the files within into the main ResourceTable.
   // If override is true, conflicting resources are allowed to override each other, in order of last
   // seen.
   // An io::IFileCollection is created from the ZIP file and added to the set of
@@ -1432,7 +1432,7 @@
     return !error;
   }
 
-  // Takes a path to load and merge into the master ResourceTable. If override is true,
+  // Takes a path to load and merge into the main ResourceTable. If override is true,
   // conflicting resources are allowed to override each other, in order of last seen.
   // If the file path ends with .flata, .jar, .jack, or .zip the file is treated
   // as ZIP archive and the files within are merged individually.
@@ -1449,7 +1449,7 @@
     return MergeFile(file, override);
   }
 
-  // Takes an AAPT Container file (.apc/.flat) to load and merge into the master ResourceTable.
+  // Takes an AAPT Container file (.apc/.flat) to load and merge into the main ResourceTable.
   // If override is true, conflicting resources are allowed to override each other, in order of last
   // seen.
   // All other file types are ignored. This is because these files could be coming from a zip,
diff --git a/tools/aapt2/cmd/Optimize.cpp b/tools/aapt2/cmd/Optimize.cpp
index e36668e..5b18a37 100644
--- a/tools/aapt2/cmd/Optimize.cpp
+++ b/tools/aapt2/cmd/Optimize.cpp
@@ -132,8 +132,8 @@
     if (context_->IsVerbose()) {
       context_->GetDiagnostics()->Note(DiagMessage() << "Optimizing APK...");
     }
-    if (!options_.resources_blacklist.empty()) {
-      ResourceFilter filter(options_.resources_blacklist);
+    if (!options_.resources_exclude_list.empty()) {
+      ResourceFilter filter(options_.resources_exclude_list);
       if (!filter.Consume(context_, apk->GetResourceTable())) {
         context_->GetDiagnostics()->Error(DiagMessage() << "failed filtering resources");
         return 1;
@@ -328,7 +328,7 @@
     }
     for (StringPiece directive : util::Tokenize(directives, ',')) {
       if (directive == "remove") {
-        options->resources_blacklist.insert(resource_name.ToResourceName());
+        options->resources_exclude_list.insert(resource_name.ToResourceName());
       } else if (directive == "no_collapse" || directive == "no_obfuscate") {
         options->table_flattener_options.name_collapse_exemptions.insert(
             resource_name.ToResourceName());
diff --git a/tools/aapt2/cmd/Optimize.h b/tools/aapt2/cmd/Optimize.h
index 5070ccc..3afc46b 100644
--- a/tools/aapt2/cmd/Optimize.h
+++ b/tools/aapt2/cmd/Optimize.h
@@ -36,8 +36,8 @@
   // Details of the app extracted from the AndroidManifest.xml
   AppInfo app_info;
 
-  // Blacklist of unused resources that should be removed from the apk.
-  std::unordered_set<ResourceName> resources_blacklist;
+  // Exclude list of unused resources that should be removed from the apk.
+  std::unordered_set<ResourceName> resources_exclude_list;
 
   // Split APK options.
   TableSplitterOptions table_splitter_options;
diff --git a/tools/aapt2/compile/PngChunkFilter.cpp b/tools/aapt2/compile/PngChunkFilter.cpp
index bc2e699..4db2392 100644
--- a/tools/aapt2/compile/PngChunkFilter.cpp
+++ b/tools/aapt2/compile/PngChunkFilter.cpp
@@ -35,7 +35,7 @@
          ((uint32_t)d);
 }
 
-// Whitelist of PNG chunk types that we want to keep in the resulting PNG.
+// Allow list of PNG chunk types that we want to keep in the resulting PNG.
 enum PngChunkTypes {
   kPngChunkIHDR = u32(73, 72, 68, 82),
   kPngChunkIDAT = u32(73, 68, 65, 84),
@@ -56,7 +56,7 @@
   return word;
 }
 
-static bool IsPngChunkWhitelisted(uint32_t type) {
+static bool IsPngChunkAllowed(uint32_t type) {
   switch (type) {
     case kPngChunkIHDR:
     case kPngChunkIDAT:
@@ -128,7 +128,7 @@
 
     // Do we strip this chunk?
     const uint32_t chunk_type = Peek32LE(data_.data() + window_end_ + sizeof(uint32_t));
-    if (IsPngChunkWhitelisted(chunk_type)) {
+    if (IsPngChunkAllowed(chunk_type)) {
       // Advance the window to include this chunk.
       window_end_ += kMinChunkHeaderSize + chunk_len;
 
diff --git a/tools/aapt2/configuration/ConfigurationParser_test.cpp b/tools/aapt2/configuration/ConfigurationParser_test.cpp
index 2ef8b99..e5b3107 100644
--- a/tools/aapt2/configuration/ConfigurationParser_test.cpp
+++ b/tools/aapt2/configuration/ConfigurationParser_test.cpp
@@ -187,7 +187,7 @@
 
 TEST_F(ConfigurationParserTest, ExtractConfiguration) {
   Maybe<PostProcessingConfiguration> maybe_config =
-      ExtractConfiguration(kValidConfig, "dummy.xml", &diag_);
+      ExtractConfiguration(kValidConfig, "fake.xml", &diag_);
 
   PostProcessingConfiguration config = maybe_config.value();
 
diff --git a/tools/aapt2/dump/DumpManifest.cpp b/tools/aapt2/dump/DumpManifest.cpp
index 53d9ffe..71c70da 100644
--- a/tools/aapt2/dump/DumpManifest.cpp
+++ b/tools/aapt2/dump/DumpManifest.cpp
@@ -188,7 +188,7 @@
 
     /** Retrieves the resource assigned to the specified resource id if one exists. */
     Value* FindValueById(const ResourceTable* table, const ResourceId& res_id,
-                         const ConfigDescription& config = DummyConfig()) {
+                         const ConfigDescription& config = DefaultConfig()) {
       if (table) {
         for (auto& package : table->packages) {
           if (package->id && package->id.value() == res_id.package_id()) {
@@ -210,7 +210,7 @@
     }
 
     /** Attempts to resolve the reference to a non-reference value. */
-    Value* ResolveReference(Reference* ref, const ConfigDescription& config = DummyConfig()) {
+    Value* ResolveReference(Reference* ref, const ConfigDescription& config = DefaultConfig()) {
       const int kMaxIterations = 40;
       int i = 0;
       while (ref && ref->id && i++ < kMaxIterations) {
@@ -231,10 +231,10 @@
      * this will attempt to resolve the reference to an integer value.
      **/
     int32_t* GetAttributeInteger(xml::Attribute* attr,
-                                 const ConfigDescription& config = DummyConfig()) {
+                                 const ConfigDescription& config = DefaultConfig()) {
       if (attr != nullptr) {
         if (attr->compiled_value) {
-          // Resolve references using the dummy configuration
+          // Resolve references using the configuration
           Value* value = attr->compiled_value.get();
           if (ValueCast<Reference>(value)) {
             value = ResolveReference(ValueCast<Reference>(value), config);
@@ -257,7 +257,7 @@
      * exist or cannot be resolved to an integer value.
      **/
     int32_t GetAttributeIntegerDefault(xml::Attribute* attr, int32_t def,
-                                       const ConfigDescription& config = DummyConfig()) {
+                                       const ConfigDescription& config = DefaultConfig()) {
       auto value = GetAttributeInteger(attr, config);
       if (value) {
         return *value;
@@ -270,10 +270,10 @@
      * this will attempt to resolve the reference to a string value.
      **/
     const std::string* GetAttributeString(xml::Attribute* attr,
-                                          const ConfigDescription& config = DummyConfig()) {
+                                          const ConfigDescription& config = DefaultConfig()) {
       if (attr != nullptr) {
         if (attr->compiled_value) {
-          // Resolve references using the dummy configuration
+          // Resolve references using the configuration
           Value* value = attr->compiled_value.get();
           if (ValueCast<Reference>(value)) {
             value = ResolveReference(ValueCast<Reference>(value), config);
@@ -305,7 +305,7 @@
      * exist or cannot be resolved to an string value.
      **/
     std::string GetAttributeStringDefault(xml::Attribute* attr, std::string def,
-                                          const ConfigDescription& config = DummyConfig()) {
+                                          const ConfigDescription& config = DefaultConfig()) {
       auto value = GetAttributeString(attr, config);
       if (value) {
         return *value;
@@ -322,7 +322,7 @@
   friend Element;
 
   /** Creates a default configuration used to retrieve resources. */
-  static ConfigDescription DummyConfig() {
+  static ConfigDescription DefaultConfig() {
     ConfigDescription config;
     config.orientation = android::ResTable_config::ORIENTATION_PORT;
     config.density = android::ResTable_config::DENSITY_MEDIUM;
@@ -1871,7 +1871,7 @@
 
             // Collect all the unique locales of the apk
             if (locales_.find(locale_str) == locales_.end()) {
-              ConfigDescription config = ManifestExtractor::DummyConfig();
+              ConfigDescription config = ManifestExtractor::DefaultConfig();
               config.setBcp47Locale(locale_str.data());
               locales_.insert(std::make_pair(locale_str, config));
             }
@@ -1880,7 +1880,7 @@
             uint16_t density = (value->config.density == 0) ? (uint16_t) 160
                                                             : value->config.density;
             if (densities_.find(density) == densities_.end()) {
-              ConfigDescription config = ManifestExtractor::DummyConfig();
+              ConfigDescription config = ManifestExtractor::DefaultConfig();
               config.density = density;
               densities_.insert(std::make_pair(density, config));
             }
diff --git a/tools/aapt2/format/binary/TableFlattener_test.cpp b/tools/aapt2/format/binary/TableFlattener_test.cpp
index 59627ce..6932baf 100644
--- a/tools/aapt2/format/binary/TableFlattener_test.cpp
+++ b/tools/aapt2/format/binary/TableFlattener_test.cpp
@@ -776,6 +776,7 @@
   OverlayableItem overlayable_item_three(group_one);
   overlayable_item_three.policies |= PolicyFlags::SIGNATURE;
   overlayable_item_three.policies |= PolicyFlags::ACTOR_SIGNATURE;
+  overlayable_item_three.policies |= PolicyFlags::CONFIG_SIGNATURE;
 
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
@@ -830,7 +831,8 @@
   EXPECT_EQ(result_overlayable.overlayable->name, "OtherName");
   EXPECT_EQ(result_overlayable.overlayable->actor, "overlay://customization");
   EXPECT_EQ(result_overlayable.policies, PolicyFlags::SIGNATURE
-                                           | PolicyFlags::ACTOR_SIGNATURE);
+                                           | PolicyFlags::ACTOR_SIGNATURE
+                                           | PolicyFlags::CONFIG_SIGNATURE);
 }
 
 TEST_F(TableFlattenerTest, FlattenOverlayableNoPolicyFails) {
diff --git a/tools/aapt2/format/proto/ProtoDeserialize.cpp b/tools/aapt2/format/proto/ProtoDeserialize.cpp
index 582bd39..06ac9e5 100644
--- a/tools/aapt2/format/proto/ProtoDeserialize.cpp
+++ b/tools/aapt2/format/proto/ProtoDeserialize.cpp
@@ -404,6 +404,9 @@
       case pb::OverlayableItem::ACTOR:
         out_overlayable->policies |= PolicyFlags::ACTOR_SIGNATURE;
         break;
+      case pb::OverlayableItem::CONFIG_SIGNATURE:
+        out_overlayable->policies |= PolicyFlags::CONFIG_SIGNATURE;
+        break;
       default:
         *out_error = "unknown overlayable policy";
         return false;
diff --git a/tools/aapt2/format/proto/ProtoSerialize.cpp b/tools/aapt2/format/proto/ProtoSerialize.cpp
index 5ab43b7..98c5175 100644
--- a/tools/aapt2/format/proto/ProtoSerialize.cpp
+++ b/tools/aapt2/format/proto/ProtoSerialize.cpp
@@ -325,6 +325,9 @@
   if (overlayable_item.policies & PolicyFlags::ACTOR_SIGNATURE) {
     pb_overlayable_item->add_policy(pb::OverlayableItem::ACTOR);
   }
+  if (overlayable_item.policies & PolicyFlags::CONFIG_SIGNATURE) {
+    pb_overlayable_item->add_policy(pb::OverlayableItem::CONFIG_SIGNATURE);
+  }
 
   if (source_pool != nullptr) {
     SerializeSourceToPb(overlayable_item.source, source_pool,
diff --git a/tools/aapt2/jni/aapt2_jni.cpp b/tools/aapt2/jni/aapt2_jni.cpp
index ba9646f..ec3c543 100644
--- a/tools/aapt2/jni/aapt2_jni.cpp
+++ b/tools/aapt2/jni/aapt2_jni.cpp
@@ -139,5 +139,5 @@
 
 JNIEXPORT void JNICALL Java_com_android_tools_aapt2_Aapt2Jni_ping(
         JNIEnv *env, jclass aapt_obj) {
-  // This is just a dummy method to see if the library has been loaded.
+  // This is just a no-op method to see if the library has been loaded.
 }
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index 49f8e1b..dac21d7 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -570,8 +570,8 @@
   }
 
   xml::XmlActionExecutorPolicy policy = options_.warn_validation
-                                            ? xml::XmlActionExecutorPolicy::kWhitelistWarning
-                                            : xml::XmlActionExecutorPolicy::kWhitelist;
+                                            ? xml::XmlActionExecutorPolicy::kAllowListWarning
+                                            : xml::XmlActionExecutorPolicy::kAllowList;
   if (!executor.Execute(policy, context->GetDiagnostics(), doc)) {
     return false;
   }
diff --git a/tools/aapt2/link/TableMerger.cpp b/tools/aapt2/link/TableMerger.cpp
index c25e450..ad56092 100644
--- a/tools/aapt2/link/TableMerger.cpp
+++ b/tools/aapt2/link/TableMerger.cpp
@@ -31,11 +31,11 @@
 
 TableMerger::TableMerger(IAaptContext* context, ResourceTable* out_table,
                          const TableMergerOptions& options)
-    : context_(context), master_table_(out_table), options_(options) {
+    : context_(context), main_table_(out_table), options_(options) {
   // Create the desired package that all tables will be merged into.
-  master_package_ =
-      master_table_->CreatePackage(context_->GetCompilationPackage(), context_->GetPackageId());
-  CHECK(master_package_ != nullptr) << "package name or ID already taken";
+  main_package_ =
+      main_table_->CreatePackage(context_->GetCompilationPackage(), context_->GetPackageId());
+  CHECK(main_package_ != nullptr) << "package name or ID already taken";
 }
 
 bool TableMerger::Merge(const Source& src, ResourceTable* table, bool overlay) {
@@ -235,7 +235,7 @@
   bool error = false;
 
   for (auto& src_type : src_package->types) {
-    ResourceTableType* dst_type = master_package_->FindOrCreateType(src_type->type);
+    ResourceTableType* dst_type = main_package_->FindOrCreateType(src_type->type);
     if (!MergeType(context_, src, dst_type, src_type.get())) {
       error = true;
       continue;
@@ -279,7 +279,7 @@
         if (dst_config_value) {
           CollisionResult collision_result = MergeConfigValue(
               context_, res_name, overlay, options_.override_styles_instead_of_overlaying,
-              dst_config_value, src_config_value.get(), &master_table_->string_pool);
+              dst_config_value, src_config_value.get(), &main_table_->string_pool);
           if (collision_result == CollisionResult::kConflict) {
             error = true;
             continue;
@@ -298,7 +298,7 @@
           if (mangle_package) {
             new_file_ref = CloneAndMangleFile(src_package->name, *f);
           } else {
-            new_file_ref = std::unique_ptr<FileReference>(f->Clone(&master_table_->string_pool));
+            new_file_ref = std::unique_ptr<FileReference>(f->Clone(&main_table_->string_pool));
           }
           dst_config_value->value = std::move(new_file_ref);
 
@@ -307,7 +307,7 @@
               ? dst_config_value->value->GetComment() : Maybe<std::string>();
 
           dst_config_value->value = std::unique_ptr<Value>(
-              src_config_value->value->Clone(&master_table_->string_pool));
+              src_config_value->value->Clone(&main_table_->string_pool));
 
           // Keep the comment from the original resource and ignore all comments from overlaying
           // resources
@@ -328,14 +328,14 @@
     std::string mangled_entry = NameMangler::MangleEntry(package, entry.to_string());
     std::string newPath = prefix.to_string() + mangled_entry + suffix.to_string();
     std::unique_ptr<FileReference> new_file_ref =
-        util::make_unique<FileReference>(master_table_->string_pool.MakeRef(newPath));
+        util::make_unique<FileReference>(main_table_->string_pool.MakeRef(newPath));
     new_file_ref->SetComment(file_ref.GetComment());
     new_file_ref->SetSource(file_ref.GetSource());
     new_file_ref->type = file_ref.type;
     new_file_ref->file = file_ref.file;
     return new_file_ref;
   }
-  return std::unique_ptr<FileReference>(file_ref.Clone(&master_table_->string_pool));
+  return std::unique_ptr<FileReference>(file_ref.Clone(&main_table_->string_pool));
 }
 
 bool TableMerger::MergeFile(const ResourceFile& file_desc, bool overlay, io::IFile* file) {
diff --git a/tools/aapt2/link/TableMerger.h b/tools/aapt2/link/TableMerger.h
index a35a134..e01a0c1 100644
--- a/tools/aapt2/link/TableMerger.h
+++ b/tools/aapt2/link/TableMerger.h
@@ -80,9 +80,9 @@
   DISALLOW_COPY_AND_ASSIGN(TableMerger);
 
   IAaptContext* context_;
-  ResourceTable* master_table_;
+  ResourceTable* main_table_;
   TableMergerOptions options_;
-  ResourceTablePackage* master_package_;
+  ResourceTablePackage* main_package_;
   std::set<std::string> merged_packages_;
 
   bool MergeImpl(const Source& src, ResourceTable* src_table, bool overlay, bool allow_new);
diff --git a/tools/aapt2/link/XmlCompatVersioner.cpp b/tools/aapt2/link/XmlCompatVersioner.cpp
index 20ebdc6..6937ca9 100644
--- a/tools/aapt2/link/XmlCompatVersioner.cpp
+++ b/tools/aapt2/link/XmlCompatVersioner.cpp
@@ -143,8 +143,8 @@
 
   // Iterate from smallest to largest API version.
   for (ApiVersion api : apis_referenced) {
-    std::set<ApiVersion> dummy;
-    versioned_docs.push_back(ProcessDoc(api, api_range.end, doc, &dummy));
+    std::set<ApiVersion> tmp;
+    versioned_docs.push_back(ProcessDoc(api, api_range.end, doc, &tmp));
   }
   return versioned_docs;
 }
diff --git a/tools/aapt2/optimize/ResourceFilter.cpp b/tools/aapt2/optimize/ResourceFilter.cpp
index 250b651..08c045b 100644
--- a/tools/aapt2/optimize/ResourceFilter.cpp
+++ b/tools/aapt2/optimize/ResourceFilter.cpp
@@ -20,8 +20,8 @@
 
 namespace aapt {
 
-ResourceFilter::ResourceFilter(const std::unordered_set<ResourceName>& blacklist)
-    : blacklist_(blacklist) {
+ResourceFilter::ResourceFilter(const std::unordered_set<ResourceName>& exclude_list)
+    : exclude_list_(exclude_list) {
 }
 
 bool ResourceFilter::Consume(IAaptContext* context, ResourceTable* table) {
@@ -29,7 +29,7 @@
     for (auto& type : package->types) {
       for (auto it = type->entries.begin(); it != type->entries.end(); ) {
         ResourceName resource = ResourceName({}, type->type, (*it)->name);
-        if (blacklist_.find(resource) != blacklist_.end()) {
+        if (exclude_list_.find(resource) != exclude_list_.end()) {
           it = type->entries.erase(it);
         } else {
           ++it;
diff --git a/tools/aapt2/optimize/ResourceFilter.h b/tools/aapt2/optimize/ResourceFilter.h
index d4baf65..a264533 100644
--- a/tools/aapt2/optimize/ResourceFilter.h
+++ b/tools/aapt2/optimize/ResourceFilter.h
@@ -25,16 +25,16 @@
 
 namespace aapt {
 
-// Removes non-whitelisted entries from resource table.
+// Removes exclude-listed entries from resource table.
 class ResourceFilter : public IResourceTableConsumer {
  public:
-  explicit ResourceFilter(const std::unordered_set<ResourceName>& blacklist);
+  explicit ResourceFilter(const std::unordered_set<ResourceName>& exclude_list);
 
   bool Consume(IAaptContext* context, ResourceTable* table) override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ResourceFilter);
-  std::unordered_set<ResourceName> blacklist_;
+  std::unordered_set<ResourceName> exclude_list_;
 };
 
 } // namespace aapt
diff --git a/tools/aapt2/optimize/ResourceFilter_test.cpp b/tools/aapt2/optimize/ResourceFilter_test.cpp
index ef57f9c..34d8fd2 100644
--- a/tools/aapt2/optimize/ResourceFilter_test.cpp
+++ b/tools/aapt2/optimize/ResourceFilter_test.cpp
@@ -31,22 +31,22 @@
 
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .AddString("android:string/notblacklisted", ResourceId{}, default_config, "value")
-          .AddString("android:string/blacklisted", ResourceId{}, default_config, "value")
-          .AddString("android:string/notblacklisted2", ResourceId{}, default_config, "value")
-          .AddString("android:string/blacklisted2", ResourceId{}, default_config, "value")
+          .AddString("android:string/notexclude_listed", ResourceId{}, default_config, "value")
+          .AddString("android:string/exclude_listed", ResourceId{}, default_config, "value")
+          .AddString("android:string/notexclude_listed2", ResourceId{}, default_config, "value")
+          .AddString("android:string/exclude_listed2", ResourceId{}, default_config, "value")
           .Build();
 
-  std::unordered_set<ResourceName> blacklist = {
-    ResourceName({}, ResourceType::kString, "blacklisted"),
-    ResourceName({}, ResourceType::kString, "blacklisted2"),
+  std::unordered_set<ResourceName> exclude_list = {
+    ResourceName({}, ResourceType::kString, "exclude_listed"),
+    ResourceName({}, ResourceType::kString, "exclude_listed2"),
   };
 
-  ASSERT_TRUE(ResourceFilter(blacklist).Consume(context.get(), table.get()));
-  EXPECT_THAT(table, HasValue("android:string/notblacklisted", default_config));
-  EXPECT_THAT(table, HasValue("android:string/notblacklisted2", default_config));
-  EXPECT_THAT(table, Not(HasValue("android:string/blacklisted", default_config)));
-  EXPECT_THAT(table, Not(HasValue("android:string/blacklisted2", default_config)));
+  ASSERT_TRUE(ResourceFilter(exclude_list).Consume(context.get(), table.get()));
+  EXPECT_THAT(table, HasValue("android:string/notexclude_listed", default_config));
+  EXPECT_THAT(table, HasValue("android:string/notexclude_listed2", default_config));
+  EXPECT_THAT(table, Not(HasValue("android:string/exclude_listed", default_config)));
+  EXPECT_THAT(table, Not(HasValue("android:string/exclude_listed2", default_config)));
 }
 
 TEST(ResourceFilterTest, TypeIsCheckedBeforeFiltering) {
@@ -55,21 +55,21 @@
 
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .AddString("android:string/notblacklisted", ResourceId{}, default_config, "value")
-          .AddString("android:string/blacklisted", ResourceId{}, default_config, "value")
-          .AddString("android:drawable/notblacklisted", ResourceId{}, default_config, "value")
-          .AddString("android:drawable/blacklisted", ResourceId{}, default_config, "value")
+          .AddString("android:string/notexclude_listed", ResourceId{}, default_config, "value")
+          .AddString("android:string/exclude_listed", ResourceId{}, default_config, "value")
+          .AddString("android:drawable/notexclude_listed", ResourceId{}, default_config, "value")
+          .AddString("android:drawable/exclude_listed", ResourceId{}, default_config, "value")
           .Build();
 
-  std::unordered_set<ResourceName> blacklist = {
-    ResourceName({}, ResourceType::kString, "blacklisted"),
+  std::unordered_set<ResourceName> exclude_list = {
+    ResourceName({}, ResourceType::kString, "exclude_listed"),
   };
 
-  ASSERT_TRUE(ResourceFilter(blacklist).Consume(context.get(), table.get()));
-  EXPECT_THAT(table, HasValue("android:string/notblacklisted", default_config));
-  EXPECT_THAT(table, HasValue("android:drawable/blacklisted", default_config));
-  EXPECT_THAT(table, HasValue("android:drawable/notblacklisted", default_config));
-  EXPECT_THAT(table, Not(HasValue("android:string/blacklisted", default_config)));
+  ASSERT_TRUE(ResourceFilter(exclude_list).Consume(context.get(), table.get()));
+  EXPECT_THAT(table, HasValue("android:string/notexclude_listed", default_config));
+  EXPECT_THAT(table, HasValue("android:drawable/exclude_listed", default_config));
+  EXPECT_THAT(table, HasValue("android:drawable/notexclude_listed", default_config));
+  EXPECT_THAT(table, Not(HasValue("android:string/exclude_listed", default_config)));
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/test/Common.cpp b/tools/aapt2/test/Common.cpp
index b54c155..23c2218 100644
--- a/tools/aapt2/test/Common.cpp
+++ b/tools/aapt2/test/Common.cpp
@@ -21,7 +21,7 @@
 namespace aapt {
 namespace test {
 
-struct DummyDiagnosticsImpl : public IDiagnostics {
+struct TestDiagnosticsImpl : public IDiagnostics {
   void Log(Level level, DiagMessageActual& actual_msg) override {
     switch (level) {
       case Level::Note:
@@ -39,7 +39,7 @@
 };
 
 IDiagnostics* GetDiagnostics() {
-  static DummyDiagnosticsImpl diag;
+  static TestDiagnosticsImpl diag;
   return &diag;
 }
 
diff --git a/tools/aapt2/trace/TraceBuffer.h b/tools/aapt2/trace/TraceBuffer.h
index 8618e0e..ba751dd 100644
--- a/tools/aapt2/trace/TraceBuffer.h
+++ b/tools/aapt2/trace/TraceBuffer.h
@@ -40,7 +40,7 @@
 void BeginTrace(const std::string& tag);
 void EndTrace();
 
-// A master trace is required to flush events to disk. Events are formatted in systrace
+// A main trace is required to flush events to disk. Events are formatted in systrace
 // json format.
 class FlushTrace {
 public:
diff --git a/tools/aapt2/util/Maybe_test.cpp b/tools/aapt2/util/Maybe_test.cpp
index 2057ddc..4c921f1 100644
--- a/tools/aapt2/util/Maybe_test.cpp
+++ b/tools/aapt2/util/Maybe_test.cpp
@@ -22,32 +22,32 @@
 
 namespace aapt {
 
-struct Dummy {
-  Dummy() {
+struct Fake {
+  Fake() {
     data = new int;
     *data = 1;
-    std::cerr << "Construct Dummy{0x" << (void*)this << "} with data=0x"
+    std::cerr << "Construct Fake{0x" << (void*)this << "} with data=0x"
               << (void*)data << std::endl;
   }
 
-  Dummy(const Dummy& rhs) {
+  Fake(const Fake& rhs) {
     data = nullptr;
     if (rhs.data) {
       data = new int;
       *data = *rhs.data;
     }
-    std::cerr << "CopyConstruct Dummy{0x" << (void*)this << "} from Dummy{0x"
+    std::cerr << "CopyConstruct Fake{0x" << (void*)this << "} from Fake{0x"
               << (const void*)&rhs << "}" << std::endl;
   }
 
-  Dummy(Dummy&& rhs) {
+  Fake(Fake&& rhs) {
     data = rhs.data;
     rhs.data = nullptr;
-    std::cerr << "MoveConstruct Dummy{0x" << (void*)this << "} from Dummy{0x"
+    std::cerr << "MoveConstruct Fake{0x" << (void*)this << "} from Fake{0x"
               << (const void*)&rhs << "}" << std::endl;
   }
 
-  Dummy& operator=(const Dummy& rhs) {
+  Fake& operator=(const Fake& rhs) {
     delete data;
     data = nullptr;
 
@@ -55,22 +55,22 @@
       data = new int;
       *data = *rhs.data;
     }
-    std::cerr << "CopyAssign Dummy{0x" << (void*)this << "} from Dummy{0x"
+    std::cerr << "CopyAssign Fake{0x" << (void*)this << "} from Fake{0x"
               << (const void*)&rhs << "}" << std::endl;
     return *this;
   }
 
-  Dummy& operator=(Dummy&& rhs) {
+  Fake& operator=(Fake&& rhs) {
     delete data;
     data = rhs.data;
     rhs.data = nullptr;
-    std::cerr << "MoveAssign Dummy{0x" << (void*)this << "} from Dummy{0x"
+    std::cerr << "MoveAssign Fake{0x" << (void*)this << "} from Fake{0x"
               << (const void*)&rhs << "}" << std::endl;
     return *this;
   }
 
-  ~Dummy() {
-    std::cerr << "Destruct Dummy{0x" << (void*)this << "} with data=0x"
+  ~Fake() {
+    std::cerr << "Destruct Fake{0x" << (void*)this << "} with data=0x"
               << (void*)data << std::endl;
     delete data;
   }
@@ -100,15 +100,15 @@
 }
 
 TEST(MaybeTest, Lifecycle) {
-  Maybe<Dummy> val = make_nothing<Dummy>();
+  Maybe<Fake> val = make_nothing<Fake>();
 
-  Maybe<Dummy> val2 = make_value(Dummy());
+  Maybe<Fake> val2 = make_value(Fake());
 }
 
 TEST(MaybeTest, MoveAssign) {
-  Maybe<Dummy> val;
+  Maybe<Fake> val;
   {
-    Maybe<Dummy> val2 = Dummy();
+    Maybe<Fake> val2 = Fake();
     val = std::move(val2);
   }
 }
diff --git a/tools/aapt2/xml/XmlActionExecutor.cpp b/tools/aapt2/xml/XmlActionExecutor.cpp
index cb844f0..fab17c9 100644
--- a/tools/aapt2/xml/XmlActionExecutor.cpp
+++ b/tools/aapt2/xml/XmlActionExecutor.cpp
@@ -74,11 +74,11 @@
         for (const StringPiece& element : *bread_crumb) {
           error_msg << "<" << element << ">";
         }
-        if (policy == XmlActionExecutorPolicy::kWhitelistWarning) {
+        if (policy == XmlActionExecutorPolicy::kAllowListWarning) {
           // Treat the error only as a warning.
           diag->Warn(error_msg);
         } else {
-          // Policy is XmlActionExecutorPolicy::kWhitelist, we should fail.
+          // Policy is XmlActionExecutorPolicy::kAllowList, we should fail.
           diag->Error(error_msg);
           error = true;
         }
@@ -94,7 +94,7 @@
 
   Element* el = doc->root.get();
   if (!el) {
-    if (policy == XmlActionExecutorPolicy::kWhitelist) {
+    if (policy == XmlActionExecutorPolicy::kAllowList) {
       source_diag.Error(DiagMessage() << "no root XML tag found");
       return false;
     }
@@ -109,7 +109,7 @@
       return iter->second.Execute(policy, &bread_crumb, &source_diag, el);
     }
 
-    if (policy == XmlActionExecutorPolicy::kWhitelist) {
+    if (policy == XmlActionExecutorPolicy::kAllowList) {
       DiagMessage error_msg(el->line_number);
       error_msg << "unexpected root element ";
       PrintElementToDiagMessage(el, &error_msg);
diff --git a/tools/aapt2/xml/XmlActionExecutor.h b/tools/aapt2/xml/XmlActionExecutor.h
index f689b2a..a0ad1da 100644
--- a/tools/aapt2/xml/XmlActionExecutor.h
+++ b/tools/aapt2/xml/XmlActionExecutor.h
@@ -37,12 +37,12 @@
   // The actions defined must match and run. If an element is found that does not match an action,
   // an error occurs.
   // Note: namespaced elements are always ignored.
-  kWhitelist,
+  kAllowList,
 
   // The actions defined should match and run. if an element is found that does not match an
   // action, a warning is printed.
   // Note: namespaced elements are always ignored.
-  kWhitelistWarning,
+  kAllowListWarning,
 };
 
 // Contains the actions to perform at this XML node. This is a recursive data structure that
diff --git a/tools/aapt2/xml/XmlActionExecutor_test.cpp b/tools/aapt2/xml/XmlActionExecutor_test.cpp
index d39854e..d47b495 100644
--- a/tools/aapt2/xml/XmlActionExecutor_test.cpp
+++ b/tools/aapt2/xml/XmlActionExecutor_test.cpp
@@ -60,10 +60,10 @@
   StdErrDiagnostics diag;
 
   doc = test::BuildXmlDom("<manifest><application /><activity /></manifest>");
-  ASSERT_FALSE(executor.Execute(XmlActionExecutorPolicy::kWhitelist, &diag, doc.get()));
+  ASSERT_FALSE(executor.Execute(XmlActionExecutorPolicy::kAllowList, &diag, doc.get()));
 
   doc = test::BuildXmlDom("<manifest><application><activity /></application></manifest>");
-  ASSERT_FALSE(executor.Execute(XmlActionExecutorPolicy::kWhitelist, &diag, doc.get()));
+  ASSERT_FALSE(executor.Execute(XmlActionExecutorPolicy::kAllowList, &diag, doc.get()));
 }
 
 }  // namespace xml
diff --git a/tools/aosp/aosp_sha.sh b/tools/aosp/aosp_sha.sh
index f25fcdc..99aaa3c 100755
--- a/tools/aosp/aosp_sha.sh
+++ b/tools/aosp/aosp_sha.sh
@@ -11,7 +11,7 @@
         if (( count == 0 )); then
             echo
         fi
-        echo -e "\033[0;31mThe source of truth for '$file' is in AOSP.\033[0m"
+        echo -e "\033[0;31;47mThe source of truth for '$file' is in AOSP.\033[0m"
         (( count++ ))
     done < <(git show --name-only --pretty=format: $1 | grep -- "$2")
     if (( count != 0 )); then