Merge "Import translations. DO NOT MERGE ANYWHERE"
diff --git a/Android.bp b/Android.bp
index 5af7756..4121b8a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -598,6 +598,12 @@
         "//frameworks/base/apex/jobscheduler/framework",
         "//frameworks/base/packages/Tethering/tests/unit",
     ],
+    errorprone: {
+        javacflags: [
+            "-Xep:AndroidFrameworkCompatChange:ERROR",
+            "-Xep:AndroidFrameworkUid:ERROR",
+        ],
+    },
 }
 
 // This "framework" module is NOT installed to the device. It's
diff --git a/apct-tests/perftests/core/src/android/text/CanvasDrawTextTest.java b/apct-tests/perftests/core/src/android/text/CanvasDrawTextTest.java
index bb6b691..66b2b0e 100644
--- a/apct-tests/perftests/core/src/android/text/CanvasDrawTextTest.java
+++ b/apct-tests/perftests/core/src/android/text/CanvasDrawTextTest.java
@@ -53,19 +53,19 @@
         final String text = mTextUtil.nextRandomParagraph(
                 WORD_LENGTH, 4 * 1024 * 1024 /* 4mb text */).toString();
         final RenderNode node = RenderNode.create("benchmark", null);
-        final RenderNode child = RenderNode.create("child", null);
-        child.setLeftTopRightBottom(50, 50, 100, 100);
-
-        RecordingCanvas canvas = node.start(100, 100);
-        node.end(canvas);
-        canvas = child.start(50, 50);
-        child.end(canvas);
 
         final Random r = new Random(0);
-
         while (state.keepRunning()) {
+            state.pauseTiming();
+            RecordingCanvas canvas = node.beginRecording();
             int start = r.nextInt(text.length() - 100);
+            state.resumeTiming();
+
             canvas.drawText(text, start, start + 100, 0, 0, PAINT);
+
+            state.pauseTiming();
+            node.endRecording();
+            state.resumeTiming();
         }
     }
 }
diff --git a/api/system-current.txt b/api/system-current.txt
index e077ae4..325175b 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -95,6 +95,7 @@
     field public static final String INJECT_EVENTS = "android.permission.INJECT_EVENTS";
     field public static final String INSTALL_DYNAMIC_SYSTEM = "android.permission.INSTALL_DYNAMIC_SYSTEM";
     field public static final String INSTALL_GRANT_RUNTIME_PERMISSIONS = "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS";
+    field public static final String INSTALL_LOCATION_TIME_ZONE_PROVIDER = "android.permission.INSTALL_LOCATION_TIME_ZONE_PROVIDER";
     field public static final String INSTALL_PACKAGE_UPDATES = "android.permission.INSTALL_PACKAGE_UPDATES";
     field public static final String INSTALL_SELF_UPDATES = "android.permission.INSTALL_SELF_UPDATES";
     field public static final String INTENT_FILTER_VERIFICATION_AGENT = "android.permission.INTENT_FILTER_VERIFICATION_AGENT";
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 35c7b96..9a9f165 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2732,6 +2732,54 @@
     public static final String ACTION_MY_PACKAGE_UNSUSPENDED = "android.intent.action.MY_PACKAGE_UNSUSPENDED";
 
     /**
+     * Broadcast Action: Sent to indicate that the package becomes startable.
+     * The intent will have the following extra values:
+     * <ul>
+     * <li> {@link #EXTRA_UID} containing the integer uid assigned to the package. </li>
+     * <li> {@link #EXTRA_PACKAGE_NAME} containing the package name. </li>
+     * </li>
+     * </ul>
+     *
+     * <p class="note">This is a protected intent that can only be sent by the system.
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_PACKAGE_STARTABLE = "android.intent.action.PACKAGE_STARTABLE";
+
+    /**
+     * Broadcast Action: Sent to indicate that the package becomes unstartable.
+     * The intent will have the following extra values:
+     * <ul>
+     * <li> {@link #EXTRA_UID} containing the integer uid assigned to the package. </li>
+     * <li> {@link #EXTRA_PACKAGE_NAME} containing the package name. </li>
+     * <li> {@link #EXTRA_REASON} containing the integer indicating the reason for the state change,
+     * @see PackageManager.UnstartableReason
+     * </li>
+     * </ul>
+     *
+     * <p class="note">This is a protected intent that can only be sent by the system.
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_PACKAGE_UNSTARTABLE =
+            "android.intent.action.PACKAGE_UNSTARTABLE";
+
+    /**
+     * Broadcast Action: Sent to indicate that the package is fully loaded.
+     * <ul>
+     * <li> {@link #EXTRA_UID} containing the integer uid assigned to the package. </li>
+     * <li> {@link #EXTRA_PACKAGE_NAME} containing the package name. </li>
+     * </li>
+     * </ul>
+     *
+     * <p class="note">This is a protected intent that can only be sent by the system.
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_PACKAGE_FULLY_LOADED =
+            "android.intent.action.PACKAGE_FULLY_LOADED";
+
+    /**
      * Broadcast Action: A user ID has been removed from the system.  The user
      * ID number is stored in the extra data under {@link #EXTRA_UID}.
      *
diff --git a/core/java/android/content/pm/IDataLoaderStatusListener.aidl b/core/java/android/content/pm/IDataLoaderStatusListener.aidl
index efb00a0..745c39b 100644
--- a/core/java/android/content/pm/IDataLoaderStatusListener.aidl
+++ b/core/java/android/content/pm/IDataLoaderStatusListener.aidl
@@ -50,7 +50,30 @@
     *            fail and all retry limits are exceeded. */
     const int DATA_LOADER_UNRECOVERABLE = 8;
 
+    /** There are no known issues with the data stream. */
+    const int STREAM_HEALTHY = 0;
+
+    /** There are issues with the current transport layer (network, adb connection, etc.) that may
+     * recover automatically or could eventually require user intervention. */
+    const int STREAM_TRANSPORT_ERROR = 1;
+
+    /** Integrity failures in the data stream, this could be due to file corruption, decompression
+     * issues or similar. This indicates a likely unrecoverable error. */
+    const int STREAM_INTEGRITY_ERROR = 2;
+
+    /** There are issues with the source of the data, e.g., backend availability issues, account
+     * issues. This indicates a potentially recoverable error, but one that may take a long time to
+     * resolve. */
+    const int STREAM_SOURCE_ERROR = 3;
+
+    /** The device or app is low on storage and cannot complete the stream as a result.
+      * A subsequent page miss resulting in app failure will transition app to unstartable state. */
+    const int STREAM_STORAGE_ERROR = 4;
+
     /** Data loader status callback */
     void onStatusChanged(in int dataLoaderId, in int status);
+
+    /** Callback to report streaming health status of a specific data loader */
+    void reportStreamHealth(in int dataLoaderId, in int streamStatus);
 }
 
diff --git a/core/java/android/content/pm/IncrementalStatesInfo.aidl b/core/java/android/content/pm/IncrementalStatesInfo.aidl
new file mode 100644
index 0000000..b5aad12
--- /dev/null
+++ b/core/java/android/content/pm/IncrementalStatesInfo.aidl
@@ -0,0 +1,20 @@
+/*
+**
+** Copyright 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.pm;
+
+parcelable IncrementalStatesInfo;
\ No newline at end of file
diff --git a/core/java/android/content/pm/IncrementalStatesInfo.java b/core/java/android/content/pm/IncrementalStatesInfo.java
new file mode 100644
index 0000000..6e91c19
--- /dev/null
+++ b/core/java/android/content/pm/IncrementalStatesInfo.java
@@ -0,0 +1,76 @@
+/*
+ * 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 android.content.pm;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Info about a package's states in Parcelable format.
+ * @hide
+ */
+public class IncrementalStatesInfo implements Parcelable {
+    private boolean mIsStartable;
+    private boolean mIsLoading;
+    private float mProgress;
+
+    public IncrementalStatesInfo(boolean isStartable, boolean isLoading, float progress) {
+        mIsStartable = isStartable;
+        mIsLoading = isLoading;
+        mProgress = progress;
+    }
+
+    private IncrementalStatesInfo(Parcel source) {
+        mIsStartable = source.readBoolean();
+        mIsLoading = source.readBoolean();
+        mProgress = source.readFloat();
+    }
+
+    public boolean isStartable() {
+        return mIsStartable;
+    }
+
+    public boolean isLoading() {
+        return mIsLoading;
+    }
+
+    public float getProgress() {
+        return mProgress;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeBoolean(mIsStartable);
+        dest.writeBoolean(mIsLoading);
+        dest.writeFloat(mProgress);
+    }
+
+    public static final @android.annotation.NonNull Creator<IncrementalStatesInfo> CREATOR =
+            new Creator<IncrementalStatesInfo>() {
+                public IncrementalStatesInfo createFromParcel(Parcel source) {
+                    return new IncrementalStatesInfo(source);
+                }
+                public IncrementalStatesInfo[] newArray(int size) {
+                    return new IncrementalStatesInfo[size];
+                }
+            };
+}
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index a600d6c..c293e4ad 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -3786,6 +3786,39 @@
      */
     public static final int SYSTEM_APP_STATE_UNINSTALLED = 3;
 
+    /**
+     * Reasons for why a package is unstartable.
+     * @hide
+     */
+    @IntDef({UNSTARTABLE_REASON_UNKNOWN,
+            UNSTARTABLE_REASON_DATALOADER_TRANSPORT,
+            UNSTARTABLE_REASON_DATALOADER_STORAGE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface UnstartableReason {}
+
+    /**
+     * Unstartable state with no root cause specified. E.g., data loader seeing missing pages but
+     * unclear about the cause. This corresponds to a generic alert window shown to the user when
+     * the user attempts to launch the app.
+     * @hide
+     */
+    public static final int UNSTARTABLE_REASON_UNKNOWN = 0;
+
+    /**
+     * Unstartable state after hint from dataloader of issues with the transport layer.
+     * This corresponds to an alert window shown to the user indicating network errors.
+     * @hide
+     */
+    public static final int UNSTARTABLE_REASON_DATALOADER_TRANSPORT = 1;
+
+    /**
+     * Unstartable state after encountering storage limitations.
+     * This corresponds to an alert window indicating limited storage.
+     * @hide
+     */
+    public static final int UNSTARTABLE_REASON_DATALOADER_STORAGE = 2;
+
     /** {@hide} */
     public int getUserId() {
         return UserHandle.myUserId();
diff --git a/core/java/android/content/pm/PackageUserState.java b/core/java/android/content/pm/PackageUserState.java
index 327d1b8..3ed21b0 100644
--- a/core/java/android/content/pm/PackageUserState.java
+++ b/core/java/android/content/pm/PackageUserState.java
@@ -44,7 +44,6 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.CollectionUtils;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index ca0981b..e62ad1f 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -852,12 +852,11 @@
 
     /**
      * Set the priority of a thread, based on Linux priorities.
-     *
-     * @param tid The identifier of the thread/process to change. It should be
-     * the native thread id but not the managed id of {@link java.lang.Thread}.
+     * 
+     * @param tid The identifier of the thread/process to change.
      * @param priority A Linux priority level, from -20 for highest scheduling
      * priority to 19 for lowest scheduling priority.
-     *
+     * 
      * @throws IllegalArgumentException Throws IllegalArgumentException if
      * <var>tid</var> does not exist.
      * @throws SecurityException Throws SecurityException if your process does
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 1dbf95f..97acd2f 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3567,6 +3567,9 @@
             if (outConfig.fontScale < 0) {
                 outConfig.fontScale = DEFAULT_FONT_SCALE;
             }
+            outConfig.forceBoldText = Settings.Secure.getIntForUser(
+                    cr, Settings.Secure.FORCE_BOLD_TEXT, Configuration.FORCE_BOLD_TEXT_NO,
+                    userHandle);
 
             final String localeValue =
                     Settings.System.getStringForUser(cr, SYSTEM_LOCALES, userHandle);
@@ -3597,6 +3600,7 @@
             if (!inoutConfig.userSetLocale && !inoutConfig.getLocales().isEmpty()) {
                 inoutConfig.clearLocales();
             }
+            inoutConfig.forceBoldText = Configuration.FORCE_BOLD_TEXT_UNDEFINED;
         }
 
         /**
@@ -3620,7 +3624,11 @@
                             DEFAULT_OVERRIDEABLE_BY_RESTORE);
         }
 
-        /** @hide */
+        /**
+         * Convenience function for checking if settings should be overwritten with config changes.
+         * @see #putConfigurationForUser(ContentResolver, Configuration, int)
+         * @hide
+         */
         public static boolean hasInterestingConfigurationChanges(int changes) {
             return (changes & ActivityInfo.CONFIG_FONT_SCALE) != 0 ||
                     (changes & ActivityInfo.CONFIG_LOCALE) != 0;
@@ -13407,15 +13415,6 @@
                 "power_button_very_long_press";
 
         /**
-         * Global settings that shouldn't be persisted.
-         *
-         * @hide
-         */
-        public static final String[] TRANSIENT_SETTINGS = {
-                LOCATION_GLOBAL_KILL_SWITCH,
-        };
-
-        /**
          * Keys we no longer back up under the current schema, but want to continue to
          * process when restoring historical backup datasets.
          *
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 44e603e..0c64eea 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -182,9 +182,6 @@
             IBinder displayToken, int mode);
     private static native void nativeDeferTransactionUntil(long transactionObj, long nativeObject,
             long barrierObject, long frame);
-    private static native void nativeDeferTransactionUntilSurface(long transactionObj,
-            long nativeObject,
-            long surfaceObject, long frame);
     private static native void nativeReparentChildren(long transactionObj, long nativeObject,
             long newParentObject);
     private static native void nativeReparent(long transactionObj, long nativeObject,
@@ -2947,22 +2944,6 @@
         /**
          * @hide
          */
-        @Deprecated
-        @UnsupportedAppUsage
-        public Transaction deferTransactionUntilSurface(SurfaceControl sc, Surface barrierSurface,
-                long frameNumber) {
-            if (frameNumber < 0) {
-                return this;
-            }
-            checkPreconditions(sc);
-            nativeDeferTransactionUntilSurface(mNativeObject, sc.mNativeObject,
-                    barrierSurface.mNativeObject, frameNumber);
-            return this;
-        }
-
-        /**
-         * @hide
-         */
         public Transaction reparentChildren(SurfaceControl sc, SurfaceControl newParent) {
             checkPreconditions(sc);
             nativeReparentChildren(mNativeObject, sc.mNativeObject, newParent.mNativeObject);
diff --git a/core/java/android/webkit/UserPackage.java b/core/java/android/webkit/UserPackage.java
index 5bcfa8b..2e5ee04 100644
--- a/core/java/android/webkit/UserPackage.java
+++ b/core/java/android/webkit/UserPackage.java
@@ -34,7 +34,7 @@
     private final UserInfo mUserInfo;
     private final PackageInfo mPackageInfo;
 
-    public static final int MINIMUM_SUPPORTED_SDK = Build.VERSION_CODES.S;
+    public static final int MINIMUM_SUPPORTED_SDK = Build.VERSION_CODES.R;
 
     public UserPackage(UserInfo user, PackageInfo packageInfo) {
         this.mUserInfo = user;
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index 5fc9344..8790bbd 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -47,7 +47,7 @@
     // visible for WebViewZygoteInit to look up the class by reflection and call preloadInZygote.
     /** @hide */
     private static final String CHROMIUM_WEBVIEW_FACTORY =
-            "com.android.webview.chromium.WebViewChromiumFactoryProviderForS";
+            "com.android.webview.chromium.WebViewChromiumFactoryProviderForR";
 
     private static final String CHROMIUM_WEBVIEW_FACTORY_METHOD = "create";
 
diff --git a/core/java/com/android/ims/internal/uce/presence/PresCmdId.aidl b/core/java/com/android/ims/internal/uce/presence/PresCmdID.aidl
similarity index 100%
rename from core/java/com/android/ims/internal/uce/presence/PresCmdId.aidl
rename to core/java/com/android/ims/internal/uce/presence/PresCmdID.aidl
diff --git a/core/java/com/android/internal/app/chooser/SelectableTargetInfo.java b/core/java/com/android/internal/app/chooser/SelectableTargetInfo.java
index 900e18d..28a9601 100644
--- a/core/java/com/android/internal/app/chooser/SelectableTargetInfo.java
+++ b/core/java/com/android/internal/app/chooser/SelectableTargetInfo.java
@@ -166,7 +166,7 @@
 
         // Now fetch app icon and raster with no badging even in work profile
         Bitmap appIcon = mSelectableTargetInfoCommunicator.makePresentationGetter(info)
-                .getIconBitmap(UserHandle.getUserHandleForUid(UserHandle.myUserId()));
+                .getIconBitmap(android.os.Process.myUserHandle());
 
         // Raster target drawable with appIcon as a badge
         SimpleIconFactory sif = SimpleIconFactory.obtain(mContext);
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index 095882e..60f1b44 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -36,7 +36,6 @@
 import com.android.server.NetworkManagementSocketTagger;
 
 import dalvik.system.RuntimeHooks;
-import dalvik.system.ThreadPrioritySetter;
 import dalvik.system.VMRuntime;
 
 import libcore.content.type.MimeMap;
@@ -208,7 +207,6 @@
      */
     public static void preForkInit() {
         if (DEBUG) Slog.d(TAG, "Entered preForkInit.");
-        RuntimeHooks.setThreadPrioritySetter(new RuntimeThreadPrioritySetter());
         RuntimeInit.enableDdms();
         // TODO(b/142019040#comment13): Decide whether to load the default instance eagerly, i.e.
         // MimeMap.setDefault(DefaultMimeMapFactory.create());
@@ -221,35 +219,6 @@
         MimeMap.setDefaultSupplier(DefaultMimeMapFactory::create);
     }
 
-    private static class RuntimeThreadPrioritySetter implements ThreadPrioritySetter {
-        // Should remain consistent with kNiceValues[] in system/libartpalette/palette_android.cc
-        private static final int[] NICE_VALUES = {
-            Process.THREAD_PRIORITY_LOWEST,  // 1 (MIN_PRIORITY)
-            Process.THREAD_PRIORITY_BACKGROUND + 6,
-            Process.THREAD_PRIORITY_BACKGROUND + 3,
-            Process.THREAD_PRIORITY_BACKGROUND,
-            Process.THREAD_PRIORITY_DEFAULT,  // 5 (NORM_PRIORITY)
-            Process.THREAD_PRIORITY_DEFAULT - 2,
-            Process.THREAD_PRIORITY_DEFAULT - 4,
-            Process.THREAD_PRIORITY_URGENT_DISPLAY + 3,
-            Process.THREAD_PRIORITY_URGENT_DISPLAY + 2,
-            Process.THREAD_PRIORITY_URGENT_DISPLAY  // 10 (MAX_PRIORITY)
-        };
-
-        @Override
-        public void setPriority(int nativeTid, int priority) {
-            // Check NICE_VALUES[] length first.
-            if (NICE_VALUES.length != (1 + Thread.MAX_PRIORITY - Thread.MIN_PRIORITY)) {
-                throw new AssertionError("Unexpected NICE_VALUES.length=" + NICE_VALUES.length);
-            }
-            // Priority should be in the range of MIN_PRIORITY (1) to MAX_PRIORITY (10).
-            if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) {
-                throw new IllegalArgumentException("Priority out of range: " + priority);
-            }
-            Process.setThreadPriority(nativeTid, NICE_VALUES[priority - Thread.MIN_PRIORITY]);
-        }
-    }
-
     @UnsupportedAppUsage
     protected static final void commonInit() {
         if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!");
diff --git a/core/java/com/android/internal/protolog/ProtoLogGroup.java b/core/java/com/android/internal/protolog/ProtoLogGroup.java
index 50ba42f..ce3efd3 100644
--- a/core/java/com/android/internal/protolog/ProtoLogGroup.java
+++ b/core/java/com/android/internal/protolog/ProtoLogGroup.java
@@ -48,6 +48,10 @@
             Consts.TAG_WM),
     WM_DEBUG_LOCKTASK(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
             Consts.TAG_WM),
+    WM_DEBUG_STATES(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+            Consts.TAG_WM),
+    WM_DEBUG_TASKS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+            Consts.TAG_WM),
     WM_DEBUG_STARTING_WINDOW(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
             Consts.TAG_WM),
     WM_SHOW_TRANSACTIONS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 1bf8efb..1419855 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -1333,17 +1333,6 @@
     transaction->deferTransactionUntil_legacy(ctrl, barrier, frameNumber);
 }
 
-static void nativeDeferTransactionUntilSurface(JNIEnv* env, jclass clazz, jlong transactionObj,
-        jlong nativeObject,
-        jlong surfaceObject, jlong frameNumber) {
-    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
-
-    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-    sp<Surface> barrier = reinterpret_cast<Surface *>(surfaceObject);
-
-    transaction->deferTransactionUntil_legacy(ctrl, barrier, frameNumber);
-}
-
 static void nativeReparentChildren(JNIEnv* env, jclass clazz, jlong transactionObj,
         jlong nativeObject,
         jlong newParentObject) {
@@ -1699,8 +1688,6 @@
             (void*)nativeGetProtectedContentSupport },
     {"nativeDeferTransactionUntil", "(JJJJ)V",
             (void*)nativeDeferTransactionUntil },
-    {"nativeDeferTransactionUntilSurface", "(JJJJ)V",
-            (void*)nativeDeferTransactionUntilSurface },
     {"nativeReparentChildren", "(JJJ)V",
             (void*)nativeReparentChildren } ,
     {"nativeReparent", "(JJJ)V",
diff --git a/core/proto/android/service/package.proto b/core/proto/android/service/package.proto
index 004b096..d289e00 100644
--- a/core/proto/android/service/package.proto
+++ b/core/proto/android/service/package.proto
@@ -124,6 +124,11 @@
         optional string originating_package_name = 2;
     }
 
+    message StatesProto {
+        optional bool is_startable = 1;
+        optional bool is_loading = 2;
+    }
+
     // Name of package. e.g. "com.android.providers.telephony".
     optional string name = 1;
     // UID for this package as assigned by Android OS.
@@ -145,4 +150,6 @@
     repeated UserInfoProto users = 9;
     // Where the request to install this package came from,
     optional InstallSourceProto install_source = 10;
+    // Whether the package is startable or is still loading
+    optional StatesProto states = 11;
 }
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 7247e4f..57c25f1 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -42,6 +42,9 @@
     <protected-broadcast android:name="android.intent.action.PACKAGE_REMOVED" />
     <protected-broadcast android:name="android.intent.action.PACKAGE_FULLY_REMOVED" />
     <protected-broadcast android:name="android.intent.action.PACKAGE_CHANGED" />
+    <protected-broadcast android:name="android.intent.action.PACKAGE_STARTABLE" />
+    <protected-broadcast android:name="android.intent.action.PACKAGE_UNSTARTABLE" />
+    <protected-broadcast android:name="android.intent.action.PACKAGE_FULLY_LOADED" />
     <protected-broadcast android:name="android.intent.action.PACKAGE_ENABLE_ROLLBACK" />
     <protected-broadcast android:name="android.intent.action.CANCEL_ENABLE_ROLLBACK" />
     <protected-broadcast android:name="android.intent.action.ROLLBACK_COMMITTED" />
@@ -1575,6 +1578,13 @@
     <permission android:name="android.permission.INSTALL_LOCATION_PROVIDER"
         android:protectionLevel="signature|privileged" />
 
+    <!-- @SystemApi @hide Allows an application to install a LocationTimeZoneProvider into the
+         LocationTimeZoneProviderManager.
+         <p>Not for use by third-party applications.
+    -->
+    <permission android:name="android.permission.INSTALL_LOCATION_TIME_ZONE_PROVIDER"
+        android:protectionLevel="signature|privileged" />
+
     <!-- @SystemApi @hide Allows HDMI-CEC service to access device and configuration files.
          This should only be used by HDMI-CEC service.
     -->
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 60f7a09..fac2f22 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -432,23 +432,17 @@
     <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"change your audio settings"</string>
     <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Allows the app to modify global audio settings such as volume and which speaker is used for output."</string>
     <string name="permlab_recordAudio" msgid="1208457423054219147">"record audio"</string>
-    <!-- no translation found for permdesc_recordAudio (5857246765327514062) -->
-    <skip />
-    <!-- no translation found for permlab_recordBackgroundAudio (5891032812308878254) -->
-    <skip />
-    <!-- no translation found for permdesc_recordBackgroundAudio (1992623135737407516) -->
-    <skip />
+    <string name="permdesc_recordAudio" msgid="5857246765327514062">"This app can record audio using the microphone while the app is in use."</string>
+    <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"record audio in the background"</string>
+    <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"This app can record audio using the microphone at any time."</string>
     <string name="permlab_sim_communication" msgid="176788115994050692">"send commands to the SIM"</string>
     <string name="permdesc_sim_communication" msgid="4179799296415957960">"Allows the app to send commands to the SIM. This is very dangerous."</string>
     <string name="permlab_activityRecognition" msgid="1782303296053990884">"recognise physical activity"</string>
     <string name="permdesc_activityRecognition" msgid="8667484762991357519">"This app can recognise your physical activity."</string>
     <string name="permlab_camera" msgid="6320282492904119413">"take pictures and videos"</string>
-    <!-- no translation found for permdesc_camera (5240801376168647151) -->
-    <skip />
-    <!-- no translation found for permlab_backgroundCamera (7549917926079731681) -->
-    <skip />
-    <!-- no translation found for permdesc_backgroundCamera (1615291686191138250) -->
-    <skip />
+    <string name="permdesc_camera" msgid="5240801376168647151">"This app can take pictures and record videos using the camera while the app is in use."</string>
+    <string name="permlab_backgroundCamera" msgid="7549917926079731681">"take pictures and videos in the background"</string>
+    <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"This app can take pictures and record videos using the camera at any time."</string>
     <string name="permlab_systemCamera" msgid="3642917457796210580">"Grant an application or service access to system cameras to take pictures and videos"</string>
     <string name="permdesc_systemCamera" msgid="5938360914419175986">"This privileged or system app can take pictures and record videos using a system camera at any time. Requires the android.permission.CAMERA permission to be held by the app as well"</string>
     <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Allow an application or service to receive callbacks about camera devices being opened or closed."</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index ae3aaab..8497658 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -432,23 +432,17 @@
     <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"change your audio settings"</string>
     <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Allows the app to modify global audio settings such as volume and which speaker is used for output."</string>
     <string name="permlab_recordAudio" msgid="1208457423054219147">"record audio"</string>
-    <!-- no translation found for permdesc_recordAudio (5857246765327514062) -->
-    <skip />
-    <!-- no translation found for permlab_recordBackgroundAudio (5891032812308878254) -->
-    <skip />
-    <!-- no translation found for permdesc_recordBackgroundAudio (1992623135737407516) -->
-    <skip />
+    <string name="permdesc_recordAudio" msgid="5857246765327514062">"This app can record audio using the microphone while the app is in use."</string>
+    <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"record audio in the background"</string>
+    <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"This app can record audio using the microphone at any time."</string>
     <string name="permlab_sim_communication" msgid="176788115994050692">"send commands to the SIM"</string>
     <string name="permdesc_sim_communication" msgid="4179799296415957960">"Allows the app to send commands to the SIM. This is very dangerous."</string>
     <string name="permlab_activityRecognition" msgid="1782303296053990884">"recognise physical activity"</string>
     <string name="permdesc_activityRecognition" msgid="8667484762991357519">"This app can recognise your physical activity."</string>
     <string name="permlab_camera" msgid="6320282492904119413">"take pictures and videos"</string>
-    <!-- no translation found for permdesc_camera (5240801376168647151) -->
-    <skip />
-    <!-- no translation found for permlab_backgroundCamera (7549917926079731681) -->
-    <skip />
-    <!-- no translation found for permdesc_backgroundCamera (1615291686191138250) -->
-    <skip />
+    <string name="permdesc_camera" msgid="5240801376168647151">"This app can take pictures and record videos using the camera while the app is in use."</string>
+    <string name="permlab_backgroundCamera" msgid="7549917926079731681">"take pictures and videos in the background"</string>
+    <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"This app can take pictures and record videos using the camera at any time."</string>
     <string name="permlab_systemCamera" msgid="3642917457796210580">"Grant an application or service access to system cameras to take pictures and videos"</string>
     <string name="permdesc_systemCamera" msgid="5938360914419175986">"This privileged or system app can take pictures and record videos using a system camera at any time. Requires the android.permission.CAMERA permission to be held by the app as well"</string>
     <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Allow an application or service to receive callbacks about camera devices being opened or closed."</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 52dcf97..12881e7 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -432,23 +432,17 @@
     <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"change your audio settings"</string>
     <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Allows the app to modify global audio settings such as volume and which speaker is used for output."</string>
     <string name="permlab_recordAudio" msgid="1208457423054219147">"record audio"</string>
-    <!-- no translation found for permdesc_recordAudio (5857246765327514062) -->
-    <skip />
-    <!-- no translation found for permlab_recordBackgroundAudio (5891032812308878254) -->
-    <skip />
-    <!-- no translation found for permdesc_recordBackgroundAudio (1992623135737407516) -->
-    <skip />
+    <string name="permdesc_recordAudio" msgid="5857246765327514062">"This app can record audio using the microphone while the app is in use."</string>
+    <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"record audio in the background"</string>
+    <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"This app can record audio using the microphone at any time."</string>
     <string name="permlab_sim_communication" msgid="176788115994050692">"send commands to the SIM"</string>
     <string name="permdesc_sim_communication" msgid="4179799296415957960">"Allows the app to send commands to the SIM. This is very dangerous."</string>
     <string name="permlab_activityRecognition" msgid="1782303296053990884">"recognise physical activity"</string>
     <string name="permdesc_activityRecognition" msgid="8667484762991357519">"This app can recognise your physical activity."</string>
     <string name="permlab_camera" msgid="6320282492904119413">"take pictures and videos"</string>
-    <!-- no translation found for permdesc_camera (5240801376168647151) -->
-    <skip />
-    <!-- no translation found for permlab_backgroundCamera (7549917926079731681) -->
-    <skip />
-    <!-- no translation found for permdesc_backgroundCamera (1615291686191138250) -->
-    <skip />
+    <string name="permdesc_camera" msgid="5240801376168647151">"This app can take pictures and record videos using the camera while the app is in use."</string>
+    <string name="permlab_backgroundCamera" msgid="7549917926079731681">"take pictures and videos in the background"</string>
+    <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"This app can take pictures and record videos using the camera at any time."</string>
     <string name="permlab_systemCamera" msgid="3642917457796210580">"Grant an application or service access to system cameras to take pictures and videos"</string>
     <string name="permdesc_systemCamera" msgid="5938360914419175986">"This privileged or system app can take pictures and record videos using a system camera at any time. Requires the android.permission.CAMERA permission to be held by the app as well"</string>
     <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Allow an application or service to receive callbacks about camera devices being opened or closed."</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 2f7f271..cb2eb7a 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -432,23 +432,17 @@
     <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"change your audio settings"</string>
     <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Allows the app to modify global audio settings such as volume and which speaker is used for output."</string>
     <string name="permlab_recordAudio" msgid="1208457423054219147">"record audio"</string>
-    <!-- no translation found for permdesc_recordAudio (5857246765327514062) -->
-    <skip />
-    <!-- no translation found for permlab_recordBackgroundAudio (5891032812308878254) -->
-    <skip />
-    <!-- no translation found for permdesc_recordBackgroundAudio (1992623135737407516) -->
-    <skip />
+    <string name="permdesc_recordAudio" msgid="5857246765327514062">"This app can record audio using the microphone while the app is in use."</string>
+    <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"record audio in the background"</string>
+    <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"This app can record audio using the microphone at any time."</string>
     <string name="permlab_sim_communication" msgid="176788115994050692">"send commands to the SIM"</string>
     <string name="permdesc_sim_communication" msgid="4179799296415957960">"Allows the app to send commands to the SIM. This is very dangerous."</string>
     <string name="permlab_activityRecognition" msgid="1782303296053990884">"recognise physical activity"</string>
     <string name="permdesc_activityRecognition" msgid="8667484762991357519">"This app can recognise your physical activity."</string>
     <string name="permlab_camera" msgid="6320282492904119413">"take pictures and videos"</string>
-    <!-- no translation found for permdesc_camera (5240801376168647151) -->
-    <skip />
-    <!-- no translation found for permlab_backgroundCamera (7549917926079731681) -->
-    <skip />
-    <!-- no translation found for permdesc_backgroundCamera (1615291686191138250) -->
-    <skip />
+    <string name="permdesc_camera" msgid="5240801376168647151">"This app can take pictures and record videos using the camera while the app is in use."</string>
+    <string name="permlab_backgroundCamera" msgid="7549917926079731681">"take pictures and videos in the background"</string>
+    <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"This app can take pictures and record videos using the camera at any time."</string>
     <string name="permlab_systemCamera" msgid="3642917457796210580">"Grant an application or service access to system cameras to take pictures and videos"</string>
     <string name="permdesc_systemCamera" msgid="5938360914419175986">"This privileged or system app can take pictures and record videos using a system camera at any time. Requires the android.permission.CAMERA permission to be held by the app as well"</string>
     <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Allow an application or service to receive callbacks about camera devices being opened or closed."</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 8f017f9..5750e50 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -432,23 +432,17 @@
     <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‏‏‏‎‏‎‏‏‏‎‎‏‎‎‏‏‎‏‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‏‎‏‏‏‎‎‏‏‎‏‏‎‎‎‏‏‏‎change your audio settings‎‏‎‎‏‎"</string>
     <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‏‏‏‏‎‎‏‏‏‎‏‏‎‏‏‏‏‎‏‏‏‏‏‎‏‏‎‎‏‏‏‎‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‏‎‎‏‎Allows the app to modify global audio settings such as volume and which speaker is used for output.‎‏‎‎‏‎"</string>
     <string name="permlab_recordAudio" msgid="1208457423054219147">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‏‎‎‎‏‎‏‎‏‎‎‏‏‎‏‏‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‏‎‏‎‎‏‎‏‎‎‏‏‏‏‎‎‎‏‎‏‏‎record audio‎‏‎‎‏‎"</string>
-    <!-- no translation found for permdesc_recordAudio (5857246765327514062) -->
-    <skip />
-    <!-- no translation found for permlab_recordBackgroundAudio (5891032812308878254) -->
-    <skip />
-    <!-- no translation found for permdesc_recordBackgroundAudio (1992623135737407516) -->
-    <skip />
+    <string name="permdesc_recordAudio" msgid="5857246765327514062">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‎‏‎‎‎‏‏‏‏‎‏‏‏‎‎‏‏‎‎‏‏‎‏‎‎‏‎‎‏‎‎‏‏‎‏‏‏‏‏‎‎‏‏‏‎‎‏‏‏‎‎This app can record audio using the microphone while the app is in use.‎‏‎‎‏‎"</string>
+    <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‏‏‏‎‎‏‎‎‎‎‏‎‏‏‏‏‎‎‏‏‏‎‏‎‏‏‏‎‏‎‏‎‎‏‏‏‎‏‎‏‏‏‎‎record audio in the background‎‏‎‎‏‎"</string>
+    <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‎‏‎‎‏‏‏‎‎‏‏‏‎‎‎‎‎‏‎‏‏‏‏‎‏‎‎‎‎‎‎‏‏‎‏‏‎‏‎‎‏‏‎‏‎‎‎‎‎‎‏‏‏‎‎‎This app can record audio using the microphone at any time.‎‏‎‎‏‎"</string>
     <string name="permlab_sim_communication" msgid="176788115994050692">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‎‏‏‏‎‏‎‎‎‎‎‏‎‎‏‏‏‏‎‏‏‎‏‎‏‏‎‏‎‏‏‎‎‏‎‏‎‏‏‎‎‎‎‎‎‎‎‎‏‎‎‎‎‏‎‎‎send commands to the SIM‎‏‎‎‏‎"</string>
     <string name="permdesc_sim_communication" msgid="4179799296415957960">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‎‎‎‎‎‎‎‏‏‎‏‎‎‎‎‏‎‏‎‏‎‎‎‎‏‎‎‎‎‏‏‏‎‏‎‎‏‏‎‏‎‎‎‎‎‎‏‏‏‏‎‎‏‎‎‎‎Allows the app to send commands to the SIM. This is very dangerous.‎‏‎‎‏‎"</string>
     <string name="permlab_activityRecognition" msgid="1782303296053990884">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‎‏‏‏‏‎‎‎‎‎‎‎‎‏‏‎‏‏‎‎‏‏‏‏‎‎‏‏‎‏‏‎‏‎‎‏‏‏‎‎‏‎‏‎‏‎‏‏‏‏‎‎‏‎‎‎recognize physical activity‎‏‎‎‏‎"</string>
     <string name="permdesc_activityRecognition" msgid="8667484762991357519">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‏‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‏‏‎‏‎‏‏‏‏‎‏‏‏‎‎‏‎‎‏‏‏‏‎This app can recognize your physical activity.‎‏‎‎‏‎"</string>
     <string name="permlab_camera" msgid="6320282492904119413">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‎‎‎‎‏‏‏‎‎‏‎‏‏‎‏‎‏‎‏‏‏‎‎‏‏‏‎‎‎‏‏‏‎‏‎‏‎take pictures and videos‎‏‎‎‏‎"</string>
-    <!-- no translation found for permdesc_camera (5240801376168647151) -->
-    <skip />
-    <!-- no translation found for permlab_backgroundCamera (7549917926079731681) -->
-    <skip />
-    <!-- no translation found for permdesc_backgroundCamera (1615291686191138250) -->
-    <skip />
+    <string name="permdesc_camera" msgid="5240801376168647151">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‏‏‎‏‏‎‎‎‏‎‎‎‏‎‎‎‏‎‏‎‏‏‎‏‎‏‏‎‎‏‏‏‎‏‎‎‏‎‎‎‏‏‎‎‏‏‏‏‎‏‏‏‏‎This app can take pictures and record videos using the camera while the app is in use.‎‏‎‎‏‎"</string>
+    <string name="permlab_backgroundCamera" msgid="7549917926079731681">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‎‏‏‎‏‎‏‏‎‎‏‎‎‏‎‏‏‎‏‎‎‏‎‎‎‎‏‏‎‏‎‏‎‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‎‎‎‏‎take pictures and videos in the background‎‏‎‎‏‎"</string>
+    <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‏‏‎‏‎‏‎‏‎‏‎‏‎‏‏‎‎‏‏‏‎‏‎‏‏‏‏‏‏‎‎‎‎‎‏‎‎‎‎‏‎‎‎‎‏‎‏‏‏‎‎‏‎‏‎‎This app can take pictures and record videos using the camera at any time.‎‏‎‎‏‎"</string>
     <string name="permlab_systemCamera" msgid="3642917457796210580">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‎‎‏‏‏‎‎‎‏‏‏‏‏‎‎‎‏‎‎‎‎‎‎‏‏‏‏‎‏‎‎‎‎‎‎‎‏‏‎‎‎‏‏‏‏‏‏‎‎‏‎‏‎‎‎Allow an application or service access to system cameras to take pictures and videos‎‏‎‎‏‎"</string>
     <string name="permdesc_systemCamera" msgid="5938360914419175986">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‏‎‎‏‎‏‎‎‏‎‏‏‏‏‎‎‏‎‎‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‎‏‏‎‏‎‎‏‎‎‎‏‏‎‎‏‎‎This privileged or system app can take pictures and record videos using a system camera at any time. Requires the android.permission.CAMERA permission to be held by the app as well‎‏‎‎‏‎"</string>
     <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎‎‏‏‏‏‎‎‎‎‏‏‏‎‎‎‎‏‎‏‎‏‏‏‎‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‎‎‎‎‏‏‎Allow an application or service to receive callbacks about camera devices being opened or closed.‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index b327342..7b376ff 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -1632,12 +1632,10 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"सिफारिस तहभन्दा आवाज ठुलो गर्नुहुन्छ?\n\nलामो समय सम्म उच्च आवाजमा सुन्दा तपाईँको सुन्ने शक्तिलाई हानी गर्न सक्छ।"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"पहुँच सम्बन्धी सर्टकट प्रयोग गर्ने हो?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"यो सर्टकट सक्रिय हुँदा, ३ सेकेन्डसम्म दुवै भोल्युम बटन थिच्नुले पहुँचसम्बन्धी कुनै सुविधा सुरु गर्ने छ।"</string>
-    <!-- no translation found for accessibility_shortcut_multiple_service_warning_title (3135860819356676426) -->
-    <skip />
+    <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"सर्वसुलभता कायम गर्ने सुविधाहरू प्रयोग गर्न सर्टकट अन गर्ने हो?"</string>
     <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"केही सेकेन्डसम्म दुवै भोल्युम बटन थिचिराख्नुभयो भने पहुँचसम्बन्धी सुविधाहरू सक्रिय हुन्छ। यसले तपाईंको यन्त्रले काम गर्ने तरिका परिवर्तन गर्न सक्छ।\n\nहालका सुविधाहरू:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nतपाईं सेटिङ &gt; पहुँचमा गएर चयन गरिएका सुविधाहरू परिवर्तन गर्न सक्नुहुन्छ।"</string>
     <string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">"	• <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
-    <!-- no translation found for accessibility_shortcut_single_service_warning_title (1909518473488345266) -->
-    <skip />
+    <string name="accessibility_shortcut_single_service_warning_title" msgid="1909518473488345266">"<xliff:g id="SERVICE">%1$s</xliff:g> प्रयोग गर्न सर्टकट अन गर्ने हो?"</string>
     <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"केही सेकेन्डसम्म दुवै भोल्युम बटन थिचिराख्नुले <xliff:g id="SERVICE">%1$s</xliff:g> नामक पहुँचसम्बन्धी सुविधा  सक्रिय गर्छ। यसले तपाईंको यन्त्रले काम गर्ने तरिका परिवर्तन गर्न सक्छ।\n\nतपाईं सेटिङ &gt; पहुँचमा गई यो सर्टकटमार्फत अर्को सुविधा खुल्ने बनाउन सक्नुहुन्छ।"</string>
     <string name="accessibility_shortcut_on" msgid="5463618449556111344">"सक्रिय गरियोस्"</string>
     <string name="accessibility_shortcut_off" msgid="3651336255403648739">"सक्रिय नगरियोस्"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index f09e7b0..450fddb 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -432,23 +432,17 @@
     <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"alterar as suas configurações de áudio"</string>
     <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Permite que o app modifique configurações de áudio globais como volume e alto-falantes de saída."</string>
     <string name="permlab_recordAudio" msgid="1208457423054219147">"gravar áudio"</string>
-    <!-- no translation found for permdesc_recordAudio (5857246765327514062) -->
-    <skip />
-    <!-- no translation found for permlab_recordBackgroundAudio (5891032812308878254) -->
-    <skip />
-    <!-- no translation found for permdesc_recordBackgroundAudio (1992623135737407516) -->
-    <skip />
+    <string name="permdesc_recordAudio" msgid="5857246765327514062">"Enquanto está sendo usado, este app pode gravar áudio usando o microfone."</string>
+    <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"gravar áudio em segundo plano"</string>
+    <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Este app pode gravar áudio usando o microfone a qualquer momento."</string>
     <string name="permlab_sim_communication" msgid="176788115994050692">"enviar comandos para o chip"</string>
     <string name="permdesc_sim_communication" msgid="4179799296415957960">"Permite que o app envie comandos ao chip. Muito perigoso."</string>
     <string name="permlab_activityRecognition" msgid="1782303296053990884">"reconhecer atividade física"</string>
     <string name="permdesc_activityRecognition" msgid="8667484762991357519">"Este app pode reconhecer sua atividade física."</string>
     <string name="permlab_camera" msgid="6320282492904119413">"tirar fotos e gravar vídeos"</string>
-    <!-- no translation found for permdesc_camera (5240801376168647151) -->
-    <skip />
-    <!-- no translation found for permlab_backgroundCamera (7549917926079731681) -->
-    <skip />
-    <!-- no translation found for permdesc_backgroundCamera (1615291686191138250) -->
-    <skip />
+    <string name="permdesc_camera" msgid="5240801376168647151">"Enquanto está sendo usado, este app pode tirar fotos e gravar vídeos usando a câmera."</string>
+    <string name="permlab_backgroundCamera" msgid="7549917926079731681">"tirar fotos e gravar vídeos em segundo plano"</string>
+    <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"Este app pode tirar fotos e gravar vídeos usando a câmera a qualquer momento."</string>
     <string name="permlab_systemCamera" msgid="3642917457796210580">"Permitir que um aplicativo ou serviço acesse as câmeras do sistema para tirar fotos e gravar vídeos"</string>
     <string name="permdesc_systemCamera" msgid="5938360914419175986">"Esse app do sistema ou com privilégios pode tirar fotos e gravar vídeos a qualquer momento usando a câmera do sistema. É necessário que o app tenha também a permissão android.permission.CAMERA"</string>
     <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Permitir que um aplicativo ou serviço receba callbacks sobre dispositivos de câmera sendo abertos ou fechados."</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index f09e7b0..450fddb 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -432,23 +432,17 @@
     <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"alterar as suas configurações de áudio"</string>
     <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Permite que o app modifique configurações de áudio globais como volume e alto-falantes de saída."</string>
     <string name="permlab_recordAudio" msgid="1208457423054219147">"gravar áudio"</string>
-    <!-- no translation found for permdesc_recordAudio (5857246765327514062) -->
-    <skip />
-    <!-- no translation found for permlab_recordBackgroundAudio (5891032812308878254) -->
-    <skip />
-    <!-- no translation found for permdesc_recordBackgroundAudio (1992623135737407516) -->
-    <skip />
+    <string name="permdesc_recordAudio" msgid="5857246765327514062">"Enquanto está sendo usado, este app pode gravar áudio usando o microfone."</string>
+    <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"gravar áudio em segundo plano"</string>
+    <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Este app pode gravar áudio usando o microfone a qualquer momento."</string>
     <string name="permlab_sim_communication" msgid="176788115994050692">"enviar comandos para o chip"</string>
     <string name="permdesc_sim_communication" msgid="4179799296415957960">"Permite que o app envie comandos ao chip. Muito perigoso."</string>
     <string name="permlab_activityRecognition" msgid="1782303296053990884">"reconhecer atividade física"</string>
     <string name="permdesc_activityRecognition" msgid="8667484762991357519">"Este app pode reconhecer sua atividade física."</string>
     <string name="permlab_camera" msgid="6320282492904119413">"tirar fotos e gravar vídeos"</string>
-    <!-- no translation found for permdesc_camera (5240801376168647151) -->
-    <skip />
-    <!-- no translation found for permlab_backgroundCamera (7549917926079731681) -->
-    <skip />
-    <!-- no translation found for permdesc_backgroundCamera (1615291686191138250) -->
-    <skip />
+    <string name="permdesc_camera" msgid="5240801376168647151">"Enquanto está sendo usado, este app pode tirar fotos e gravar vídeos usando a câmera."</string>
+    <string name="permlab_backgroundCamera" msgid="7549917926079731681">"tirar fotos e gravar vídeos em segundo plano"</string>
+    <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"Este app pode tirar fotos e gravar vídeos usando a câmera a qualquer momento."</string>
     <string name="permlab_systemCamera" msgid="3642917457796210580">"Permitir que um aplicativo ou serviço acesse as câmeras do sistema para tirar fotos e gravar vídeos"</string>
     <string name="permdesc_systemCamera" msgid="5938360914419175986">"Esse app do sistema ou com privilégios pode tirar fotos e gravar vídeos a qualquer momento usando a câmera do sistema. É necessário que o app tenha também a permissão android.permission.CAMERA"</string>
     <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Permitir que um aplicativo ou serviço receba callbacks sobre dispositivos de câmera sendo abertos ou fechados."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index fc2fd35..d074960 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1325,7 +1325,7 @@
     <string name="sms_short_code_confirm_deny" msgid="1356917469323768230">"Отмена"</string>
     <string name="sms_short_code_remember_choice" msgid="1374526438647744862">"Запомнить выбор"</string>
     <string name="sms_short_code_remember_undo_instruction" msgid="2620984439143080410">"Это можно изменить позже в разделе настроек \"Приложения\"."</string>
-    <string name="sms_short_code_confirm_always_allow" msgid="2223014893129755950">"Всегда разрешать"</string>
+    <string name="sms_short_code_confirm_always_allow" msgid="2223014893129755950">"Разрешать всегда"</string>
     <string name="sms_short_code_confirm_never_allow" msgid="2688828813521652079">"Не разрешать"</string>
     <string name="sim_removed_title" msgid="5387212933992546283">"SIM-карта удалена"</string>
     <string name="sim_removed_message" msgid="9051174064474904617">"Пока вы не вставите действующую SIM-карту, мобильная сеть будет недоступна."</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index cc4d306..71e9ed7 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1578,6 +1578,16 @@
          config_timeZoneRulesUpdateTrackingEnabled are true.] -->
     <integer name="config_timeZoneRulesCheckRetryCount">5</integer>
 
+    <!-- Whether to enable primary location time zone provider overlay which allows the primary
+         location time zone provider to be replaced by an app at run-time. When disabled, only the
+         config_primaryLocationTimeZoneProviderPackageName package will be searched for the primary
+         location time zone provider, otherwise any system package is eligible. Anyone who wants to
+         disable the overlay mechanism can set it to false. -->
+    <bool name="config_enablePrimaryLocationTimeZoneOverlay" translatable="false">false</bool>
+    <!-- Package name providing the primary location time zone provider. Used only when
+         config_enablePrimaryLocationTimeZoneOverlay is false. -->
+    <string name="config_primaryLocationTimeZoneProviderPackageName" translatable="false">@null</string>
+
     <!-- Whether to enable network location overlay which allows network location provider to be
          replaced by an app at run-time. When disabled, only the
          config_networkLocationProviderPackageName package will be searched for network location
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 812e895..3e59549 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2158,6 +2158,8 @@
   <java-symbol type="string" name="config_defaultNetworkScorerPackageName" />
   <java-symbol type="string" name="config_persistentDataPackageName" />
   <java-symbol type="string" name="config_deviceConfiguratorPackageName" />
+  <java-symbol type="bool" name="config_enablePrimaryLocationTimeZoneOverlay" />
+  <java-symbol type="string" name="config_primaryLocationTimeZoneProviderPackageName" />
 
   <java-symbol type="layout" name="resolver_list" />
   <java-symbol type="id" name="resolver_list" />
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index c53ea87..29c8de6 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -49,6 +49,18 @@
       "group": "WM_ERROR",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "-2062338592": {
+      "message": "Looking for task of %s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
+    },
+    "-2054442123": {
+      "message": "Setting Intent of %s to %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
     "-2049725903": {
       "message": "Task back pressed on root taskId=%d",
       "level": "VERBOSE",
@@ -103,6 +115,12 @@
       "group": "WM_DEBUG_WINDOW_ORGANIZER",
       "at": "com\/android\/server\/wm\/DisplayAreaOrganizerController.java"
     },
+    "-1977793524": {
+      "message": "moveStackToDisplay: moving stackId=%d to displayId=%d",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
+    },
     "-1976930686": {
       "message": "Attempted to add Accessibility overlay window with bad token %s.  Aborting.",
       "level": "WARN",
@@ -163,6 +181,12 @@
       "group": "WM_DEBUG_WINDOW_ORGANIZER",
       "at": "com\/android\/server\/wm\/TaskOrganizerController.java"
     },
+    "-1890326172": {
+      "message": "no-history finish of %s on new resume",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
     "-1884933373": {
       "message": "enableScreenAfterBoot: mDisplayEnabled=%b mForceDisplayEnabled=%b mShowingBootMessages=%b mSystemBooted=%b. %s",
       "level": "INFO",
@@ -199,6 +223,12 @@
       "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
       "at": "com\/android\/server\/wm\/AppTransition.java"
     },
+    "-1861864501": {
+      "message": "resumeTopActivityLocked: Going to sleep and all paused",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
     "-1847087163": {
       "message": "TRANSIT_TASK_OPEN_BEHIND,  adding %s to mOpeningApps",
       "level": "DEBUG",
@@ -259,6 +289,12 @@
       "group": "WM_DEBUG_RECENTS_ANIMATIONS",
       "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
     },
+    "-1768090656": {
+      "message": "Re-launching after pause: %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
     "-1750206390": {
       "message": "Exception thrown when creating surface for client %s (%s). %s",
       "level": "WARN",
@@ -295,6 +331,12 @@
       "group": "WM_DEBUG_ORIENTATION",
       "at": "com\/android\/server\/wm\/DisplayContent.java"
     },
+    "-1704402370": {
+      "message": "resetTaskIntendedTask: calling finishActivity on %s",
+      "level": "WARN",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/ResetTargetTaskHelper.java"
+    },
     "-1699018375": {
       "message": "Adding activity %s to task %s callers: %s",
       "level": "INFO",
@@ -307,6 +349,12 @@
       "group": "WM_DEBUG_ADD_REMOVE",
       "at": "com\/android\/server\/wm\/ActivityRecord.java"
     },
+    "-1679411993": {
+      "message": "setVr2dDisplayId called for: %d",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
+    },
     "-1670695197": {
       "message": "Attempted to add presentation window to a non-suitable display.  Aborting.",
       "level": "WARN",
@@ -319,6 +367,18 @@
       "group": "WM_ERROR",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "-1655805455": {
+      "message": "Enqueue pending stop if needed: %s wasStopping=%b visibleRequested=%b",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
+    "-1647332198": {
+      "message": "remove RecentTask %s when finishing user %d",
+      "level": "INFO",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/RecentTasks.java"
+    },
     "-1638958146": {
       "message": "Removing activity %s from task=%s adding to task=%s Callers=%s",
       "level": "INFO",
@@ -337,6 +397,24 @@
       "group": "WM_DEBUG_LOCKTASK",
       "at": "com\/android\/server\/wm\/LockTaskController.java"
     },
+    "-1613096551": {
+      "message": "Top resumed state released %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityStackSupervisor.java"
+    },
+    "-1607026519": {
+      "message": "Ready to stop: %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityStackSupervisor.java"
+    },
+    "-1601745126": {
+      "message": "Launch on display check: allow launch for owner of the display",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/ActivityStackSupervisor.java"
+    },
     "-1598452494": {
       "message": "activityDestroyedLocked: r=%s",
       "level": "DEBUG",
@@ -355,6 +433,18 @@
       "group": "WM_DEBUG_WINDOW_TRANSITIONS",
       "at": "com\/android\/server\/wm\/Transition.java"
     },
+    "-1585311008": {
+      "message": "Bring to front target: %s from %s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/ActivityStarter.java"
+    },
+    "-1575977269": {
+      "message": "Skipping %s: mismatch root %s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
+    },
     "-1568331821": {
       "message": "Enabling listeners",
       "level": "VERBOSE",
@@ -367,6 +457,12 @@
       "group": "WM_DEBUG_WINDOW_TRANSITIONS",
       "at": "com\/android\/server\/wm\/Transition.java"
     },
+    "-1558137010": {
+      "message": "Config is relaunching invisible activity %s called by %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "-1554521902": {
       "message": "showInsets(ime) was requested by different window: %s ",
       "level": "WARN",
@@ -433,6 +529,18 @@
       "group": "WM_DEBUG_CONFIGURATION",
       "at": "com\/android\/server\/wm\/ActivityStarter.java"
     },
+    "-1492696222": {
+      "message": "App died during pause, not stopping: %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
+    "-1474292612": {
+      "message": "Could not find task for id: %d",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
+    },
     "-1471946192": {
       "message": "Marking app token %s with replacing child windows.",
       "level": "DEBUG",
@@ -463,6 +571,12 @@
       "group": "WM_DEBUG_RECENTS_ANIMATIONS",
       "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
     },
+    "-1432963966": {
+      "message": "Moving to DESTROYING: %s (destroy requested)",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "-1427184084": {
       "message": "addWindow: New client %s: window=%s Callers=%s",
       "level": "VERBOSE",
@@ -499,6 +613,12 @@
       "group": "WM_DEBUG_SYNC_ENGINE",
       "at": "com\/android\/server\/wm\/BLASTSyncEngine.java"
     },
+    "-1376035390": {
+      "message": "No task found",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
+    },
     "-1375751630": {
       "message": "  --- Start combine pass ---",
       "level": "VERBOSE",
@@ -541,12 +661,36 @@
       "group": "WM_DEBUG_IME",
       "at": "com\/android\/server\/wm\/WindowState.java"
     },
+    "-1305966693": {
+      "message": "Sending position change to %s, onTop: %b",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
+    "-1305791032": {
+      "message": "Moving to STOPPED: %s (stop complete)",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "-1305755880": {
       "message": "Initial config: %s",
       "level": "VERBOSE",
       "group": "WM_DEBUG_CONFIGURATION",
       "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
     },
+    "-1304806505": {
+      "message": "Starting new activity %s in new task %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/ActivityStarter.java"
+    },
+    "-1295684101": {
+      "message": "Launch on display check: no caller info, skip check",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/ActivityStackSupervisor.java"
+    },
     "-1292329638": {
       "message": "Added starting %s: startingWindow=%s startingView=%s",
       "level": "VERBOSE",
@@ -601,12 +745,30 @@
       "group": "WM_DEBUG_RECENTS_ANIMATIONS",
       "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
     },
+    "-1198579104": {
+      "message": "Pushing next activity %s out to target's task %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/ResetTargetTaskHelper.java"
+    },
+    "-1193946201": {
+      "message": "Can't report activity position update - client not running, activityRecord=%s",
+      "level": "WARN",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "-1176488860": {
       "message": "SURFACE isSecure=%b: %s",
       "level": "INFO",
       "group": "WM_SHOW_TRANSACTIONS",
       "at": "com\/android\/server\/wm\/WindowSurfaceController.java"
     },
+    "-1164930508": {
+      "message": "Moving to RESUMED: %s (starting new instance) callers=%s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
     "-1156118957": {
       "message": "Updated config=%s",
       "level": "DEBUG",
@@ -631,6 +793,12 @@
       "group": "WM_DEBUG_FOCUS",
       "at": "com\/android\/server\/wm\/DisplayContent.java"
     },
+    "-1136139407": {
+      "message": "no-history finish of %s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "-1130891072": {
       "message": "Orientation continue waiting for draw in %s",
       "level": "VERBOSE",
@@ -697,12 +865,24 @@
       "group": "WM_DEBUG_STARTING_WINDOW",
       "at": "com\/android\/server\/wm\/ActivityRecord.java"
     },
+    "-1084548141": {
+      "message": "Launch on display check: allow launch any on display",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/ActivityStackSupervisor.java"
+    },
     "-1076978367": {
       "message": "thawRotation: mRotation=%d",
       "level": "VERBOSE",
       "group": "WM_DEBUG_ORIENTATION",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "-1066383762": {
+      "message": "Sleep still waiting to pause %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
     "-1060365734": {
       "message": "Attempted to add QS dialog window with bad token %s.  Aborting.",
       "level": "WARN",
@@ -727,12 +907,30 @@
       "group": "WM_ERROR",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "-1022146708": {
+      "message": "Skipping %s: mismatch activity type",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
+    },
+    "-1016578046": {
+      "message": "Moving to %s Relaunching %s callers=%s",
+      "level": "INFO",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "-1009117329": {
       "message": "isFetchingAppTransitionSpecs=true",
       "level": "VERBOSE",
       "group": "WM_DEBUG_APP_TRANSITIONS",
       "at": "com\/android\/server\/wm\/AppTransitionController.java"
     },
+    "-1003060523": {
+      "message": "Finish needs to pause: %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "-993378225": {
       "message": "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING %s in %s",
       "level": "VERBOSE",
@@ -751,6 +949,12 @@
       "group": "WM_DEBUG_WINDOW_ORGANIZER",
       "at": "com\/android\/server\/wm\/TaskOrganizerController.java"
     },
+    "-937498525": {
+      "message": "Executing finish of failed to pause activity: %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "-930893991": {
       "message": "Set sync ready, syncId=%d",
       "level": "VERBOSE",
@@ -775,6 +979,18 @@
       "group": "WM_DEBUG_CONFIGURATION",
       "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
     },
+    "-926231510": {
+      "message": "State unchanged from:%s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
+    "-917215012": {
+      "message": "%s: caller %d is using old GET_TASKS but privileged; allowing",
+      "level": "WARN",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
+    },
     "-916108501": {
       "message": "Adding %s to %s",
       "level": "VERBOSE",
@@ -787,18 +1003,36 @@
       "group": "WM_ERROR",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "-903853754": {
+      "message": "pauseBackStacks: stack=%s mResumedActivity=%s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/TaskDisplayArea.java"
+    },
     "-883738232": {
       "message": "Adding more than one toast window for UID at a time.",
       "level": "WARN",
       "group": "WM_ERROR",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "-877494781": {
+      "message": "Start pushing activity %s out to bottom task %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/ResetTargetTaskHelper.java"
+    },
     "-874446906": {
       "message": "showBootMessage: msg=%s always=%b mAllowBootMessages=%b mShowingBootMessages=%b mSystemBooted=%b. %s",
       "level": "INFO",
       "group": "WM_DEBUG_BOOT",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "-866966979": {
+      "message": "Moving to PAUSED: %s (starting in paused state)",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityStackSupervisor.java"
+    },
     "-861859917": {
       "message": "Attempted to add window to a display that does not exist: %d. Aborting.",
       "level": "WARN",
@@ -841,6 +1075,12 @@
       "group": "WM_DEBUG_CONFIGURATION",
       "at": "com\/android\/server\/wm\/ActivityRecord.java"
     },
+    "-814760297": {
+      "message": "Looking for task of %s in %s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
+    },
     "-809771899": {
       "message": "findFocusedWindow: Reached focused app=%s",
       "level": "VERBOSE",
@@ -871,6 +1111,12 @@
       "group": "WM_DEBUG_ORIENTATION",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "-775004869": {
+      "message": "Not a match: %s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
+    },
     "-771177730": {
       "message": "Removing focused app token:%s displayId=%d",
       "level": "VERBOSE",
@@ -901,12 +1147,24 @@
       "group": "WM_DEBUG_CONFIGURATION",
       "at": "com\/android\/server\/wm\/ActivityRecord.java"
     },
+    "-729530161": {
+      "message": "Moving to DESTROYED: %s (no app)",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "-716565534": {
       "message": "moveActivityStackToFront: unfocusable activity=%s",
       "level": "DEBUG",
       "group": "WM_DEBUG_FOCUS",
       "at": "com\/android\/server\/wm\/ActivityRecord.java"
     },
+    "-705939410": {
+      "message": "Waiting for pause to complete...",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "-703543418": {
       "message": "      check sibling %s",
       "level": "VERBOSE",
@@ -925,6 +1183,12 @@
       "group": "WM_DEBUG_SYNC_ENGINE",
       "at": "com\/android\/server\/wm\/BLASTSyncEngine.java"
     },
+    "-672228342": {
+      "message": "resumeTopActivityLocked: Top activity resumed %s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
     "-668956537": {
       "message": "  THUMBNAIL %s: CREATE",
       "level": "INFO",
@@ -943,6 +1207,12 @@
       "group": "WM_DEBUG_REMOTE_ANIMATIONS",
       "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
     },
+    "-650261962": {
+      "message": "Sleep needs to pause %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
     "-639305784": {
       "message": "Could not report config changes to the window token client.",
       "level": "WARN",
@@ -979,6 +1249,18 @@
       "group": "WM_DEBUG_BOOT",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "-606328116": {
+      "message": "resumeTopActivityLocked: Top activity resumed (dontWaitForPause) %s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
+    "-596163537": {
+      "message": "Waiting for top state to be released by %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityStackSupervisor.java"
+    },
     "-593535526": {
       "message": "Binding proc %s with config %s",
       "level": "VERBOSE",
@@ -997,6 +1279,12 @@
       "group": "WM_DEBUG_ORIENTATION",
       "at": "com\/android\/server\/wm\/DisplayRotation.java"
     },
+    "-571686216": {
+      "message": "Launch on display check: disallow launch on virtual display for not-embedded activity.",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/ActivityStackSupervisor.java"
+    },
     "-561092364": {
       "message": "onPointerDownOutsideFocusLocked called on %s",
       "level": "INFO",
@@ -1027,12 +1315,24 @@
       "group": "WM_SHOW_TRANSACTIONS",
       "at": "com\/android\/server\/wm\/WindowAnimator.java"
     },
+    "-533690126": {
+      "message": "resumeTopActivityLocked: Resumed %s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
     "-532081937": {
       "message": "  Commit activity becoming invisible: %s",
       "level": "VERBOSE",
       "group": "WM_DEBUG_WINDOW_TRANSITIONS",
       "at": "com\/android\/server\/wm\/Transition.java"
     },
+    "-527683022": {
+      "message": "resumeTopActivityLocked: Skip resume: some activity pausing.",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
     "-519504830": {
       "message": "applyAnimation: anim=%s nextAppTransition=ANIM_CUSTOM transit=%s isEntrance=%b Callers=%s",
       "level": "VERBOSE",
@@ -1117,6 +1417,18 @@
       "group": "WM_DEBUG_ORIENTATION",
       "at": "com\/android\/server\/wm\/DisplayRotation.java"
     },
+    "-427457280": {
+      "message": "App died while pausing: %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
+    "-417514857": {
+      "message": "Key dispatch not paused for screen off",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
     "-415865166": {
       "message": "findFocusedWindow: Found new focus @ %s",
       "level": "VERBOSE",
@@ -1135,6 +1447,18 @@
       "group": "WM_DEBUG_CONTAINERS",
       "at": "com\/android\/server\/wm\/ActivityRecord.java"
     },
+    "-401029526": {
+      "message": "%s: caller %d does not hold REAL_GET_TASKS; limiting output",
+      "level": "WARN",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
+    },
+    "-399343789": {
+      "message": "Skipping %s: different user",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
+    },
     "-395922585": {
       "message": "InsetsSource setWin %s",
       "level": "DEBUG",
@@ -1183,6 +1507,12 @@
       "group": "WM_DEBUG_STARTING_WINDOW",
       "at": "com\/android\/server\/wm\/WindowStateAnimator.java"
     },
+    "-332679827": {
+      "message": "resumeNextFocusableActivityWhenStackIsEmpty: %s, go home",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
     "-324085783": {
       "message": "SURFACE CROP %s: %s",
       "level": "INFO",
@@ -1225,12 +1555,30 @@
       "group": "WM_DEBUG_WINDOW_TRANSITIONS",
       "at": "com\/android\/server\/wm\/Transition.java"
     },
+    "-300896109": {
+      "message": "moveTaskToStack: moving task=%d to stackId=%d toTop=%b",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
+    },
+    "-279436615": {
+      "message": "Moving to PAUSING: %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
     "-272719931": {
       "message": "startLockTaskModeLocked: %s",
       "level": "WARN",
       "group": "WM_DEBUG_LOCKTASK",
       "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
     },
+    "-262984451": {
+      "message": "Relaunch failed %s",
+      "level": "INFO",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "-260960989": {
       "message": "Removing and adding activity %s to stack at top callers=%s",
       "level": "INFO",
@@ -1249,6 +1597,12 @@
       "group": "WM_DEBUG_CONFIGURATION",
       "at": "com\/android\/server\/wm\/ActivityRecord.java"
     },
+    "-234244777": {
+      "message": "Activity config changed during resume: %s, new next: %s",
+      "level": "INFO",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
     "-198463978": {
       "message": "updateRotationUnchecked: alwaysSendConfiguration=%b forceRelayout=%b",
       "level": "VERBOSE",
@@ -1273,6 +1627,12 @@
       "group": "WM_DEBUG_RECENTS_ANIMATIONS",
       "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
     },
+    "-172326720": {
+      "message": "Saving icicle of %s: %s",
+      "level": "INFO",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "-168799453": {
       "message": "Allowing features %d:0x%s",
       "level": "WARN",
@@ -1291,6 +1651,12 @@
       "group": "WM_DEBUG_APP_TRANSITIONS",
       "at": "com\/android\/server\/wm\/AppTransitionController.java"
     },
+    "-118786523": {
+      "message": "Resume failed; resetting state to %s: %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
     "-116086365": {
       "message": "******************** ENABLING SCREEN!",
       "level": "INFO",
@@ -1351,6 +1717,12 @@
       "group": "WM_SHOW_TRANSACTIONS",
       "at": "com\/android\/server\/wm\/WindowSurfaceController.java"
     },
+    "-21399771": {
+      "message": "activity %s already destroying, skipping request with reason:%s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "-7343917": {
       "message": "onAnimationFinished(): targetStack=%s targetActivity=%s mRestoreTargetBehindStack=%s",
       "level": "DEBUG",
@@ -1411,6 +1783,12 @@
       "group": "WM_ERROR",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "51927339": {
+      "message": "Skipping %s: voice session",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
+    },
     "73987756": {
       "message": "ControlAdapter onAnimationCancelled mSource: %s mControlTarget: %s",
       "level": "INFO",
@@ -1429,12 +1807,24 @@
       "group": "WM_DEBUG_RECENTS_ANIMATIONS",
       "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
     },
+    "86989930": {
+      "message": "setTaskWindowingMode: moving task=%d to windowingMode=%d toTop=%b",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
+    },
     "91350919": {
       "message": "Attempted to set IME flag to a display that does not exist: %d",
       "level": "WARN",
       "group": "WM_ERROR",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "94402792": {
+      "message": "Moving to RESUMED: %s (in existing)",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
     "95216706": {
       "message": "hideIme target: %s ",
       "level": "DEBUG",
@@ -1537,6 +1927,12 @@
       "group": "WM_DEBUG_APP_TRANSITIONS",
       "at": "com\/android\/server\/wm\/AppTransitionController.java"
     },
+    "189628502": {
+      "message": "Moving to STOPPING: %s (stop requested)",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "194124419": {
       "message": "goodToGo(): Animation finished already, canceled=%s mPendingAnimations=%d",
       "level": "DEBUG",
@@ -1657,6 +2053,12 @@
       "group": "WM_DEBUG_RECENTS_ANIMATIONS",
       "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
     },
+    "306524472": {
+      "message": "Stop failed; moving to STOPPED: %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "309039362": {
       "message": "SURFACE MATRIX [%f,%f,%f,%f]: %s",
       "level": "INFO",
@@ -1729,6 +2131,12 @@
       "group": "WM_DEBUG_FOCUS",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "397382873": {
+      "message": "Moving to PAUSED: %s %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "399841913": {
       "message": "SURFACE RECOVER DESTROY: %s",
       "level": "INFO",
@@ -1783,6 +2191,12 @@
       "group": "WM_DEBUG_RECENTS_ANIMATIONS",
       "at": "com\/android\/server\/wm\/RecentsAnimation.java"
     },
+    "485170982": {
+      "message": "Not finishing noHistory %s on stop because we're just sleeping",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "487621047": {
       "message": "DisplayArea vanished name=%s",
       "level": "VERBOSE",
@@ -1849,6 +2263,12 @@
       "group": "WM_SHOW_TRANSACTIONS",
       "at": "com\/android\/server\/wm\/WindowSurfaceController.java"
     },
+    "579298675": {
+      "message": "Moving to DESTROYED: %s (removed from history)",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "585096182": {
       "message": "SURFACE isColorSpaceAgnostic=%b: %s",
       "level": "INFO",
@@ -1969,6 +2389,12 @@
       "group": "WM_DEBUG_SCREEN_ON",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "674932310": {
+      "message": "Setting Intent of %s to target %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
     "685047360": {
       "message": "Resizing window %s",
       "level": "VERBOSE",
@@ -1993,12 +2419,24 @@
       "group": "WM_ERROR",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "709500946": {
+      "message": "resumeTopActivityLocked: Skip resume: need to start pausing",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
     "715749922": {
       "message": "Allowlisting %d:%s",
       "level": "WARN",
       "group": "WM_DEBUG_LOCKTASK",
       "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
     },
+    "726205185": {
+      "message": "Moving to DESTROYED: %s (destroy skipped)",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "736692676": {
       "message": "Config is relaunching %s",
       "level": "VERBOSE",
@@ -2083,6 +2521,12 @@
       "group": "WM_DEBUG_RECENTS_ANIMATIONS",
       "at": "com\/android\/server\/wm\/RecentsAnimation.java"
     },
+    "864551564": {
+      "message": "Launch on display check: disallow activity embedding without permission.",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/ActivityStackSupervisor.java"
+    },
     "869266572": {
       "message": "Removing activity %s from stack, reason= %s callers=%s",
       "level": "INFO",
@@ -2101,12 +2545,30 @@
       "group": "WM_DEBUG_REMOTE_ANIMATIONS",
       "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
     },
+    "875196661": {
+      "message": "Skipping stack: (mismatch activity\/stack) %s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/TaskDisplayArea.java"
+    },
     "892244061": {
       "message": "Waiting for drawn %s: removed=%b visible=%b mHasSurface=%b drawState=%d",
       "level": "INFO",
       "group": "WM_DEBUG_SCREEN_ON",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "895158150": {
+      "message": "allPausedActivitiesComplete: r=%s state=%s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
+    },
+    "897964776": {
+      "message": "Complete pause: %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
     "898863925": {
       "message": "Attempted to add QS dialog window with unknown token %s.  Aborting.",
       "level": "WARN",
@@ -2161,6 +2623,12 @@
       "group": "WM_DEBUG_REMOTE_ANIMATIONS",
       "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
     },
+    "988389910": {
+      "message": "resumeTopActivityLocked: Pausing %s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
     "996960396": {
       "message": "Starting Transition %d",
       "level": "VERBOSE",
@@ -2173,12 +2641,30 @@
       "group": "WM_DEBUG_SYNC_ENGINE",
       "at": "com\/android\/server\/wm\/BLASTSyncEngine.java"
     },
+    "1001509841": {
+      "message": "Auto-PIP allowed, entering PIP mode directly: %s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
     "1001904964": {
       "message": "***** BOOT TIMEOUT: forcing display enabled",
       "level": "WARN",
       "group": "WM_ERROR",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "1015542198": {
+      "message": "Launch on display check: displayId=%d callingPid=%d callingUid=%d",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/ActivityStackSupervisor.java"
+    },
+    "1023413388": {
+      "message": "Finish waiting for pause of: %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "1040675582": {
       "message": "Can't report activity configuration update - client not running, activityRecord=%s",
       "level": "WARN",
@@ -2191,6 +2677,12 @@
       "group": "WM_ERROR",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "1047769218": {
+      "message": "Finishing activity r=%s, result=%d, data=%s, reason=%s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "1049367566": {
       "message": "Sending to proc %s new config %s",
       "level": "VERBOSE",
@@ -2203,6 +2695,12 @@
       "group": "WM_DEBUG_ADD_REMOVE",
       "at": "com\/android\/server\/wm\/WindowState.java"
     },
+    "1068803972": {
+      "message": "Activity paused: token=%s, timeout=%b",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "1073230342": {
       "message": "startAnimation",
       "level": "DEBUG",
@@ -2221,6 +2719,12 @@
       "group": "WM_SHOW_SURFACE_ALLOC",
       "at": "com\/android\/server\/wm\/ScreenRotationAnimation.java"
     },
+    "1098891625": {
+      "message": "realStartActivityLocked: Skipping start of r=%s some activities pausing...",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityStackSupervisor.java"
+    },
     "1112047265": {
       "message": "finishDrawingWindow: %s mDrawState=%s",
       "level": "DEBUG",
@@ -2239,6 +2743,12 @@
       "group": "WM_ERROR",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "1126328412": {
+      "message": "Scheduling idle now: forceIdle=%b immediate=%b",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "1140424002": {
       "message": "Finished screen turning on...",
       "level": "INFO",
@@ -2263,12 +2773,24 @@
       "group": "WM_DEBUG_WINDOW_TRANSITIONS",
       "at": "com\/android\/server\/wm\/Transition.java"
     },
+    "1192413464": {
+      "message": "Comparing existing cls=%s \/aff=%s to new cls=%s \/aff=%s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
+    },
     "1208313423": {
       "message": "addWindowToken: Attempted to add token: %s for non-exiting displayId=%d",
       "level": "WARN",
       "group": "WM_ERROR",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "1217926207": {
+      "message": "Activity not running, resuming next.",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
     "1219600119": {
       "message": "addWindow: win=%s Callers=%s",
       "level": "DEBUG",
@@ -2305,12 +2827,24 @@
       "group": "WM_DEBUG_STARTING_WINDOW",
       "at": "com\/android\/server\/wm\/ActivityRecord.java"
     },
+    "1270792394": {
+      "message": "Resumed after relaunch %s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "1288731814": {
       "message": "WindowState.hideLw: setting mFocusMayChange true",
       "level": "INFO",
       "group": "WM_DEBUG_FOCUS_LIGHT",
       "at": "com\/android\/server\/wm\/WindowState.java"
     },
+    "1316533291": {
+      "message": "State movement: %s from:%s to:%s reason:%s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "1325649102": {
       "message": "Bad requesting window %s",
       "level": "WARN",
@@ -2353,6 +2887,12 @@
       "group": "WM_DEBUG_CONFIGURATION",
       "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
     },
+    "1364126018": {
+      "message": "Resumed activity; dropping state of: %s",
+      "level": "INFO",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "1364498663": {
       "message": "notifyAppResumed: wasStopped=%b %s",
       "level": "VERBOSE",
@@ -2503,6 +3043,12 @@
       "group": "WM_DEBUG_IME",
       "at": "com\/android\/server\/wm\/WindowState.java"
     },
+    "1557732761": {
+      "message": "For Intent %s bringing to top: %s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
+    },
     "1563755163": {
       "message": "Permission Denial: %s from pid=%d, uid=%d requires %s",
       "level": "WARN",
@@ -2527,12 +3073,24 @@
       "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
       "at": "com\/android\/server\/wm\/WindowContainer.java"
     },
+    "1585450696": {
+      "message": "resumeTopActivityLocked: Restarting %s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
     "1589610525": {
       "message": "applyAnimation NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS: anim=%s transit=%s isEntrance=true Callers=%s",
       "level": "VERBOSE",
       "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
       "at": "com\/android\/server\/wm\/AppTransition.java"
     },
+    "1610646518": {
+      "message": "Enqueueing pending finish: %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "1628345525": {
       "message": "Now opening app %s",
       "level": "VERBOSE",
@@ -2593,6 +3151,18 @@
       "group": "WM_DEBUG_CONFIGURATION",
       "at": "com\/android\/server\/wm\/ActivityRecord.java"
     },
+    "1696210756": {
+      "message": "Launch on display check: allow launch on public display",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/ActivityStackSupervisor.java"
+    },
+    "1706082525": {
+      "message": "Stopping %s: nowVisible=%b animating=%b finishing=%s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/ActivityStackSupervisor.java"
+    },
     "1720229827": {
       "message": "Creating animation bounds layer",
       "level": "INFO",
@@ -2659,6 +3229,12 @@
       "group": "WM_DEBUG_WINDOW_TRANSITIONS",
       "at": "com\/android\/server\/wm\/TransitionController.java"
     },
+    "1804435108": {
+      "message": "allResumedActivitiesIdle: stack=%d %s not idle",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
+    },
     "1822843721": {
       "message": "Aborted starting %s: startingData=%s",
       "level": "VERBOSE",
@@ -2695,6 +3271,12 @@
       "group": "WM_DEBUG_ORIENTATION",
       "at": "com\/android\/server\/wm\/ActivityRecord.java"
     },
+    "1837992242": {
+      "message": "Executing finish of activity: %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
     "1853793312": {
       "message": "Notify removed startingWindow %s",
       "level": "VERBOSE",
@@ -2713,12 +3295,24 @@
       "group": "WM_ERROR",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "1884961873": {
+      "message": "Sleep still need to stop %d activities",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
     "1891501279": {
       "message": "cancelAnimation(): reason=%s",
       "level": "DEBUG",
       "group": "WM_DEBUG_REMOTE_ANIMATIONS",
       "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
     },
+    "1894239744": {
+      "message": "Enqueueing pending pause: %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STATES",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
     "1903353011": {
       "message": "notifyAppStopped: %s",
       "level": "VERBOSE",
@@ -2749,6 +3343,12 @@
       "group": "WM_DEBUG_ORIENTATION",
       "at": "com\/android\/server\/wm\/DisplayRotation.java"
     },
+    "1947936538": {
+      "message": "Found matching class!",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
+    },
     "1964565370": {
       "message": "Starting remote animation",
       "level": "INFO",
@@ -2827,12 +3427,24 @@
       "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
       "at": "com\/android\/server\/wm\/AppTransition.java"
     },
+    "2034714267": {
+      "message": "Launch on display check: allow launch for caller present on the display",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/ActivityStackSupervisor.java"
+    },
     "2034780299": {
       "message": "CHECK_IF_BOOT_ANIMATION_FINISHED:",
       "level": "INFO",
       "group": "WM_DEBUG_BOOT",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "2039056415": {
+      "message": "Found matching affinity candidate!",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
+    },
     "2045641491": {
       "message": "Checking %d opening apps (frozen=%b timeout=%b)...",
       "level": "VERBOSE",
@@ -2881,6 +3493,12 @@
       "group": "WM_DEBUG_ADD_REMOVE",
       "at": "com\/android\/server\/wm\/WindowState.java"
     },
+    "2117696413": {
+      "message": "moveTaskToFront: moving taskId=%d",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_TASKS",
+      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
+    },
     "2119122320": {
       "message": "setInputMethodTarget %s",
       "level": "INFO",
@@ -2964,12 +3582,18 @@
     "WM_DEBUG_STARTING_WINDOW": {
       "tag": "WindowManager"
     },
+    "WM_DEBUG_STATES": {
+      "tag": "WindowManager"
+    },
     "WM_DEBUG_SWITCH": {
       "tag": "WindowManager"
     },
     "WM_DEBUG_SYNC_ENGINE": {
       "tag": "WindowManager"
     },
+    "WM_DEBUG_TASKS": {
+      "tag": "WindowManager"
+    },
     "WM_DEBUG_WINDOW_MOVEMENT": {
       "tag": "WindowManager"
     },
diff --git a/errorprone/java/com/google/errorprone/bugpatterns/android/CompatChangeChecker.java b/errorprone/java/com/google/errorprone/bugpatterns/android/CompatChangeChecker.java
new file mode 100644
index 0000000..9c84f50
--- /dev/null
+++ b/errorprone/java/com/google/errorprone/bugpatterns/android/CompatChangeChecker.java
@@ -0,0 +1,125 @@
+/*
+ * 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.google.errorprone.bugpatterns.android;
+
+import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
+import static com.google.errorprone.bugpatterns.android.TargetSdkChecker.binaryTreeExact;
+import static com.google.errorprone.matchers.FieldMatchers.anyFieldInClass;
+import static com.google.errorprone.matchers.FieldMatchers.staticField;
+import static com.google.errorprone.matchers.Matchers.allOf;
+import static com.google.errorprone.matchers.Matchers.anyOf;
+import static com.google.errorprone.matchers.Matchers.anything;
+import static com.google.errorprone.matchers.Matchers.kindIs;
+import static com.google.errorprone.matchers.Matchers.not;
+
+import com.google.auto.service.AutoService;
+import com.google.errorprone.BugPattern;
+import com.google.errorprone.VisitorState;
+import com.google.errorprone.bugpatterns.BugChecker;
+import com.google.errorprone.bugpatterns.BugChecker.BinaryTreeMatcher;
+import com.google.errorprone.matchers.Description;
+import com.google.errorprone.matchers.Matcher;
+import com.sun.source.tree.BinaryTree;
+import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.Tree.Kind;
+
+/**
+ * Each SDK level often has dozens of different behavior changes, which can be
+ * difficult for large app developers to adjust to during preview or beta
+ * releases. For this reason, {@code android.app.compat.CompatChanges} was
+ * introduced as a new best-practice for adding behavior changes.
+ * <p>
+ * During a preview or beta release, developers can temporarily opt-out of each
+ * individual change to aid debugging. This opt-out is only available during
+ * preview of beta releases, and cannot be adjusted on finalized builds.
+ */
+@AutoService(BugChecker.class)
+@BugPattern(
+    name = "AndroidFrameworkCompatChange",
+    summary = "Verifies that behavior changes use the modern compatibility framework",
+    severity = WARNING)
+public final class CompatChangeChecker extends BugChecker implements BinaryTreeMatcher {
+    private static final Matcher<ExpressionTree> VERSION_CODE =
+            anyFieldInClass("android.os.Build.VERSION_CODES");
+
+    // Ship has already sailed on these SDK levels; not worth fixing
+    private static final Matcher<ExpressionTree> LEGACY_VERSION_CODE = anyOf(
+            staticField("android.os.Build.VERSION_CODES", "BASE"),
+            staticField("android.os.Build.VERSION_CODES", "BASE_1_1"),
+            staticField("android.os.Build.VERSION_CODES", "CUPCAKE"),
+            staticField("android.os.Build.VERSION_CODES", "DONUT"),
+            staticField("android.os.Build.VERSION_CODES", "ECLAIR"),
+            staticField("android.os.Build.VERSION_CODES", "ECLAIR_0_1"),
+            staticField("android.os.Build.VERSION_CODES", "ECLAIR_MR1"),
+            staticField("android.os.Build.VERSION_CODES", "FROYO"),
+            staticField("android.os.Build.VERSION_CODES", "GINGERBREAD"),
+            staticField("android.os.Build.VERSION_CODES", "GINGERBREAD_MR1"),
+            staticField("android.os.Build.VERSION_CODES", "HONEYCOMB"),
+            staticField("android.os.Build.VERSION_CODES", "HONEYCOMB_MR1"),
+            staticField("android.os.Build.VERSION_CODES", "HONEYCOMB_MR2"),
+            staticField("android.os.Build.VERSION_CODES", "ICE_CREAM_SANDWICH"),
+            staticField("android.os.Build.VERSION_CODES", "ICE_CREAM_SANDWICH_MR1"),
+            staticField("android.os.Build.VERSION_CODES", "JELLY_BEAN"),
+            staticField("android.os.Build.VERSION_CODES", "JELLY_BEAN_MR1"),
+            staticField("android.os.Build.VERSION_CODES", "JELLY_BEAN_MR2"),
+            staticField("android.os.Build.VERSION_CODES", "KITKAT"),
+            staticField("android.os.Build.VERSION_CODES", "KITKAT_WATCH"),
+            staticField("android.os.Build.VERSION_CODES", "L"),
+            staticField("android.os.Build.VERSION_CODES", "LOLLIPOP"),
+            staticField("android.os.Build.VERSION_CODES", "LOLLIPOP_MR1"),
+            staticField("android.os.Build.VERSION_CODES", "M"),
+            staticField("android.os.Build.VERSION_CODES", "N"),
+            staticField("android.os.Build.VERSION_CODES", "N_MR1"),
+            staticField("android.os.Build.VERSION_CODES", "O"),
+            staticField("android.os.Build.VERSION_CODES", "O_MR1"),
+            staticField("android.os.Build.VERSION_CODES", "P"),
+            staticField("android.os.Build.VERSION_CODES", "Q"),
+            staticField("android.os.Build.VERSION_CODES", "R"));
+
+    private static final Matcher<ExpressionTree> R_VERSION_CODE =
+            staticField("android.os.Build.VERSION_CODES", "R");
+
+    private static final Matcher<ExpressionTree> CUR_DEVELOPMENT_VERSION_CODE =
+            staticField("android.os.Build.VERSION_CODES", "CUR_DEVELOPMENT");
+
+    private static final Matcher<ExpressionTree> MODERN_VERSION_CODE =
+            allOf(VERSION_CODE, not(LEGACY_VERSION_CODE), not(CUR_DEVELOPMENT_VERSION_CODE));
+
+    private static final Matcher<ExpressionTree> BOOLEAN_OPERATOR = anyOf(
+            kindIs(Kind.LESS_THAN), kindIs(Kind.LESS_THAN_EQUAL),
+            kindIs(Kind.GREATER_THAN), kindIs(Kind.GREATER_THAN_EQUAL),
+            kindIs(Kind.EQUAL_TO), kindIs(Kind.NOT_EQUAL_TO));
+
+    private static final Matcher<BinaryTree> INVALID = anyOf(
+            allOf(BOOLEAN_OPERATOR, binaryTreeExact(MODERN_VERSION_CODE, anything())),
+            allOf(BOOLEAN_OPERATOR, binaryTreeExact(anything(), MODERN_VERSION_CODE)),
+            allOf(kindIs(Kind.GREATER_THAN), binaryTreeExact(anything(), R_VERSION_CODE)),
+            allOf(kindIs(Kind.LESS_THAN), binaryTreeExact(R_VERSION_CODE, anything())));
+
+    @Override
+    public Description matchBinary(BinaryTree tree, VisitorState state) {
+        if (INVALID.matches(tree, state)) {
+            return buildDescription(tree)
+                    .setMessage("Behavior changes should use CompatChanges.isChangeEnabled() "
+                            + "instead of direct SDK checks to ease developer transitions; "
+                            + "see go/compat-framework for more details")
+                    .build();
+
+        }
+        return Description.NO_MATCH;
+    }
+}
diff --git a/errorprone/java/com/google/errorprone/bugpatterns/android/TargetSdkChecker.java b/errorprone/java/com/google/errorprone/bugpatterns/android/TargetSdkChecker.java
index 232cf3f..e1ebf42 100644
--- a/errorprone/java/com/google/errorprone/bugpatterns/android/TargetSdkChecker.java
+++ b/errorprone/java/com/google/errorprone/bugpatterns/android/TargetSdkChecker.java
@@ -89,7 +89,7 @@
         return Description.NO_MATCH;
     }
 
-    private static Matcher<BinaryTree> binaryTreeExact(Matcher<ExpressionTree> left,
+    static Matcher<BinaryTree> binaryTreeExact(Matcher<ExpressionTree> left,
             Matcher<ExpressionTree> right) {
         return new Matcher<BinaryTree>() {
             @Override
diff --git a/errorprone/java/com/google/errorprone/matchers/FieldMatchers.java b/errorprone/java/com/google/errorprone/matchers/FieldMatchers.java
index 46f0fb2..08969d6 100644
--- a/errorprone/java/com/google/errorprone/matchers/FieldMatchers.java
+++ b/errorprone/java/com/google/errorprone/matchers/FieldMatchers.java
@@ -36,7 +36,8 @@
     return new FieldReferenceMatcher() {
       @Override
       boolean classIsAppropriate(ClassSymbol classSymbol) {
-        return classSymbol.getQualifiedName().contentEquals(className);
+        return classSymbol != null
+                && classSymbol.getQualifiedName().contentEquals(className);
       }
 
       @Override
@@ -50,12 +51,14 @@
     return new FieldReferenceMatcher() {
       @Override
       boolean classIsAppropriate(ClassSymbol classSymbol) {
-        return classSymbol.getQualifiedName().contentEquals(className);
+        return classSymbol != null
+                && classSymbol.getQualifiedName().contentEquals(className);
       }
 
       @Override
       boolean fieldSymbolIsAppropriate(Symbol symbol) {
-        return symbol.isStatic() && symbol.getSimpleName().contentEquals(fieldName);
+        return symbol != null
+                && symbol.isStatic() && symbol.getSimpleName().contentEquals(fieldName);
       }
     };
   }
@@ -64,12 +67,14 @@
     return new FieldReferenceMatcher() {
       @Override
       boolean classIsAppropriate(ClassSymbol classSymbol) {
-        return classSymbol.getQualifiedName().contentEquals(className);
+        return classSymbol != null
+                && classSymbol.getQualifiedName().contentEquals(className);
       }
 
       @Override
       boolean fieldSymbolIsAppropriate(Symbol symbol) {
-        return !symbol.isStatic() && symbol.getSimpleName().contentEquals(fieldName);
+        return symbol != null
+                && !symbol.isStatic() && symbol.getSimpleName().contentEquals(fieldName);
       }
     };
   }
diff --git a/errorprone/tests/java/com/google/errorprone/bugpatterns/android/CompatChangeCheckerTest.java b/errorprone/tests/java/com/google/errorprone/bugpatterns/android/CompatChangeCheckerTest.java
new file mode 100644
index 0000000..4625d43
--- /dev/null
+++ b/errorprone/tests/java/com/google/errorprone/bugpatterns/android/CompatChangeCheckerTest.java
@@ -0,0 +1,102 @@
+/*
+ * 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.google.errorprone.bugpatterns.android;
+
+import com.google.errorprone.CompilationTestHelper;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class CompatChangeCheckerTest {
+    private CompilationTestHelper compilationHelper;
+
+    @Before
+    public void setUp() {
+        compilationHelper = CompilationTestHelper.newInstance(
+                CompatChangeChecker.class, getClass());
+    }
+
+    @Test
+    public void testSimple() {
+        compilationHelper
+                .addSourceFile("/android/os/Build.java")
+                .addSourceLines("Example.java",
+                        "import android.os.Build;",
+                        "public class Example {",
+                        "  void test(int targetSdkVersion) {",
+                        "    // BUG: Diagnostic contains:",
+                        "    if (targetSdkVersion < Build.VERSION_CODES.S) { }",
+                        "    // BUG: Diagnostic contains:",
+                        "    if (targetSdkVersion <= Build.VERSION_CODES.S) { }",
+                        "    // BUG: Diagnostic contains:",
+                        "    if (targetSdkVersion > Build.VERSION_CODES.S) { }",
+                        "    // BUG: Diagnostic contains:",
+                        "    if (targetSdkVersion >= Build.VERSION_CODES.S) { }",
+                        "    // BUG: Diagnostic contains:",
+                        "    if (targetSdkVersion == Build.VERSION_CODES.S) { }",
+                        "    // BUG: Diagnostic contains:",
+                        "    if (targetSdkVersion != Build.VERSION_CODES.S) { }",
+                        "  }",
+                        "}")
+                .doTest();
+    }
+
+    @Test
+    public void testObscure() {
+        compilationHelper
+                .addSourceFile("/android/os/Build.java")
+                .addSourceLines("Example.java",
+                        "import android.os.Build;",
+                        "import static android.os.Build.VERSION_CODES.S;",
+                        "public class Example {",
+                        "  void test(int targetSdkVersion) {",
+                        "    // BUG: Diagnostic contains:",
+                        "    boolean indirect = S >= targetSdkVersion;",
+                        "    // BUG: Diagnostic contains:",
+                        "    if (targetSdkVersion > Build.VERSION_CODES.R) { }",
+                        "    if (targetSdkVersion >= Build.VERSION_CODES.R) { }",
+                        "    if (targetSdkVersion < Build.VERSION_CODES.R) { }",
+                        "    if (targetSdkVersion <= Build.VERSION_CODES.R) { }",
+                        "    // BUG: Diagnostic contains:",
+                        "    if (Build.VERSION_CODES.R < targetSdkVersion) { }",
+                        "    if (Build.VERSION_CODES.R <= targetSdkVersion) { }",
+                        "    if (Build.VERSION_CODES.R > targetSdkVersion) { }",
+                        "    if (Build.VERSION_CODES.R >= targetSdkVersion) { }",
+                        "  }",
+                        "}")
+                .doTest();
+    }
+
+    @Test
+    public void testIgnored() {
+        compilationHelper
+                .addSourceFile("/android/os/Build.java")
+                .addSourceLines("Example.java",
+                        "import android.os.Build;",
+                        "public class Example {",
+                        "  void test(int targetSdkVersion) {",
+                        "    if (targetSdkVersion < Build.VERSION_CODES.DONUT) { }",
+                        "    String result = \"test\" + Build.VERSION_CODES.S;",
+                        "    if (targetSdkVersion != Build.VERSION_CODES.CUR_DEVELOPMENT) { }",
+                        "  }",
+                        "}")
+                .doTest();
+    }
+}
diff --git a/errorprone/tests/res/android/os/Build.java b/errorprone/tests/res/android/os/Build.java
index bbf7ef2..2d354e2 100644
--- a/errorprone/tests/res/android/os/Build.java
+++ b/errorprone/tests/res/android/os/Build.java
@@ -18,6 +18,9 @@
 
 public class Build {
     public static class VERSION_CODES {
+        public static final int CUR_DEVELOPMENT = 10000;
         public static final int DONUT = 4;
+        public static final int R = 30;
+        public static final int S = CUR_DEVELOPMENT;
     }
 }
diff --git a/non-updatable-api/system-current.txt b/non-updatable-api/system-current.txt
index f116c80..1849529 100644
--- a/non-updatable-api/system-current.txt
+++ b/non-updatable-api/system-current.txt
@@ -95,6 +95,7 @@
     field public static final String INJECT_EVENTS = "android.permission.INJECT_EVENTS";
     field public static final String INSTALL_DYNAMIC_SYSTEM = "android.permission.INSTALL_DYNAMIC_SYSTEM";
     field public static final String INSTALL_GRANT_RUNTIME_PERMISSIONS = "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS";
+    field public static final String INSTALL_LOCATION_TIME_ZONE_PROVIDER = "android.permission.INSTALL_LOCATION_TIME_ZONE_PROVIDER";
     field public static final String INSTALL_PACKAGE_UPDATES = "android.permission.INSTALL_PACKAGE_UPDATES";
     field public static final String INSTALL_SELF_UPDATES = "android.permission.INSTALL_SELF_UPDATES";
     field public static final String INTENT_FILTER_VERIFICATION_AGENT = "android.permission.INTENT_FILTER_VERIFICATION_AGENT";
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index d2485cc..506b608 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -892,9 +892,6 @@
                 Settings.Global.LOCATION_SETTINGS_LINK_TO_PERMISSIONS_ENABLED,
                 GlobalSettingsProto.Location.SETTINGS_LINK_TO_PERMISSIONS_ENABLED);
         dumpSetting(s, p,
-                Settings.Global.LOCATION_GLOBAL_KILL_SWITCH,
-                GlobalSettingsProto.Location.GLOBAL_KILL_SWITCH);
-        dumpSetting(s, p,
                 Settings.Global.GNSS_SATELLITE_BLACKLIST,
                 GlobalSettingsProto.Location.GNSS_SATELLITE_BLACKLIST);
         dumpSetting(s, p,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 3ccb1f4..710c016 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -328,10 +328,6 @@
         return SettingsState.getUserIdFromKey(key);
     }
 
-    public static String settingTypeToString(int type) {
-        return SettingsState.settingTypeToString(type);
-    }
-
     public static String keyToString(int key) {
         return SettingsState.keyToString(key);
     }
@@ -373,8 +369,7 @@
             }
 
             case Settings.CALL_METHOD_GET_SECURE: {
-                Setting setting = getSecureSetting(name, requestingUserId,
-                        /*enableOverride=*/ true);
+                Setting setting = getSecureSetting(name, requestingUserId);
                 return packageValueForCallResult(setting, isTrackingGeneration(args));
             }
 
@@ -581,7 +576,7 @@
     }
 
     private ArrayList<String> buildSettingsList(Cursor cursor) {
-        final ArrayList<String> lines = new ArrayList<String>();
+        final ArrayList<String> lines = new ArrayList<>();
         try {
             while (cursor != null && cursor.moveToNext()) {
                 lines.add(cursor.getString(1) + "=" + cursor.getString(2));
@@ -1381,10 +1376,6 @@
     }
 
     private Setting getSecureSetting(String name, int requestingUserId) {
-        return getSecureSetting(name, requestingUserId, /*enableOverride=*/ false);
-    }
-
-    private Setting getSecureSetting(String name, int requestingUserId, boolean enableOverride) {
         if (DEBUG) {
             Slog.v(LOG_TAG, "getSecureSetting(" + name + ", " + requestingUserId + ")");
         }
@@ -1414,14 +1405,6 @@
                 return getSsaidSettingLocked(callingPkg, owningUserId);
             }
         }
-        if (enableOverride) {
-            if (Secure.LOCATION_MODE.equals(name)) {
-                final Setting overridden = getLocationModeSetting(owningUserId);
-                if (overridden != null) {
-                    return overridden;
-                }
-            }
-        }
 
         // Not the SSAID; do a straight lookup
         synchronized (mLock) {
@@ -1511,35 +1494,6 @@
         return null;
     }
 
-    private Setting getLocationModeSetting(int owningUserId) {
-        synchronized (mLock) {
-            final Setting setting = getGlobalSetting(
-                    Global.LOCATION_GLOBAL_KILL_SWITCH);
-            if (!"1".equals(setting.getValue())) {
-                return null;
-            }
-            // Global kill-switch is enabled. Return an empty value.
-            final SettingsState settingsState = mSettingsRegistry.getSettingsLocked(
-                    SETTINGS_TYPE_SECURE, owningUserId);
-            return settingsState.new Setting(
-                    Secure.LOCATION_MODE,
-                    "", // value
-                    "", // tag
-                    "", // default value
-                    "", // package name
-                    false, // from system
-                    "0" // id
-            ) {
-                @Override
-                public boolean update(String value, boolean setDefault, String packageName,
-                        String tag, boolean forceNonSystemPackage, boolean overrideableByRestore) {
-                    Slog.wtf(LOG_TAG, "update shouldn't be called on this instance.");
-                    return false;
-                }
-            };
-        }
-    }
-
     private boolean insertSecureSetting(String name, String value, String tag,
             boolean makeDefault, int requestingUserId, boolean forceNotify,
             boolean overrideableByRestore) {
@@ -1808,12 +1762,8 @@
 
     private boolean hasWriteSecureSettingsPermission() {
         // Write secure settings is a more protected permission. If caller has it we are good.
-        if (getContext().checkCallingOrSelfPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
-                == PackageManager.PERMISSION_GRANTED) {
-            return true;
-        }
-
-        return false;
+        return getContext().checkCallingOrSelfPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
+                == PackageManager.PERMISSION_GRANTED;
     }
 
     private void validateSystemSettingValue(String name, String value) {
@@ -3174,12 +3124,6 @@
             if (isGlobalSettingsKey(key) || isConfigSettingsKey(key)) {
                 final long token = Binder.clearCallingIdentity();
                 try {
-                    if (Global.LOCATION_GLOBAL_KILL_SWITCH.equals(name)
-                            && isGlobalSettingsKey(key)) {
-                        // When the global kill switch is updated, send the
-                        // change notification for the location setting.
-                        notifyLocationChangeForRunningUsers();
-                    }
                     notifySettingChangeForRunningUsers(key, name);
                 } finally {
                     Binder.restoreCallingIdentity(token);
@@ -3257,26 +3201,6 @@
             }
         }
 
-        private void notifyLocationChangeForRunningUsers() {
-            final List<UserInfo> users = mUserManager.getAliveUsers();
-
-            for (int i = 0; i < users.size(); i++) {
-                final int userId = users.get(i).id;
-
-                if (!mUserManager.isUserRunning(UserHandle.of(userId))) {
-                    continue;
-                }
-
-                // Increment the generation first, so observers always see the new value
-                final int key = makeKey(SETTINGS_TYPE_SECURE, userId);
-                mGenerationRegistry.incrementGeneration(key);
-
-                final Uri uri = getNotificationUriFor(key, Secure.LOCATION_MODE);
-                mHandler.obtainMessage(MyHandler.MSG_NOTIFY_URI_CHANGED,
-                        userId, 0, uri).sendToTarget();
-            }
-        }
-
         private boolean isConfigSettingsKey(int key) {
             return getTypeFromKey(key) == SETTINGS_TYPE_CONFIG;
         }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index 6678cf6..b061df1 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -34,7 +34,6 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings;
-import android.provider.Settings.Global;
 import android.providers.settings.SettingsOperationProto;
 import android.text.TextUtils;
 import android.util.ArrayMap;
@@ -47,7 +46,6 @@
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FrameworkStatsLog;
 
 import libcore.io.IoUtils;
@@ -817,13 +815,6 @@
                 for (int i = 0; i < settingCount; i++) {
                     Setting setting = settings.valueAt(i);
 
-                    if (setting.isTransient()) {
-                        if (DEBUG_PERSISTENCE) {
-                            Slog.i(LOG_TAG, "[SKIPPED PERSISTING]" + setting.getName());
-                        }
-                        continue;
-                    }
-
                     writeSingleSetting(mVersion, serializer, setting.getId(), setting.getName(),
                             setting.getValue(), setting.getDefaultValue(), setting.getPackageName(),
                             setting.getTag(), setting.isDefaultFromSystem(),
@@ -1109,8 +1100,7 @@
                         ATTR_DEFAULT_VALUE_BASE64);
                 String isPreservedInRestoreString = parser.getAttributeValue(null,
                         ATTR_PRESERVE_IN_RESTORE);
-                boolean isPreservedInRestore = isPreservedInRestoreString != null
-                        && Boolean.parseBoolean(isPreservedInRestoreString);
+                boolean isPreservedInRestore = Boolean.parseBoolean(isPreservedInRestoreString);
                 String tag = null;
                 boolean fromSystem = false;
                 if (defaultValue != null) {
@@ -1308,14 +1298,6 @@
                     /* resetToDefault */ true);
         }
 
-        public boolean isTransient() {
-            switch (getTypeFromKey(getKey())) {
-                case SETTINGS_TYPE_GLOBAL:
-                    return ArrayUtils.contains(Global.TRANSIENT_SETTINGS, getName());
-            }
-            return false;
-        }
-
         public boolean update(String value, boolean setDefault, String packageName, String tag,
                 boolean forceNonSystemPackage, boolean overrideableByRestore) {
             return update(value, setDefault, packageName, tag, forceNonSystemPackage,
@@ -1444,7 +1426,7 @@
     }
 
     private static String fromBytes(byte[] bytes) {
-        final StringBuffer sb = new StringBuffer(bytes.length / 2);
+        final StringBuilder sb = new StringBuilder(bytes.length / 2);
 
         final int last = bytes.length - 1;
 
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
index 911bf9e..a705ec7 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
@@ -37,6 +37,7 @@
 import com.android.systemui.SystemUI;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.statusbar.CommandQueue;
 
 import javax.inject.Inject;
@@ -66,7 +67,8 @@
 
     @Inject
     public WindowMagnification(Context context, @Main Handler mainHandler,
-            CommandQueue commandQueue, ModeSwitchesController modeSwitchesController) {
+            CommandQueue commandQueue, ModeSwitchesController modeSwitchesController,
+            NavigationModeController navigationModeController) {
         super(context);
         mHandler = mainHandler;
         mLastConfiguration = new Configuration(context.getResources().getConfiguration());
@@ -77,6 +79,9 @@
         final WindowMagnificationController controller = new WindowMagnificationController(mContext,
                 mHandler, new SfVsyncFrameCallbackProvider(), null,
                 new SurfaceControl.Transaction(), this);
+        final int navBarMode = navigationModeController.addListener(
+                controller::onNavigationModeChanged);
+        controller.onNavigationModeChanged(navBarMode);
         mWindowMagnificationAnimationController = new WindowMagnificationAnimationController(
                 mContext, controller);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
index 3832ff30..c3474bb 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
@@ -17,6 +17,8 @@
 package com.android.systemui.accessibility;
 
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -117,6 +119,9 @@
     // The boundary of magnification frame.
     private final Rect mMagnificationFrameBoundary = new Rect();
 
+    private int mNavBarMode;
+    private int mNavGestureHeight;
+
     private final SfVsyncFrameCallbackProvider mSfVsyncFrameProvider;
     private Choreographer.FrameCallback mMirrorViewGeometryVsyncCallback;
     private Locale mLocale;
@@ -195,6 +200,19 @@
                 R.dimen.magnification_drag_view_size);
         mOuterBorderSize = mResources.getDimensionPixelSize(
                 R.dimen.magnification_outer_border_margin);
+        updateNavigationBarDimensions();
+    }
+
+    private void updateNavigationBarDimensions() {
+        if (!supportsSwipeUpGesture()) {
+            mNavGestureHeight = 0;
+            return;
+        }
+        mNavGestureHeight = (mDisplaySize.x > mDisplaySize.y)
+                ? mResources.getDimensionPixelSize(
+                com.android.internal.R.dimen.navigation_bar_height_landscape)
+                : mResources.getDimensionPixelSize(
+                        com.android.internal.R.dimen.navigation_bar_gesture_height);
     }
 
     /**
@@ -239,6 +257,13 @@
         }
     }
 
+    /** Handles MirrorWindow position when the navigation bar mode changed. */
+    public void onNavigationModeChanged(int mode) {
+        mNavBarMode = mode;
+        updateNavigationBarDimensions();
+        updateMirrorViewLayout();
+    }
+
     /** Handles MirrorWindow position when the device rotation changed. */
     private void onRotate() {
         final Display display = mContext.getDisplay();
@@ -246,6 +271,7 @@
         display.getRealSize(mDisplaySize);
         setMagnificationFrameBoundary();
         mRotation = display.getRotation();
+        updateNavigationBarDimensions();
 
         if (!isWindowVisible()) {
             return;
@@ -401,15 +427,23 @@
      * moved close to the screen edges.
      */
     private void updateMirrorViewLayout() {
+        if (!isWindowVisible()) {
+            return;
+        }
+        final int maxMirrorViewX = mDisplaySize.x - mMirrorView.getWidth();
+        final int maxMirrorViewY = mDisplaySize.y - mMirrorView.getHeight() - mNavGestureHeight;
         WindowManager.LayoutParams params =
                 (WindowManager.LayoutParams) mMirrorView.getLayoutParams();
         params.x = mMagnificationFrame.left - mMirrorSurfaceMargin;
         params.y = mMagnificationFrame.top - mMirrorSurfaceMargin;
+        // If nav bar mode supports swipe-up gesture, the Y position of mirror view should not
+        // overlap nav bar window to prevent window-dragging obscured.
+        if (supportsSwipeUpGesture()) {
+            params.y = Math.min(params.y, maxMirrorViewY);
+        }
 
         // Translates MirrorView position to make MirrorSurfaceView that is inside MirrorView
         // able to move close to the screen edges.
-        final int maxMirrorViewX = mDisplaySize.x - mMirrorView.getWidth();
-        final int maxMirrorViewY = mDisplaySize.y - mMirrorView.getHeight();
         final float translationX;
         final float translationY;
         if (params.x < 0) {
@@ -621,6 +655,10 @@
         return mMirrorView != null;
     }
 
+    private boolean supportsSwipeUpGesture() {
+        return mNavBarMode == NAV_BAR_MODE_2BUTTON || mNavBarMode == NAV_BAR_MODE_GESTURAL;
+    }
+
     private CharSequence formatStateDescription(float scale) {
         // Cache the locale-appropriate NumberFormat.  Configuration locale is guaranteed
         // non-null, so the first time this is called we will always get the appropriate
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java
index fa33284..1e239b1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java
@@ -17,30 +17,44 @@
 package com.android.systemui.qs;
 
 import com.android.systemui.R;
+import com.android.systemui.util.ViewController;
 
 import javax.inject.Inject;
 
-public class QSContainerImplController {
-    private final QSContainerImpl mView;
+class QSContainerImplController extends ViewController<QSContainerImpl> {
     private final QuickStatusBarHeaderController mQuickStatusBarHeaderController;
 
     private QSContainerImplController(QSContainerImpl view,
             QuickStatusBarHeaderController.Builder quickStatusBarHeaderControllerBuilder) {
-        mView = view;
+        super(view);
         mQuickStatusBarHeaderController = quickStatusBarHeaderControllerBuilder
                 .setQuickStatusBarHeader(mView.findViewById(R.id.header)).build();
     }
 
+    @Override
+    public void init() {
+        super.init();
+        mQuickStatusBarHeaderController.init();
+    }
+
     public void setListening(boolean listening) {
         mQuickStatusBarHeaderController.setListening(listening);
     }
 
-    public static class Builder {
+    @Override
+    protected void onViewAttached() {
+    }
+
+    @Override
+    protected void onViewDetached() {
+    }
+
+    static class Builder {
         private final QuickStatusBarHeaderController.Builder mQuickStatusBarHeaderControllerBuilder;
         private QSContainerImpl mView;
 
         @Inject
-        public Builder(
+        Builder(
                 QuickStatusBarHeaderController.Builder quickStatusBarHeaderControllerBuilder) {
             mQuickStatusBarHeaderControllerBuilder = quickStatusBarHeaderControllerBuilder;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index f1bb899..3a78365 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -142,7 +142,7 @@
         mQSContainerImplController = mQSContainerImplControllerBuilder
                 .setQSContainerImpl((QSContainerImpl) view)
                 .build();
-
+        mQSContainerImplController.init();
 
         mQSDetail.setQsPanel(mQSPanel, mHeader, (View) mFooter);
         mQSAnimator = new QSAnimator(this, mHeader.findViewById(R.id.quick_qs_panel), mQSPanel);
@@ -367,14 +367,13 @@
         if (DEBUG) Log.d(TAG, "setListening " + listening);
         mListening = listening;
         mQSContainerImplController.setListening(listening);
-        mHeader.setListening(listening);
         mFooter.setListening(listening);
         mQSPanel.setListening(mListening, mQsExpanded);
     }
 
     @Override
     public void setHeaderListening(boolean listening) {
-        mHeader.setListening(listening);
+        mQSContainerImplController.setListening(listening);
         mFooter.setListening(listening);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index 544249a..a9fbc74 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -17,27 +17,16 @@
 import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS;
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 
-import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
-
 import android.annotation.ColorInt;
-import android.app.AlarmManager;
+import android.app.AlarmManager.AlarmClockInfo;
 import android.content.Context;
-import android.content.Intent;
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Color;
 import android.graphics.Rect;
 import android.media.AudioManager;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.provider.AlarmClock;
-import android.provider.Settings;
-import android.service.notification.ZenModeConfig;
-import android.text.format.DateUtils;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.util.MathUtils;
 import android.util.Pair;
 import android.view.ContextThemeWrapper;
@@ -53,93 +42,48 @@
 import android.widget.TextView;
 
 import androidx.annotation.NonNull;
-import androidx.annotation.VisibleForTesting;
 import androidx.lifecycle.Lifecycle;
 import androidx.lifecycle.LifecycleOwner;
 import androidx.lifecycle.LifecycleRegistry;
 
-import com.android.internal.logging.UiEventLogger;
 import com.android.settingslib.Utils;
 import com.android.systemui.BatteryMeterView;
 import com.android.systemui.DualToneHandler;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
-import com.android.systemui.demomode.DemoMode;
-import com.android.systemui.demomode.DemoModeController;
-import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
 import com.android.systemui.privacy.OngoingPrivacyChip;
-import com.android.systemui.privacy.PrivacyChipEvent;
-import com.android.systemui.privacy.PrivacyItem;
-import com.android.systemui.privacy.PrivacyItemController;
 import com.android.systemui.qs.QSDetail.Callback;
-import com.android.systemui.qs.carrier.QSCarrierGroup;
-import com.android.systemui.settings.UserTracker;
-import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager;
 import com.android.systemui.statusbar.phone.StatusBarWindowView;
-import com.android.systemui.statusbar.phone.StatusIconContainer;
 import com.android.systemui.statusbar.policy.Clock;
-import com.android.systemui.statusbar.policy.DateView;
-import com.android.systemui.statusbar.policy.NextAlarmController;
-import com.android.systemui.statusbar.policy.ZenModeController;
-import com.android.systemui.util.RingerModeTracker;
 
-import java.util.ArrayList;
-import java.util.List;
 import java.util.Locale;
 import java.util.Objects;
 
-import javax.inject.Inject;
-import javax.inject.Named;
-
 /**
  * View that contains the top-most bits of the screen (primarily the status bar with date, time, and
  * battery) and also contains the {@link QuickQSPanel} along with some of the panel's inner
  * contents.
  */
-public class QuickStatusBarHeader extends RelativeLayout implements
-        View.OnClickListener, NextAlarmController.NextAlarmChangeCallback,
-        ZenModeController.Callback, LifecycleOwner {
-    private static final String TAG = "QuickStatusBarHeader";
-    private static final boolean DEBUG = false;
+public class QuickStatusBarHeader extends RelativeLayout implements LifecycleOwner {
 
-    /** Delay for auto fading out the long press tooltip after it's fully visible (in ms). */
-    private static final long AUTO_FADE_OUT_DELAY_MS = DateUtils.SECOND_IN_MILLIS * 6;
-    private static final int FADE_ANIMATION_DURATION_MS = 300;
-    private static final int TOOLTIP_NOT_YET_SHOWN_COUNT = 0;
     public static final int MAX_TOOLTIP_SHOWN_COUNT = 2;
 
-    private final NextAlarmController mAlarmController;
-    private final ZenModeController mZenController;
-    private final StatusBarIconController mStatusBarIconController;
-    private final ActivityStarter mActivityStarter;
-
-    private QSPanel mQsPanel;
-
     private boolean mExpanded;
-    private boolean mListening;
     private boolean mQsDisabled;
 
-    private QSCarrierGroup mCarrierGroup;
     protected QuickQSPanel mHeaderQsPanel;
-    protected QSTileHost mHost;
-    private TintedIconManager mIconManager;
     private TouchAnimator mStatusIconsAlphaAnimator;
     private TouchAnimator mHeaderTextContainerAlphaAnimator;
     private TouchAnimator mPrivacyChipAlphaAnimator;
     private DualToneHandler mDualToneHandler;
-    private final CommandQueue mCommandQueue;
 
     private View mSystemIconsView;
     private View mQuickQsStatusIcons;
     private View mHeaderTextContainerView;
 
-    private int mRingerMode = AudioManager.RINGER_MODE_NORMAL;
-    private AlarmManager.AlarmClockInfo mNextAlarm;
-
     private ImageView mNextAlarmIcon;
     /** {@link TextView} containing the actual text indicating when the next alarm will go off. */
     private TextView mNextAlarmTextView;
@@ -149,23 +93,13 @@
     private TextView mRingerModeTextView;
     private View mRingerContainer;
     private Clock mClockView;
-    private DateView mDateView;
     private OngoingPrivacyChip mPrivacyChip;
     private Space mSpace;
     private BatteryMeterView mBatteryRemainingIcon;
-    private RingerModeTracker mRingerModeTracker;
-    private DemoModeController mDemoModeController;
-    private DemoMode mDemoModeReceiver;
-    private UserTracker mUserTracker;
-    private boolean mAllIndicatorsEnabled;
-    private boolean mMicCameraIndicatorsEnabled;
 
-    private PrivacyItemController mPrivacyItemController;
-    private final UiEventLogger mUiEventLogger;
     // Used for RingerModeTracker
     private final LifecycleRegistry mLifecycle = new LifecycleRegistry(this);
 
-    private boolean mHasTopCutout = false;
     private int mStatusBarPaddingTop = 0;
     private int mRoundedCornerPadding = 0;
     private int mContentMarginStart;
@@ -175,59 +109,11 @@
     private int mCutOutPaddingRight;
     private float mExpandedHeaderAlpha = 1.0f;
     private float mKeyguardExpansionFraction;
-    private boolean mPrivacyChipLogged = false;
 
-    private PrivacyItemController.Callback mPICCallback = new PrivacyItemController.Callback() {
-        @Override
-        public void onPrivacyItemsChanged(List<PrivacyItem> privacyItems) {
-            mPrivacyChip.setPrivacyList(privacyItems);
-            setChipVisibility(!privacyItems.isEmpty());
-        }
-
-        @Override
-        public void onFlagAllChanged(boolean flag) {
-            if (mAllIndicatorsEnabled != flag) {
-                mAllIndicatorsEnabled = flag;
-                update();
-            }
-        }
-
-        @Override
-        public void onFlagMicCameraChanged(boolean flag) {
-            if (mMicCameraIndicatorsEnabled != flag) {
-                mMicCameraIndicatorsEnabled = flag;
-                update();
-            }
-        }
-
-        private void update() {
-            StatusIconContainer iconContainer = requireViewById(R.id.statusIcons);
-            iconContainer.setIgnoredSlots(getIgnoredIconSlots());
-            setChipVisibility(!mPrivacyChip.getPrivacyList().isEmpty());
-        }
-    };
-
-    @Inject
-    public QuickStatusBarHeader(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
-            NextAlarmController nextAlarmController, ZenModeController zenModeController,
-            StatusBarIconController statusBarIconController,
-            ActivityStarter activityStarter, PrivacyItemController privacyItemController,
-            CommandQueue commandQueue, RingerModeTracker ringerModeTracker,
-            UiEventLogger uiEventLogger, DemoModeController demoModeController,
-            UserTracker userTracker) {
+    public QuickStatusBarHeader(Context context, AttributeSet attrs) {
         super(context, attrs);
-        mAlarmController = nextAlarmController;
-        mZenController = zenModeController;
-        mStatusBarIconController = statusBarIconController;
-        mActivityStarter = activityStarter;
-        mPrivacyItemController = privacyItemController;
         mDualToneHandler = new DualToneHandler(
                 new ContextThemeWrapper(context, R.style.QSHeaderTheme));
-        mCommandQueue = commandQueue;
-        mRingerModeTracker = ringerModeTracker;
-        mUiEventLogger = uiEventLogger;
-        mDemoModeController = demoModeController;
-        mUserTracker = userTracker;
     }
 
     @Override
@@ -237,11 +123,6 @@
         mHeaderQsPanel = findViewById(R.id.quick_qs_panel);
         mSystemIconsView = findViewById(R.id.quick_status_bar_system_icons);
         mQuickQsStatusIcons = findViewById(R.id.quick_qs_status_icons);
-        StatusIconContainer iconContainer = findViewById(R.id.statusIcons);
-        // Ignore privacy icons because they show in the space above QQS
-        iconContainer.addIgnoredSlots(getIgnoredIconSlots());
-        iconContainer.setShouldRestrictIcons(false);
-        mIconManager = new TintedIconManager(iconContainer, mCommandQueue);
 
         // Views corresponding to the header info section (e.g. ringer and next alarm).
         mHeaderTextContainerView = findViewById(R.id.header_text_container);
@@ -249,36 +130,18 @@
         mNextAlarmIcon = findViewById(R.id.next_alarm_icon);
         mNextAlarmTextView = findViewById(R.id.next_alarm_text);
         mNextAlarmContainer = findViewById(R.id.alarm_container);
-        mNextAlarmContainer.setOnClickListener(this::onClick);
         mRingerModeIcon = findViewById(R.id.ringer_mode_icon);
         mRingerModeTextView = findViewById(R.id.ringer_mode_text);
         mRingerContainer = findViewById(R.id.ringer_container);
-        mRingerContainer.setOnClickListener(this::onClick);
         mPrivacyChip = findViewById(R.id.privacy_chip);
-        mPrivacyChip.setOnClickListener(this::onClick);
-        mCarrierGroup = findViewById(R.id.carrier_group);
-
 
         updateResources();
 
         Rect tintArea = new Rect(0, 0, 0, 0);
-        int colorForeground = Utils.getColorAttrDefaultColor(getContext(),
-                android.R.attr.colorForeground);
-        float intensity = getColorIntensity(colorForeground);
-        int fillColor = mDualToneHandler.getSingleColor(intensity);
-
         // Set light text on the header icons because they will always be on a black background
         applyDarkness(R.id.clock, tintArea, 0, DarkIconDispatcher.DEFAULT_ICON_TINT);
 
-        // Set the correct tint for the status icons so they contrast
-        mIconManager.setTint(fillColor);
-        mNextAlarmIcon.setImageTintList(ColorStateList.valueOf(fillColor));
-        mRingerModeIcon.setImageTintList(ColorStateList.valueOf(fillColor));
-
         mClockView = findViewById(R.id.clock);
-        mClockView.setOnClickListener(this);
-        mDemoModeReceiver = new ClockDemoModeReceiver(mClockView);
-        mDateView = findViewById(R.id.date);
         mSpace = findViewById(R.id.space);
 
         // Tint for the battery icons are handled in setupHost()
@@ -290,33 +153,28 @@
         mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE);
         mRingerModeTextView.setSelected(true);
         mNextAlarmTextView.setSelected(true);
+    }
 
-        mAllIndicatorsEnabled = mPrivacyItemController.getAllIndicatorsAvailable();
-        mMicCameraIndicatorsEnabled = mPrivacyItemController.getMicCameraAvailable();
+    void onAttach(TintedIconManager iconManager) {
+        int colorForeground = Utils.getColorAttrDefaultColor(getContext(),
+                android.R.attr.colorForeground);
+        float intensity = getColorIntensity(colorForeground);
+        int fillColor = mDualToneHandler.getSingleColor(intensity);
+
+        // Set the correct tint for the status icons so they contrast
+        iconManager.setTint(fillColor);
+        mNextAlarmIcon.setImageTintList(ColorStateList.valueOf(fillColor));
+        mRingerModeIcon.setImageTintList(ColorStateList.valueOf(fillColor));
     }
 
     public QuickQSPanel getHeaderQsPanel() {
         return mHeaderQsPanel;
     }
 
-    private List<String> getIgnoredIconSlots() {
-        ArrayList<String> ignored = new ArrayList<>();
-        if (getChipEnabled()) {
-            ignored.add(mContext.getResources().getString(
-                    com.android.internal.R.string.status_bar_camera));
-            ignored.add(mContext.getResources().getString(
-                    com.android.internal.R.string.status_bar_microphone));
-            if (mAllIndicatorsEnabled) {
-                ignored.add(mContext.getResources().getString(
-                        com.android.internal.R.string.status_bar_location));
-            }
-        }
-
-        return ignored;
-    }
-
-    private void updateStatusText() {
-        boolean changed = updateRingerStatus() || updateAlarmStatus();
+    void updateStatusText(int ringerMode, AlarmClockInfo nextAlarm, boolean zenOverridingRinger,
+            boolean use24HourFormat) {
+        boolean changed = updateRingerStatus(ringerMode, zenOverridingRinger)
+                || updateAlarmStatus(nextAlarm, use24HourFormat);
 
         if (changed) {
             boolean alarmVisible = mNextAlarmTextView.getVisibility() == View.VISIBLE;
@@ -326,32 +184,17 @@
         }
     }
 
-    private void setChipVisibility(boolean chipVisible) {
-        if (chipVisible && getChipEnabled()) {
-            mPrivacyChip.setVisibility(View.VISIBLE);
-            // Makes sure that the chip is logged as viewed at most once each time QS is opened
-            // mListening makes sure that the callback didn't return after the user closed QS
-            if (!mPrivacyChipLogged && mListening) {
-                mPrivacyChipLogged = true;
-                mUiEventLogger.log(PrivacyChipEvent.ONGOING_INDICATORS_CHIP_VIEW);
-            }
-        } else {
-            mPrivacyChip.setVisibility(View.GONE);
-        }
-    }
-
-    private boolean updateRingerStatus() {
+    private boolean updateRingerStatus(int ringerMode, boolean zenOverridingRinger) {
         boolean isOriginalVisible = mRingerModeTextView.getVisibility() == View.VISIBLE;
         CharSequence originalRingerText = mRingerModeTextView.getText();
 
         boolean ringerVisible = false;
-        if (!ZenModeConfig.isZenOverridingRinger(mZenController.getZen(),
-                mZenController.getConsolidatedPolicy())) {
-            if (mRingerMode == AudioManager.RINGER_MODE_VIBRATE) {
+        if (!zenOverridingRinger) {
+            if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
                 mRingerModeIcon.setImageResource(R.drawable.ic_volume_ringer_vibrate);
                 mRingerModeTextView.setText(R.string.qs_status_phone_vibrate);
                 ringerVisible = true;
-            } else if (mRingerMode == AudioManager.RINGER_MODE_SILENT) {
+            } else if (ringerMode == AudioManager.RINGER_MODE_SILENT) {
                 mRingerModeIcon.setImageResource(R.drawable.ic_volume_ringer_mute);
                 mRingerModeTextView.setText(R.string.qs_status_phone_muted);
                 ringerVisible = true;
@@ -365,14 +208,14 @@
                 !Objects.equals(originalRingerText, mRingerModeTextView.getText());
     }
 
-    private boolean updateAlarmStatus() {
+    private boolean updateAlarmStatus(AlarmClockInfo nextAlarm, boolean use24HourFormat) {
         boolean isOriginalVisible = mNextAlarmTextView.getVisibility() == View.VISIBLE;
         CharSequence originalAlarmText = mNextAlarmTextView.getText();
 
         boolean alarmVisible = false;
-        if (mNextAlarm != null) {
+        if (nextAlarm != null) {
             alarmVisible = true;
-            mNextAlarmTextView.setText(formatNextAlarm(mNextAlarm));
+            mNextAlarmTextView.setText(formatNextAlarm(nextAlarm, use24HourFormat));
         }
         mNextAlarmIcon.setVisibility(alarmVisible ? View.VISIBLE : View.GONE);
         mNextAlarmTextView.setVisibility(alarmVisible ? View.VISIBLE : View.GONE);
@@ -419,7 +262,7 @@
         setMinimumHeight(sbHeight + qqsHeight);
     }
 
-    private void updateResources() {
+    void updateResources() {
         Resources resources = mContext.getResources();
         updateMinimumHeight();
 
@@ -529,18 +372,6 @@
     }
 
     @Override
-    public void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        mRingerModeTracker.getRingerModeInternal().observe(this, ringer -> {
-            mRingerMode = ringer;
-            updateStatusText();
-        });
-        mStatusBarIconController.addIconGroup(mIconManager);
-        mDemoModeController.addCallback(mDemoModeReceiver);
-        requestApplyInsets();
-    }
-
-    @Override
     public WindowInsets onApplyWindowInsets(WindowInsets insets) {
         // Handle padding of the clock
         DisplayCutout cutout = insets.getDisplayCutout();
@@ -563,17 +394,14 @@
         if (cutout != null) {
             Rect topCutout = cutout.getBoundingRectTop();
             if (topCutout.isEmpty() || cornerCutout) {
-                mHasTopCutout = false;
                 lp.width = 0;
                 mSpace.setVisibility(View.GONE);
             } else {
-                mHasTopCutout = true;
                 lp.width = topCutout.width();
                 mSpace.setVisibility(View.VISIBLE);
             }
         }
         mSpace.setLayoutParams(lp);
-        setChipVisibility(mPrivacyChip.getVisibility() == View.VISIBLE);
         mCutOutPaddingLeft = padding.first;
         mCutOutPaddingRight = padding.second;
         mWaterfallTopInset = cutout == null ? 0 : cutout.getWaterfallInsets().top;
@@ -611,103 +439,14 @@
                 0);
     }
 
-    @Override
-    @VisibleForTesting
-    public void onDetachedFromWindow() {
-        setListening(false);
-        mRingerModeTracker.getRingerModeInternal().removeObservers(this);
-        mStatusBarIconController.removeIconGroup(mIconManager);
-        mDemoModeController.removeCallback(mDemoModeReceiver);
-        super.onDetachedFromWindow();
-    }
-
-    public void setListening(boolean listening) {
-        if (listening == mListening) {
-            return;
-        }
-        mHeaderQsPanel.setListening(listening);
-        if (mHeaderQsPanel.switchTileLayout()) {
-            updateResources();
-        }
-        mListening = listening;
-
-        if (listening) {
-            mZenController.addCallback(this);
-            mAlarmController.addCallback(this);
-            mLifecycle.setCurrentState(Lifecycle.State.RESUMED);
-            // Get the most up to date info
-            mAllIndicatorsEnabled = mPrivacyItemController.getAllIndicatorsAvailable();
-            mMicCameraIndicatorsEnabled = mPrivacyItemController.getMicCameraAvailable();
-            mPrivacyItemController.addCallback(mPICCallback);
-        } else {
-            mZenController.removeCallback(this);
-            mAlarmController.removeCallback(this);
-            mLifecycle.setCurrentState(Lifecycle.State.CREATED);
-            mPrivacyItemController.removeCallback(mPICCallback);
-            mPrivacyChipLogged = false;
-        }
-    }
-
-    @Override
-    public void onClick(View v) {
-        if (v == mClockView) {
-            mActivityStarter.postStartActivityDismissingKeyguard(new Intent(
-                    AlarmClock.ACTION_SHOW_ALARMS), 0);
-        } else if (v == mNextAlarmContainer && mNextAlarmContainer.isVisibleToUser()) {
-            if (mNextAlarm.getShowIntent() != null) {
-                mActivityStarter.postStartActivityDismissingKeyguard(
-                        mNextAlarm.getShowIntent());
-            } else {
-                Log.d(TAG, "No PendingIntent for next alarm. Using default intent");
-                mActivityStarter.postStartActivityDismissingKeyguard(new Intent(
-                        AlarmClock.ACTION_SHOW_ALARMS), 0);
-            }
-        } else if (v == mPrivacyChip) {
-            // If the privacy chip is visible, it means there were some indicators
-            Handler mUiHandler = new Handler(Looper.getMainLooper());
-            mUiEventLogger.log(PrivacyChipEvent.ONGOING_INDICATORS_CHIP_CLICK);
-            mUiHandler.post(() -> {
-                mActivityStarter.postStartActivityDismissingKeyguard(
-                        new Intent(Intent.ACTION_REVIEW_ONGOING_PERMISSION_USAGE), 0);
-                mHost.collapsePanels();
-            });
-        } else if (v == mRingerContainer && mRingerContainer.isVisibleToUser()) {
-            mActivityStarter.postStartActivityDismissingKeyguard(new Intent(
-                    Settings.ACTION_SOUND_SETTINGS), 0);
-        }
-    }
-
-    @Override
-    public void onNextAlarmChanged(AlarmManager.AlarmClockInfo nextAlarm) {
-        mNextAlarm = nextAlarm;
-        updateStatusText();
-    }
-
-    @Override
-    public void onZenChanged(int zen) {
-        updateStatusText();
-    }
-
-    @Override
-    public void onConfigChanged(ZenModeConfig config) {
-        updateStatusText();
-    }
-
     public void updateEverything() {
         post(() -> setClickable(!mExpanded));
     }
 
     public void setQSPanel(final QSPanel qsPanel) {
-        mQsPanel = qsPanel;
-        setupHost(qsPanel.getHost());
-    }
-
-    public void setupHost(final QSTileHost host) {
-        mHost = host;
         //host.setHeaderView(mExpandIndicator);
-        mHeaderQsPanel.setQSPanelAndHeader(mQsPanel, this);
-        mHeaderQsPanel.setHost(host, null /* No customization in header */);
-
+        mHeaderQsPanel.setQSPanelAndHeader(qsPanel, this);
+        mHeaderQsPanel.setHost(qsPanel.getHost(), null /* No customization in header */);
 
         Rect tintArea = new Rect(0, 0, 0, 0);
         int colorForeground = Utils.getColorAttrDefaultColor(getContext(),
@@ -721,12 +460,11 @@
         mHeaderQsPanel.setCallback(qsPanelCallback);
     }
 
-    private String formatNextAlarm(AlarmManager.AlarmClockInfo info) {
+    private String formatNextAlarm(AlarmClockInfo info, boolean use24HourFormat) {
         if (info == null) {
             return "";
         }
-        String skeleton = android.text.format.DateFormat
-                .is24HourFormat(mContext, mUserTracker.getUserId()) ? "EHm" : "Ehma";
+        String skeleton = use24HourFormat ? "EHm" : "Ehma";
         String pattern = android.text.format.DateFormat
                 .getBestDateTimePattern(Locale.getDefault(), skeleton);
         return android.text.format.DateFormat.format(pattern, info.getTriggerTime()).toString();
@@ -777,37 +515,4 @@
             updateHeaderTextContainerAlphaAnimator();
         }
     }
-
-    private boolean getChipEnabled() {
-        return mMicCameraIndicatorsEnabled || mAllIndicatorsEnabled;
-    }
-
-    private static class ClockDemoModeReceiver implements DemoMode {
-        private Clock mClockView;
-
-        @Override
-        public List<String> demoCommands() {
-            return List.of(COMMAND_CLOCK);
-        }
-
-        ClockDemoModeReceiver(Clock clockView) {
-            mClockView = clockView;
-        }
-
-        @Override
-        public void dispatchDemoCommand(String command, Bundle args) {
-            mClockView.dispatchDemoCommand(command, args);
-        }
-
-        @Override
-        public void onDemoModeStarted() {
-            mClockView.onDemoModeStarted();
-        }
-
-        @Override
-        public void onDemoModeFinished() {
-            mClockView.onDemoModeFinished();
-        }
-    }
-
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
index d899acb..676a300 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
@@ -16,36 +16,393 @@
 
 package com.android.systemui.qs;
 
+import android.app.AlarmManager.AlarmClockInfo;
+import android.content.Intent;
+import android.media.AudioManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.provider.AlarmClock;
+import android.provider.Settings;
+import android.service.notification.ZenModeConfig;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+
+import androidx.annotation.NonNull;
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleOwner;
+import androidx.lifecycle.LifecycleRegistry;
+
+import com.android.internal.logging.UiEventLogger;
 import com.android.systemui.R;
+import com.android.systemui.demomode.DemoMode;
+import com.android.systemui.demomode.DemoModeController;
+import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.privacy.OngoingPrivacyChip;
+import com.android.systemui.privacy.PrivacyChipEvent;
+import com.android.systemui.privacy.PrivacyItem;
+import com.android.systemui.privacy.PrivacyItemController;
 import com.android.systemui.qs.carrier.QSCarrierGroupController;
+import com.android.systemui.settings.UserTracker;
+import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.phone.StatusBarIconController;
+import com.android.systemui.statusbar.phone.StatusIconContainer;
+import com.android.systemui.statusbar.policy.Clock;
+import com.android.systemui.statusbar.policy.NextAlarmController;
+import com.android.systemui.statusbar.policy.NextAlarmController.NextAlarmChangeCallback;
+import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.statusbar.policy.ZenModeController.Callback;
+import com.android.systemui.util.RingerModeTracker;
+import com.android.systemui.util.ViewController;
+
+import java.util.ArrayList;
+import java.util.List;
 
 import javax.inject.Inject;
 
-public class QuickStatusBarHeaderController {
-    private final QuickStatusBarHeader mView;
+/**
+ * Controller for {@link QuickStatusBarHeader}.
+ */
+class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader> {
+    private static final String TAG = "QuickStatusBarHeader";
+
+    private final ZenModeController mZenModeController;
+    private final NextAlarmController mNextAlarmController;
+    private final PrivacyItemController mPrivacyItemController;
+    private final RingerModeTracker mRingerModeTracker;
+    private final ActivityStarter mActivityStarter;
+    private final UiEventLogger mUiEventLogger;
     private final QSCarrierGroupController mQSCarrierGroupController;
+    private final QuickQSPanel mHeaderQsPanel;
+    private final LifecycleRegistry mLifecycle;
+    private final OngoingPrivacyChip mPrivacyChip;
+    private final Clock mClockView;
+    private final View mNextAlarmContainer;
+    private final View mRingerContainer;
+    private final QSTileHost mQSTileHost;
+    private final StatusBarIconController mStatusBarIconController;
+    private final CommandQueue mCommandQueue;
+    private final DemoModeController mDemoModeController;
+    private final UserTracker mUserTracker;
+    private final StatusIconContainer mIconContainer;
+    private final StatusBarIconController.TintedIconManager mIconManager;
+    private final DemoMode mDemoModeReceiver;
+
+    private boolean mListening;
+    private AlarmClockInfo mNextAlarm;
+    private boolean mAllIndicatorsEnabled;
+    private boolean mMicCameraIndicatorsEnabled;
+    private boolean mPrivacyChipLogged;
+    private int mRingerMode = AudioManager.RINGER_MODE_NORMAL;
+
+    private final ZenModeController.Callback mZenModeControllerCallback = new Callback() {
+        @Override
+        public void onZenChanged(int zen) {
+            mView.updateStatusText(mRingerMode, mNextAlarm, isZenOverridingRinger(),
+                    use24HourFormat());
+        }
+
+        @Override
+        public void onConfigChanged(ZenModeConfig config) {
+            mView.updateStatusText(mRingerMode, mNextAlarm, isZenOverridingRinger(),
+                    use24HourFormat());
+        }
+    };
+
+    private boolean use24HourFormat() {
+        return android.text.format.DateFormat.is24HourFormat(
+                mView.getContext(), mUserTracker.getUserId());
+
+    }
+
+    private final NextAlarmChangeCallback mNextAlarmChangeCallback = new NextAlarmChangeCallback() {
+        @Override
+        public void onNextAlarmChanged(AlarmClockInfo nextAlarm) {
+            mNextAlarm = nextAlarm;
+            mView.updateStatusText(mRingerMode, mNextAlarm, isZenOverridingRinger(),
+                    use24HourFormat());
+        }
+    };
+
+    private final LifecycleOwner mLifecycleOwner = new LifecycleOwner() {
+        @NonNull
+        @Override
+        public Lifecycle getLifecycle() {
+            return mLifecycle;
+        }
+    };
+
+    private PrivacyItemController.Callback mPICCallback = new PrivacyItemController.Callback() {
+        @Override
+        public void onPrivacyItemsChanged(@NonNull List<PrivacyItem> privacyItems) {
+            mPrivacyChip.setPrivacyList(privacyItems);
+            setChipVisibility(!privacyItems.isEmpty());
+        }
+
+        @Override
+        public void onFlagAllChanged(boolean flag) {
+            if (mAllIndicatorsEnabled != flag) {
+                mAllIndicatorsEnabled = flag;
+                update();
+            }
+        }
+
+        @Override
+        public void onFlagMicCameraChanged(boolean flag) {
+            if (mMicCameraIndicatorsEnabled != flag) {
+                mMicCameraIndicatorsEnabled = flag;
+                update();
+            }
+        }
+
+        private void update() {
+            StatusIconContainer iconContainer = mView.requireViewById(R.id.statusIcons);
+            iconContainer.setIgnoredSlots(getIgnoredIconSlots());
+            setChipVisibility(!mPrivacyChip.getPrivacyList().isEmpty());
+        }
+    };
+
+    private View.OnClickListener mOnClickListener = new OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            if (v == mClockView) {
+                mActivityStarter.postStartActivityDismissingKeyguard(new Intent(
+                        AlarmClock.ACTION_SHOW_ALARMS), 0);
+            } else if (v == mNextAlarmContainer && mNextAlarmContainer.isVisibleToUser()) {
+                if (mNextAlarm.getShowIntent() != null) {
+                    mActivityStarter.postStartActivityDismissingKeyguard(
+                            mNextAlarm.getShowIntent());
+                } else {
+                    Log.d(TAG, "No PendingIntent for next alarm. Using default intent");
+                    mActivityStarter.postStartActivityDismissingKeyguard(new Intent(
+                            AlarmClock.ACTION_SHOW_ALARMS), 0);
+                }
+            } else if (v == mPrivacyChip) {
+                // If the privacy chip is visible, it means there were some indicators
+                Handler mUiHandler = new Handler(Looper.getMainLooper());
+                mUiEventLogger.log(PrivacyChipEvent.ONGOING_INDICATORS_CHIP_CLICK);
+                mUiHandler.post(() -> {
+                    mActivityStarter.postStartActivityDismissingKeyguard(
+                            new Intent(Intent.ACTION_REVIEW_ONGOING_PERMISSION_USAGE), 0);
+                    mQSTileHost.collapsePanels();
+                });
+            } else if (v == mRingerContainer && mRingerContainer.isVisibleToUser()) {
+                mActivityStarter.postStartActivityDismissingKeyguard(new Intent(
+                        Settings.ACTION_SOUND_SETTINGS), 0);
+            }
+        }
+    };
 
     private QuickStatusBarHeaderController(QuickStatusBarHeader view,
+            ZenModeController zenModeController, NextAlarmController nextAlarmController,
+            PrivacyItemController privacyItemController, RingerModeTracker ringerModeTracker,
+            ActivityStarter activityStarter, UiEventLogger uiEventLogger,
+            QSTileHost qsTileHost, StatusBarIconController statusBarIconController,
+            CommandQueue commandQueue, DemoModeController demoModeController,
+            UserTracker userTracker,
             QSCarrierGroupController.Builder qsCarrierGroupControllerBuilder) {
-        mView = view;
+        super(view);
+        mZenModeController = zenModeController;
+        mNextAlarmController = nextAlarmController;
+        mPrivacyItemController = privacyItemController;
+        mRingerModeTracker = ringerModeTracker;
+        mActivityStarter = activityStarter;
+        mUiEventLogger = uiEventLogger;
+        mQSTileHost = qsTileHost;
+        mStatusBarIconController = statusBarIconController;
+        mCommandQueue = commandQueue;
+        mDemoModeController = demoModeController;
+        mUserTracker = userTracker;
+        mLifecycle = new LifecycleRegistry(mLifecycleOwner);
+
         mQSCarrierGroupController = qsCarrierGroupControllerBuilder
                 .setQSCarrierGroup(mView.findViewById(R.id.carrier_group))
                 .build();
+
+
+        mPrivacyChip = mView.findViewById(R.id.privacy_chip);
+        mHeaderQsPanel = mView.findViewById(R.id.quick_qs_panel);
+        mNextAlarmContainer = mView.findViewById(R.id.alarm_container);
+        mClockView = mView.findViewById(R.id.clock);
+        mRingerContainer = mView.findViewById(R.id.ringer_container);
+        mIconContainer = mView.findViewById(R.id.statusIcons);
+
+        mIconManager = new StatusBarIconController.TintedIconManager(mIconContainer, mCommandQueue);
+        mDemoModeReceiver = new ClockDemoModeReceiver(mClockView);
+    }
+
+    @Override
+    protected void onViewAttached() {
+        mRingerModeTracker.getRingerModeInternal().observe(mLifecycleOwner, ringer -> {
+            mRingerMode = ringer;
+            mView.updateStatusText(mRingerMode, mNextAlarm, isZenOverridingRinger(),
+                    use24HourFormat());
+        });
+
+        mClockView.setOnClickListener(mOnClickListener);
+        mNextAlarmContainer.setOnClickListener(mOnClickListener);
+        mRingerContainer.setOnClickListener(mOnClickListener);
+        mPrivacyChip.setOnClickListener(mOnClickListener);
+
+        // Ignore privacy icons because they show in the space above QQS
+        mIconContainer.addIgnoredSlots(getIgnoredIconSlots());
+        mIconContainer.setShouldRestrictIcons(false);
+        mStatusBarIconController.addIconGroup(mIconManager);
+
+        mAllIndicatorsEnabled = mPrivacyItemController.getAllIndicatorsAvailable();
+        mMicCameraIndicatorsEnabled = mPrivacyItemController.getMicCameraAvailable();
+
+        setChipVisibility(mPrivacyChip.getVisibility() == View.VISIBLE);
+
+        mView.onAttach(mIconManager);
+
+        mDemoModeController.addCallback(mDemoModeReceiver);
+    }
+
+    @Override
+    protected void onViewDetached() {
+        mRingerModeTracker.getRingerModeInternal().removeObservers(mLifecycleOwner);
+        mClockView.setOnClickListener(null);
+        mNextAlarmContainer.setOnClickListener(null);
+        mRingerContainer.setOnClickListener(null);
+        mPrivacyChip.setOnClickListener(null);
+        mStatusBarIconController.removeIconGroup(mIconManager);
+        mDemoModeController.removeCallback(mDemoModeReceiver);
+        setListening(false);
     }
 
     public void setListening(boolean listening) {
         mQSCarrierGroupController.setListening(listening);
-        // TODO: move mView.setListening logic into here.
-        mView.setListening(listening);
+
+        if (listening == mListening) {
+            return;
+        }
+        mListening = listening;
+
+        mHeaderQsPanel.setListening(listening);
+        if (mHeaderQsPanel.switchTileLayout()) {
+            mView.updateResources();
+        }
+
+        if (listening) {
+            mZenModeController.addCallback(mZenModeControllerCallback);
+            mNextAlarmController.addCallback(mNextAlarmChangeCallback);
+            mLifecycle.setCurrentState(Lifecycle.State.RESUMED);
+            // Get the most up to date info
+            mAllIndicatorsEnabled = mPrivacyItemController.getAllIndicatorsAvailable();
+            mMicCameraIndicatorsEnabled = mPrivacyItemController.getMicCameraAvailable();
+            mPrivacyItemController.addCallback(mPICCallback);
+        } else {
+            mZenModeController.removeCallback(mZenModeControllerCallback);
+            mNextAlarmController.removeCallback(mNextAlarmChangeCallback);
+            mLifecycle.setCurrentState(Lifecycle.State.CREATED);
+            mPrivacyItemController.removeCallback(mPICCallback);
+            mPrivacyChipLogged = false;
+        }
+    }
+
+    private void setChipVisibility(boolean chipVisible) {
+        if (chipVisible && getChipEnabled()) {
+            mPrivacyChip.setVisibility(View.VISIBLE);
+            // Makes sure that the chip is logged as viewed at most once each time QS is opened
+            // mListening makes sure that the callback didn't return after the user closed QS
+            if (!mPrivacyChipLogged && mListening) {
+                mPrivacyChipLogged = true;
+                mUiEventLogger.log(PrivacyChipEvent.ONGOING_INDICATORS_CHIP_VIEW);
+            }
+        } else {
+            mPrivacyChip.setVisibility(View.GONE);
+        }
+    }
+
+    private List<String> getIgnoredIconSlots() {
+        ArrayList<String> ignored = new ArrayList<>();
+        if (getChipEnabled()) {
+            ignored.add(mView.getResources().getString(
+                    com.android.internal.R.string.status_bar_camera));
+            ignored.add(mView.getResources().getString(
+                    com.android.internal.R.string.status_bar_microphone));
+            if (mAllIndicatorsEnabled) {
+                ignored.add(mView.getResources().getString(
+                        com.android.internal.R.string.status_bar_location));
+            }
+        }
+
+        return ignored;
+    }
+
+    private boolean getChipEnabled() {
+        return mMicCameraIndicatorsEnabled || mAllIndicatorsEnabled;
+    }
+
+    private boolean isZenOverridingRinger() {
+        return ZenModeConfig.isZenOverridingRinger(mZenModeController.getZen(),
+                mZenModeController.getConsolidatedPolicy());
     }
 
 
-    public static class Builder {
+    private static class ClockDemoModeReceiver implements DemoMode {
+        private Clock mClockView;
+
+        @Override
+        public List<String> demoCommands() {
+            return List.of(COMMAND_CLOCK);
+        }
+
+        ClockDemoModeReceiver(Clock clockView) {
+            mClockView = clockView;
+        }
+
+        @Override
+        public void dispatchDemoCommand(String command, Bundle args) {
+            mClockView.dispatchDemoCommand(command, args);
+        }
+
+        @Override
+        public void onDemoModeStarted() {
+            mClockView.onDemoModeStarted();
+        }
+
+        @Override
+        public void onDemoModeFinished() {
+            mClockView.onDemoModeFinished();
+        }
+    }
+
+    static class Builder {
+        private final ZenModeController mZenModeController;
+        private final NextAlarmController mNextAlarmController;
+        private final PrivacyItemController mPrivacyItemController;
+        private final RingerModeTracker mRingerModeTracker;
+        private final ActivityStarter mActivityStarter;
+        private final UiEventLogger mUiEventLogger;
+        private final QSTileHost mQsTileHost;
+        private final StatusBarIconController mStatusBarIconController;
+        private final CommandQueue mCommandQueue;
+        private final DemoModeController mDemoModeController;
+        private final UserTracker mUserTracker;
         private final QSCarrierGroupController.Builder mQSCarrierGroupControllerBuilder;
         private QuickStatusBarHeader mView;
 
         @Inject
-        public Builder(QSCarrierGroupController.Builder qsCarrierGroupControllerBuilder) {
+        Builder(ZenModeController zenModeController, NextAlarmController nextAlarmController,
+                PrivacyItemController privacyItemController, RingerModeTracker ringerModeTracker,
+                ActivityStarter activityStarter, UiEventLogger uiEventLogger, QSTileHost qsTileHost,
+                StatusBarIconController statusBarIconController, CommandQueue commandQueue,
+                DemoModeController demoModeController, UserTracker userTracker,
+                QSCarrierGroupController.Builder qsCarrierGroupControllerBuilder) {
+            mZenModeController = zenModeController;
+            mNextAlarmController = nextAlarmController;
+            mPrivacyItemController = privacyItemController;
+            mRingerModeTracker = ringerModeTracker;
+            mActivityStarter = activityStarter;
+            mUiEventLogger = uiEventLogger;
+            mQsTileHost = qsTileHost;
+            mStatusBarIconController = statusBarIconController;
+            mCommandQueue = commandQueue;
+            mDemoModeController = demoModeController;
+            mUserTracker = userTracker;
             mQSCarrierGroupControllerBuilder = qsCarrierGroupControllerBuilder;
         }
 
@@ -54,8 +411,13 @@
             return this;
         }
 
-        public QuickStatusBarHeaderController build() {
-            return new QuickStatusBarHeaderController(mView, mQSCarrierGroupControllerBuilder);
+
+        QuickStatusBarHeaderController build() {
+            return new QuickStatusBarHeaderController(mView, mZenModeController,
+                    mNextAlarmController, mPrivacyItemController, mRingerModeTracker,
+                    mActivityStarter, mUiEventLogger, mQsTileHost, mStatusBarIconController,
+                    mCommandQueue, mDemoModeController, mUserTracker,
+                    mQSCarrierGroupControllerBuilder);
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
index a6cd350..344f0d2 100644
--- a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
+++ b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
@@ -27,7 +27,6 @@
 import com.android.systemui.qs.QSFooterImpl;
 import com.android.systemui.qs.QSPanel;
 import com.android.systemui.qs.QuickQSPanel;
-import com.android.systemui.qs.QuickStatusBarHeader;
 import com.android.systemui.qs.customize.QSCustomizer;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 
@@ -93,10 +92,6 @@
         }
 
         /**
-         * Creates the QuickStatusBarHeader.
-         */
-        QuickStatusBarHeader createQsHeader();
-        /**
          * Creates the QSFooterImpl.
          */
         QSFooterImpl createQsFooter();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java
index 1e969c2..fa78d1c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java
@@ -36,6 +36,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.statusbar.CommandQueue;
 
 import org.junit.Before;
@@ -65,6 +66,8 @@
     @Mock
     private ModeSwitchesController mModeSwitchesController;
     @Mock
+    private NavigationModeController mNavigationModeController;
+    @Mock
     private IRemoteMagnificationAnimationCallback mAnimationCallback;
     private IWindowMagnificationConnection mIWindowMagnificationConnection;
     private WindowMagnification mWindowMagnification;
@@ -79,7 +82,8 @@
         }).when(mAccessibilityManager).setWindowMagnificationConnection(
                 any(IWindowMagnificationConnection.class));
         mWindowMagnification = new WindowMagnification(getContext(),
-                getContext().getMainThreadHandler(), mCommandQueue, mModeSwitchesController);
+                getContext().getMainThreadHandler(), mCommandQueue, mModeSwitchesController,
+                mNavigationModeController);
         mWindowMagnification.mWindowMagnificationAnimationController =
                 mWindowMagnificationAnimationController;
         mWindowMagnification.requestWindowMagnificationConnection(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
index c6440f4..5f2fd69 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
@@ -17,6 +17,7 @@
 package com.android.systemui.accessibility;
 
 import static android.view.Choreographer.FrameCallback;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
 import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 
 import static org.hamcrest.Matchers.containsString;
@@ -28,6 +29,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.verify;
@@ -294,4 +296,15 @@
         assertTrue(
                 mMirrorView.performAccessibilityAction(R.id.accessibility_action_move_left, null));
     }
+
+    @Test
+    public void onNavigationModeChanged_updateMirrorViewLayout() {
+        mInstrumentation.runOnMainSync(() -> {
+            mWindowMagnificationController.enableWindowMagnification(Float.NaN, Float.NaN,
+                    Float.NaN);
+            mWindowMagnificationController.onNavigationModeChanged(NAV_BAR_MODE_GESTURAL);
+        });
+
+        verify(mWindowManager).updateViewLayout(eq(mMirrorView), any());
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java
index 936558b..4a0e216 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java
@@ -35,6 +35,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.statusbar.CommandQueue;
 
 import org.junit.Before;
@@ -53,6 +54,8 @@
     private AccessibilityManager mAccessibilityManager;
     @Mock
     private ModeSwitchesController mModeSwitchesController;
+    @Mock
+    private NavigationModeController mNavigationModeController;
     private CommandQueue mCommandQueue;
     private WindowMagnification mWindowMagnification;
 
@@ -63,7 +66,8 @@
 
         mCommandQueue = new CommandQueue(getContext());
         mWindowMagnification = new WindowMagnification(getContext(),
-                getContext().getMainThreadHandler(), mCommandQueue, mModeSwitchesController);
+                getContext().getMainThreadHandler(), mCommandQueue, mModeSwitchesController,
+                mNavigationModeController);
         mWindowMagnification.start();
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
index ca328fb..9ebb587 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
@@ -36,6 +36,7 @@
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.statusbar.phone.ShadeController;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -73,6 +74,11 @@
         when(mMediaDevice.getFeatures()).thenReturn(mFeatures);
     }
 
+    @After
+    public void tearDown() {
+        mMediaOutputDialog.dismissDialog();
+    }
+
     @Test
     public void getStopButtonVisibility_remoteDevice_returnVisible() {
         mFeatures.add(MediaRoute2Info.FEATURE_REMOTE_PLAYBACK);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index 1c2d0840..e472cb2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -37,7 +37,6 @@
 import com.android.internal.logging.UiEventLogger;
 import com.android.keyguard.CarrierText;
 import com.android.systemui.Dependency;
-import com.android.systemui.R;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.SysuiBaseFragmentTest;
 import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -116,11 +115,6 @@
 
         qs.setListening(false);
         processAllMessages();
-
-        // Manually push header through detach so it can handle standard cleanup it does on
-        // removed from window.
-        ((QuickStatusBarHeader) qs.getView().findViewById(R.id.header)).onDetachedFromWindow();
-
         host.destroy();
         processAllMessages();
     }
diff --git a/services/Android.bp b/services/Android.bp
index ef52c2a..25a0d7e 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -3,6 +3,12 @@
     plugins: [
         "error_prone_android_framework",
     ],
+    errorprone: {
+        javacflags: [
+            "-Xep:AndroidFrameworkCompatChange:ERROR",
+            "-Xep:AndroidFrameworkUid:ERROR",
+        ],
+    },
 }
 
 filegroup {
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 5e65563..8e01c4f 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -1918,7 +1918,9 @@
 
             String instructionSet = null;
             if (app.info.primaryCpuAbi != null) {
-                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
+                // If ABI override is specified, use the isa derived from the value of ABI override.
+                // Otherwise, use the isa derived from primary ABI
+                instructionSet = VMRuntime.getInstructionSet(requiredAbi);
             }
 
             app.gids = gids;
@@ -1927,7 +1929,7 @@
 
             // If instructionSet is non-null, this indicates that the system_server is spawning a
             // process with an ISA that may be different from its own. System (kernel and hardware)
-            // compatililty for these features is checked in the decideTaggingLevel in the
+            // compatibility for these features is checked in the decideTaggingLevel in the
             // system_server process (not the child process). As both MTE and TBI are only supported
             // in aarch64, we can simply ensure that the new process is also aarch64. This prevents
             // the mismatch where a 64-bit system server spawns a 32-bit child that thinks it should
diff --git a/services/core/java/com/android/server/biometrics/sensors/GenerateChallengeClient.java b/services/core/java/com/android/server/biometrics/sensors/GenerateChallengeClient.java
index 92c498c..bac944f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/GenerateChallengeClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/GenerateChallengeClient.java
@@ -27,8 +27,6 @@
 
     private static final String TAG = "GenerateChallengeClient";
 
-    protected long mChallenge;
-
     public GenerateChallengeClient(@NonNull Context context, @NonNull LazyDaemon<T> lazyDaemon,
             @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener,
             @NonNull String owner, int sensorId) {
@@ -51,12 +49,5 @@
         super.start(callback);
 
         startHalOperation();
-        try {
-            getListener().onChallengeGenerated(getSensorId(), mChallenge);
-            mCallback.onClientFinished(this, true /* success */);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Remote exception", e);
-            mCallback.onClientFinished(this, false /* success */);
-        }
     }
 }
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceGenerateChallengeClient.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceGenerateChallengeClient.java
index ba401f2..406a7cc 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceGenerateChallengeClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceGenerateChallengeClient.java
@@ -59,7 +59,14 @@
     @Override
     protected void startHalOperation() {
         try {
-            mChallenge = getFreshDaemon().generateChallenge(CHALLENGE_TIMEOUT_SEC).value;
+            final long challenge = getFreshDaemon().generateChallenge(CHALLENGE_TIMEOUT_SEC).value;
+            try {
+                getListener().onChallengeGenerated(getSensorId(), challenge);
+                mCallback.onClientFinished(this, true /* success */);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote exception", e);
+                mCallback.onClientFinished(this, false /* success */);
+            }
         } catch (RemoteException e) {
             Slog.e(TAG, "generateChallenge failed", e);
         }
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintGenerateChallengeClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintGenerateChallengeClient.java
index abaaac5..5169c7d 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintGenerateChallengeClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintGenerateChallengeClient.java
@@ -45,7 +45,14 @@
     @Override
     protected void startHalOperation() {
         try {
-            mChallenge = getFreshDaemon().preEnroll();
+            final long challenge = getFreshDaemon().preEnroll();
+            try {
+                getListener().onChallengeGenerated(getSensorId(), challenge);
+                mCallback.onClientFinished(this, true /* success */);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote exception", e);
+                mCallback.onClientFinished(this, false /* success */);
+            }
         } catch (RemoteException e) {
             Slog.e(TAG, "preEnroll failed", e);
         }
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
index 68473c1..29bdd6c 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
@@ -379,7 +379,8 @@
         assertRunOnServiceThread();
         if (reason == mService.INITIATED_BY_ENABLE_CEC) {
             mService.setAndBroadcastActiveSource(mService.getPhysicalAddress(),
-                    getDeviceInfo().getDeviceType(), Constants.ADDR_BROADCAST);
+                    getDeviceInfo().getDeviceType(), Constants.ADDR_BROADCAST,
+                    "HdmiCecLocalDeviceAudioSystem#onAddressAllocated()");
         }
         mService.sendCecCommand(
                 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
@@ -1324,7 +1325,8 @@
         if (getRoutingPort() == Constants.CEC_SWITCH_HOME && mService.isPlaybackDevice()) {
             routeToInputFromPortId(Constants.CEC_SWITCH_HOME);
             mService.setAndBroadcastActiveSourceFromOneDeviceType(
-                    message.getSource(), mService.getPhysicalAddress());
+                    message.getSource(), mService.getPhysicalAddress(),
+                    "HdmiCecLocalDeviceAudioSystem#handleRoutingChangeAndInformationForSwitch()");
             return;
         }
 
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index 6e6d848..6257032 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -16,6 +16,7 @@
 
 package com.android.server.hdmi;
 
+import android.annotation.CallSuper;
 import android.hardware.hdmi.HdmiControlManager;
 import android.hardware.hdmi.HdmiDeviceInfo;
 import android.hardware.hdmi.IHdmiControlCallback;
@@ -96,7 +97,8 @@
         assertRunOnServiceThread();
         if (reason == mService.INITIATED_BY_ENABLE_CEC) {
             mService.setAndBroadcastActiveSource(mService.getPhysicalAddress(),
-                    getDeviceInfo().getDeviceType(), Constants.ADDR_BROADCAST);
+                    getDeviceInfo().getDeviceType(), Constants.ADDR_BROADCAST,
+                    "HdmiCecLocalDevicePlayback#onAddressAllocated()");
         }
         mService.sendCecCommand(HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
                 mAddress, mService.getPhysicalAddress(), mDeviceType));
@@ -165,7 +167,7 @@
     void onHotplug(int portId, boolean connected) {
         assertRunOnServiceThread();
         mCecMessageCache.flushAll();
-        // We'll not clear mIsActiveSource on the hotplug event to pass CETC 11.2.2-2 ~ 3.
+        // We'll not invalidate the active source on the hotplug event to pass CETC 11.2.2-2 ~ 3.
         if (!connected) {
             getWakeLock().release();
         }
@@ -178,13 +180,12 @@
         if (!mService.isControlEnabled()) {
             return;
         }
-        if (mIsActiveSource) {
+        if (isActiveSource()) {
             mService.sendCecCommand(HdmiCecMessageBuilder.buildInactiveSource(
                     mAddress, mService.getPhysicalAddress()));
         }
-        boolean wasActiveSource = mIsActiveSource;
+        boolean wasActiveSource = isActiveSource();
         // Invalidate the internal active source record when goes to standby
-        // This set will also update mIsActiveSource
         mService.setActiveSource(Constants.ADDR_INVALID, Constants.INVALID_PHYSICAL_ADDRESS,
                 "HdmiCecLocalDevicePlayback#onStandby()");
         if (initiatedByCec || !mAutoTvOff || !wasActiveSource) {
@@ -229,12 +230,13 @@
     }
 
     @Override
+    @CallSuper
     @ServiceThreadOnly
     @VisibleForTesting
-    void setIsActiveSource(boolean on) {
+    protected void setActiveSource(int logicalAddress, int physicalAddress, String caller) {
         assertRunOnServiceThread();
-        super.setIsActiveSource(on);
-        if (on) {
+        super.setActiveSource(logicalAddress, physicalAddress, caller);
+        if (isActiveSource()) {
             getWakeLock().acquire();
         } else {
             getWakeLock().release();
@@ -291,7 +293,7 @@
 
     @Override
     protected void wakeUpIfActiveSource() {
-        if (!mIsActiveSource) {
+        if (!isActiveSource()) {
             return;
         }
         // Wake up the device if the power is in standby mode, or its screen is off -
@@ -399,9 +401,16 @@
                     "HdmiCecLocalDevicePlayback#handleRoutingChangeAndInformation()");
             return;
         }
+        if (!isActiveSource()) {
+            // If routing is changed to the device while Active Source, don't invalidate the
+            // Active Source
+            setActiveSource(physicalAddress,
+                    "HdmiCecLocalDevicePlayback#handleRoutingChangeAndInformation()");
+        }
         switch (mPlaybackDeviceActionOnRoutingControl) {
             case WAKE_UP_AND_SEND_ACTIVE_SOURCE:
-                setAndBroadcastActiveSource(message, physicalAddress);
+                setAndBroadcastActiveSource(message, physicalAddress,
+                        "HdmiCecLocalDevicePlayback#handleRoutingChangeAndInformation()");
                 break;
             case WAKE_UP_ONLY:
                 mService.wakeUp();
@@ -436,7 +445,7 @@
     @Override
     protected void dump(final IndentingPrintWriter pw) {
         super.dump(pw);
-        pw.println("mIsActiveSource: " + mIsActiveSource);
+        pw.println("isActiveSource(): " + isActiveSource());
         pw.println("mAutoTvOff:" + mAutoTvOff);
     }
 
@@ -457,7 +466,7 @@
         @Override
         public void acquire() {
             mWakeLock.acquire();
-            HdmiLogger.debug("active source: %b. Wake lock acquired", mIsActiveSource);
+            HdmiLogger.debug("active source: %b. Wake lock acquired", isActiveSource());
         }
 
         @Override
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java
index 4ff36c4..4325f79 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java
@@ -16,6 +16,7 @@
 
 package com.android.server.hdmi;
 
+import android.annotation.CallSuper;
 import android.hardware.hdmi.HdmiControlManager;
 import android.hardware.hdmi.HdmiPortInfo;
 import android.hardware.hdmi.IHdmiControlCallback;
@@ -36,10 +37,6 @@
 
     private static final String TAG = "HdmiCecLocalDeviceSource";
 
-    // Indicate if current device is Active Source or not
-    @VisibleForTesting
-    protected boolean mIsActiveSource = false;
-
     // Device has cec switch functionality or not.
     // Default is false.
     protected boolean mIsSwitchDevice = HdmiProperties.is_switch().orElse(false);
@@ -78,7 +75,7 @@
         if (mService.getPortInfo(portId).getType() == HdmiPortInfo.PORT_OUTPUT) {
             mCecMessageCache.flushAll();
         }
-        // We'll not clear mIsActiveSource on the hotplug event to pass CETC 11.2.2-2 ~ 3.
+        // We'll not invalidate the active source on the hotplug event to pass CETC 11.2.2-2 ~ 3.
         if (connected) {
             mService.wakeUp();
         }
@@ -118,10 +115,21 @@
         // Nothing to do.
     }
 
+    @Override
+    @CallSuper
+    @ServiceThreadOnly
+    void setActiveSource(int logicalAddress, int physicalAddress, String caller) {
+        boolean wasActiveSource = isActiveSource();
+        super.setActiveSource(logicalAddress, physicalAddress, caller);
+        if (wasActiveSource && !isActiveSource()) {
+            onActiveSourceLost();
+        }
+    }
+
     @ServiceThreadOnly
     protected void setActiveSource(int physicalAddress, String caller) {
         assertRunOnServiceThread();
-        // Invalidate the internal active source record. This will also update mIsActiveSource.
+        // Invalidate the internal active source record.
         ActiveSource activeSource = ActiveSource.of(Constants.ADDR_INVALID, physicalAddress);
         setActiveSource(activeSource, caller);
     }
@@ -135,7 +143,6 @@
         if (!getActiveSource().equals(activeSource)) {
             setActiveSource(activeSource, "HdmiCecLocalDeviceSource#handleActiveSource()");
         }
-        setIsActiveSource(physicalAddress == mService.getPhysicalAddress());
         updateDevicePowerStatus(logicalAddress, HdmiControlManager.POWER_STATUS_ON);
         if (isRoutingControlFeatureEnabled()) {
             switchInputOnReceivingNewActivePath(physicalAddress);
@@ -159,9 +166,11 @@
         // If current device is the target path, set to Active Source.
         // If the path is under the current device, should switch
         if (physicalAddress == mService.getPhysicalAddress() && mService.isPlaybackDevice()) {
-            setAndBroadcastActiveSource(message, physicalAddress);
-        }
-        if (physicalAddress != mService.getPhysicalAddress()) {
+            setAndBroadcastActiveSource(message, physicalAddress,
+                    "HdmiCecLocalDeviceSource#handleSetStreamPath()");
+        } else if (physicalAddress != mService.getPhysicalAddress() || !isActiveSource()) {
+            // Invalidate the active source if stream path is set to other physical address or
+            // our physical address while not active source
             setActiveSource(physicalAddress, "HdmiCecLocalDeviceSource#handleSetStreamPath()");
         }
         switchInputOnReceivingNewActivePath(physicalAddress);
@@ -173,19 +182,15 @@
     protected boolean handleRoutingChange(HdmiCecMessage message) {
         assertRunOnServiceThread();
         int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams(), 2);
-        if (physicalAddress != mService.getPhysicalAddress()) {
+        if (physicalAddress != mService.getPhysicalAddress() || !isActiveSource()) {
+            // Invalidate the active source if routing is changed to other physical address or
+            // our physical address while not active source
             setActiveSource(physicalAddress, "HdmiCecLocalDeviceSource#handleRoutingChange()");
         }
         if (!isRoutingControlFeatureEnabled()) {
             mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
             return true;
         }
-        // if the current device is a pure playback device
-        if (!mIsSwitchDevice
-                && physicalAddress == mService.getPhysicalAddress()
-                && mService.isPlaybackDevice()) {
-            setAndBroadcastActiveSource(message, physicalAddress);
-        }
         handleRoutingChangeAndInformation(physicalAddress, message);
         return true;
     }
@@ -195,19 +200,15 @@
     protected boolean handleRoutingInformation(HdmiCecMessage message) {
         assertRunOnServiceThread();
         int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams());
-        if (physicalAddress != mService.getPhysicalAddress()) {
+        if (physicalAddress != mService.getPhysicalAddress() || !isActiveSource()) {
+            // Invalidate the active source if routing is changed to other physical address or
+            // our physical address while not active source
             setActiveSource(physicalAddress, "HdmiCecLocalDeviceSource#handleRoutingInformation()");
         }
         if (!isRoutingControlFeatureEnabled()) {
             mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
             return true;
         }
-        // if the current device is a pure playback device
-        if (!mIsSwitchDevice
-                && physicalAddress == mService.getPhysicalAddress()
-                && mService.isPlaybackDevice()) {
-            setAndBroadcastActiveSource(message, physicalAddress);
-        }
         handleRoutingChangeAndInformation(physicalAddress, message);
         return true;
     }
@@ -236,23 +237,21 @@
     // since service can decide who will be the active source when the device supports
     // multiple device types in this method.
     // This method should only be called when the device can be the active source.
-    protected void setAndBroadcastActiveSource(HdmiCecMessage message, int physicalAddress) {
+    protected void setAndBroadcastActiveSource(HdmiCecMessage message, int physicalAddress,
+            String caller) {
         mService.setAndBroadcastActiveSource(
-                physicalAddress, getDeviceInfo().getDeviceType(), message.getSource());
+                physicalAddress, getDeviceInfo().getDeviceType(), message.getSource(), caller);
     }
 
+    // Indicates if current device is the active source or not
     @ServiceThreadOnly
-    void setIsActiveSource(boolean on) {
-        assertRunOnServiceThread();
-        boolean wasActiveSource = mIsActiveSource;
-        mIsActiveSource = on;
-        if (wasActiveSource && !mIsActiveSource) {
-            onActiveSourceLost();
-        }
+    protected boolean isActiveSource() {
+        return getActiveSource().equals(getDeviceInfo().getLogicalAddress(),
+                getDeviceInfo().getPhysicalAddress());
     }
 
     protected void wakeUpIfActiveSource() {
-        if (!mIsActiveSource) {
+        if (!isActiveSource()) {
             return;
         }
         // Wake up the device
@@ -261,7 +260,7 @@
     }
 
     protected void maySendActiveSource(int dest) {
-        if (!mIsActiveSource) {
+        if (!isActiveSource()) {
             return;
         }
         addAndStartAction(new ActiveSourceAction(this, dest));
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index b407234..a60a676 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -1600,7 +1600,7 @@
                 if (isPlaybackDevice()) {
                     // if playback device itself is the active source,
                     // return its own device info.
-                    if (playback() != null && playback().mIsActiveSource) {
+                    if (playback() != null && playback().isActiveSource()) {
                         return playback().getDeviceInfo();
                     }
                     // Otherwise get the active source and look for it from the device list
@@ -3242,20 +3242,12 @@
                 HdmiUtils.pathRelationship(getPhysicalAddress(), physicalAddress));
 
         // If the current device is a source device, check if the current Active Source matches
-        // the local device info. Set mIsActiveSource of the local device accordingly.
+        // the local device info.
         for (HdmiCecLocalDevice device : getAllLocalDevices()) {
-            // mIsActiveSource only exists in source device, ignore this setting if the current
-            // device is not an HdmiCecLocalDeviceSource.
-            if (!(device instanceof HdmiCecLocalDeviceSource)) {
-                device.addActiveSourceHistoryItem(new ActiveSource(logicalAddress, physicalAddress),
-                        false, caller);
-                continue;
-            }
             boolean deviceIsActiveSource =
                     logicalAddress == device.getDeviceInfo().getLogicalAddress()
                             && physicalAddress == getPhysicalAddress();
 
-            ((HdmiCecLocalDeviceSource) device).setIsActiveSource(deviceIsActiveSource);
             device.addActiveSourceHistoryItem(new ActiveSource(logicalAddress, physicalAddress),
                     deviceIsActiveSource, caller);
         }
@@ -3266,22 +3258,22 @@
     // For example, when receiving broadcast messages, all the device types will call this
     // method but only one of them will be the Active Source.
     protected void setAndBroadcastActiveSource(
-            int physicalAddress, int deviceType, int source) {
+            int physicalAddress, int deviceType, int source, String caller) {
         // If the device has both playback and audio system logical addresses,
         // playback will claim active source. Otherwise audio system will.
         if (deviceType == HdmiDeviceInfo.DEVICE_PLAYBACK) {
             HdmiCecLocalDevicePlayback playback = playback();
-            playback.setIsActiveSource(true);
+            playback.setActiveSource(playback.getDeviceInfo().getLogicalAddress(), physicalAddress,
+                    caller);
             playback.wakeUpIfActiveSource();
             playback.maySendActiveSource(source);
         }
 
         if (deviceType == HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM) {
             HdmiCecLocalDeviceAudioSystem audioSystem = audioSystem();
-            if (playback() != null) {
-                audioSystem.setIsActiveSource(false);
-            } else {
-                audioSystem.setIsActiveSource(true);
+            if (playback() == null) {
+                audioSystem.setActiveSource(audioSystem.getDeviceInfo().getLogicalAddress(),
+                        physicalAddress, caller);
                 audioSystem.wakeUpIfActiveSource();
                 audioSystem.maySendActiveSource(source);
             }
@@ -3294,24 +3286,21 @@
     // and this method updates Active Source in all the device types sharing the same
     // Physical Address.
     protected void setAndBroadcastActiveSourceFromOneDeviceType(
-            int sourceAddress, int physicalAddress) {
+            int sourceAddress, int physicalAddress, String caller) {
         // If the device has both playback and audio system logical addresses,
         // playback will claim active source. Otherwise audio system will.
         HdmiCecLocalDevicePlayback playback = playback();
         HdmiCecLocalDeviceAudioSystem audioSystem = audioSystem();
         if (playback != null) {
-            playback.setIsActiveSource(true);
+            playback.setActiveSource(playback.getDeviceInfo().getLogicalAddress(), physicalAddress,
+                    caller);
             playback.wakeUpIfActiveSource();
             playback.maySendActiveSource(sourceAddress);
-            if (audioSystem != null) {
-                audioSystem.setIsActiveSource(false);
-            }
-        } else {
-            if (audioSystem != null) {
-                audioSystem.setIsActiveSource(true);
-                audioSystem.wakeUpIfActiveSource();
-                audioSystem.maySendActiveSource(sourceAddress);
-            }
+        } else if (audioSystem != null) {
+            audioSystem.setActiveSource(audioSystem.getDeviceInfo().getLogicalAddress(),
+                    physicalAddress, caller);
+            audioSystem.wakeUpIfActiveSource();
+            audioSystem.maySendActiveSource(sourceAddress);
         }
     }
 
diff --git a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
index 4962af1..e78a86c 100644
--- a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
+++ b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
@@ -85,7 +85,7 @@
         // Because only source device can create this action, it's safe to cast.
         HdmiCecLocalDeviceSource source = source();
         source.mService.setAndBroadcastActiveSourceFromOneDeviceType(
-                mTargetAddress, getSourcePath());
+                mTargetAddress, getSourcePath(), "OneTouchPlayAction#broadcastActiveSource()");
         // When OneTouchPlay is called, client side should be responsible to send out the intent
         // of which internal source, for example YouTube, it would like to switch to.
         // Here we only update the active port and the active source records in the local
diff --git a/services/core/java/com/android/server/hdmi/SystemAudioInitiationActionFromAvr.java b/services/core/java/com/android/server/hdmi/SystemAudioInitiationActionFromAvr.java
index 0907e5d..acafda6 100644
--- a/services/core/java/com/android/server/hdmi/SystemAudioInitiationActionFromAvr.java
+++ b/services/core/java/com/android/server/hdmi/SystemAudioInitiationActionFromAvr.java
@@ -119,7 +119,8 @@
         // claim Active Source and start to query TV system audio mode support.
         if (audioSystem().mService.isPlaybackDevice()) {
             audioSystem().mService.setAndBroadcastActiveSourceFromOneDeviceType(
-                    Constants.ADDR_BROADCAST, getSourcePath());
+                    Constants.ADDR_BROADCAST, getSourcePath(),
+                    "SystemAudioInitiationActionFromAvr#handleActiveSourceTimeout()");
             mState = STATE_WAITING_FOR_TV_SUPPORT;
             queryTvSystemAudioModeSupport();
         } else {
diff --git a/services/core/java/com/android/server/location/timezone/LocationTimeZoneManagerService.java b/services/core/java/com/android/server/location/timezone/LocationTimeZoneManagerService.java
index c9a211d..97d3b82 100644
--- a/services/core/java/com/android/server/location/timezone/LocationTimeZoneManagerService.java
+++ b/services/core/java/com/android/server/location/timezone/LocationTimeZoneManagerService.java
@@ -178,9 +178,6 @@
         if (isInSimulationMode(PRIMARY_PROVIDER_NAME)) {
             proxy = new SimulatedLocationTimeZoneProviderProxy(mContext, mThreadingDomain);
         } else {
-            // TODO Uncomment this code in a later commit.
-            throw new UnsupportedOperationException("Not implemented");
-            /*
             proxy = RealLocationTimeZoneProviderProxy.createAndRegister(
                     mContext,
                     mThreadingDomain,
@@ -188,7 +185,6 @@
                     com.android.internal.R.bool.config_enablePrimaryLocationTimeZoneOverlay,
                     com.android.internal.R.string.config_primaryLocationTimeZoneProviderPackageName
             );
-            */
         }
         return createLocationTimeZoneProvider(PRIMARY_PROVIDER_NAME, proxy);
     }
diff --git a/services/core/java/com/android/server/pm/IncrementalStates.java b/services/core/java/com/android/server/pm/IncrementalStates.java
new file mode 100644
index 0000000..dda5faf
--- /dev/null
+++ b/services/core/java/com/android/server/pm/IncrementalStates.java
@@ -0,0 +1,480 @@
+/*
+ * 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.pm;
+
+import android.content.pm.IDataLoaderStatusListener;
+import android.content.pm.IncrementalStatesInfo;
+import android.content.pm.PackageManager;
+import android.os.Handler;
+import android.os.incremental.IStorageHealthListener;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.function.pooled.PooledLambda;
+
+import java.util.function.BiConsumer;
+
+/**
+ * Manages state transitions of a package installed on Incremental File System. Currently manages:
+ * 1. startable state (whether a package is allowed to be launched), and
+ * 2. loading state (whether a package is still loading or has been fully loaded).
+ *
+ * The following events might change the states of a package:
+ * 1. Installation commit
+ * 2. Incremental storage health
+ * 3. Data loader stream health
+ * 4. Loading progress changes
+ *
+ * @hide
+ */
+public final class IncrementalStates {
+    private static final String TAG = "IncrementalStates";
+    private static final boolean DEBUG = false;
+    private final Handler mHandler = BackgroundThread.getHandler();
+    private final Object mLock = new Object();
+    @GuardedBy("mLock")
+    private int mStreamStatus = IDataLoaderStatusListener.STREAM_HEALTHY;
+    @GuardedBy("mLock")
+    private int mStorageHealthStatus = IStorageHealthListener.HEALTH_STATUS_OK;
+    @GuardedBy("mLock")
+    private final LoadingState mLoadingState;
+    @GuardedBy("mLock")
+    private StartableState mStartableState;
+    @GuardedBy("mLock")
+    private Callback mCallback = null;
+    private final BiConsumer<Integer, Integer> mStatusConsumer;
+
+    public IncrementalStates() {
+        // By default the package is not startable and not fully loaded (i.e., is loading)
+        this(false, true);
+    }
+
+    public IncrementalStates(boolean isStartable, boolean isLoading) {
+        mStartableState = new StartableState(isStartable);
+        mLoadingState = new LoadingState(isLoading);
+        mStatusConsumer = new StatusConsumer();
+    }
+
+    /**
+     * Callback interface to report that the startable state of this package has changed.
+     */
+    public interface Callback {
+        /**
+         * Reports that the package is now unstartable and the unstartable reason.
+         */
+        void onPackageUnstartable(int reason);
+
+        /**
+         * Reports that the package is now startable.
+         */
+        void onPackageStartable();
+
+        /**
+         * Reports that package is fully loaded.
+         */
+        void onPackageFullyLoaded();
+    }
+
+    /**
+     * By calling this method, the caller indicates that package installation has just been
+     * committed. The package becomes startable. Set the initial loading state after the package
+     * is committed. Incremental packages are by-default loading; non-Incremental packages are not.
+     *
+     * @param isIncremental whether a package is installed on Incremental or not.
+     */
+    public void onCommit(boolean isIncremental) {
+        if (DEBUG) {
+            Slog.i(TAG, "received package commit event");
+        }
+        synchronized (mLock) {
+            if (!mStartableState.isStartable()) {
+                mStartableState.adoptNewStartableStateLocked(true);
+            }
+            if (mLoadingState.isLoading() != isIncremental) {
+                mLoadingState.adoptNewLoadingStateLocked(isIncremental);
+            }
+        }
+        mHandler.post(PooledLambda.obtainRunnable(
+                IncrementalStates::reportStartableState,
+                IncrementalStates.this).recycleOnUse());
+        if (!isIncremental) {
+            mHandler.post(PooledLambda.obtainRunnable(
+                    IncrementalStates::reportFullyLoaded,
+                    IncrementalStates.this).recycleOnUse());
+        }
+    }
+
+    private void reportStartableState() {
+        final Callback callback;
+        final boolean startable;
+        final int reason;
+        synchronized (mLock) {
+            callback = mCallback;
+            startable = mStartableState.isStartable();
+            reason = mStartableState.getUnstartableReason();
+        }
+        if (callback == null) {
+            return;
+        }
+        if (startable) {
+            callback.onPackageStartable();
+        } else {
+            callback.onPackageUnstartable(reason);
+        }
+    }
+
+    private void reportFullyLoaded() {
+        final Callback callback;
+        synchronized (mLock) {
+            callback = mCallback;
+        }
+        if (callback != null) {
+            callback.onPackageFullyLoaded();
+        }
+    }
+
+    private class StatusConsumer implements BiConsumer<Integer, Integer> {
+        @Override
+        public void accept(Integer streamStatus, Integer storageStatus) {
+            if (streamStatus == null && storageStatus == null) {
+                return;
+            }
+            final boolean oldState, newState;
+            synchronized (mLock) {
+                if (!mLoadingState.isLoading()) {
+                    // Do nothing if the package is already fully loaded
+                    return;
+                }
+                oldState = mStartableState.isStartable();
+                if (streamStatus != null) {
+                    mStreamStatus = (Integer) streamStatus;
+                }
+                if (storageStatus != null) {
+                    mStorageHealthStatus = (Integer) storageStatus;
+                }
+                updateStartableStateLocked();
+                newState = mStartableState.isStartable();
+            }
+            if (oldState != newState) {
+                mHandler.post(PooledLambda.obtainRunnable(IncrementalStates::reportStartableState,
+                        IncrementalStates.this).recycleOnUse());
+            }
+        }
+    };
+
+    /**
+     * By calling this method, the caller indicates that there issues with the Incremental
+     * Storage,
+     * on which the package is installed. The state will change according to the status
+     * code defined in {@code IStorageHealthListener}.
+     */
+    public void onStorageHealthStatusChanged(int storageHealthStatus) {
+        if (DEBUG) {
+            Slog.i(TAG, "received storage health status changed event : storageHealthStatus="
+                    + storageHealthStatus);
+        }
+        mStatusConsumer.accept(null, storageHealthStatus);
+    }
+
+    /**
+     * By calling this method, the caller indicates that the stream status of the package has
+     * been
+     * changed. This could indicate a streaming error. The state will change according to the
+     * status
+     * code defined in {@code IDataLoaderStatusListener}.
+     */
+    public void onStreamStatusChanged(int streamState) {
+        if (DEBUG) {
+            Slog.i(TAG, "received stream status changed event : streamState=" + streamState);
+        }
+        mStatusConsumer.accept(streamState, null);
+    }
+
+    /**
+     * Use the specified callback to report state changing events.
+     *
+     * @param callback Object to report new state.
+     */
+    public void setCallback(Callback callback) {
+        if (DEBUG) {
+            Slog.i(TAG, "registered callback");
+        }
+        synchronized (mLock) {
+            mCallback = callback;
+        }
+    }
+
+    /**
+     * Update the package loading progress to specified value. This might change startable state.
+     *
+     * @param progress Value between [0, 1].
+     */
+    public void setProgress(float progress) {
+        final boolean newLoadingState;
+        final boolean oldStartableState, newStartableState;
+        synchronized (mLock) {
+            oldStartableState = mStartableState.isStartable();
+            updateProgressLocked(progress);
+            newLoadingState = mLoadingState.isLoading();
+            newStartableState = mStartableState.isStartable();
+        }
+        if (!newLoadingState) {
+            mHandler.post(PooledLambda.obtainRunnable(
+                    IncrementalStates::reportFullyLoaded,
+                    IncrementalStates.this).recycleOnUse());
+        }
+        if (newStartableState != oldStartableState) {
+            mHandler.post(PooledLambda.obtainRunnable(
+                    IncrementalStates::reportStartableState,
+                    IncrementalStates.this).recycleOnUse());
+        }
+    }
+
+    /**
+     * @return the current startable state.
+     */
+    public boolean isStartable() {
+        synchronized (mLock) {
+            return mStartableState.isStartable();
+        }
+    }
+
+    /**
+     * @return Whether the package is still being loaded or has been fully loaded.
+     */
+    public boolean isLoading() {
+        synchronized (mLock) {
+            return mLoadingState.isLoading();
+        }
+    }
+
+    /**
+     * @return all current states in a Parcelable.
+     */
+    public IncrementalStatesInfo getIncrementalStatesInfo() {
+        synchronized (mLock) {
+            return new IncrementalStatesInfo(mStartableState.isStartable(),
+                    mLoadingState.isLoading(),
+                    mLoadingState.getProgress());
+        }
+    }
+
+    /**
+     * Determine the next state based on the current state, current stream status and storage
+     * health
+     * status. If the next state is different from the current state, proceed with state
+     * change.
+     */
+    private void updateStartableStateLocked() {
+        final boolean currentState = mStartableState.isStartable();
+        boolean nextState = currentState;
+        if (!currentState) {
+            if (mStorageHealthStatus == IStorageHealthListener.HEALTH_STATUS_OK
+                    && mStreamStatus == IDataLoaderStatusListener.STREAM_HEALTHY) {
+                // change from unstartable -> startable when both stream and storage are healthy
+                nextState = true;
+            }
+        } else {
+            if (mStorageHealthStatus == IStorageHealthListener.HEALTH_STATUS_UNHEALTHY) {
+                // unrecoverable if storage is unhealthy
+                nextState = false;
+            } else {
+                switch (mStreamStatus) {
+                    case IDataLoaderStatusListener.STREAM_INTEGRITY_ERROR:
+                        // unrecoverable, fall through
+                    case IDataLoaderStatusListener.STREAM_SOURCE_ERROR: {
+                        // unrecoverable
+                        nextState = false;
+                        break;
+                    }
+                    case IDataLoaderStatusListener.STREAM_STORAGE_ERROR: {
+                        if (mStorageHealthStatus != IStorageHealthListener.HEALTH_STATUS_OK) {
+                            // unrecoverable if there is a pending read AND storage is limited
+                            nextState = false;
+                        }
+                        break;
+                    }
+                    default:
+                        // anything else, remain startable
+                        break;
+                }
+            }
+        }
+        if (nextState == currentState) {
+            return;
+        }
+        mStartableState.adoptNewStartableStateLocked(nextState);
+    }
+
+    private void updateProgressLocked(float progress) {
+        if (DEBUG) {
+            Slog.i(TAG, "received progress update: " + progress);
+        }
+        mLoadingState.setProgress(progress);
+        if (1 - progress < 0.001) {
+            if (DEBUG) {
+                Slog.i(TAG, "package is fully loaded");
+            }
+            mLoadingState.setProgress(1);
+            if (mLoadingState.isLoading()) {
+                mLoadingState.adoptNewLoadingStateLocked(false);
+            }
+            // Also updates startable state if necessary
+            if (!mStartableState.isStartable()) {
+                mStartableState.adoptNewStartableStateLocked(true);
+            }
+        }
+    }
+
+    private class StartableState {
+        private boolean mIsStartable;
+        private int mUnstartableReason = PackageManager.UNSTARTABLE_REASON_UNKNOWN;
+
+        StartableState(boolean isStartable) {
+            mIsStartable = isStartable;
+        }
+
+        public boolean isStartable() {
+            return mIsStartable;
+        }
+
+        public int getUnstartableReason() {
+            return mUnstartableReason;
+        }
+
+        public void adoptNewStartableStateLocked(boolean nextState) {
+            if (DEBUG) {
+                Slog.i(TAG, "startable state changed from " + mIsStartable + " to " + nextState);
+            }
+            mIsStartable = nextState;
+            mUnstartableReason = getUnstartableReasonLocked();
+        }
+
+        private int getUnstartableReasonLocked() {
+            if (mIsStartable) {
+                return PackageManager.UNSTARTABLE_REASON_UNKNOWN;
+            }
+            // Translate stream status to reason for unstartable state
+            switch (mStreamStatus) {
+                case IDataLoaderStatusListener.STREAM_TRANSPORT_ERROR:
+                    // fall through
+                case IDataLoaderStatusListener.STREAM_INTEGRITY_ERROR:
+                    // fall through
+                case IDataLoaderStatusListener.STREAM_SOURCE_ERROR: {
+                    return PackageManager.UNSTARTABLE_REASON_DATALOADER_TRANSPORT;
+                }
+                case IDataLoaderStatusListener.STREAM_STORAGE_ERROR: {
+                    return PackageManager.UNSTARTABLE_REASON_DATALOADER_STORAGE;
+                }
+                default:
+                    return PackageManager.UNSTARTABLE_REASON_UNKNOWN;
+            }
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o == this) {
+                return true;
+            }
+            if (!(o instanceof StartableState)) {
+                return false;
+            }
+            StartableState l = (StartableState) o;
+            return l.mIsStartable == mIsStartable;
+        }
+
+        @Override
+        public int hashCode() {
+            return Boolean.hashCode(mIsStartable);
+        }
+    }
+
+    private class LoadingState {
+        private boolean mIsLoading;
+        private float mProgress;
+
+        LoadingState(boolean isLoading) {
+            mIsLoading = isLoading;
+            mProgress = isLoading ? 0 : 1;
+        }
+
+        public boolean isLoading() {
+            return mIsLoading;
+        }
+
+        public float getProgress() {
+            return mProgress;
+        }
+
+        public void setProgress(float progress) {
+            mProgress = progress;
+        }
+
+        public void adoptNewLoadingStateLocked(boolean nextState) {
+            if (DEBUG) {
+                Slog.i(TAG, "Loading state changed from " + mIsLoading + " to " + nextState);
+            }
+            mIsLoading = nextState;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o == this) {
+                return true;
+            }
+            if (!(o instanceof LoadingState)) {
+                return false;
+            }
+            LoadingState l = (LoadingState) o;
+            return l.mIsLoading == mIsLoading && l.mProgress == mProgress;
+        }
+
+        @Override
+        public int hashCode() {
+            int hashCode = Boolean.hashCode(mIsLoading);
+            hashCode = 31 * hashCode + Float.hashCode(mProgress);
+            return hashCode;
+        }
+    }
+
+
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+        if (!(o instanceof IncrementalStates)) {
+            return false;
+        }
+        IncrementalStates l = (IncrementalStates) o;
+        return l.mStorageHealthStatus == mStorageHealthStatus
+                && l.mStreamStatus == mStreamStatus
+                && l.mStartableState.equals(mStartableState)
+                && l.mLoadingState.equals(mLoadingState);
+    }
+
+    @Override
+    public int hashCode() {
+        int hashCode = mStartableState.hashCode();
+        hashCode = 31 * hashCode + mLoadingState.hashCode();
+        hashCode = 31 * hashCode + mStorageHealthStatus;
+        hashCode = 31 * hashCode + mStreamStatus;
+        return hashCode;
+    }
+}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 9e6e1d9..2aafe9a 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -141,6 +141,7 @@
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Preconditions;
+import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.LocalServices;
 import com.android.server.pm.Installer.InstallerException;
 import com.android.server.pm.dex.DexManager;
@@ -1700,20 +1701,26 @@
         }
     }
 
-    private void onStorageUnhealthy() {
+    private void onStorageHealthStatusChanged(int status) {
         final String packageName = getPackageName();
         if (TextUtils.isEmpty(packageName)) {
             // The package has not been installed.
             return;
         }
-        final PackageManagerService packageManagerService = mPm;
-        mHandler.post(() -> {
-            if (packageManagerService.deletePackageX(packageName,
-                    PackageManager.VERSION_CODE_HIGHEST, UserHandle.USER_SYSTEM,
-                    PackageManager.DELETE_ALL_USERS) != PackageManager.DELETE_SUCCEEDED) {
-                Slog.e(TAG, "Failed to uninstall package with failed dataloader: " + packageName);
-            }
-        });
+        mHandler.post(PooledLambda.obtainRunnable(
+                PackageManagerService::onStorageHealthStatusChanged,
+                mPm, packageName, status, userId).recycleOnUse());
+    }
+
+    private void onStreamHealthStatusChanged(int status) {
+        final String packageName = getPackageName();
+        if (TextUtils.isEmpty(packageName)) {
+            // The package has not been installed.
+            return;
+        }
+        mHandler.post(PooledLambda.obtainRunnable(
+                PackageManagerService::onStreamStatusChanged,
+                mPm, packageName, status, userId).recycleOnUse());
     }
 
     /**
@@ -3261,7 +3268,9 @@
                 if (isDestroyedOrDataLoaderFinished) {
                     switch (status) {
                         case IDataLoaderStatusListener.DATA_LOADER_UNRECOVERABLE:
-                            onStorageUnhealthy();
+                            // treat as unhealthy storage
+                            onStorageHealthStatusChanged(
+                                    IStorageHealthListener.HEALTH_STATUS_UNHEALTHY);
                             return;
                     }
                     return;
@@ -3358,6 +3367,16 @@
                     sendPendingStreaming(mContext, statusReceiver, sessionId, e.getMessage());
                 }
             }
+            @Override
+            public void reportStreamHealth(int dataLoaderId, int streamStatus) {
+                synchronized (mLock) {
+                    if (!mDestroyed && !mDataLoaderFinished) {
+                        // ignore streaming status if package isn't installed
+                        return;
+                    }
+                }
+                onStreamHealthStatusChanged(streamStatus);
+            }
         };
 
         if (!manualStartAndDestroy) {
@@ -3377,11 +3396,7 @@
                     }
                     if (isDestroyedOrDataLoaderFinished) {
                         // App's installed.
-                        switch (status) {
-                            case IStorageHealthListener.HEALTH_STATUS_UNHEALTHY:
-                                onStorageUnhealthy();
-                                return;
-                        }
+                        onStorageHealthStatusChanged(status);
                         return;
                     }
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index fb683d9..54dbe2e 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -16392,12 +16392,24 @@
                 } else if (!previousUserIds.contains(userId)) {
                     ps.setInstallReason(installReason, userId);
                 }
+
+                // TODO(b/169721400): generalize Incremental States and create a Callback object
+                // that can be used for all the packages.
+                final IncrementalStatesCallback incrementalStatesCallback =
+                        new IncrementalStatesCallback(ps, userId);
+                final String codePath = ps.getPathString();
+                if (IncrementalManager.isIncrementalPath(codePath) && mIncrementalManager != null) {
+                    mIncrementalManager.registerCallback(codePath, incrementalStatesCallback);
+                    ps.setIncrementalStatesCallback(incrementalStatesCallback);
+                }
+
                 // Ensure that the uninstall reason is UNKNOWN for users with the package installed.
                 for (int currentUserId : allUsersList) {
                     if (ps.getInstalled(currentUserId)) {
                         ps.setUninstallReason(UNINSTALL_REASON_UNKNOWN, currentUserId);
                     }
                 }
+
                 mSettings.writeKernelMappingLPr(ps);
             }
             res.name = pkgName;
@@ -17194,6 +17206,7 @@
                 mDexManager.notifyPackageUpdated(pkg.getPackageName(),
                         pkg.getBaseApkPath(), pkg.getSplitCodePaths());
             }
+            reconciledPkg.pkgSetting.setStatesOnCommit();
 
             // Prepare the application profiles for the new code paths.
             // This needs to be done before invoking dexopt so that any install-time profile
@@ -17290,6 +17303,155 @@
         NativeLibraryHelper.waitForNativeBinariesExtraction(incrementalStorages);
     }
 
+    private class IncrementalStatesCallback extends IPackageLoadingProgressCallback.Stub
+            implements IncrementalStates.Callback {
+        @GuardedBy("mPackageSetting")
+        private final PackageSetting mPackageSetting;
+        private final String mPackageName;
+        private final String mPathString;
+        private final int mUserId;
+        private final int[] mInstalledUserIds;
+
+        IncrementalStatesCallback(PackageSetting packageSetting, int userId) {
+            mPackageSetting = packageSetting;
+            mPackageName = packageSetting.name;
+            mUserId = userId;
+            mPathString = packageSetting.getPathString();
+            final int[] allUserIds = resolveUserIds(userId);
+            final ArrayList<Integer> installedUserIds = new ArrayList<>();
+            for (int i = 0; i < allUserIds.length; i++) {
+                if (packageSetting.getInstalled(allUserIds[i])) {
+                    installedUserIds.add(allUserIds[i]);
+                }
+            }
+            final int numInstalledUserId = installedUserIds.size();
+            mInstalledUserIds = new int[numInstalledUserId];
+            for (int i = 0; i < numInstalledUserId; i++) {
+                mInstalledUserIds[i] = installedUserIds.get(i);
+            }
+        }
+
+        @Override
+        public void onPackageLoadingProgressChanged(float progress) {
+            synchronized (mPackageSetting) {
+                mPackageSetting.setLoadingProgress(progress);
+            }
+        }
+
+        @Override
+        public void onPackageFullyLoaded() {
+            mIncrementalManager.unregisterCallback(mPathString, this);
+            final SparseArray<int[]> newBroadcastAllowList;
+            synchronized (mLock) {
+                newBroadcastAllowList = mAppsFilter.getVisibilityAllowList(
+                        getPackageSettingInternal(mPackageName, Process.SYSTEM_UID),
+                        mInstalledUserIds, mSettings.mPackages);
+            }
+            Bundle extras = new Bundle(1);
+            extras.putInt(Intent.EXTRA_UID, mUserId);
+            extras.putString(Intent.EXTRA_PACKAGE_NAME, mPackageName);
+            sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_LOADED, mPackageName,
+                    extras, 0 /*flags*/,
+                    null /*targetPackage*/, null /*finishedReceiver*/,
+                    mInstalledUserIds, null /* instantUserIds */, newBroadcastAllowList);
+        }
+
+        @Override
+        public void onPackageUnstartable(int reason) {
+            final SparseArray<int[]> newBroadcastAllowList;
+            synchronized (mLock) {
+                newBroadcastAllowList = mAppsFilter.getVisibilityAllowList(
+                        getPackageSettingInternal(mPackageName, Process.SYSTEM_UID),
+                        mInstalledUserIds, mSettings.mPackages);
+            }
+            Bundle extras = new Bundle(1);
+            extras.putInt(Intent.EXTRA_UID, mUserId);
+            extras.putString(Intent.EXTRA_PACKAGE_NAME, mPackageName);
+            extras.putInt(Intent.EXTRA_REASON, reason);
+            // send broadcast to users with this app installed
+            sendPackageBroadcast(Intent.ACTION_PACKAGE_UNSTARTABLE, mPackageName,
+                    extras, 0 /*flags*/,
+                    null /*targetPackage*/, null /*finishedReceiver*/,
+                    mInstalledUserIds, null /* instantUserIds */, newBroadcastAllowList);
+        }
+
+        @Override
+        public void onPackageStartable() {
+            final SparseArray<int[]> newBroadcastAllowList;
+            synchronized (mLock) {
+                newBroadcastAllowList = mAppsFilter.getVisibilityAllowList(
+                        getPackageSettingInternal(mPackageName, Process.SYSTEM_UID),
+                        mInstalledUserIds, mSettings.mPackages);
+            }
+            Bundle extras = new Bundle(1);
+            extras.putInt(Intent.EXTRA_UID, mUserId);
+            extras.putString(Intent.EXTRA_PACKAGE_NAME, mPackageName);
+            // send broadcast to users with this app installed
+            sendPackageBroadcast(Intent.ACTION_PACKAGE_STARTABLE, mPackageName,
+                    extras, 0 /*flags*/,
+                    null /*targetPackage*/, null /*finishedReceiver*/,
+                    mInstalledUserIds, null /* instantUserIds */, newBroadcastAllowList);
+        }
+    }
+
+    /**
+     * This is an internal method that is used to indicate changes on the health status of the
+     * Incremental Storage used by an installed package with an associated user id. This might
+     * result in a change in the loading state of the package.
+     */
+    public void onStorageHealthStatusChanged(String packageName, int status, int userId) {
+        final int callingUid = Binder.getCallingUid();
+        mPermissionManager.enforceCrossUserPermission(
+                callingUid, userId, true, false,
+                "onStorageHealthStatusChanged");
+        final PackageSetting ps = getPackageSettingForUser(packageName, callingUid, userId);
+        if (ps == null) {
+            return;
+        }
+        ps.setStorageHealthStatus(status);
+    }
+
+    /**
+     * This is an internal method that is used to indicate changes on the stream status of the
+     * data loader used by an installed package with an associated user id. This might
+     * result in a change in the loading state of the package.
+     */
+    public void onStreamStatusChanged(String packageName, int status, int userId) {
+        final int callingUid = Binder.getCallingUid();
+        mPermissionManager.enforceCrossUserPermission(
+                callingUid, userId, true, false,
+                "onStreamStatusChanged");
+        final PackageSetting ps = getPackageSettingForUser(packageName, callingUid, userId);
+        if (ps == null) {
+            return;
+        }
+        ps.setStreamStatus(status);
+    }
+
+    @Nullable PackageSetting getPackageSettingForUser(String packageName, int callingUid,
+            int userId) {
+        final PackageSetting ps;
+        synchronized (mLock) {
+            ps = mSettings.mPackages.get(packageName);
+            if (ps == null) {
+                Slog.w(TAG, "Failed to get package setting. Package " + packageName
+                        + " is not installed");
+                return null;
+            }
+            if (!ps.getInstalled(userId)) {
+                Slog.w(TAG, "Failed to get package setting. Package " + packageName
+                        + " is not installed for user " + userId);
+                return null;
+            }
+            if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
+                Slog.w(TAG, "Failed to get package setting. Package " + packageName
+                        + " is not visible to the calling app");
+                return null;
+            }
+        }
+        return ps;
+    }
+
     private void notifyPackageChangeObserversOnUpdate(ReconciledPackage reconciledPkg) {
       final PackageSetting pkgSetting = reconciledPkg.pkgSetting;
       final PackageInstalledInfo pkgInstalledInfo = reconciledPkg.installResult;
@@ -25409,24 +25571,15 @@
         @Override
         public boolean registerInstalledLoadingProgressCallback(String packageName,
                 PackageManagerInternal.InstalledLoadingProgressCallback callback, int userId) {
-            final int callingUid = Binder.getCallingUid();
-            mPermissionManager.enforceCrossUserPermission(
-                    callingUid, userId, true, false,
-                    "registerLoadingProgressCallback");
-            final PackageSetting ps;
-            synchronized (mLock) {
-                ps = mSettings.mPackages.get(packageName);
-                if (ps == null) {
-                    Slog.w(TAG, "Failed registering loading progress callback. Package "
-                            + packageName + " is not installed");
-                    return false;
-                }
-                if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
-                    Slog.w(TAG, "Failed registering loading progress callback. Package "
-                            + packageName + " is not visible to the calling app");
-                    return false;
-                }
-                // TODO(b/165841827): return false if package is fully loaded
+            final PackageSetting ps = getPackageSettingForUser(packageName, Binder.getCallingUid(),
+                    userId);
+            if (ps == null) {
+                return false;
+            }
+            if (!ps.isPackageLoading()) {
+                Slog.w(TAG,
+                        "Failed registering loading progress callback. Package is fully loaded.");
+                return false;
             }
             if (mIncrementalManager == null) {
                 Slog.w(TAG,
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index 855a5ff5..2ff18f8 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -333,6 +333,8 @@
                     installSource.originatingPackageName);
             proto.end(sourceToken);
         }
+        proto.write(PackageProto.StatesProto.IS_STARTABLE, incrementalStates.isStartable());
+        proto.write(PackageProto.StatesProto.IS_LOADING, incrementalStates.isLoading());
         writeUsersInfoToProto(proto, PackageProto.USERS);
         proto.end(packageToken);
     }
diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index a7bbf8d..d52ad46 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -25,6 +25,7 @@
 import android.annotation.UserIdInt;
 import android.content.ComponentName;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.IncrementalStatesInfo;
 import android.content.pm.IntentFilterVerificationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.UninstallReason;
@@ -33,6 +34,7 @@
 import android.content.pm.Signature;
 import android.content.pm.SuspendDialogInfo;
 import android.os.PersistableBundle;
+import android.os.incremental.IncrementalManager;
 import android.service.pm.PackageProto;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -133,6 +135,9 @@
 
     boolean forceQueryableOverride;
 
+    @NonNull
+    public IncrementalStates incrementalStates;
+
     PackageSettingBase(String name, String realName, @NonNull File path,
             String legacyNativeLibraryPathString, String primaryCpuAbiString,
             String secondaryCpuAbiString, String cpuAbiOverrideString,
@@ -151,6 +156,7 @@
         this.versionCode = pVersionCode;
         this.signatures = new PackageSignatures();
         this.installSource = InstallSource.EMPTY;
+        this.incrementalStates = new IncrementalStates();
     }
 
     /**
@@ -257,6 +263,7 @@
                        orig.usesStaticLibrariesVersions.length) : null;
         updateAvailable = orig.updateAvailable;
         forceQueryableOverride = orig.forceQueryableOverride;
+        incrementalStates = orig.incrementalStates;
     }
 
     @VisibleForTesting
@@ -733,6 +740,66 @@
         modifyUserState(userId).resetOverrideComponentLabelIcon();
     }
 
+    /**
+     * @return True if package is startable, false otherwise.
+     */
+    public boolean isPackageStartable() {
+        return incrementalStates.isStartable();
+    }
+
+    /**
+     * @return True if package is still being loaded, false if the package is fully loaded.
+     */
+    public boolean isPackageLoading() {
+        return incrementalStates.isLoading();
+    }
+
+    /**
+     * @return all current states in a Parcelable.
+     */
+    public IncrementalStatesInfo getIncrementalStates() {
+        return incrementalStates.getIncrementalStatesInfo();
+    }
+
+    /**
+     * Called to indicate that the package installation has been committed. This will create a
+     * new startable state and a new loading state with default values. By default, the package is
+     * startable after commit. For a package installed on Incremental, the loading state is true.
+     * For non-Incremental packages, the loading state is false.
+     */
+    public void setStatesOnCommit() {
+        incrementalStates.onCommit(IncrementalManager.isIncrementalPath(getPathString()));
+    }
+
+    /**
+     * Called to set the callback to listen for startable state changes.
+     */
+    public void setIncrementalStatesCallback(IncrementalStates.Callback callback) {
+        incrementalStates.setCallback(callback);
+    }
+
+    /**
+     * Called to report progress changes. This might trigger loading state change.
+     * @see IncrementalStates#setProgress(float)
+     */
+    public void setLoadingProgress(float progress) {
+        incrementalStates.setProgress(progress);
+    }
+
+    /**
+     * @see IncrementalStates#onStorageHealthStatusChanged(int)
+     */
+    public void setStorageHealthStatus(int status) {
+        incrementalStates.onStorageHealthStatusChanged(status);
+    }
+
+    /**
+     * @see IncrementalStates#onStreamStatusChanged(int)
+     */
+    public void setStreamStatus(int status) {
+        incrementalStates.onStreamStatusChanged(status);
+    }
+
     protected PackageSettingBase updateFrom(PackageSettingBase other) {
         super.copyFrom(other);
         setPath(other.getPath());
@@ -756,6 +823,7 @@
         this.updateAvailable = other.updateAvailable;
         this.verificationInfo = other.verificationInfo;
         this.forceQueryableOverride = other.forceQueryableOverride;
+        this.incrementalStates = other.incrementalStates;
 
         if (mOldCodePaths != null) {
             if (other.mOldCodePaths != null) {
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index a922d76..c16bd5c 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -2809,6 +2809,12 @@
         if (pkg.forceQueryableOverride) {
             serializer.attribute(null, "forceQueryable", "true");
         }
+        if (pkg.isPackageStartable()) {
+            serializer.attribute(null, "isStartable", "true");
+        }
+        if (pkg.isPackageLoading()) {
+            serializer.attribute(null, "isLoading", "true");
+        }
 
         writeUsesStaticLibLPw(serializer, pkg.usesStaticLibraries, pkg.usesStaticLibrariesVersions);
 
@@ -3594,6 +3600,8 @@
         String version = null;
         long versionCode = 0;
         String installedForceQueryable = null;
+        String isStartable = null;
+        String isLoading = null;
         try {
             name = parser.getAttributeValue(null, ATTR_NAME);
             realName = parser.getAttributeValue(null, "realName");
@@ -3610,6 +3618,8 @@
             cpuAbiOverrideString = parser.getAttributeValue(null, "cpuAbiOverride");
             updateAvailable = parser.getAttributeValue(null, "updateAvailable");
             installedForceQueryable = parser.getAttributeValue(null, "forceQueryable");
+            isStartable = parser.getAttributeValue(null, "isStartable");
+            isLoading = parser.getAttributeValue(null, "isLoading");
 
             if (primaryCpuAbiString == null && legacyCpuAbiString != null) {
                 primaryCpuAbiString = legacyCpuAbiString;
@@ -3793,6 +3803,8 @@
             packageSetting.secondaryCpuAbiString = secondaryCpuAbiString;
             packageSetting.updateAvailable = "true".equals(updateAvailable);
             packageSetting.forceQueryableOverride = "true".equals(installedForceQueryable);
+            packageSetting.incrementalStates = new IncrementalStates("true".equals(isStartable),
+                    "true".equals(isLoading));
             // Handle legacy string here for single-user mode
             final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED);
             if (enabledStr != null) {
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index b062b28..9868fc1 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -116,6 +116,7 @@
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_SWITCH;
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
@@ -150,10 +151,7 @@
 import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
 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_PAUSE;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SAVED_STATE;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TRANSITION;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING;
@@ -1133,16 +1131,14 @@
 
     boolean scheduleTopResumedActivityChanged(boolean onTop) {
         if (!attachedToProcess()) {
-            if (DEBUG_STATES) {
-                Slog.w(TAG, "Can't report activity position update - client not running"
-                                + ", activityRecord=" + this);
-            }
+            ProtoLog.w(WM_DEBUG_STATES,
+                    "Can't report activity position update - client not running, "
+                            + "activityRecord=%s", this);
             return false;
         }
         try {
-            if (DEBUG_STATES) {
-                Slog.v(TAG, "Sending position change to " + this + ", onTop: " + onTop);
-            }
+            ProtoLog.v(WM_DEBUG_STATES, "Sending position change to %s, onTop: %b",
+                    this, onTop);
 
             mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
                     TopResumedActivityChangeItem.obtain(onTop));
@@ -2518,10 +2514,8 @@
      */
     @FinishRequest int finishIfPossible(int resultCode, Intent resultData,
             NeededUriGrants resultGrants, String reason, boolean oomAdj) {
-        if (DEBUG_RESULTS || DEBUG_STATES) {
-            Slog.v(TAG_STATES, "Finishing activity r=" + this + ", result=" + resultCode
-                    + ", data=" + resultData + ", reason=" + reason);
-        }
+        ProtoLog.v(WM_DEBUG_STATES, "Finishing activity r=%s, result=%d, data=%s, "
+                + "reason=%s", this, resultCode, resultData, reason);
 
         if (finishing) {
             Slog.w(TAG, "Duplicate finish request for r=" + this);
@@ -2603,7 +2597,7 @@
                 setVisibility(false);
 
                 if (stack.mPausingActivity == null) {
-                    if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish needs to pause: " + this);
+                    ProtoLog.v(WM_DEBUG_STATES, "Finish needs to pause: %s", this);
                     if (DEBUG_USER_LEAVING) {
                         Slog.v(TAG_USER_LEAVING, "finish() => pause with userLeaving=false");
                     }
@@ -2650,7 +2644,7 @@
                 }
                 return removedActivity ? FINISH_RESULT_REMOVED : FINISH_RESULT_REQUESTED;
             } else {
-                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + this);
+                ProtoLog.v(WM_DEBUG_STATES, "Finish waiting for pause of: %s", this);
             }
 
             return FINISH_RESULT_REQUESTED;
@@ -2807,7 +2801,7 @@
      */
     @VisibleForTesting
     boolean addToFinishingAndWaitForIdle() {
-        if (DEBUG_STATES) Slog.v(TAG, "Enqueueing pending finish: " + this);
+        ProtoLog.v(WM_DEBUG_STATES, "Enqueueing pending finish: %s", this);
         setState(FINISHING, "addToFinishingAndWaitForIdle");
         if (!mStackSupervisor.mFinishingActivities.contains(this)) {
             mStackSupervisor.mFinishingActivities.add(this);
@@ -2835,10 +2829,8 @@
         }
 
         if (isState(DESTROYING, DESTROYED)) {
-            if (DEBUG_STATES) {
-                Slog.v(TAG_STATES, "activity " + this + " already destroying."
-                        + "skipping request with reason:" + reason);
-            }
+            ProtoLog.v(WM_DEBUG_STATES, "activity %s already destroying, skipping "
+                    + "request with reason:%s", this, reason);
             return false;
         }
 
@@ -2879,16 +2871,13 @@
             // the list yet.  Otherwise, we can just immediately put it in the destroyed state since
             // we are not removing it from the list.
             if (finishing && !skipDestroy) {
-                if (DEBUG_STATES) {
-                    Slog.v(TAG_STATES, "Moving to DESTROYING: " + this + " (destroy requested)");
-                }
+                ProtoLog.v(WM_DEBUG_STATES, "Moving to DESTROYING: %s (destroy requested)", this);
                 setState(DESTROYING,
                         "destroyActivityLocked. finishing and not skipping destroy");
                 mAtmService.mH.postDelayed(mDestroyTimeoutRunnable, DESTROY_TIMEOUT);
             } else {
-                if (DEBUG_STATES) {
-                    Slog.v(TAG_STATES, "Moving to DESTROYED: " + this + " (destroy skipped)");
-                }
+                ProtoLog.v(WM_DEBUG_STATES, "Moving to DESTROYED: %s "
+                        + "(destroy skipped)", this);
                 setState(DESTROYED,
                         "destroyActivityLocked. not finishing or skipping destroy");
                 if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during destroy for activity " + this);
@@ -2900,7 +2889,7 @@
                 removeFromHistory(reason + " hadNoApp");
                 removedFromHistory = true;
             } else {
-                if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYED: " + this + " (no app)");
+                ProtoLog.v(WM_DEBUG_STATES, "Moving to DESTROYED: %s (no app)", this);
                 setState(DESTROYED, "destroyActivityLocked. not finishing and had no app");
             }
         }
@@ -2935,9 +2924,8 @@
 
         takeFromHistory();
         removeTimeouts();
-        if (DEBUG_STATES) {
-            Slog.v(TAG_STATES, "Moving to DESTROYED: " + this + " (removed from history)");
-        }
+        ProtoLog.v(WM_DEBUG_STATES, "Moving to DESTROYED: %s (removed from history)",
+                this);
         setState(DESTROYED, "removeFromHistory");
         if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during remove for activity " + this);
         detachFromProcess();
@@ -4455,12 +4443,12 @@
     }
 
     void setState(ActivityState state, String reason) {
-        if (DEBUG_STATES) Slog.v(TAG_STATES, "State movement: " + this + " from:" + getState()
-                        + " to:" + state + " reason:" + reason);
+        ProtoLog.v(WM_DEBUG_STATES, "State movement: %s from:%s to:%s reason:%s",
+                this, getState(), state, reason);
 
         if (state == mState) {
             // No need to do anything if state doesn't change.
-            if (DEBUG_STATES) Slog.v(TAG_STATES, "State unchanged from:" + state);
+            ProtoLog.v(WM_DEBUG_STATES, "State unchanged from:%s", state);
             return;
         }
 
@@ -4943,7 +4931,7 @@
 
     static void activityResumedLocked(IBinder token) {
         final ActivityRecord r = ActivityRecord.forTokenLocked(token);
-        if (DEBUG_SAVED_STATE) Slog.i(TAG_STATES, "Resumed activity; dropping state of: " + r);
+        ProtoLog.i(WM_DEBUG_STATES, "Resumed activity; dropping state of: %s", r);
         if (r == null) {
             // If an app reports resumed after a long delay, the record on server side might have
             // been removed (e.g. destroy timeout), so the token could be null.
@@ -5014,8 +5002,8 @@
     }
 
     void activityPaused(boolean timeout) {
-        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE,
-                "Activity paused: token=" + appToken + ", timeout=" + timeout);
+        ProtoLog.v(WM_DEBUG_STATES, "Activity paused: token=%s, timeout=%b", appToken,
+                timeout);
 
         final Task stack = getStack();
 
@@ -5023,8 +5011,8 @@
             removePauseTimeout();
 
             if (stack.mPausingActivity == this) {
-                if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + this
-                        + (timeout ? " (due to timeout)" : " (pause complete)"));
+                ProtoLog.v(WM_DEBUG_STATES, "Moving to PAUSED: %s %s", this,
+                        (timeout ? "(due to timeout)" : " (pause complete)"));
                 mAtmService.deferWindowLayout();
                 try {
                     stack.completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
@@ -5039,8 +5027,8 @@
                 if (isState(PAUSING)) {
                     setState(PAUSED, "activityPausedLocked");
                     if (finishing) {
-                        if (DEBUG_PAUSE) Slog.v(TAG,
-                                "Executing finish of failed to pause activity: " + this);
+                        ProtoLog.v(WM_DEBUG_STATES,
+                                "Executing finish of failed to pause activity: %s", this);
                         completeFinishing("activityPausedLocked");
                     }
                 }
@@ -5057,7 +5045,7 @@
     void schedulePauseTimeout() {
         pauseTime = SystemClock.uptimeMillis();
         mAtmService.mH.postDelayed(mPauseTimeoutRunnable, PAUSE_TIMEOUT);
-        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Waiting for pause to complete...");
+        ProtoLog.v(WM_DEBUG_STATES, "Waiting for pause to complete...");
     }
 
     private void removePauseTimeout() {
@@ -5086,17 +5074,15 @@
         if (isNoHistory()) {
             if (!finishing) {
                 if (!stack.shouldSleepActivities()) {
-                    if (DEBUG_STATES) Slog.d(TAG_STATES, "no-history finish of " + this);
+                    ProtoLog.d(WM_DEBUG_STATES, "no-history finish of %s", this);
                     if (finishIfPossible("stop-no-history", false /* oomAdj */)
                             != FINISH_RESULT_CANCELLED) {
                         resumeKeyDispatchingLocked();
                         return;
                     }
                 } else {
-                    if (DEBUG_STATES) {
-                        Slog.d(TAG_STATES, "Not finishing noHistory " + this
-                                + " on stop because we're just sleeping");
-                    }
+                    ProtoLog.d(WM_DEBUG_STATES, "Not finishing noHistory %s on stop "
+                            + "because we're just sleeping", this);
                 }
             }
         }
@@ -5107,9 +5093,8 @@
         resumeKeyDispatchingLocked();
         try {
             stopped = false;
-            if (DEBUG_STATES) {
-                Slog.v(TAG_STATES, "Moving to STOPPING: " + this + " (stop requested)");
-            }
+            ProtoLog.v(WM_DEBUG_STATES, "Moving to STOPPING: %s (stop requested)", this);
+
             setState(STOPPING, "stopIfPossible");
             if (DEBUG_VISIBILITY) {
                 Slog.v(TAG_VISIBILITY, "Stopping:" + this);
@@ -5129,7 +5114,7 @@
             Slog.w(TAG, "Exception thrown during pause", e);
             // Just in case, assume it to be stopped.
             stopped = true;
-            if (DEBUG_STATES) Slog.v(TAG_STATES, "Stop failed; moving to STOPPED: " + this);
+            ProtoLog.v(WM_DEBUG_STATES, "Stop failed; moving to STOPPED: %s", this);
             setState(STOPPED, "stopIfPossible");
             if (deferRelaunchUntilPaused) {
                 destroyImmediately("stop-except");
@@ -5158,9 +5143,9 @@
             launchCount = 0;
             updateTaskDescription(description);
         }
-        if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE, "Saving icicle of " + this + ": " + mIcicle);
+        ProtoLog.i(WM_DEBUG_STATES, "Saving icicle of %s: %s", this, mIcicle);
         if (!stopped) {
-            if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to STOPPED: " + this + " (stop complete)");
+            ProtoLog.v(WM_DEBUG_STATES, "Moving to STOPPED: %s (stop complete)", this);
             removeStopTimeout();
             stopped = true;
             if (isStopping) {
@@ -5196,10 +5181,9 @@
         boolean forceIdle = mStackSupervisor.mStoppingActivities.size() > MAX_STOPPING_TO_FORCE
                 || (isRootOfTask() && stack.getChildCount() <= 1);
         if (scheduleIdle || forceIdle) {
-            if (DEBUG_PAUSE) {
-                Slog.v(TAG_PAUSE, "Scheduling idle now: forceIdle=" + forceIdle
-                        + "immediate=" + !idleDelayed);
-            }
+            ProtoLog.v(WM_DEBUG_STATES,
+                    "Scheduling idle now: forceIdle=%b immediate=%b", forceIdle, !idleDelayed);
+
             if (!idleDelayed) {
                 mStackSupervisor.scheduleIdle();
             } else {
@@ -7126,9 +7110,9 @@
             } else {
                 ProtoLog.v(WM_DEBUG_CONFIGURATION, "Config is relaunching %s",
                         this);
-                if (DEBUG_STATES && !mVisibleRequested) {
-                    Slog.v(TAG_STATES, "Config is relaunching invisible activity " + this
-                            + " called by " + Debug.getCallers(4));
+                if (!mVisibleRequested) {
+                    ProtoLog.v(WM_DEBUG_STATES, "Config is relaunching invisible "
+                            + "activity %s called by %s", this, Debug.getCallers(4));
                 }
                 relaunchActivityLocked(preserveWindow);
             }
@@ -7261,9 +7245,8 @@
         startFreezingScreenLocked(0);
 
         try {
-            if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH,
-                    "Moving to " + (andResume ? "RESUMED" : "PAUSED") + " Relaunching " + this
-                            + " callers=" + Debug.getCallers(6));
+            ProtoLog.i(WM_DEBUG_STATES, "Moving to %s Relaunching %s callers=%s" ,
+                    (andResume ? "RESUMED" : "PAUSED"), this, Debug.getCallers(6));
             forceNewConfig = false;
             startRelaunching();
             final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(pendingResults,
@@ -7286,13 +7269,11 @@
             // request resume if this activity is currently resumed, which implies we aren't
             // sleeping.
         } catch (RemoteException e) {
-            if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH, "Relaunch failed", e);
+            ProtoLog.i(WM_DEBUG_STATES, "Relaunch failed %s", e);
         }
 
         if (andResume) {
-            if (DEBUG_STATES) {
-                Slog.d(TAG_STATES, "Resumed after relaunch " + this);
-            }
+            ProtoLog.d(WM_DEBUG_STATES, "Resumed after relaunch %s", this);
             results = null;
             newIntents = null;
             mAtmService.getAppWarningsLocked().onResumeActivity(this);
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index 3ef383b..e2c1303 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -44,15 +44,14 @@
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.view.Display.DEFAULT_DISPLAY;
 
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_IDLE;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PAUSE;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_IDLE;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_PAUSE;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
@@ -66,7 +65,6 @@
 import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
 import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
 import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;
-import static com.android.server.wm.RootWindowContainer.TAG_STATES;
 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
 import static com.android.server.wm.Task.ActivityState.PAUSED;
@@ -135,6 +133,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.content.ReferrerIntent;
 import com.android.internal.os.TransferPipe;
+import com.android.internal.protolog.common.ProtoLog;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.function.pooled.PooledConsumer;
 import com.android.internal.util.function.pooled.PooledLambda;
@@ -721,9 +720,9 @@
             // While there are activities pausing we skipping starting any new activities until
             // pauses are complete. NOTE: that we also do this for activities that are starting in
             // the paused state because they will first be resumed then paused on the client side.
-            if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
-                    "realStartActivityLocked: Skipping start of r=" + r
-                    + " some activities pausing...");
+            ProtoLog.v(WM_DEBUG_STATES,
+                    "realStartActivityLocked: Skipping start of r=%s some activities pausing...",
+                    r);
             return false;
         }
 
@@ -919,8 +918,8 @@
             // This activity is not starting in the resumed state... which should look like we asked
             // it to pause+stop (but remain visible), and it has done so and reported back the
             // current icicle and other state.
-            if (DEBUG_STATES) Slog.v(TAG_STATES,
-                    "Moving to PAUSED: " + r + " (starting in paused state)");
+            ProtoLog.v(WM_DEBUG_STATES, "Moving to PAUSED: %s "
+                    + "(starting in paused state)", r);
             r.setState(PAUSED, "realStartActivityLocked");
             mRootWindowContainer.executeAppTransitionForAllDisplay();
         }
@@ -1071,11 +1070,11 @@
     /** Check if caller is allowed to launch activities on specified display. */
     boolean isCallerAllowedToLaunchOnDisplay(int callingPid, int callingUid, int launchDisplayId,
             ActivityInfo aInfo) {
-        if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check: displayId=" + launchDisplayId
-                + " callingPid=" + callingPid + " callingUid=" + callingUid);
+        ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: displayId=%d callingPid=%d "
+                + "callingUid=%d", launchDisplayId, callingPid, callingUid);
 
         if (callingPid == -1 && callingUid == -1) {
-            if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check: no caller info, skip check");
+            ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: no caller info, skip check");
             return true;
         }
 
@@ -1091,8 +1090,7 @@
         final int startAnyPerm = mService.checkPermission(INTERNAL_SYSTEM_WINDOW, callingPid,
                 callingUid);
         if (startAnyPerm == PERMISSION_GRANTED) {
-            if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
-                    + " allow launch any on display");
+            ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: allow launch any on display");
             return true;
         }
 
@@ -1104,36 +1102,36 @@
             // Limit launching on untrusted displays because their contents can be read from Surface
             // by apps that created them.
             if ((aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
-                if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
-                        + " disallow launch on virtual display for not-embedded activity.");
+                ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: disallow launch on "
+                        + "virtual display for not-embedded activity.");
                 return false;
             }
             // Check if the caller is allowed to embed activities from other apps.
             if (mService.checkPermission(ACTIVITY_EMBEDDING, callingPid, callingUid)
                     == PERMISSION_DENIED && !uidPresentOnDisplay) {
-                if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
-                        + " disallow activity embedding without permission.");
+                ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: disallow activity "
+                        + "embedding without permission.");
                 return false;
             }
         }
 
         if (!displayContent.isPrivate()) {
             // Anyone can launch on a public display.
-            if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
-                    + " allow launch on public display");
+            ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: allow launch on public "
+                    + "display");
             return true;
         }
 
         // Check if the caller is the owner of the display.
         if (display.getOwnerUid() == callingUid) {
-            if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
-                    + " allow launch for owner of the display");
+            ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: allow launch for owner of the"
+                    + " display");
             return true;
         }
 
         if (uidPresentOnDisplay) {
-            if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
-                    + " allow launch for caller present on the display");
+            ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: allow launch for caller "
+                    + "present on the display");
             return true;
         }
 
@@ -1832,8 +1830,8 @@
             final boolean animating = s.isAnimating(TRANSITION | PARENTS,
                     ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_RECENTS)
                     || mService.getTransitionController().inTransition(s);
-            if (DEBUG_STATES) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + s.nowVisible
-                    + " animating=" + animating + " finishing=" + s.finishing);
+            ProtoLog.v(WM_DEBUG_STATES, "Stopping %s: nowVisible=%b animating=%b "
+                    + "finishing=%s", s, s.nowVisible, animating, s.finishing);
             if (!animating || mService.mShuttingDown) {
                 if (!processPausingActivities && s.isState(PAUSING)) {
                     // Defer processing pausing activities in this iteration and reschedule
@@ -1843,7 +1841,7 @@
                     continue;
                 }
 
-                if (DEBUG_STATES) Slog.v(TAG, "Ready to stop: " + s);
+                ProtoLog.v(WM_DEBUG_STATES, "Ready to stop: %s", s);
                 if (readyToStopActivities == null) {
                     readyToStopActivities = new ArrayList<>();
                 }
@@ -2077,7 +2075,7 @@
         msg.obj = r;
         r.topResumedStateLossTime = SystemClock.uptimeMillis();
         mHandler.sendMessageDelayed(msg, TOP_RESUMED_STATE_LOSS_TIMEOUT);
-        if (DEBUG_STATES) Slog.v(TAG_STATES, "Waiting for top state to be released by " + r);
+        ProtoLog.v(WM_DEBUG_STATES, "Waiting for top state to be released by %s", r);
     }
 
     /**
@@ -2085,10 +2083,9 @@
      * activity if needed.
      */
     void handleTopResumedStateReleased(boolean timeout) {
-        if (DEBUG_STATES) {
-            Slog.v(TAG_STATES, "Top resumed state released "
-                    + (timeout ? " (due to timeout)" : " (transition complete)"));
-        }
+        ProtoLog.v(WM_DEBUG_STATES, "Top resumed state released %s",
+                    (timeout ? "(due to timeout)" : "(transition complete)"));
+
         mHandler.removeMessages(TOP_RESUMED_STATE_LOSS_TIMEOUT_MSG);
         if (!mTopResumedActivityWaitingForPrev) {
             // Top resumed activity state loss already handled.
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index fa4373f..28e71fa 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -57,14 +57,13 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
 import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME;
 import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
 import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
-import static com.android.server.wm.ActivityStackSupervisor.TAG_TASKS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ACTIVITY_STARTS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
@@ -1909,10 +1908,8 @@
             // if that is the case, so this is it!  And for paranoia, make sure we have
             // correctly resumed the top activity.
             if (!mMovedToFront && mDoResume) {
-                if (DEBUG_TASKS) {
-                    Slog.d(TAG_TASKS, "Bring to front target: " + mTargetStack
-                            + " from " + targetTaskTop);
-                }
+                ProtoLog.d(WM_DEBUG_TASKS, "Bring to front target: %s from %s", mTargetStack,
+                        targetTaskTop);
                 mTargetStack.moveToFront("intentActivityFound");
             }
             resumeTargetStackIfNeeded();
@@ -2564,10 +2561,8 @@
                 mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions);
         addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
 
-        if (DEBUG_TASKS) {
-            Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
-                    + " in new task " + mStartActivity.getTask());
-        }
+        ProtoLog.v(WM_DEBUG_TASKS, "Starting new activity %s in new task %s",
+                mStartActivity, mStartActivity.getTask());
 
         if (taskToAffiliate != null) {
             mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerDebugConfig.java b/services/core/java/com/android/server/wm/ActivityTaskManagerDebugConfig.java
index 3c562a6..b5675a9 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerDebugConfig.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerDebugConfig.java
@@ -43,14 +43,10 @@
     // Enable all debug log categories for activities.
     private static final boolean DEBUG_ALL_ACTIVITIES = DEBUG_ALL || false;
 
-    static final boolean DEBUG_PAUSE = DEBUG_ALL || false;
     static final boolean DEBUG_RECENTS = DEBUG_ALL || false;
     static final boolean DEBUG_RECENTS_TRIM_TASKS = DEBUG_RECENTS || false;
-    static final boolean DEBUG_SAVED_STATE = DEBUG_ALL_ACTIVITIES || false;
     static final boolean DEBUG_STACK = DEBUG_ALL || false;
-    static final boolean DEBUG_STATES = DEBUG_ALL_ACTIVITIES || false;
     public static final boolean DEBUG_SWITCH = DEBUG_ALL || false;
-    static final boolean DEBUG_TASKS = DEBUG_ALL || false;
     static final boolean DEBUG_TRANSITION = DEBUG_ALL || false;
     static final boolean DEBUG_VISIBILITY = DEBUG_ALL || false;
     static final boolean DEBUG_APP = DEBUG_ALL_ACTIVITIES || false;
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index c0e31f9..f1529bd 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -70,6 +70,7 @@
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_IMMERSIVE;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_LOCKTASK;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
 import static com.android.server.am.ActivityManagerService.ANR_TRACE_DIR;
 import static com.android.server.am.ActivityManagerService.MY_PID;
 import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
@@ -96,9 +97,7 @@
 import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
 import static com.android.server.wm.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
@@ -324,14 +323,14 @@
     /** Hardware-reported OpenGLES version. */
     final int GL_ES_VERSION;
 
-    public static final String DUMP_ACTIVITIES_CMD = "activities" ;
-    public static final String DUMP_ACTIVITIES_SHORT_CMD = "a" ;
-    public static final String DUMP_LASTANR_CMD = "lastanr" ;
-    public static final String DUMP_LASTANR_TRACES_CMD = "lastanr-traces" ;
-    public static final String DUMP_STARTER_CMD = "starter" ;
-    public static final String DUMP_CONTAINERS_CMD = "containers" ;
-    public static final String DUMP_RECENTS_CMD = "recents" ;
-    public static final String DUMP_RECENTS_SHORT_CMD = "r" ;
+    public static final String DUMP_ACTIVITIES_CMD = "activities";
+    public static final String DUMP_ACTIVITIES_SHORT_CMD = "a";
+    public static final String DUMP_LASTANR_CMD = "lastanr";
+    public static final String DUMP_LASTANR_TRACES_CMD = "lastanr-traces";
+    public static final String DUMP_STARTER_CMD = "starter";
+    public static final String DUMP_CONTAINERS_CMD = "containers";
+    public static final String DUMP_RECENTS_CMD = "recents";
+    public static final String DUMP_RECENTS_SHORT_CMD = "r";
 
     /** This activity is not being relaunched, or being relaunched for a non-resize reason. */
     public static final int RELAUNCH_REASON_NONE = 0;
@@ -614,7 +613,9 @@
             LAYOUT_REASON_CONFIG_CHANGED,
             LAYOUT_REASON_VISIBILITY_CHANGED,
     })
-    @interface LayoutReason {}
+    @interface LayoutReason {
+    }
+
     static final int LAYOUT_REASON_CONFIG_CHANGED = 0x1;
     static final int LAYOUT_REASON_VISIBILITY_CHANGED = 0x2;
 
@@ -653,7 +654,8 @@
      *
      * @see #updateResumedAppTrace
      */
-    private @Nullable ActivityRecord mTracedResumedActivity;
+    @Nullable
+    private ActivityRecord mTracedResumedActivity;
 
     /** If non-null, we are tracking the time the user spends in the currently focused app. */
     AppTimeTracker mCurAppTimeTracker;
@@ -716,6 +718,7 @@
         int OOM_ADJUSTMENT = 1;
         int LRU_UPDATE = 2;
         int PROCESS_CHANGE = 3;
+
         int caller() default NONE;
     }
 
@@ -873,7 +876,8 @@
     }
 
     protected ActivityStackSupervisor createStackSupervisor() {
-        final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper());
+        final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this,
+                mH.getLooper());
         supervisor.initialize();
         return supervisor;
     }
@@ -1128,7 +1132,7 @@
             throw new IllegalArgumentException("Bad PendingIntent object");
         }
 
-        PendingIntentRecord pir = (PendingIntentRecord)target;
+        PendingIntentRecord pir = (PendingIntentRecord) target;
 
         synchronized (mGlobalLock) {
             // If this is coming from the currently resumed activity, it is
@@ -1181,14 +1185,14 @@
 
                 // Look for the original activity in the list...
                 final int N = resolves != null ? resolves.size() : 0;
-                for (int i=0; i<N; i++) {
+                for (int i = 0; i < N; i++) {
                     ResolveInfo rInfo = resolves.get(i);
                     if (rInfo.activityInfo.packageName.equals(r.packageName)
                             && rInfo.activityInfo.name.equals(r.info.name)) {
                         // We found the current one...  the next matching is
                         // after it.
                         i++;
-                        if (i<N) {
+                        if (i < N) {
                             aInfo = resolves.get(i).activityInfo;
                         }
                         if (debug) {
@@ -1212,11 +1216,10 @@
 
             intent.setComponent(new ComponentName(
                     aInfo.applicationInfo.packageName, aInfo.name));
-            intent.setFlags(intent.getFlags()&~(
-                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
-                            Intent.FLAG_ACTIVITY_CLEAR_TOP|
-                            Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
-                            FLAG_ACTIVITY_NEW_TASK));
+            intent.setFlags(intent.getFlags() & ~(Intent.FLAG_ACTIVITY_FORWARD_RESULT
+                    | Intent.FLAG_ACTIVITY_CLEAR_TOP
+                    | Intent.FLAG_ACTIVITY_MULTIPLE_TASK
+                    | FLAG_ACTIVITY_NEW_TASK));
 
             // Okay now we need to start the new activity, replacing the currently running activity.
             // This is a little tricky because we want to start the new one as if the current one is
@@ -1581,7 +1584,7 @@
     /**
      * Start the recents activity to perform the recents animation.
      *
-     * @param intent The intent to start the recents activity.
+     * @param intent                 The intent to start the recents activity.
      * @param recentsAnimationRunner Pass {@code null} to only preload the activity.
      */
     @Override
@@ -1637,12 +1640,12 @@
      *
      * If the target display is private or virtual, some restrictions will apply.
      *
-     * @param displayId Target display id.
-     * @param intent Intent used to launch the activity.
+     * @param displayId    Target display id.
+     * @param intent       Intent used to launch the activity.
      * @param resolvedType The MIME type of the intent.
-     * @param userId The id of the user for whom the call is made.
+     * @param userId       The id of the user for whom the call is made.
      * @return {@code true} if a call to start an activity on the target display should succeed and
-     *         no {@link SecurityException} will be thrown, {@code false} otherwise.
+     * no {@link SecurityException} will be thrown, {@code false} otherwise.
      */
     @Override
     public final boolean isActivityStartAllowedOnDisplay(int displayId, Intent intent,
@@ -1671,11 +1674,10 @@
     /**
      * This is the internal entry point for handling Activity.finish().
      *
-     * @param token The Binder token referencing the Activity we want to finish.
+     * @param token      The Binder token referencing the Activity we want to finish.
      * @param resultCode Result code, if any, from this Activity.
      * @param resultData Result data (Intent), if any, from this Activity.
      * @param finishTask Whether to finish the task associated with this Activity.
-     *
      * @return Returns true if the activity successfully finished, or false if it is still running.
      */
     @Override
@@ -2310,14 +2312,14 @@
      * There are several possible results of this call:
      * - if the task is locked, then we will show the lock toast
      * - if there is a task behind the provided task, then that task is made visible and resumed as
-     *   this task is moved to the back
+     * this task is moved to the back
      * - otherwise, if there are no other tasks in the stack:
-     *     - if this task is in the pinned stack, then we remove the stack completely, which will
-     *       have the effect of moving the task to the top or bottom of the fullscreen stack
-     *       (depending on whether it is visible)
-     *     - otherwise, we simply return home and hide this task
+     * - if this task is in the pinned stack, then we remove the stack completely, which will
+     * have the effect of moving the task to the top or bottom of the fullscreen stack
+     * (depending on whether it is visible)
+     * - otherwise, we simply return home and hide this task
      *
-     * @param token A reference to the activity we wish to move
+     * @param token   A reference to the activity we wish to move
      * @param nonRoot If false then this only works if the activity is the root
      *                of a task; if true it will work for any activity in a task.
      * @return Returns true if the move completed, false if not.
@@ -2398,8 +2400,8 @@
                     return false;
                 }
 
-                if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
-                        + " to windowingMode=" + windowingMode + " toTop=" + toTop);
+                ProtoLog.d(WM_DEBUG_TASKS, "setTaskWindowingMode: moving task=%d "
+                        + "to windowingMode=%d toTop=%b", taskId, windowingMode, toTop);
 
                 if (!task.isActivityTypeStandardOrUndefined()) {
                     throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
@@ -2462,7 +2464,8 @@
 
     @Override
     public void unhandledBack() {
-        mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
+        mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
+                "unhandledBack()");
 
         synchronized (mGlobalLock) {
             final long origId = Binder.clearCallingIdentity();
@@ -2509,9 +2512,10 @@
     @Override
     public void moveTaskToFront(IApplicationThread appThread, String callingPackage, int taskId,
             int flags, Bundle bOptions) {
-        mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
+        mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
+                "moveTaskToFront()");
 
-        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
+        ProtoLog.d(WM_DEBUG_TASKS, "moveTaskToFront: moving taskId=%d", taskId);
         synchronized (mGlobalLock) {
             moveTaskToFrontLocked(appThread, callingPackage, taskId, flags,
                     SafeActivityOptions.fromBundle(bOptions));
@@ -2543,7 +2547,7 @@
         try {
             final Task task = mRootWindowContainer.anyTaskForId(taskId);
             if (task == null) {
-                Slog.d(TAG, "Could not find task for id: "+ taskId);
+                ProtoLog.d(WM_DEBUG_TASKS, "Could not find task for id: %d", taskId);
                 SafeActivityOptions.abort(options);
                 return;
             }
@@ -2756,8 +2760,8 @@
                     return;
                 }
 
-                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
-                        + " to stackId=" + stackId + " toTop=" + toTop);
+                ProtoLog.d(WM_DEBUG_TASKS, "moveTaskToStack: moving task=%d to "
+                        + "stackId=%d toTop=%b", taskId, stackId, toTop);
 
                 final Task stack = mRootWindowContainer.getStack(stackId);
                 if (stack == null) {
@@ -2780,7 +2784,7 @@
      * Moves the specified task to the primary-split-screen stack.
      *
      * @param taskId Id of task to move.
-     * @param toTop If the task and stack should be moved to the top.
+     * @param toTop  If the task and stack should be moved to the top.
      * @return Whether the task was successfully put into splitscreen.
      */
     @Override
@@ -3293,8 +3297,8 @@
                 if (intent.getSourceBounds() != null) {
                     intent.setSourceBounds(null);
                 }
-                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
-                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
+                if ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
+                    if ((intent.getFlags() & Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
                         // The caller has added this as an auto-remove task...  that makes no
                         // sense, so turn off auto-remove.
                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
@@ -3492,8 +3496,8 @@
         synchronized (mGlobalLock) {
             final long ident = Binder.clearCallingIdentity();
             try {
-                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
-                        + " to displayId=" + displayId);
+                ProtoLog.d(WM_DEBUG_TASKS, "moveStackToDisplay: moving stackId=%d to "
+                        + "displayId=%d", stackId, displayId);
                 mRootWindowContainer.moveStackToDisplay(stackId, displayId, ON_TOP);
             } finally {
                 Binder.restoreCallingIdentity(ident);
@@ -3652,14 +3656,16 @@
                 try {
                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
                         allowed = true;
-                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
-                                + " is using old GET_TASKS but privileged; allowing");
+                        ProtoLog.w(WM_DEBUG_TASKS,
+                                "%s: caller %d is using old GET_TASKS but privileged; allowing",
+                                caller, callingUid);
                     }
                 } catch (RemoteException e) {
                 }
             }
-            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
-                    + " does not hold REAL_GET_TASKS; limiting output");
+            ProtoLog.w(WM_DEBUG_TASKS,
+                    "%s: caller %d does not hold REAL_GET_TASKS; limiting output", caller,
+                    callingUid);
         }
         return allowed;
     }
@@ -3978,7 +3984,8 @@
 
     @Override
     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
-        mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
+        mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS,
+                "suppressResizeConfigChanges()");
         synchronized (mGlobalLock) {
             mSuppressResizeConfigChanges = suppress;
         }
@@ -3988,10 +3995,9 @@
      * Moves the top activity in the input stackId to the pinned stack.
      *
      * @param stackId Id of stack to move the top activity to pinned stack.
-     * @param bounds Bounds to use for pinned stack.
-     *
+     * @param bounds  Bounds to use for pinned stack.
      * @return True if the top activity of the input stack was successfully moved to the pinned
-     *          stack.
+     * stack.
      */
     @Override
     public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
@@ -4146,7 +4152,7 @@
 
         if (params.hasSetAspectRatio()
                 && !mWindowManager.isValidPictureInPictureAspectRatio(
-                        r.mDisplayContent, params.getAspectRatio())) {
+                r.mDisplayContent, params.getAspectRatio())) {
             final float minAspectRatio = mContext.getResources().getFloat(
                     com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
             final float maxAspectRatio = mContext.getResources().getFloat(
@@ -4194,8 +4200,8 @@
                 final WindowContainerTransaction wct = new WindowContainerTransaction();
                 final Rect primaryRect =
                         tempDockedTaskInsetBounds != null ? tempDockedTaskInsetBounds
-                            : (tempDockedTaskBounds != null ? tempDockedTaskBounds
-                                    : dockedBounds);
+                                : (tempDockedTaskBounds != null ? tempDockedTaskBounds
+                                        : dockedBounds);
                 wct.setBounds(primary.mRemoteToken.toWindowContainerToken(), primaryRect);
                 Rect otherRect = tempOtherTaskInsetBounds != null ? tempOtherTaskInsetBounds
                         : tempOtherTaskBounds;
@@ -4464,7 +4470,8 @@
     public void updateLockTaskFeatures(int userId, int flags) {
         final int callingUid = Binder.getCallingUid();
         if (callingUid != 0 && callingUid != SYSTEM_UID) {
-            mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
+            mAmInternal.enforceCallingPermission(
+                    android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
                     "updateLockTaskFeatures()");
         }
         synchronized (mGlobalLock) {
@@ -4768,11 +4775,12 @@
 
     /**
      * Clears launch params for the given package.
+     *
      * @param packageNames the names of the packages of which the launch params are to be cleared
      */
     @Override
     public void clearLaunchParamsForPackages(List<String> packageNames) {
-        mAmInternal.enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS,
+        mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS,
                 "clearLaunchParamsForPackages");
         synchronized (mGlobalLock) {
             for (int i = 0; i < packageNames.size(); ++i) {
@@ -4787,7 +4795,7 @@
      */
     @Override
     public void setDisplayToSingleTaskInstance(int displayId) {
-        mAmInternal.enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS,
+        mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS,
                 "setDisplayToSingleTaskInstance");
         final long origId = Binder.clearCallingIdentity();
         try {
@@ -4806,7 +4814,7 @@
      */
     @Override
     public void requestPictureInPictureMode(IBinder token) throws RemoteException {
-        mAmInternal.enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS,
+        mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS,
                 "requestPictureInPictureMode");
         final long origId = Binder.clearCallingIdentity();
         try {
@@ -4902,7 +4910,7 @@
         boolean needSep = printedAnything;
 
         boolean printed = ActivityStackSupervisor.printThisActivity(pw,
-                mRootWindowContainer.getTopResumedActivity(),  dumpPackage, needSep,
+                mRootWindowContainer.getTopResumedActivity(), dumpPackage, needSep,
                 "  ResumedActivity: ", null);
         if (printed) {
             printedAnything = true;
@@ -4936,19 +4944,20 @@
 
     /**
      * There are three things that cmd can be:
-     *  - a flattened component name that matches an existing activity
-     *  - the cmd arg isn't the flattened component name of an existing activity:
-     *    dump all activity whose component contains the cmd as a substring
-     *  - A hex number of the ActivityRecord object instance.
+     * - a flattened component name that matches an existing activity
+     * - the cmd arg isn't the flattened component name of an existing activity:
+     * dump all activity whose component contains the cmd as a substring
+     * - A hex number of the ActivityRecord object instance.
      * <p>
      * The caller should not hold lock when calling this method because it will wait for the
      * activities to complete the dump.
      *
-     *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
-     *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
+     * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
+     * @param dumpFocusedStackOnly  dump activity with {@param name} only if in the focused stack
      */
     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
-            int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
+            int opti, boolean dumpAll, boolean dumpVisibleStacksOnly,
+            boolean dumpFocusedStackOnly) {
         ArrayList<ActivityRecord> activities;
 
         synchronized (mGlobalLock) {
@@ -4975,9 +4984,12 @@
                 final Task task = r.getTask();
                 if (lastTask != task) {
                     lastTask = task;
-                    pw.print("TASK "); pw.print(lastTask.affinity);
-                    pw.print(" id="); pw.print(lastTask.mTaskId);
-                    pw.print(" userId="); pw.println(lastTask.mUserId);
+                    pw.print("TASK ");
+                    pw.print(lastTask.affinity);
+                    pw.print(" id=");
+                    pw.print(lastTask.mTaskId);
+                    pw.print(" userId=");
+                    pw.println(lastTask.mUserId);
                     if (dumpAll) {
                         lastTask.dump(pw, "  ");
                     }
@@ -4997,8 +5009,11 @@
         String innerPrefix = prefix + "  ";
         IApplicationThread appThread = null;
         synchronized (mGlobalLock) {
-            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
-            pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
+            pw.print(prefix);
+            pw.print("ACTIVITY ");
+            pw.print(r.shortComponentName);
+            pw.print(" ");
+            pw.print(Integer.toHexString(System.identityHashCode(r)));
             pw.print(" pid=");
             if (r.hasProcess()) {
                 pw.println(r.app.getPid());
@@ -5057,7 +5072,7 @@
 
     public Configuration getConfiguration() {
         Configuration ci;
-        synchronized(mGlobalLock) {
+        synchronized (mGlobalLock) {
             ci = new Configuration(getGlobalConfigurationForCallingPid());
             ci.userSetLocale = false;
         }
@@ -5902,7 +5917,7 @@
 
         final IBinder threadBinder = thread.asBinder();
         final ArrayMap<String, SparseArray<WindowProcessController>> pmap = mProcessNames.getMap();
-        for (int i = pmap.size()-1; i >= 0; i--) {
+        for (int i = pmap.size() - 1; i >= 0; i--) {
             final SparseArray<WindowProcessController> procs = pmap.valueAt(i);
             for (int j = procs.size() - 1; j >= 0; j--) {
                 final WindowProcessController proc = procs.valueAt(j);
@@ -5967,7 +5982,7 @@
                         TimeMigrationUtils.formatMillisWithFixedFormat(System.currentTimeMillis());
                 sb.append(timeString);
                 sb.append(": ");
-                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
+                TimeUtils.formatDuration(SystemClock.uptimeMillis() - startTime, sb);
                 sb.append(" since ");
                 sb.append(msg);
                 FileOutputStream fos = new FileOutputStream(tracesFile);
@@ -5990,7 +6005,7 @@
 
             File lastTracesFile = null;
             File curTracesFile = null;
-            for (int i=9; i>=0; i--) {
+            for (int i = 9; i >= 0; i--) {
                 String name = String.format(Locale.US, "slow%02d.txt", i);
                 curTracesFile = new File(tracesDir, name);
                 if (curTracesFile.exists()) {
@@ -6037,7 +6052,8 @@
                 case REPORT_TIME_TRACKER_MSG: {
                     AppTimeTracker tracker = (AppTimeTracker) msg.obj;
                     tracker.deliverResult(mContext);
-                } break;
+                }
+                break;
             }
         }
     }
@@ -6233,7 +6249,7 @@
          */
         @Override
         public void setVr2dDisplayId(int vr2dDisplayId) {
-            if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
+            ProtoLog.d(WM_DEBUG_TASKS, "setVr2dDisplayId called for: %d", vr2dDisplayId);
             synchronized (mGlobalLock) {
                 mVr2dDisplayId = vr2dDisplayId;
             }
@@ -6541,7 +6557,7 @@
          * Set the corresponding display information for the process global configuration. To be
          * called when we need to show IME on a different display.
          *
-         * @param pid The process id associated with the IME window.
+         * @param pid       The process id associated with the IME window.
          * @param displayId The ID of the display showing the IME.
          */
         @Override
@@ -6553,7 +6569,7 @@
 
             if (pid == MY_PID || pid < 0) {
                 ProtoLog.w(WM_DEBUG_CONFIGURATION,
-                            "Trying to update display configuration for system/invalid process.");
+                        "Trying to update display configuration for system/invalid process.");
                 return;
             }
             synchronized (mGlobalLock) {
@@ -6943,7 +6959,8 @@
                 pw.println();
                 getActivityStartController().dump(pw, "  ", null);
                 pw.println();
-                pw.println("-------------------------------------------------------------------------------");
+                pw.println("-------------------------------------------------------------------"
+                        + "------------");
                 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
                         true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
                         "" /* header */);
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index 255b3f1..d292580 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -35,10 +35,10 @@
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.os.Process.SYSTEM_UID;
 
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
 import static com.android.server.wm.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS_TRIM_TASKS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
@@ -72,6 +72,7 @@
 import android.view.WindowManagerPolicyConstants.PointerEventListener;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.protolog.common.ProtoLog;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.am.ActivityManagerService;
 
@@ -157,7 +158,8 @@
      */
     private int mRecentsUid = -1;
     private ComponentName mRecentsComponent = null;
-    private @Nullable String mFeatureId;
+    @Nullable
+    private String mFeatureId;
 
     /**
      * Mapping of user id -> whether recent tasks have been loaded for that user.
@@ -397,7 +399,7 @@
 
     /**
      * @return whether the given component is the recents component and shares the same uid as the
-     *         recents component.
+     * recents component.
      */
     boolean isRecentsComponent(ComponentName cn, int uid) {
         return cn.equals(mRecentsComponent) && UserHandle.isSameApp(uid, mRecentsUid);
@@ -423,7 +425,8 @@
     /**
      * @return the featureId for the recents component.
      */
-    @Nullable String getRecentsComponentFeatureId() {
+    @Nullable
+    String getRecentsComponentFeatureId() {
         return mFeatureId;
     }
 
@@ -617,7 +620,7 @@
 
     /** Remove recent tasks for a user. */
     private void removeTasksForUserLocked(int userId) {
-        if(userId <= 0) {
+        if (userId <= 0) {
             Slog.i(TAG, "Can't remove recent task on user " + userId);
             return;
         }
@@ -625,8 +628,8 @@
         for (int i = mTasks.size() - 1; i >= 0; --i) {
             Task task = mTasks.get(i);
             if (task.mUserId == userId) {
-                if(DEBUG_TASKS) Slog.i(TAG_TASKS,
-                        "remove RecentTask " + task + " when finishing user" + userId);
+                ProtoLog.i(WM_DEBUG_TASKS, "remove RecentTask %s when finishing user "
+                        + "%d", task, userId);
                 remove(task);
             }
         }
@@ -640,11 +643,11 @@
                     && packageNames.contains(task.realActivity.getPackageName())
                     && task.mUserId == userId
                     && task.realActivitySuspended != suspended) {
-               task.realActivitySuspended = suspended;
-               if (suspended) {
-                   mSupervisor.removeTask(task, false, REMOVE_FROM_RECENTS, "suspended-package");
-               }
-               notifyTaskPersisterLocked(task, false);
+                task.realActivitySuspended = suspended;
+                if (suspended) {
+                    mSupervisor.removeTask(task, false, REMOVE_FROM_RECENTS, "suspended-package");
+                }
+                notifyTaskPersisterLocked(task, false);
             }
         }
     }
@@ -780,25 +783,31 @@
                         continue;
                     } else {
                         // Otherwise just not available for now.
-                        if (DEBUG_RECENTS && task.isAvailable) Slog.d(TAG_RECENTS,
-                                "Making recent unavailable: " + task);
+                        if (DEBUG_RECENTS && task.isAvailable) {
+                            Slog.d(TAG_RECENTS,
+                                    "Making recent unavailable: " + task);
+                        }
                         task.isAvailable = false;
                     }
                 } else {
                     if (!ai.enabled || !ai.applicationInfo.enabled
                             || (ai.applicationInfo.flags
-                                    & ApplicationInfo.FLAG_INSTALLED) == 0) {
-                        if (DEBUG_RECENTS && task.isAvailable) Slog.d(TAG_RECENTS,
-                                "Making recent unavailable: " + task
-                                        + " (enabled=" + ai.enabled + "/"
-                                        + ai.applicationInfo.enabled
-                                        + " flags="
-                                        + Integer.toHexString(ai.applicationInfo.flags)
-                                        + ")");
+                            & ApplicationInfo.FLAG_INSTALLED) == 0) {
+                        if (DEBUG_RECENTS && task.isAvailable) {
+                            Slog.d(TAG_RECENTS,
+                                    "Making recent unavailable: " + task
+                                            + " (enabled=" + ai.enabled + "/"
+                                            + ai.applicationInfo.enabled
+                                            + " flags="
+                                            + Integer.toHexString(ai.applicationInfo.flags)
+                                            + ")");
+                        }
                         task.isAvailable = false;
                     } else {
-                        if (DEBUG_RECENTS && !task.isAvailable) Slog.d(TAG_RECENTS,
-                                "Making recent available: " + task);
+                        if (DEBUG_RECENTS && !task.isAvailable) {
+                            Slog.d(TAG_RECENTS,
+                                    "Making recent available: " + task);
+                        }
                         task.isAvailable = true;
                     }
                 }
@@ -974,16 +983,20 @@
         final int size = mTasks.size();
         for (int i = 0; i < size; i++) {
             final Task task = mTasks.get(i);
-            if (TaskPersister.DEBUG) Slog.d(TAG, "LazyTaskWriter: task=" + task
-                    + " persistable=" + task.isPersistable);
+            if (TaskPersister.DEBUG) {
+                Slog.d(TAG, "LazyTaskWriter: task=" + task
+                        + " persistable=" + task.isPersistable);
+            }
             final Task rootTask = task.getRootTask();
             if ((task.isPersistable || task.inRecents)
                     && (rootTask == null || !rootTask.isHomeOrRecentsStack())) {
                 if (TaskPersister.DEBUG) Slog.d(TAG, "adding to persistentTaskIds task=" + task);
                 persistentTaskIds.add(task.mTaskId);
             } else {
-                if (TaskPersister.DEBUG) Slog.d(TAG, "omitting from persistentTaskIds task="
-                        + task);
+                if (TaskPersister.DEBUG) {
+                    Slog.d(TAG, "omitting from persistentTaskIds task="
+                            + task);
+                }
             }
         }
     }
@@ -1051,8 +1064,10 @@
         // TODO: VI what about if it's just an activity?
         // Probably nothing to do here
         if (task.voiceSession != null) {
-            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
-                    "addRecent: not adding voice interaction " + task);
+            if (DEBUG_RECENTS) {
+                Slog.d(TAG_RECENTS,
+                        "addRecent: not adding voice interaction " + task);
+            }
             return;
         }
         // Another quick case: check if the top-most recent task is the same.
@@ -1064,8 +1079,10 @@
         // tasks that are at the top.
         if (isAffiliated && recentsCount > 0 && task.inRecents
                 && task.mAffiliatedTaskId == mTasks.get(0).mAffiliatedTaskId) {
-            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: affiliated " + mTasks.get(0)
-                    + " at top when adding " + task);
+            if (DEBUG_RECENTS) {
+                Slog.d(TAG_RECENTS, "addRecent: affiliated " + mTasks.get(0)
+                        + " at top when adding " + task);
+            }
             return;
         }
 
@@ -1122,14 +1139,17 @@
                     if (other == task.mNextAffiliate) {
                         // We found the index of our next affiliation, which is who is
                         // before us in the list, so add after that point.
-                        taskIndex = otherIndex+1;
+                        taskIndex = otherIndex + 1;
                     } else {
                         // We found the index of our previous affiliation, which is who is
                         // after us in the list, so add at their position.
                         taskIndex = otherIndex;
                     }
-                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
-                            "addRecent: new affiliated task added at " + taskIndex + ": " + task);
+                    if (DEBUG_RECENTS) {
+                        Slog.d(TAG_RECENTS,
+                                "addRecent: new affiliated task added at " + taskIndex + ": "
+                                        + task);
+                    }
                     mTasks.add(taskIndex, task);
                     notifyTaskAdded(task);
 
@@ -1143,13 +1163,17 @@
                     // everything and then go through our general path of adding a new task.
                     needAffiliationFix = true;
                 } else {
-                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
-                            "addRecent: couldn't find other affiliation " + other);
+                    if (DEBUG_RECENTS) {
+                        Slog.d(TAG_RECENTS,
+                                "addRecent: couldn't find other affiliation " + other);
+                    }
                     needAffiliationFix = true;
                 }
             } else {
-                if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
-                        "addRecent: adding affiliated task without next/prev:" + task);
+                if (DEBUG_RECENTS) {
+                    Slog.d(TAG_RECENTS,
+                            "addRecent: adding affiliated task without next/prev:" + task);
+                }
                 needAffiliationFix = true;
             }
         }
@@ -1204,8 +1228,10 @@
             final Task task = mTasks.remove(recentsCount - 1);
             notifyTaskRemoved(task, true /* wasTrimmed */, false /* killProcess */);
             recentsCount--;
-            if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "Trimming over max-recents task=" + task
-                    + " max=" + mGlobalMaxNumTasks);
+            if (DEBUG_RECENTS_TRIM_TASKS) {
+                Slog.d(TAG, "Trimming over max-recents task=" + task
+                        + " max=" + mGlobalMaxNumTasks);
+            }
         }
 
         // Remove any tasks that belong to currently quiet profiles
@@ -1216,13 +1242,15 @@
             if (userInfo != null && userInfo.isManagedProfile() && userInfo.isQuietModeEnabled()) {
                 mTmpQuietProfileUserIds.put(userId, true);
             }
-            if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "User: " + userInfo
-                    + " quiet=" + mTmpQuietProfileUserIds.get(userId));
+            if (DEBUG_RECENTS_TRIM_TASKS) {
+                Slog.d(TAG, "User: " + userInfo
+                        + " quiet=" + mTmpQuietProfileUserIds.get(userId));
+            }
         }
 
         // Remove any inactive tasks, calculate the latest set of visible tasks.
         int numVisibleTasks = 0;
-        for (int i = 0; i < mTasks.size();) {
+        for (int i = 0; i < mTasks.size(); ) {
             final Task task = mTasks.get(i);
 
             if (isActiveRecentTask(task, mTmpQuietProfileUserIds)) {
@@ -1246,8 +1274,10 @@
                     } else {
                         // Fall through to trim visible tasks that are no longer in range and
                         // trimmable
-                        if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG,
-                                "Trimming out-of-range visible task=" + task);
+                        if (DEBUG_RECENTS_TRIM_TASKS) {
+                            Slog.d(TAG,
+                                    "Trimming out-of-range visible task=" + task);
+                        }
                     }
                 }
             } else {
@@ -1266,8 +1296,10 @@
      * @return whether the given task should be considered active.
      */
     private boolean isActiveRecentTask(Task task, SparseBooleanArray quietProfileUserIds) {
-        if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "isActiveRecentTask: task=" + task
-                + " globalMax=" + mGlobalMaxNumTasks);
+        if (DEBUG_RECENTS_TRIM_TASKS) {
+            Slog.d(TAG, "isActiveRecentTask: task=" + task
+                    + " globalMax=" + mGlobalMaxNumTasks);
+        }
 
         if (quietProfileUserIds.get(task.mUserId)) {
             // Quiet profile user's tasks are never active
@@ -1280,8 +1312,10 @@
             final Task affiliatedTask = getTask(task.mAffiliatedTaskId);
             if (affiliatedTask != null) {
                 if (!isActiveRecentTask(affiliatedTask, quietProfileUserIds)) {
-                    if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG,
-                            "\taffiliatedWithTask=" + affiliatedTask + " is not active");
+                    if (DEBUG_RECENTS_TRIM_TASKS) {
+                        Slog.d(TAG,
+                                "\taffiliatedWithTask=" + affiliatedTask + " is not active");
+                    }
                     return false;
                 }
             }
@@ -1296,13 +1330,15 @@
      */
     @VisibleForTesting
     boolean isVisibleRecentTask(Task task) {
-        if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "isVisibleRecentTask: task=" + task
-                + " minVis=" + mMinNumVisibleTasks + " maxVis=" + mMaxNumVisibleTasks
-                + " sessionDuration=" + mActiveTasksSessionDurationMs
-                + " inactiveDuration=" + task.getInactiveDuration()
-                + " activityType=" + task.getActivityType()
-                + " windowingMode=" + task.getWindowingMode()
-                + " intentFlags=" + task.getBaseIntent().getFlags());
+        if (DEBUG_RECENTS_TRIM_TASKS) {
+            Slog.d(TAG, "isVisibleRecentTask: task=" + task
+                    + " minVis=" + mMinNumVisibleTasks + " maxVis=" + mMaxNumVisibleTasks
+                    + " sessionDuration=" + mActiveTasksSessionDurationMs
+                    + " inactiveDuration=" + task.getInactiveDuration()
+                    + " activityType=" + task.getActivityType()
+                    + " windowingMode=" + task.getWindowingMode()
+                    + " intentFlags=" + task.getBaseIntent().getFlags());
+        }
 
         switch (task.getActivityType()) {
             case ACTIVITY_TYPE_HOME:
@@ -1468,8 +1504,10 @@
                 mHiddenTasks.add(removedTask);
             }
             notifyTaskRemoved(removedTask, false /* wasTrimmed */, false /* killProcess */);
-            if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "Trimming task=" + removedTask
-                    + " for addition of task=" + task);
+            if (DEBUG_RECENTS_TRIM_TASKS) {
+                Slog.d(TAG, "Trimming task=" + removedTask
+                        + " for addition of task=" + task);
+            }
         }
         notifyTaskPersisterLocked(removedTask, false /* flush */);
     }
@@ -1622,16 +1660,20 @@
             top = top.mNextAffiliate;
             topIndex--;
         }
-        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: adding affilliates starting at "
-                + topIndex + " from intial " + taskIndex);
+        if (DEBUG_RECENTS) {
+            Slog.d(TAG_RECENTS, "addRecent: adding affiliates starting at "
+                    + topIndex + " from initial " + taskIndex);
+        }
         // Find the end of the chain, doing a validity check along the way.
         boolean isValid = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
         int endIndex = topIndex;
         Task prev = top;
         while (endIndex < recentsCount) {
             Task cur = mTasks.get(endIndex);
-            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: looking at next chain @"
-                    + endIndex + " " + cur);
+            if (DEBUG_RECENTS) {
+                Slog.d(TAG_RECENTS, "addRecent: looking at next chain @"
+                        + endIndex + " " + cur);
+            }
             if (cur == top) {
                 // Verify start of the chain.
                 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) {
@@ -1701,14 +1743,18 @@
         if (isValid) {
             // All looks good, we can just move all of the affiliated tasks
             // to the top.
-            for (int i=topIndex; i<=endIndex; i++) {
-                if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: moving affiliated " + task
-                        + " from " + i + " to " + (i-topIndex));
+            for (int i = topIndex; i <= endIndex; i++) {
+                if (DEBUG_RECENTS) {
+                    Slog.d(TAG_RECENTS, "addRecent: moving affiliated " + task
+                            + " from " + i + " to " + (i - topIndex));
+                }
                 Task cur = mTasks.remove(i);
                 mTasks.add(i - topIndex, cur);
             }
-            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: done moving tasks  " +  topIndex
-                    + " to " + endIndex);
+            if (DEBUG_RECENTS) {
+                Slog.d(TAG_RECENTS, "addRecent: done moving tasks  " + topIndex
+                        + " to " + endIndex);
+            }
             return true;
         }
 
@@ -1768,7 +1814,9 @@
                 printedHeader = true;
                 printedAnything = true;
             }
-            pw.print("  * Recent #"); pw.print(i); pw.print(": ");
+            pw.print("  * Recent #");
+            pw.print(i);
+            pw.print(": ");
             pw.println(task);
             if (dumpAll) {
                 task.dump(pw, "    ");
@@ -1787,7 +1835,7 @@
                     boolean match = taskInfo.baseIntent != null
                             && taskInfo.baseIntent.getComponent() != null
                             && dumpPackage.equals(
-                                    taskInfo.baseIntent.getComponent().getPackageName());
+                            taskInfo.baseIntent.getComponent().getPackageName());
                     if (!match) {
                         match |= taskInfo.baseActivity != null
                                 && dumpPackage.equals(taskInfo.baseActivity.getPackageName());
@@ -1818,7 +1866,9 @@
                     printedAnything = true;
                 }
 
-                pw.print("  * RecentTaskInfo #"); pw.print(i); pw.print(": ");
+                pw.print("  * RecentTaskInfo #");
+                pw.print(i);
+                pw.print(": ");
                 taskInfo.dump(pw, "    ");
             }
         }
@@ -1842,8 +1892,8 @@
 
     /**
      * @return Whether the activity types and windowing modes of the two tasks are considered
-     *         compatible. This is necessary because we currently don't persist the activity type
-     *         or the windowing mode with the task, so they can be undefined when restored.
+     * compatible. This is necessary because we currently don't persist the activity type
+     * or the windowing mode with the task, so they can be undefined when restored.
      */
     private boolean hasCompatibleActivityTypeAndWindowingMode(Task t1, Task t2) {
         final int activityType = t1.getActivityType();
diff --git a/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java b/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java
index c3953b4..9181a0f 100644
--- a/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java
+++ b/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java
@@ -17,14 +17,12 @@
 package com.android.server.wm;
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
-import static com.android.server.wm.Task.TAG_TASKS;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
 
 import android.app.ActivityOptions;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.os.Debug;
-import android.util.Slog;
 
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.internal.util.function.pooled.PooledConsumer;
@@ -201,8 +199,8 @@
 
             noOptions = takeOption(p, noOptions);
 
-            if (DEBUG_TASKS) Slog.w(TAG_TASKS,
-                    "resetTaskIntendedTask: calling finishActivity on " + p);
+            ProtoLog.w(WM_DEBUG_TASKS, "resetTaskIntendedTask: calling finishActivity "
+                    + "on %s", p);
             p.finishIfPossible(reason, false /* oomAdj */);
         }
     }
@@ -213,15 +211,15 @@
 
         while (!mResultActivities.isEmpty()) {
             final ActivityRecord p = mResultActivities.remove(0);
-            if (ignoreFinishing&& p.finishing) continue;
+            if (ignoreFinishing && p.finishing) continue;
 
             if (takeOptions) {
                 noOptions = takeOption(p, noOptions);
             }
             ProtoLog.i(WM_DEBUG_ADD_REMOVE, "Removing activity %s from task=%s "
-                    + "adding to task=%s Callers=%s", p, mTask,  targetTask, Debug.getCallers(4));
-            if (DEBUG_TASKS) Slog.v(TAG_TASKS,
-                    "Pushing next activity " + p + " out to target's task " + target);
+                    + "adding to task=%s Callers=%s", p, mTask, targetTask, Debug.getCallers(4));
+            ProtoLog.v(WM_DEBUG_TASKS, "Pushing next activity %s out to target's task %s", p,
+                    target);
             p.reparent(targetTask, position, "resetTargetTaskIfNeeded");
         }
     }
@@ -253,8 +251,8 @@
                 // If the activity currently at the bottom has the same task affinity as
                 // the one we are moving, then merge it into the same task.
                 targetTask = task;
-                if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Start pushing activity "
-                        + r + " out to bottom task " + targetTask);
+                ProtoLog.v(WM_DEBUG_TASKS, "Start pushing activity %s out to bottom task %s", r,
+                        targetTask);
             }
             if (targetTask == null) {
                 if (alwaysCreateTask) {
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 2df56a3..cabf1bf 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -44,6 +44,8 @@
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_KEEP_SCREEN_ON;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
 import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC;
 import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
 import static com.android.server.policy.PhoneWindowManager.SYSTEM_DIALOG_REASON_ASSIST;
@@ -55,11 +57,8 @@
 import static com.android.server.wm.ActivityStackSupervisor.printThisActivity;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STATES;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
 import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
@@ -179,7 +178,6 @@
     private static final int SET_SCREEN_BRIGHTNESS_OVERRIDE = 1;
     private static final int SET_USER_ACTIVITY_TIMEOUT = 2;
     static final String TAG_TASKS = TAG + POSTFIX_TASKS;
-    private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
     static final String TAG_STATES = TAG + POSTFIX_STATES;
     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
 
@@ -235,7 +233,9 @@
             MATCH_TASK_IN_STACKS_OR_RECENT_TASKS,
             MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE
     })
-    public @interface AnyTaskForIdMatchTaskMode {}
+    public @interface AnyTaskForIdMatchTaskMode {
+    }
+
     // Match only tasks in the current stacks
     static final int MATCH_TASK_IN_STACKS_ONLY = 0;
     // Match either tasks in the current stacks, or in the recent tasks if not found in the stacks
@@ -305,6 +305,7 @@
     };
 
     private final FindTaskResult mTmpFindTaskResult = new FindTaskResult();
+
     static class FindTaskResult implements Function<Task, Boolean> {
         ActivityRecord mRecord;
         boolean mIdealMatch;
@@ -335,7 +336,8 @@
             // If documentData is non-null then it must match the existing task data.
             documentData = isDocument ? intent.getData() : null;
 
-            if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + target + " in " + parent);
+            ProtoLog.d(WM_DEBUG_TASKS, "Looking for task of %s in %s", target,
+                    parent);
             parent.forAllLeafTasks(this);
         }
 
@@ -353,12 +355,12 @@
         public Boolean apply(Task task) {
             if (task.voiceSession != null) {
                 // We never match voice sessions; those always run independently.
-                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": voice session");
+                ProtoLog.d(WM_DEBUG_TASKS, "Skipping %s: voice session", task);
                 return false;
             }
             if (task.mUserId != userId) {
                 // Looking for a different task.
-                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": different user");
+                ProtoLog.d(WM_DEBUG_TASKS, "Skipping %s: different user", task);
                 return false;
             }
 
@@ -366,11 +368,11 @@
             final ActivityRecord r = task.getTopNonFinishingActivity(false /* includeOverlays */);
             if (r == null || r.finishing || r.mUserId != userId
                     || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
-                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch root " + r);
+                ProtoLog.d(WM_DEBUG_TASKS, "Skipping %s: mismatch root %s", task, r);
                 return false;
             }
             if (!r.hasCompatibleActivityType(mTarget)) {
-                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch activity type");
+                ProtoLog.d(WM_DEBUG_TASKS, "Skipping %s: mismatch activity type", task);
                 return false;
             }
 
@@ -389,40 +391,40 @@
                 taskDocumentData = null;
             }
 
-            if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Comparing existing cls="
-                    + (task.realActivity != null ? task.realActivity.flattenToShortString() : "")
-                    + "/aff=" + r.getTask().rootAffinity + " to new cls="
-                    + intent.getComponent().flattenToShortString() + "/aff=" + info.taskAffinity);
+            ProtoLog.d(WM_DEBUG_TASKS, "Comparing existing cls=%s /aff=%s to new cls=%s /aff=%s",
+                    r.getTask().rootAffinity, intent.getComponent().flattenToShortString(),
+                    info.taskAffinity, (task.realActivity != null
+                            ? task.realActivity.flattenToShortString() : ""));
             // TODO Refactor to remove duplications. Check if logic can be simplified.
             if (task.realActivity != null && task.realActivity.compareTo(cls) == 0
                     && Objects.equals(documentData, taskDocumentData)) {
-                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!");
+                ProtoLog.d(WM_DEBUG_TASKS, "Found matching class!");
                 //dump();
-                if (DEBUG_TASKS) Slog.d(TAG_TASKS,
-                        "For Intent " + intent + " bringing to top: " + r.intent);
+                ProtoLog.d(WM_DEBUG_TASKS, "For Intent %s bringing to top: %s", intent, r.intent);
                 mRecord = r;
                 mIdealMatch = true;
                 return true;
             } else if (affinityIntent != null && affinityIntent.getComponent() != null
                     && affinityIntent.getComponent().compareTo(cls) == 0 &&
                     Objects.equals(documentData, taskDocumentData)) {
-                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!");
-                if (DEBUG_TASKS) Slog.d(TAG_TASKS,
-                        "For Intent " + intent + " bringing to top: " + r.intent);
+                ProtoLog.d(WM_DEBUG_TASKS, "Found matching class!");
+                ProtoLog.d(WM_DEBUG_TASKS, "For Intent %s bringing to top: %s", intent, r.intent);
                 mRecord = r;
                 mIdealMatch = true;
                 return true;
             } else if (!isDocument && !taskIsDocument
                     && mRecord == null && task.rootAffinity != null) {
                 if (task.rootAffinity.equals(mTarget.taskAffinity)) {
-                    if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching affinity candidate!");
+                    ProtoLog.d(WM_DEBUG_TASKS, "Found matching affinity candidate!");
                     // It is possible for multiple tasks to have the same root affinity especially
                     // if they are in separate stacks. We save off this candidate, but keep looking
                     // to see if there is a better candidate.
                     mRecord = r;
                     mIdealMatch = false;
                 }
-            } else if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Not a match: " + task);
+            } else {
+                ProtoLog.d(WM_DEBUG_TASKS, "Not a match: %s", task);
+            }
 
             return false;
         }
@@ -578,6 +580,7 @@
      * Returns {@code true} if the callingUid has any non-toast window currently visible to the
      * user. Also ignores {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_STARTING},
      * since those windows don't belong to apps.
+     *
      * @see WindowState#isNonToastOrStarting()
      */
     boolean isAnyNonToastWindowVisibleForUid(int callingUid) {
@@ -791,7 +794,7 @@
                         "Looks like we have reclaimed some memory, clearing surface for retry.");
                 if (surfaceController != null) {
                     ProtoLog.i(WM_SHOW_SURFACE_ALLOC,
-                            "SURFACE RECOVER DESTROY: %s",  winAnimator.mWin);
+                            "SURFACE RECOVER DESTROY: %s", winAnimator.mWin);
                     winAnimator.destroySurface();
                     if (winAnimator.mWin.mActivityRecord != null) {
                         winAnimator.mWin.mActivityRecord.removeStartingWindow();
@@ -822,8 +825,10 @@
     // "Something has changed!  Let's make it correct now."
     // TODO: Super long method that should be broken down...
     void performSurfacePlacementNoTrace() {
-        if (DEBUG_WINDOW_TRACE) Slog.v(TAG, "performSurfacePlacementInner: entry. Called by "
-                + Debug.getCallers(3));
+        if (DEBUG_WINDOW_TRACE) {
+            Slog.v(TAG, "performSurfacePlacementInner: entry. Called by "
+                    + Debug.getCallers(3));
+        }
 
         int i;
 
@@ -851,8 +856,10 @@
         final DisplayContent defaultDisplay = mWmService.getDefaultDisplayContentLocked();
         final WindowSurfacePlacer surfacePlacer = mWmService.mWindowPlacerLocked;
 
-        if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
-                ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
+        if (SHOW_LIGHT_TRANSACTIONS) {
+            Slog.i(TAG,
+                    ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
+        }
         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applySurfaceChanges");
         mWmService.openSurfaceTransaction();
         try {
@@ -862,8 +869,10 @@
         } finally {
             mWmService.closeSurfaceTransaction("performLayoutAndPlaceSurfaces");
             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
-            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
-                    "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
+            if (SHOW_LIGHT_TRANSACTIONS) {
+                Slog.i(TAG,
+                        "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
+            }
         }
         mWmService.mAnimator.executeAfterPrepareSurfacesRunnables();
 
@@ -896,8 +905,10 @@
 
         if (isLayoutNeeded()) {
             defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
-            if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("mLayoutNeeded",
-                    defaultDisplay.pendingLayoutChanges);
+            if (DEBUG_LAYOUT_REPEATS) {
+                surfacePlacer.debugLayoutRepeats("mLayoutNeeded",
+                        defaultDisplay.pendingLayoutChanges);
+            }
         }
 
         handleResizingWindows();
@@ -1105,11 +1116,11 @@
     }
 
     /**
-     * @param w WindowState this method is applied to.
+     * @param w        WindowState this method is applied to.
      * @param obscured True if there is a window on top of this obscuring the display.
-     * @param syswin System window?
+     * @param syswin   System window?
      * @return True when the display contains content to show the user. When false, the display
-     *          manager may choose to mirror or blank the display.
+     * manager may choose to mirror or blank the display.
      */
     boolean handleNotObscuredLocked(WindowState w, boolean obscured, boolean syswin) {
         final WindowManager.LayoutParams attrs = w.mAttrs;
@@ -1243,7 +1254,8 @@
     }
 
     void dumpTopFocusedDisplayId(PrintWriter pw) {
-        pw.print("  mTopFocusedDisplayId="); pw.println(mTopFocusedDisplayId);
+        pw.print("  mTopFocusedDisplayId=");
+        pw.println(mTopFocusedDisplayId);
     }
 
     void dumpLayoutNeededDisplayIds(PrintWriter pw) {
@@ -1359,7 +1371,8 @@
         }
     }
 
-    @Nullable Context getDisplayUiContext(int displayId) {
+    @Nullable
+    Context getDisplayUiContext(int displayId) {
         return getDisplayContent(displayId) != null
                 ? getDisplayContent(displayId).getDisplayUiContext() : null;
     }
@@ -1437,7 +1450,8 @@
      * corresponding record in display manager.
      */
     // TODO: Look into consolidating with getDisplayContent()
-    @Nullable DisplayContent getDisplayContentOrCreate(int displayId) {
+    @Nullable
+    DisplayContent getDisplayContentOrCreate(int displayId) {
         DisplayContent displayContent = getDisplayContent(displayId);
         if (displayContent != null) {
             return displayContent;
@@ -1494,8 +1508,8 @@
 
         final DisplayContent display = getDisplayContent(displayId);
         return display.reduceOnAllTaskDisplayAreas((taskDisplayArea, result) ->
-                result | startHomeOnTaskDisplayArea(userId, reason, taskDisplayArea,
-                        allowInstrumenting, fromHomeKey),
+                        result | startHomeOnTaskDisplayArea(userId, reason, taskDisplayArea,
+                                allowInstrumenting, fromHomeKey),
                 false /* initValue */);
     }
 
@@ -1504,11 +1518,11 @@
      * displayId - default display area always uses primary home component.
      * For secondary display areas, the home activity must have category SECONDARY_HOME and then
      * resolves according to the priorities listed below.
-     *  - If default home is not set, always use the secondary home defined in the config.
-     *  - Use currently selected primary home activity.
-     *  - Use the activity in the same package as currently selected primary home activity.
-     *    If there are multiple activities matched, use first one.
-     *  - Use the secondary home defined in the config.
+     * - If default home is not set, always use the secondary home defined in the config.
+     * - Use currently selected primary home activity.
+     * - Use the activity in the same package as currently selected primary home activity.
+     * If there are multiple activities matched, use first one.
+     * - Use the secondary home defined in the config.
      */
     boolean startHomeOnTaskDisplayArea(int userId, String reason, TaskDisplayArea taskDisplayArea,
             boolean allowInstrumenting, boolean fromHomeKey) {
@@ -1556,6 +1570,7 @@
 
     /**
      * This resolves the home activity info.
+     *
      * @return the home activity info if any.
      */
     @VisibleForTesting
@@ -1629,7 +1644,8 @@
         }
 
         if (aInfo != null) {
-            if (!canStartHomeOnDisplayArea(aInfo, taskDisplayArea, false /* allowInstrumenting */)) {
+            if (!canStartHomeOnDisplayArea(aInfo, taskDisplayArea,
+                    false /* allowInstrumenting */)) {
                 aInfo = null;
             }
         }
@@ -1687,6 +1703,7 @@
 
     /**
      * Check if the display area is valid for secondary home activity.
+     *
      * @param taskDisplayArea The target display area.
      * @return {@code true} if allow to launch, {@code false} otherwise.
      */
@@ -1727,8 +1744,10 @@
 
     /**
      * Check if home activity start should be allowed on a display.
-     * @param homeInfo {@code ActivityInfo} of the home activity that is going to be launched.
-     * @param taskDisplayArea The target display area.
+     *
+     * @param homeInfo           {@code ActivityInfo} of the home activity that is going to be
+     *                           launched.
+     * @param taskDisplayArea    The target display area.
      * @param allowInstrumenting Whether launching home should be allowed if being instrumented.
      * @return {@code true} if allow to launch, {@code false} otherwise.
      */
@@ -1773,13 +1792,14 @@
     /**
      * Ensure all activities visibility, update orientation and configuration.
      *
-     * @param starting The currently starting activity or {@code null} if there is none.
-     * @param displayId The id of the display where operation is executed.
+     * @param starting                  The currently starting activity or {@code null} if there is
+     *                                  none.
+     * @param displayId                 The id of the display where operation is executed.
      * @param markFrozenIfConfigChanged Whether to set {@link ActivityRecord#frozenBeforeDestroy} to
      *                                  {@code true} if config changed.
-     * @param deferResume Whether to defer resume while updating config.
+     * @param deferResume               Whether to defer resume while updating config.
      * @return 'true' if starting activity was kept or wasn't provided, 'false' if it was relaunched
-     *         because of configuration update.
+     * because of configuration update.
      */
     boolean ensureVisibilityAndConfig(ActivityRecord starting, int displayId,
             boolean markFrozenIfConfigChanged, boolean deferResume) {
@@ -2066,9 +2086,10 @@
 
     /**
      * Move stack with all its existing content to specified task display area.
-     * @param stackId Id of stack to move.
+     *
+     * @param stackId         Id of stack to move.
      * @param taskDisplayArea The task display area to move stack to.
-     * @param onTop Indicates whether container should be place on top or on bottom.
+     * @param onTop           Indicates whether container should be place on top or on bottom.
      */
     void moveStackToTaskDisplayArea(int stackId, TaskDisplayArea taskDisplayArea, boolean onTop) {
         final Task stack = getStack(stackId);
@@ -2098,9 +2119,10 @@
 
     /**
      * Move stack with all its existing content to specified display.
-     * @param stackId Id of stack to move.
+     *
+     * @param stackId   Id of stack to move.
      * @param displayId Id of display to move stack to.
-     * @param onTop Indicates whether container should be place on top or on bottom.
+     * @param onTop     Indicates whether container should be place on top or on bottom.
      */
     void moveStackToDisplay(int stackId, int displayId, boolean onTop) {
         final DisplayContent displayContent = getDisplayContentOrCreate(displayId);
@@ -2192,7 +2214,7 @@
                 final ActivityRecord oldTopActivity = task.getTopMostActivity();
                 if (oldTopActivity != null && oldTopActivity.isState(STOPPED)
                         && task.getDisplayContent().mAppTransition.getAppTransition()
-                                == TRANSIT_TASK_TO_BACK) {
+                        == TRANSIT_TASK_TO_BACK) {
                     task.getDisplayContent().mClosingApps.add(oldTopActivity);
                     oldTopActivity.mRequestForceTransition = true;
                 }
@@ -2227,6 +2249,7 @@
 
     /**
      * Notifies when an activity enters or leaves PIP mode.
+     *
      * @param r indicates the activity currently in PIP, can be null to indicate no activity is
      *          currently in PIP mode.
      */
@@ -2249,7 +2272,7 @@
 
     @Nullable
     ActivityRecord findTask(ActivityRecord r, TaskDisplayArea preferredTaskDisplayArea) {
-        if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r);
+        ProtoLog.d(WM_DEBUG_TASKS, "Looking for task of %s", r);
         mTmpFindTaskResult.clear();
 
         // Looking up task on preferred display area first
@@ -2277,13 +2300,16 @@
             return task;
         }
 
-        if (DEBUG_TASKS && mTmpFindTaskResult.mRecord == null) Slog.d(TAG_TASKS, "No task found");
+        if (WM_DEBUG_TASKS.isEnabled() && mTmpFindTaskResult.mRecord == null) {
+            ProtoLog.d(WM_DEBUG_TASKS, "No task found");
+        }
         return mTmpFindTaskResult.mRecord;
     }
 
     /**
      * Finish the topmost activities in all stacks that belong to the crashed app.
-     * @param app The app that crashed.
+     *
+     * @param app    The app that crashed.
      * @param reason Reason to perform this action.
      * @return The task id that was finished in this stack, or INVALID_TASK_ID if none was finished.
      */
@@ -2751,9 +2777,11 @@
     private void destroyActivity(ActivityRecord r) {
         if (r.finishing || !r.isDestroyable()) return;
 
-        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Destroying " + r + " in state " + r.getState()
-                + " resumed=" + r.getStack().mResumedActivity + " pausing="
-                + r.getStack().mPausingActivity + " for reason " + mDestroyAllActivitiesReason);
+        if (DEBUG_SWITCH) {
+            Slog.v(TAG_SWITCH, "Destroying " + r + " in state " + r.getState()
+                    + " resumed=" + r.getStack().mResumedActivity + " pausing="
+                    + r.getStack().mPausingActivity + " for reason " + mDestroyAllActivitiesReason);
+        }
 
         r.destroyImmediately(mDestroyAllActivitiesReason);
     }
@@ -2814,7 +2842,7 @@
 
     private static boolean matchesActivity(ActivityRecord r, int userId,
             boolean compareIntentFilters, Intent intent, ComponentName cls) {
-        if (!r.canBeTopRunning() || r.mUserId != userId)  return false;
+        if (!r.canBeTopRunning() || r.mUserId != userId) return false;
 
         if (compareIntentFilters) {
             if (r.intent.filterEquals(intent)) {
@@ -2849,10 +2877,10 @@
     /**
      * Returns the right stack to use for launching factoring in all the input parameters.
      *
-     * @param r The activity we are trying to launch. Can be null.
-     * @param options The activity options used to the launch. Can be null.
-     * @param candidateTask The possible task the activity might be launched in. Can be null.
-     * @param launchParams The resolved launch params to use.
+     * @param r              The activity we are trying to launch. Can be null.
+     * @param options        The activity options used to the launch. Can be null.
+     * @param candidateTask  The possible task the activity might be launched in. Can be null.
+     * @param launchParams   The resolved launch params to use.
      * @param realCallingPid The pid from {@link ActivityStarter#setRealCallingPid}
      * @param realCallingUid The uid from {@link ActivityStarter#setRealCallingUid}
      * @return The stack to use for the launch or INVALID_STACK_ID.
@@ -2986,9 +3014,10 @@
     /**
      * Get a topmost stack on the display area, that is a valid launch stack for specified activity.
      * If there is no such stack, new dynamic stack can be created.
+     *
      * @param taskDisplayArea Target display area.
-     * @param r Activity that should be launched there.
-     * @param candidateTask The possible task the activity might be put in.
+     * @param r               Activity that should be launched there.
+     * @param candidateTask   The possible task the activity might be put in.
      * @return Existing stack if there is a valid one, new dynamic stack if it is valid or null.
      */
     @VisibleForTesting
@@ -3054,10 +3083,14 @@
     // TODO: Can probably be consolidated into getLaunchStack()...
     private boolean isValidLaunchStack(Task stack, ActivityRecord r, int windowingMode) {
         switch (stack.getActivityType()) {
-            case ACTIVITY_TYPE_HOME: return r.isActivityTypeHome();
-            case ACTIVITY_TYPE_RECENTS: return r.isActivityTypeRecents();
-            case ACTIVITY_TYPE_ASSISTANT: return r.isActivityTypeAssistant();
-            case ACTIVITY_TYPE_DREAM: return r.isActivityTypeDream();
+            case ACTIVITY_TYPE_HOME:
+                return r.isActivityTypeHome();
+            case ACTIVITY_TYPE_RECENTS:
+                return r.isActivityTypeRecents();
+            case ACTIVITY_TYPE_ASSISTANT:
+                return r.isActivityTypeAssistant();
+            case ACTIVITY_TYPE_DREAM:
+                return r.isActivityTypeDream();
         }
         if (stack.mCreatedByOrganizer) {
             // Don't launch directly into task created by organizer...but why can't we?
@@ -3097,9 +3130,9 @@
      * from the target stack. If no valid candidates will be found, it will then go through all
      * displays and stacks in last-focused order.
      *
-     * @param currentFocus The stack that previously had focus.
+     * @param currentFocus  The stack that previously had focus.
      * @param ignoreCurrent If we should ignore {@param currentFocus} when searching for next
-     *                     candidate.
+     *                      candidate.
      * @return Next focusable {@link Task}, {@code null} if not found.
      */
     Task getNextFocusableStack(@NonNull Task currentFocus,
@@ -3162,6 +3195,7 @@
 
     FinishDisabledPackageActivitiesHelper mFinishDisabledPackageActivitiesHelper =
             new FinishDisabledPackageActivitiesHelper();
+
     class FinishDisabledPackageActivitiesHelper {
         private String mPackageName;
         private Set<String> mFilterByClasses;
@@ -3318,10 +3352,8 @@
             }
             final ActivityRecord resumedActivity = stack.getResumedActivity();
             if (resumedActivity == null || !resumedActivity.idle) {
-                if (DEBUG_STATES) {
-                    Slog.d(TAG_STATES, "allResumedActivitiesIdle: stack="
-                            + stack.getRootTaskId() + " " + resumedActivity + " not idle");
-                }
+                ProtoLog.d(WM_DEBUG_STATES, "allResumedActivitiesIdle: stack=%d %s "
+                        + "not idle", stack.getRootTaskId(), resumedActivity);
                 return false;
             }
         }
@@ -3360,9 +3392,9 @@
                         final Task stack = taskDisplayArea.getStackAt(sNdx);
                         final ActivityRecord r = stack.mPausingActivity;
                         if (r != null && !r.isState(PAUSED, STOPPED, STOPPING, FINISHING)) {
-                            if (DEBUG_STATES) {
-                                Slog.d(TAG_STATES, "allPausedActivitiesComplete: r=" + r
-                                        + " state=" + r.getState());
+                            ProtoLog.d(WM_DEBUG_STATES, "allPausedActivitiesComplete: "
+                                    + "r=%s state=%s", r, r.getState());
+                            if (WM_DEBUG_STATES.isEnabled()) {
                                 pausing[0] = false;
                             } else {
                                 return true;
@@ -3441,10 +3473,11 @@
 
     /**
      * Returns a {@link Task} for the input id if available. {@code null} otherwise.
-     * @param id Id of the task we would like returned.
+     *
+     * @param id        Id of the task we would like returned.
      * @param matchMode The mode to match the given task id in.
-     * @param aOptions The activity options to use for restoration. Can be null.
-     * @param onTop If the stack for the task should be the topmost on the display.
+     * @param aOptions  The activity options to use for restoration. Can be null.
+     * @param onTop     If the stack for the task should be the topmost on the display.
      */
     Task anyTaskForId(int id, @RootWindowContainer.AnyTaskForIdMatchTaskMode int matchMode,
             @Nullable ActivityOptions aOptions, boolean onTop) {
@@ -3499,8 +3532,10 @@
 
         // Implicitly, this case is MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE
         if (!mStackSupervisor.restoreRecentTaskLocked(task, aOptions, onTop)) {
-            if (DEBUG_RECENTS) Slog.w(TAG_RECENTS,
-                    "Couldn't restore task id=" + id + " found in recents");
+            if (DEBUG_RECENTS) {
+                Slog.w(TAG_RECENTS,
+                        "Couldn't restore task id=" + id + " found in recents");
+            }
             return null;
         }
         if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, "Restored task id=" + id + " from in recents");
@@ -3611,14 +3646,19 @@
 
     /**
      * Dump all connected displays' configurations.
+     *
      * @param prefix Prefix to apply to each line of the dump.
      */
     void dumpDisplayConfigs(PrintWriter pw, String prefix) {
-        pw.print(prefix); pw.println("Display override configurations:");
+        pw.print(prefix);
+        pw.println("Display override configurations:");
         final int displayCount = getChildCount();
         for (int i = 0; i < displayCount; i++) {
             final DisplayContent displayContent = getChildAt(i);
-            pw.print(prefix); pw.print("  "); pw.print(displayContent.mDisplayId); pw.print(": ");
+            pw.print(prefix);
+            pw.print("  ");
+            pw.print(displayContent.mDisplayId);
+            pw.print(": ");
             pw.println(displayContent.getRequestedOverrideConfiguration());
         }
     }
@@ -3632,7 +3672,8 @@
             if (printed[0]) {
                 pw.println();
             }
-            pw.print("Display #"); pw.print(displayContent.mDisplayId);
+            pw.print("Display #");
+            pw.print(displayContent.mDisplayId);
             pw.println(" (activities from top to bottom):");
             displayContent.forAllTaskDisplayAreas(taskDisplayArea -> {
                 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 14230cd..f984576 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -80,6 +80,8 @@
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_LOCKTASK;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_RECENTS_ANIMATIONS;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
 import static com.android.server.wm.ActivityRecord.STARTING_WINDOW_SHOWN;
 import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME;
 import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
@@ -87,13 +89,9 @@
 import static com.android.server.wm.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
 import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList;
 import static com.android.server.wm.ActivityStackSupervisor.printThisActivity;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PAUSE;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TRANSITION;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_ADD_REMOVE;
@@ -1280,7 +1278,7 @@
                     _intent.setSourceBounds(null);
                 }
             }
-            if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Setting Intent of " + this + " to " + _intent);
+            ProtoLog.v(WM_DEBUG_TASKS, "Setting Intent of %s to %s", this, _intent);
             intent = _intent;
             realActivity = _intent != null ? _intent.getComponent() : null;
             origActivity = null;
@@ -1291,8 +1289,7 @@
                 Intent targetIntent = new Intent(_intent);
                 targetIntent.setSelector(null);
                 targetIntent.setSourceBounds(null);
-                if (DEBUG_TASKS) Slog.v(TAG_TASKS,
-                        "Setting Intent of " + this + " to target " + targetIntent);
+                ProtoLog.v(WM_DEBUG_TASKS, "Setting Intent of %s to target %s", this, targetIntent);
                 intent = targetIntent;
                 realActivity = targetComponent;
                 origActivity = _intent.getComponent();
@@ -5317,8 +5314,8 @@
     }
 
     void minimalResumeActivityLocked(ActivityRecord r) {
-        if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + r + " (starting new instance)"
-                + " callers=" + Debug.getCallers(5));
+        ProtoLog.v(WM_DEBUG_STATES, "Moving to RESUMED: %s (starting new instance) "
+                + "callers=%s", r, Debug.getCallers(5));
         r.setState(RESUMED, "minimalResumeActivityLocked");
         r.completeResumeLocked();
     }
@@ -5362,7 +5359,7 @@
 
         if (mResumedActivity != null) {
             // Still have something resumed; can't sleep until it is paused.
-            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep needs to pause " + mResumedActivity);
+            ProtoLog.v(WM_DEBUG_STATES, "Sleep needs to pause %s", mResumedActivity);
             if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
                     "Sleep => pause with userLeaving=false");
 
@@ -5371,15 +5368,15 @@
             shouldSleep = false ;
         } else if (mPausingActivity != null) {
             // Still waiting for something to pause; can't sleep yet.
-            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still waiting to pause " + mPausingActivity);
+            ProtoLog.v(WM_DEBUG_STATES, "Sleep still waiting to pause %s", mPausingActivity);
             shouldSleep = false;
         }
 
         if (!shuttingDown) {
             if (containsActivityFromStack(mStackSupervisor.mStoppingActivities)) {
                 // Still need to tell some activities to stop; can't sleep yet.
-                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to stop "
-                        + mStackSupervisor.mStoppingActivities.size() + " activities");
+                ProtoLog.v(WM_DEBUG_STATES, "Sleep still need to stop %d activities",
+                        mStackSupervisor.mStoppingActivities.size());
 
                 mStackSupervisor.scheduleIdle();
                 shouldSleep = false;
@@ -5458,8 +5455,7 @@
             return false;
         }
 
-        if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSING: " + prev);
-        else if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Start pausing: " + prev);
+        ProtoLog.v(WM_DEBUG_STATES, "Moving to PAUSING: %s", prev);
         mPausingActivity = prev;
         mLastPausedActivity = prev;
         mLastNoHistoryActivity = prev.isNoHistory() ? prev : null;
@@ -5490,13 +5486,13 @@
         boolean didAutoPip = false;
         if (prev.attachedToProcess()) {
             if (shouldAutoPip) {
-                if (DEBUG_PAUSE) {
-                    Slog.d(TAG_PAUSE, "Auto-PIP allowed, entering PIP mode directly: " + prev);
-                }
+                ProtoLog.d(WM_DEBUG_STATES, "Auto-PIP allowed, entering PIP mode "
+                        + "directly: %s", prev);
+
                 didAutoPip = mAtmService.enterPictureInPictureMode(prev, prev.pictureInPictureArgs);
                 mPausingActivity = null;
             } else {
-                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
+                ProtoLog.v(WM_DEBUG_STATES, "Enqueueing pending pause: %s", prev);
                 try {
                     EventLogTags.writeWmPauseActivity(prev.mUserId, System.identityHashCode(prev),
                             prev.shortComponentName, "userLeaving=" + userLeaving, reason);
@@ -5536,8 +5532,8 @@
             // key dispatch; the same activity will pick it up again on wakeup.
             if (!uiSleeping) {
                 prev.pauseKeyDispatchingLocked();
-            } else if (DEBUG_PAUSE) {
-                Slog.v(TAG_PAUSE, "Key dispatch not paused for screen off");
+            } else {
+                ProtoLog.v(WM_DEBUG_STATES, "Key dispatch not paused for screen off");
             }
 
             if (pauseImmediately) {
@@ -5554,7 +5550,7 @@
         } else {
             // This activity failed to schedule the
             // pause, so just treat it as being paused now.
-            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity not running, resuming next.");
+            ProtoLog.v(WM_DEBUG_STATES, "Activity not running, resuming next.");
             if (resuming == null) {
                 mRootWindowContainer.resumeFocusedStacksTopActivities();
             }
@@ -5565,22 +5561,22 @@
     @VisibleForTesting
     void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
         ActivityRecord prev = mPausingActivity;
-        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev);
+        ProtoLog.v(WM_DEBUG_STATES, "Complete pause: %s", prev);
 
         if (prev != null) {
             prev.setWillCloseOrEnterPip(false);
             final boolean wasStopping = prev.isState(STOPPING);
             prev.setState(PAUSED, "completePausedLocked");
             if (prev.finishing) {
-                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev);
+                ProtoLog.v(WM_DEBUG_STATES, "Executing finish of activity: %s", prev);
                 prev = prev.completeFinishing("completePausedLocked");
             } else if (prev.hasProcess()) {
-                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueue pending stop if needed: " + prev
-                        + " wasStopping=" + wasStopping
-                        + " visibleRequested=" + prev.mVisibleRequested);
+                ProtoLog.v(WM_DEBUG_STATES, "Enqueue pending stop if needed: %s "
+                        + "wasStopping=%b visibleRequested=%b",  prev,  wasStopping,
+                        prev.mVisibleRequested);
                 if (prev.deferRelaunchUntilPaused) {
                     // Complete the deferred relaunch that was waiting for pause to complete.
-                    if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev);
+                    ProtoLog.v(WM_DEBUG_STATES, "Re-launching after pause: %s", prev);
                     prev.relaunchActivityLocked(prev.preserveWindowOnDeferredRelaunch);
                 } else if (wasStopping) {
                     // We are also stopping, the stop request must have gone soon after the pause.
@@ -5596,7 +5592,7 @@
                             "completePauseLocked");
                 }
             } else {
-                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev);
+                ProtoLog.v(WM_DEBUG_STATES, "App died during pause, not stopping: %s", prev);
                 prev = null;
             }
             // It is possible the activity was freezing the screen before it was paused.
@@ -5892,8 +5888,8 @@
             // Make sure we have executed any pending transitions, since there
             // should be nothing left to do at this point.
             executeAppTransition(options);
-            if (DEBUG_STATES) Slog.d(TAG_STATES,
-                    "resumeTopActivityLocked: Top activity resumed " + next);
+            ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivityLocked: Top activity "
+                    + "resumed %s", next);
             return false;
         }
 
@@ -5904,9 +5900,9 @@
         // If we are currently pausing an activity, then don't do anything until that is done.
         final boolean allPausedComplete = mRootWindowContainer.allPausedActivitiesComplete();
         if (!allPausedComplete) {
-            if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) {
-                Slog.v(TAG_PAUSE, "resumeTopActivityLocked: Skip resume: some activity pausing.");
-            }
+            ProtoLog.v(WM_DEBUG_STATES,
+                    "resumeTopActivityLocked: Skip resume: some activity pausing.");
+
             return false;
         }
 
@@ -5918,8 +5914,8 @@
             // Make sure we have executed any pending transitions, since there
             // should be nothing left to do at this point.
             executeAppTransition(options);
-            if (DEBUG_STATES) Slog.d(TAG_STATES,
-                    "resumeTopActivityLocked: Going to sleep and all paused");
+            ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivityLocked: Going to sleep and"
+                    + " all paused");
             return false;
         }
 
@@ -5941,7 +5937,7 @@
 
         // If we are currently pausing an activity, then don't do anything until that is done.
         if (!mRootWindowContainer.allPausedActivitiesComplete()) {
-            if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
+            ProtoLog.v(WM_DEBUG_STATES,
                     "resumeTopActivityLocked: Skip resume: some activity pausing.");
 
             return false;
@@ -5967,14 +5963,13 @@
 
         boolean pausing = taskDisplayArea.pauseBackStacks(userLeaving, next);
         if (mResumedActivity != null) {
-            if (DEBUG_STATES) Slog.d(TAG_STATES,
-                    "resumeTopActivityLocked: Pausing " + mResumedActivity);
+            ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivityLocked: Pausing %s", mResumedActivity);
             pausing |= startPausingLocked(userLeaving, false /* uiSleeping */, next,
-                "resumeTopActivityInnerLocked");
+                    "resumeTopActivityInnerLocked");
         }
         if (pausing) {
-            if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG_STATES,
-                    "resumeTopActivityLocked: Skip resume: need to start pausing");
+            ProtoLog.v(WM_DEBUG_STATES, "resumeTopActivityLocked: Skip resume: need to"
+                    + " start pausing");
             // At this point we want to put the upcoming activity's process
             // at the top of the LRU list, since we know we will be needing it
             // very soon and it would be a waste to let it get killed if it
@@ -6003,8 +5998,8 @@
             // Make sure we have executed any pending transitions, since there
             // should be nothing left to do at this point.
             executeAppTransition(options);
-            if (DEBUG_STATES) Slog.d(TAG_STATES,
-                    "resumeTopActivityLocked: Top activity resumed (dontWaitForPause) " + next);
+            ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivityLocked: Top activity resumed "
+                    + "(dontWaitForPause) %s", next);
             return true;
         }
 
@@ -6014,8 +6009,8 @@
         if (shouldSleepActivities() && mLastNoHistoryActivity != null
                 && !mLastNoHistoryActivity.finishing
                 && mLastNoHistoryActivity != next) {
-            if (DEBUG_STATES) Slog.d(TAG_STATES,
-                    "no-history finish of " + mLastNoHistoryActivity + " on new resume");
+            ProtoLog.d(WM_DEBUG_STATES, "no-history finish of %s on new resume",
+                    mLastNoHistoryActivity);
             mLastNoHistoryActivity.finishIfPossible("resume-no-history", false /* oomAdj */);
             mLastNoHistoryActivity = null;
         }
@@ -6134,8 +6129,7 @@
 
             mAtmService.updateCpuStats();
 
-            if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + next
-                    + " (in existing)");
+            ProtoLog.v(WM_DEBUG_STATES, "Moving to RESUMED: %s (in existing)", next);
 
             next.setState(RESUMED, "resumeTopActivityInnerLocked");
 
@@ -6165,9 +6159,8 @@
                 // is still at the top and schedule another run if something
                 // weird happened.
                 ActivityRecord nextNext = topRunningActivity();
-                if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_STATES,
-                        "Activity config changed during resume: " + next
-                                + ", new next: " + nextNext);
+                ProtoLog.i(WM_DEBUG_STATES, "Activity config changed during resume: "
+                        + "%s, new next: %s", next, nextNext);
                 if (nextNext != next) {
                     // Do over!
                     mStackSupervisor.scheduleResumeTopActivities();
@@ -6214,12 +6207,11 @@
                                 dc.isNextTransitionForward()));
                 mAtmService.getLifecycleManager().scheduleTransaction(transaction);
 
-                if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Resumed "
-                        + next);
+                ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivityLocked: Resumed %s", next);
             } catch (Exception e) {
                 // Whoops, need to restart this activity!
-                if (DEBUG_STATES) Slog.v(TAG_STATES, "Resume failed; resetting state to "
-                        + lastState + ": " + next);
+                ProtoLog.v(WM_DEBUG_STATES, "Resume failed; resetting state to %s: "
+                        + "%s", lastState, next);
                 next.setState(lastState, "resumeTopActivityInnerLocked");
 
                 // lastResumedActivity being non-null implies there is a lastStack present.
@@ -6261,7 +6253,7 @@
                 }
                 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
             }
-            if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
+            ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivityLocked: Restarting %s", next);
             mStackSupervisor.startSpecificActivity(next, true, true);
         }
 
@@ -6293,8 +6285,8 @@
         // If the current stack is a home stack, or if focus didn't switch to a different stack -
         // just start up the Launcher...
         ActivityOptions.abort(options);
-        if (DEBUG_STATES) Slog.d(TAG_STATES,
-                "resumeNextFocusableActivityWhenStackIsEmpty: " + reason + ", go home");
+        ProtoLog.d(WM_DEBUG_STATES, "resumeNextFocusableActivityWhenStackIsEmpty: %s, "
+                + "go home", reason);
         return mRootWindowContainer.resumeHomeActivity(prev, reason, getDisplayArea());
     }
 
@@ -7022,8 +7014,8 @@
     boolean handleAppDied(WindowProcessController app) {
         boolean isPausingDied = false;
         if (mPausingActivity != null && mPausingActivity.app == app) {
-            if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG_PAUSE,
-                    "App died while pausing: " + mPausingActivity);
+            ProtoLog.v(WM_DEBUG_STATES, "App died while pausing: %s",
+                    mPausingActivity);
             mPausingActivity = null;
             isPausingDied = true;
         }
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index 2c8770f..696e1ca 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -33,12 +33,10 @@
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
-import static com.android.server.wm.ActivityStackSupervisor.TAG_TASKS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
 import static com.android.server.wm.ActivityTaskManagerService.TAG_STACK;
 import static com.android.server.wm.DisplayContent.alwaysCreateStack;
-import static com.android.server.wm.RootWindowContainer.TAG_STATES;
 import static com.android.server.wm.Task.ActivityState.RESUMED;
 import static com.android.server.wm.Task.STACK_VISIBILITY_VISIBLE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
@@ -212,11 +210,13 @@
         return mChildren.indexOf(task);
     }
 
-    @Nullable Task getRootHomeTask() {
+    @Nullable
+    Task getRootHomeTask() {
         return mRootHomeTask;
     }
 
-    @Nullable Task getRootRecentsTask() {
+    @Nullable
+    Task getRootRecentsTask() {
         return mRootRecentsTask;
     }
 
@@ -526,19 +526,20 @@
      * When stack is added or repositioned, find a proper position for it.
      *
      * The order is defined as:
-     *  - Dream is on top of everything
-     *  - PiP is directly below the Dream
-     *  - always-on-top stacks are directly below PiP; new always-on-top stacks are added above
-     *    existing ones
-     *  - other non-always-on-top stacks come directly below always-on-top stacks; new
-     *    non-always-on-top stacks are added directly below always-on-top stacks and above existing
-     *    non-always-on-top stacks
-     *  - if {@link #mAssistantOnTopOfDream} is enabled, then Assistant is on top of everything
-     *    (including the Dream); otherwise, it is a normal non-always-on-top stack
+     * - Dream is on top of everything
+     * - PiP is directly below the Dream
+     * - always-on-top stacks are directly below PiP; new always-on-top stacks are added above
+     * existing ones
+     * - other non-always-on-top stacks come directly below always-on-top stacks; new
+     * non-always-on-top stacks are added directly below always-on-top stacks and above existing
+     * non-always-on-top stacks
+     * - if {@link #mAssistantOnTopOfDream} is enabled, then Assistant is on top of everything
+     * (including the Dream); otherwise, it is a normal non-always-on-top stack
      *
      * @param requestedPosition Position requested by caller.
-     * @param stack Stack to be added or positioned.
-     * @param adding Flag indicates whether we're adding a new stack or positioning an existing.
+     * @param stack             Stack to be added or positioned.
+     * @param adding            Flag indicates whether we're adding a new stack or positioning an
+     *                          existing.
      * @return The proper position for the stack.
      */
     private int findPositionForStack(int requestedPosition, Task stack, boolean adding) {
@@ -655,6 +656,7 @@
 
     /**
      * Sets whether the task display area should ignore fixed-orientation request from apps.
+     *
      * @return Whether the display orientation changed
      */
     boolean setIgnoreOrientationRequest(boolean ignoreOrientationRequest) {
@@ -774,7 +776,7 @@
      * Adjusts the layer of the stack which belongs to the same group.
      * Note that there are three stack groups: home stacks, always on top stacks, and normal stacks.
      *
-     * @param startLayer The beginning layer of this group of stacks.
+     * @param startLayer   The beginning layer of this group of stacks.
      * @param normalStacks Set {@code true} if this group is neither home nor always on top.
      * @return The adjusted layer value.
      */
@@ -921,6 +923,7 @@
     /**
      * Returns an existing stack compatible with the windowing mode and activity type or creates one
      * if a compatible stack doesn't exist.
+     *
      * @see #getOrCreateStack(int, int, boolean, Intent, Task)
      */
     Task getOrCreateStack(int windowingMode, int activityType, boolean onTop) {
@@ -933,6 +936,7 @@
      * existing compatible root task or creates a new one.
      * For one level task, the candidate task would be reused to also be the root task or create
      * a new root task if no candidate task.
+     *
      * @see #getStack(int, int)
      * @see #createStack(int, int, boolean)
      */
@@ -978,6 +982,7 @@
     /**
      * Returns an existing stack compatible with the input params or creates one
      * if a compatible stack doesn't exist.
+     *
      * @see #getOrCreateStack(int, int, boolean)
      */
     Task getOrCreateStack(@Nullable ActivityRecord r,
@@ -1006,17 +1011,21 @@
 
     /**
      * Creates a stack matching the input windowing mode and activity type on this display.
-     * @param windowingMode The windowing mode the stack should be created in. If
-     *                      {@link WindowConfiguration#WINDOWING_MODE_UNDEFINED} then the stack will
-     *                      inherit its parent's windowing mode.
-     * @param activityType The activityType the stack should be created in. If
-     *                     {@link WindowConfiguration#ACTIVITY_TYPE_UNDEFINED} then the stack will
-     *                     be created in {@link WindowConfiguration#ACTIVITY_TYPE_STANDARD}.
-     * @param onTop If true the stack will be created at the top of the display, else at the bottom.
-     * @param info The started activity info.
-     * @param intent The intent that started this task.
+     *
+     * @param windowingMode      The windowing mode the stack should be created in. If
+     *                           {@link WindowConfiguration#WINDOWING_MODE_UNDEFINED} then the stack
+     *                           will
+     *                           inherit its parent's windowing mode.
+     * @param activityType       The activityType the stack should be created in. If
+     *                           {@link WindowConfiguration#ACTIVITY_TYPE_UNDEFINED} then the stack
+     *                           will
+     *                           be created in {@link WindowConfiguration#ACTIVITY_TYPE_STANDARD}.
+     * @param onTop              If true the stack will be created at the top of the display, else
+     *                           at the bottom.
+     * @param info               The started activity info.
+     * @param intent             The intent that started this task.
      * @param createdByOrganizer @{code true} if this is created by task organizer, @{code false}
-     *                          otherwise.
+     *                           otherwise.
      * @return The newly created stack.
      */
     Task createStack(int windowingMode, int activityType, boolean onTop, ActivityInfo info,
@@ -1223,8 +1232,9 @@
      * paused in stacks that are no longer visible or in pinned windowing mode. This does not
      * pause activities in visible stacks, so if an activity is launched within the same stack/task,
      * then we should explicitly pause that stack's top activity.
+     *
      * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
-     * @param resuming The resuming activity.
+     * @param resuming    The resuming activity.
      * @return {@code true} if any activity was paused as a result of this call.
      */
     boolean pauseBackStacks(boolean userLeaving, ActivityRecord resuming) {
@@ -1235,10 +1245,8 @@
             if (resumedActivity != null
                     && (stack.getVisibility(resuming) != STACK_VISIBILITY_VISIBLE
                     || !stack.isTopActivityFocusable())) {
-                if (DEBUG_STATES) {
-                    Slog.d(TAG_STATES, "pauseBackStacks: stack=" + stack
-                            + " mResumedActivity=" + resumedActivity);
-                }
+                ProtoLog.d(WM_DEBUG_STATES, "pauseBackStacks: stack=%s "
+                        + "mResumedActivity=%s", stack, resumedActivity);
                 someActivityPaused |= stack.startPausingLocked(userLeaving, false /* uiSleeping*/,
                         resuming, "pauseBackStacks");
             }
@@ -1255,9 +1263,8 @@
         for (int stackNdx = getStackCount() - 1; stackNdx >= 0; --stackNdx) {
             final Task stack = getStackAt(stackNdx);
             if (!r.hasCompatibleActivityType(stack) && stack.isLeafTask()) {
-                if (DEBUG_TASKS) {
-                    Slog.d(TAG_TASKS, "Skipping stack: (mismatch activity/stack) " + stack);
-                }
+                ProtoLog.d(WM_DEBUG_TASKS, "Skipping stack: (mismatch activity/stack) "
+                        + "%s", stack);
                 continue;
             }
 
@@ -1400,12 +1407,13 @@
 
     /**
      * Returns true if the {@param windowingMode} is supported based on other parameters passed in.
-     * @param windowingMode The windowing mode we are checking support for.
+     *
+     * @param windowingMode       The windowing mode we are checking support for.
      * @param supportsMultiWindow If we should consider support for multi-window mode in general.
      * @param supportsSplitScreen If we should consider support for split-screen multi-window.
-     * @param supportsFreeform If we should consider support for freeform multi-window.
-     * @param supportsPip If we should consider support for picture-in-picture mutli-window.
-     * @param activityType The activity type under consideration.
+     * @param supportsFreeform    If we should consider support for freeform multi-window.
+     * @param supportsPip         If we should consider support for picture-in-picture mutli-window.
+     * @param activityType        The activity type under consideration.
      * @return true if the windowing mode is supported.
      */
     private boolean isWindowingModeSupported(int windowingMode, boolean supportsMultiWindow,
@@ -1444,9 +1452,9 @@
      * Resolves the windowing mode that an {@link ActivityRecord} would be in if started on this
      * display with the provided parameters.
      *
-     * @param r The ActivityRecord in question.
-     * @param options Options to start with.
-     * @param task The task within-which the activity would start.
+     * @param r            The ActivityRecord in question.
+     * @param options      Options to start with.
+     * @param task         The task within-which the activity would start.
      * @param activityType The type of activity to start.
      * @return The resolved (not UNDEFINED) windowing-mode that the activity would be in.
      */
@@ -1481,9 +1489,9 @@
      * on this display.
      *
      * @param windowingMode The windowing-mode to validate.
-     * @param r The {@link ActivityRecord} to check against.
-     * @param task The {@link Task} to check against.
-     * @param activityType An activity type.
+     * @param r             The {@link ActivityRecord} to check against.
+     * @param task          The {@link Task} to check against.
+     * @param activityType  An activity type.
      * @return {@code true} if windowingMode is valid, {@code false} otherwise.
      */
     boolean isValidWindowingMode(int windowingMode, @Nullable ActivityRecord r, @Nullable Task task,
@@ -1508,7 +1516,7 @@
 
         return windowingMode != WINDOWING_MODE_UNDEFINED
                 && isWindowingModeSupported(windowingMode, supportsMultiWindow, supportsSplitScreen,
-                        supportsFreeform, supportsPip, activityType);
+                supportsFreeform, supportsPip, activityType);
     }
 
     /**
@@ -1516,9 +1524,9 @@
      * on this display.
      *
      * @param windowingMode The windowing-mode to validate.
-     * @param r The {@link ActivityRecord} to check against.
-     * @param task The {@link Task} to check against.
-     * @param activityType An activity type.
+     * @param r             The {@link ActivityRecord} to check against.
+     * @param task          The {@link Task} to check against.
+     * @param activityType  An activity type.
      * @return The provided windowingMode or the closest valid mode which is appropriate.
      */
     int validateWindowingMode(int windowingMode, @Nullable ActivityRecord r, @Nullable Task task,
@@ -1606,6 +1614,7 @@
     /**
      * Returns the existing home stack or creates and returns a new one if it should exist for the
      * display.
+     *
      * @param onTop Only be used when there is no existing home stack. If true the home stack will
      *              be created at the top of the display, else at the bottom.
      */
@@ -1743,7 +1752,7 @@
 
     /**
      * @return the stack currently above the {@param stack}. Can be null if the {@param stack} is
-     *         already top-most.
+     * already top-most.
      */
     static Task getStackAbove(Task stack) {
         final WindowContainer wc = stack.getParent();
@@ -1789,6 +1798,7 @@
 
     /**
      * Notifies of a stack order change
+     *
      * @param stack The stack which triggered the order change
      */
     void onStackOrderChanged(Task stack) {
@@ -1832,6 +1842,7 @@
 
     /**
      * Removes the stacks in the node applying the content removal node from the display.
+     *
      * @return last reparented stack, or {@code null} if the stacks had to be destroyed.
      */
     Task remove() {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 282cee0..09ba6ef 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -2128,11 +2128,10 @@
 
     ActiveAdmin getActiveAdminUncheckedLocked(ComponentName who, int userHandle, boolean parent) {
         ensureLocked();
-        if (parent) {
-            Preconditions.checkCallAuthorization(isManagedProfile(userHandle), String.format(
-                    "You can not call APIs on the parent profile outside a managed profile, "
-                            + "userId = %d", userHandle));
-        }
+        Preconditions.checkCallAuthorization(!parent || isManagedProfile(userHandle),
+                String.format("You can not call APIs on the parent profile outside a "
+                        + "managed profile, userId = %d", userHandle));
+
         ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
         if (admin != null && parent) {
             admin = admin.getParentActiveAdmin();
@@ -2302,9 +2301,9 @@
             boolean parent,
             @Nullable String permission) throws SecurityException {
         ensureLocked();
-        if (parent) {
-            Preconditions.checkCallingUser(isManagedProfile(getCallerIdentity().getUserId()));
-        }
+        Preconditions.checkCallingUser(!parent
+                || isManagedProfile(getCallerIdentity().getUserId()));
+
         ActiveAdmin admin = getActiveAdminOrCheckPermissionForCallerLocked(
                 who, reqPolicy, permission);
         return parent ? admin.getParentActiveAdmin() : admin;
@@ -3179,7 +3178,10 @@
             return;
         }
         Objects.requireNonNull(adminReceiver, "ComponentName is null");
-        enforceShell("forceRemoveActiveAdmin");
+
+        Preconditions.checkCallAuthorization(isAdb(getCallerIdentity()),
+                "Non-shell user attempted to call forceRemoveActiveAdmin");
+
         mInjector.binderWithCleanCallingIdentity(() -> {
             synchronized (getLockObject()) {
                 if (!isAdminTestOnlyLocked(adminReceiver, userHandle)) {
@@ -3258,13 +3260,6 @@
         return (admin != null) && admin.testOnlyAdmin;
     }
 
-    private void enforceShell(String method) {
-        final int callingUid = mInjector.binderGetCallingUid();
-        if (callingUid != Process.SHELL_UID && callingUid != Process.ROOT_UID) {
-            throw new SecurityException("Non-shell user attempted to call " + method);
-        }
-    }
-
     @Override
     public void removeActiveAdmin(ComponentName adminReceiver, int userHandle) {
         if (!mHasFeature) {
@@ -3274,7 +3269,8 @@
 
         final CallerIdentity caller = getCallerIdentity();
         Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userHandle));
-        enforceUserUnlocked(userHandle);
+        Preconditions.checkState(mUserManager.isUserUnlocked(userHandle),
+                "User must be running and unlocked");
 
         synchronized (getLockObject()) {
             ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver, userHandle);
@@ -3288,10 +3284,8 @@
                         adminReceiver);
                 return;
             }
-            if (admin.getUid() != mInjector.binderGetCallingUid()) {
-                mContext.enforceCallingOrSelfPermission(
-                        android.Manifest.permission.MANAGE_DEVICE_ADMINS, null);
-            }
+            Preconditions.checkCallAuthorization((admin.getUid() == caller.getUid())
+                    || hasCallingOrSelfPermission(permission.MANAGE_DEVICE_ADMINS));
             mInjector.binderWithCleanCallingIdentity(() ->
                     removeActiveAdminLocked(adminReceiver, userHandle));
         }
@@ -3299,7 +3293,8 @@
 
     @Override
     public boolean isSeparateProfileChallengeAllowed(int userHandle) {
-        enforceSystemCaller("query separate challenge support");
+        Preconditions.checkCallAuthorization(isSystemUid(getCallerIdentity()),
+                "Only the system can query separate challenge support");
 
         ComponentName profileOwner = getProfileOwner(userHandle);
         // Profile challenge is supported on N or newer release.
@@ -4071,7 +4066,9 @@
 
         final CallerIdentity caller = getCallerIdentity();
         Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userHandle));
-        enforceUserUnlocked(userHandle, parent);
+        Preconditions.checkState(
+                mUserManager.isUserUnlocked(parent ? getProfileParentId(userHandle) : userHandle),
+                "User must be running and unlocked");
 
         synchronized (getLockObject()) {
             // This API can only be called by an active device admin,
@@ -4112,15 +4109,15 @@
         Preconditions.checkCallAuthorization(isManagedProfile(userHandle), String.format(
                 "can not call APIs refering to the parent profile outside a managed profile, "
                         + "userId = %d", userHandle));
+        Preconditions.checkState(mUserManager.isUserUnlocked(getProfileParentId(userHandle)),
+                "User must be running and unlocked");
 
         synchronized (getLockObject()) {
-            final int targetUser = getProfileParentId(userHandle);
-            enforceUserUnlocked(targetUser, false);
             int credentialOwner = getCredentialOwner(userHandle, false);
             DevicePolicyData policy = getUserDataUnchecked(credentialOwner);
             PasswordMetrics metrics = mLockSettingsInternal.getUserPasswordMetrics(credentialOwner);
-            return isActivePasswordSufficientForUserLocked(
-                    policy.mPasswordValidAtLastCheckpoint, metrics, targetUser, false);
+            return isActivePasswordSufficientForUserLocked(policy.mPasswordValidAtLastCheckpoint,
+                    metrics, getProfileParentId(userHandle), false);
         }
     }
 
@@ -4136,7 +4133,8 @@
         Preconditions.checkCallAuthorization(!isManagedProfile(userHandle), String.format(
                 "You can not check password sufficiency for a managed profile, userId = %d",
                 userHandle));
-        enforceUserUnlocked(userHandle);
+        Preconditions.checkState(mUserManager.isUserUnlocked(userHandle),
+                "User must be running and unlocked");
 
         synchronized (getLockObject()) {
             PasswordMetrics metrics = mLockSettingsInternal.getUserPasswordMetrics(userHandle);
@@ -4194,24 +4192,22 @@
     @Override
     @PasswordComplexity
     public int getPasswordComplexity(boolean parent) {
+        final CallerIdentity caller = getCallerIdentity();
+        Preconditions.checkState(mUserManager.isUserUnlocked(caller.getUserId()),
+                "User must be running and unlocked");
+        Preconditions.checkCallAuthorization(!parent || isCallerDeviceOwner(caller.getUid())
+                || isCallerProfileOwner(caller.getUid()) || isSystemUid(caller));
+        Preconditions.checkCallAuthorization(
+                hasCallingOrSelfPermission(REQUEST_PASSWORD_COMPLEXITY));
+
         DevicePolicyEventLogger
                 .createEvent(DevicePolicyEnums.GET_USER_PASSWORD_COMPLEXITY_LEVEL)
                 .setStrings(parent ? CALLED_FROM_PARENT : NOT_CALLED_FROM_PARENT,
-                        mInjector.getPackageManager().getPackagesForUid(
-                                mInjector.binderGetCallingUid()))
+                        mInjector.getPackageManager().getPackagesForUid(caller.getUid()))
                 .write();
-        final int callingUserId = mInjector.userHandleGetCallingUserId();
-
-        if (parent) {
-            enforceProfileOwnerOrSystemUser();
-        }
-        enforceUserUnlocked(callingUserId);
-        mContext.enforceCallingOrSelfPermission(
-                REQUEST_PASSWORD_COMPLEXITY,
-                "Must have " + REQUEST_PASSWORD_COMPLEXITY + " permission.");
 
         synchronized (getLockObject()) {
-            final int credentialOwner = getCredentialOwner(callingUserId, parent);
+            final int credentialOwner = getCredentialOwner(caller.getUserId(), parent);
             PasswordMetrics metrics = mLockSettingsInternal.getUserPasswordMetrics(credentialOwner);
             return metrics == null ? PASSWORD_COMPLEXITY_NONE : metrics.determineComplexity();
         }
@@ -4360,22 +4356,24 @@
             Slog.w(LOG_TAG, "Cannot reset password when the device has no lock screen");
             return false;
         }
-        if (password == null) password = "";
-        final int callingUid = mInjector.binderGetCallingUid();
-        final int userHandle = mInjector.userHandleGetCallingUserId();
 
-        // As of R, only privlleged caller holding RESET_PASSWORD can call resetPassword() to
+        final CallerIdentity caller = getCallerIdentity();
+        // As of R, only privileged caller holding RESET_PASSWORD can call resetPassword() to
         // set password to an unsecured user.
         if (hasCallingPermission(permission.RESET_PASSWORD)) {
-            return setPasswordPrivileged(password, flags, callingUid);
+            if (password == null) {
+                password = "";
+            }
+            return setPasswordPrivileged(password, flags, caller.getUid());
         }
 
         synchronized (getLockObject()) {
             // If caller has PO (or DO) throw or fail silently depending on its target SDK level.
             ActiveAdmin admin = getActiveAdminWithPolicyForUidLocked(
-                    null, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, callingUid);
+                    null, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, caller.getUid());
             if (admin != null) {
-                if (getTargetSdk(admin.info.getPackageName(), userHandle) < Build.VERSION_CODES.O) {
+                if (getTargetSdk(admin.info.getPackageName(),
+                        caller.getUserId()) < Build.VERSION_CODES.O) {
                     Slog.e(LOG_TAG, "DPC can no longer call resetPassword()");
                     return false;
                 }
@@ -4386,7 +4384,7 @@
             admin = getActiveAdminForCallerLocked(
                     null, DeviceAdminInfo.USES_POLICY_RESET_PASSWORD, false);
             if (getTargetSdk(admin.info.getPackageName(),
-                    userHandle) <= android.os.Build.VERSION_CODES.M) {
+                    caller.getUserId()) <= android.os.Build.VERSION_CODES.M) {
                 Slog.e(LOG_TAG, "Device admin can no longer call resetPassword()");
                 return false;
             }
@@ -4482,8 +4480,9 @@
 
     @Override
     public boolean getDoNotAskCredentialsOnBoot() {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.QUERY_DO_NOT_ASK_CREDENTIALS_ON_BOOT, null);
+        Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(
+                permission.QUERY_DO_NOT_ASK_CREDENTIALS_ON_BOOT));
+
         synchronized (getLockObject()) {
             DevicePolicyData policyData = getUserData(UserHandle.USER_SYSTEM);
             return policyData.mDoNotAskCredentialsOnBoot;
@@ -5225,12 +5224,13 @@
     @Override
     public void choosePrivateKeyAlias(final int uid, final Uri uri, final String alias,
             final IBinder response) {
-        enforceSystemCaller("choose private key alias");
+        final CallerIdentity caller = getCallerIdentity();
+        Preconditions.checkCallAuthorization(isSystemUid(caller),
+                "Only the system can choose private key alias");
 
-        final UserHandle caller = mInjector.binderGetCallingUserHandle();
         // If there is a profile owner, redirect to that; otherwise query the device owner.
-        ComponentName aliasChooser = getProfileOwner(caller.getIdentifier());
-        if (aliasChooser == null && caller.isSystem()) {
+        ComponentName aliasChooser = getProfileOwner(caller.getUserId());
+        if (aliasChooser == null && caller.getUserHandle().isSystem()) {
             synchronized (getLockObject()) {
                 final ActiveAdmin deviceOwnerAdmin = getDeviceOwnerAdminLocked();
                 if (deviceOwnerAdmin != null) {
@@ -5252,7 +5252,7 @@
 
         final ComponentName delegateReceiver;
         delegateReceiver = resolveDelegateReceiver(DELEGATION_CERT_SELECTION,
-                DeviceAdminReceiver.ACTION_CHOOSE_PRIVATE_KEY_ALIAS, caller.getIdentifier());
+                DeviceAdminReceiver.ACTION_CHOOSE_PRIVATE_KEY_ALIAS, caller.getUserId());
 
         final boolean isDelegate;
         if (delegateReceiver != null) {
@@ -5264,7 +5264,8 @@
         }
 
         mInjector.binderWithCleanCallingIdentity(() -> {
-            mContext.sendOrderedBroadcastAsUser(intent, caller, null, new BroadcastReceiver() {
+            mContext.sendOrderedBroadcastAsUser(intent, caller.getUserHandle(), null,
+                    new BroadcastReceiver() {
                 @Override
                 public void onReceive(Context context, Intent intent) {
                     final String chosenAlias = getResultData();
@@ -5428,21 +5429,14 @@
             String delegatePackage) throws SecurityException {
         Objects.requireNonNull(delegatePackage, "Delegate package is null");
 
+        final CallerIdentity caller = getCallerIdentity(who, delegatePackage);
+        Preconditions.checkCallAuthorization((caller.hasAdminComponent() && (isDeviceOwner(caller)
+                || isProfileOwner(caller))) || (caller.hasPackage() && isCallingFromPackage(
+                delegatePackage, caller.getUid())));
+
         // Retrieve the user ID of the calling process.
-        final int callingUid = mInjector.binderGetCallingUid();
-        final int userId = UserHandle.getUserId(callingUid);
         synchronized (getLockObject()) {
-            // Ensure calling process is device/profile owner.
-            if (who != null) {
-                getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
-            // Or ensure calling process is delegatePackage itself.
-            } else {
-                if (!isCallingFromPackage(delegatePackage, callingUid)) {
-                    throw new SecurityException("Caller with uid " + callingUid + " is not "
-                            + delegatePackage);
-                }
-            }
-            final DevicePolicyData policy = getUserData(userId);
+            final DevicePolicyData policy = getUserData(caller.getUserId());
             // Retrieve the scopes assigned to delegatePackage, or null if no scope was given.
             final List<String> scopes = policy.mDelegationMap.get(delegatePackage);
             return scopes == null ? Collections.EMPTY_LIST : scopes;
@@ -5721,7 +5715,9 @@
 
     @Override
     public String getAlwaysOnVpnPackageForUser(int userHandle) {
-        enforceSystemCaller("getAlwaysOnVpnPackageForUser");
+        Preconditions.checkCallAuthorization(isSystemUid(getCallerIdentity()),
+                "Only the system can get always on VPN package for user");
+
         synchronized (getLockObject()) {
             ActiveAdmin admin = getDeviceOrProfileOwnerAdminLocked(userHandle);
             return admin != null ? admin.mAlwaysOnVpnPackage : null;
@@ -5742,7 +5738,9 @@
 
     @Override
     public boolean isAlwaysOnVpnLockdownEnabledForUser(int userHandle) {
-        enforceSystemCaller("isAlwaysOnVpnLockdownEnabledForUser");
+        Preconditions.checkCallAuthorization(isSystemUid(getCallerIdentity()),
+                "Only the system can query always on VPN lockdown enabled for user");
+
         synchronized (getLockObject()) {
             ActiveAdmin admin = getDeviceOrProfileOwnerAdminLocked(userHandle);
             return admin != null ? admin.mAlwaysOnVpnLockdown : null;
@@ -5973,19 +5971,18 @@
         if (!mHasFeature) {
             return null;
         }
+        final CallerIdentity caller = getCallerIdentityOptionalAdmin(who);
 
         final int frpManagementAgentUid = getFrpManagementAgentUidOrThrow();
         final ActiveAdmin admin;
         synchronized (getLockObject()) {
             if (who == null) {
-                Preconditions.checkCallAuthorization(
-                        frpManagementAgentUid == mInjector.binderGetCallingUid()
+                Preconditions.checkCallAuthorization(frpManagementAgentUid == caller.getUid()
                                 || hasCallingPermission(permission.MASTER_CLEAR),
                         "Must be called by the FRP management agent on device");
                 admin = getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceLocked(
                         UserHandle.getUserId(frpManagementAgentUid));
             } else {
-                final CallerIdentity caller = getCallerIdentity(who);
                 Preconditions.checkCallAuthorization(
                         isDeviceOwner(caller) || isProfileOwnerOfOrganizationOwnedDevice(caller));
                 admin = getProfileOwnerOrDeviceOwnerLocked(caller);
@@ -6049,9 +6046,7 @@
         if (!mHasFeature || !mLockPatternUtils.hasSecureLockScreen()) {
             return;
         }
-
-        final CallerIdentity caller = getCallerIdentity();
-        Preconditions.checkCallAuthorization(isSystemUid(caller));
+        Preconditions.checkCallAuthorization(isSystemUid(getCallerIdentity()));
         // Managed Profile password can only be changed when it has a separate challenge.
         if (!isSeparateProfileChallengeEnabled(userId)) {
             Preconditions.checkCallAuthorization(!isManagedProfile(userId), String.format("You can "
@@ -6571,9 +6566,8 @@
         Objects.requireNonNull(who, "ComponentName is null");
 
         final CallerIdentity caller = getCallerIdentity(who);
-        if (parent) {
-            Preconditions.checkCallAuthorization(isProfileOwnerOfOrganizationOwnedDevice(caller));
-        }
+        Preconditions.checkCallAuthorization(!parent
+                || isProfileOwnerOfOrganizationOwnedDevice(caller));
 
         synchronized (getLockObject()) {
             ActiveAdmin ap = getActiveAdminForCallerLocked(who,
@@ -6947,9 +6941,8 @@
         Objects.requireNonNull(who, "ComponentName is null");
 
         final CallerIdentity caller = getCallerIdentity(who);
-        if (parent) {
-            Preconditions.checkCallAuthorization(isProfileOwnerOfOrganizationOwnedDevice(caller));
-        }
+        Preconditions.checkCallAuthorization(!parent
+                || isProfileOwnerOfOrganizationOwnedDevice(caller));
 
         final int userHandle = caller.getUserId();
         synchronized (getLockObject()) {
@@ -7187,15 +7180,14 @@
                     + " as device owner for user " + userId);
             return false;
         }
-        if (admin == null
-                || !isPackageInstalledForUser(admin.getPackageName(), userId)) {
-            throw new IllegalArgumentException("Invalid component " + admin
-                    + " for device owner");
-        }
-        final boolean hasIncompatibleAccountsOrNonAdb =
-                hasIncompatibleAccountsOrNonAdbNoLock(userId, admin);
+        Objects.requireNonNull(admin, "ComponentName is null");
+        Preconditions.checkArgument(isPackageInstalledForUser(admin.getPackageName(), userId),
+                String.format("Invalid component %s for device owner", admin));
+
+        final CallerIdentity caller = getCallerIdentity();
         synchronized (getLockObject()) {
-            enforceCanSetDeviceOwnerLocked(admin, userId, hasIncompatibleAccountsOrNonAdb);
+            enforceCanSetDeviceOwnerLocked(caller, userId);
+
             final ActiveAdmin activeAdmin = getActiveAdminUncheckedLocked(admin, userId);
             if (activeAdmin == null
                     || getUserData(userId).mRemovingAdmins.contains(admin)) {
@@ -7204,7 +7196,7 @@
 
             // Shutting down backup manager service permanently.
             toggleBackupServiceActive(UserHandle.USER_SYSTEM, /* makeActive= */ false);
-            if (isAdb()) {
+            if (isAdb(caller)) {
                 // Log device owner provisioning was started using adb.
                 MetricsLogger.action(mContext, PROVISIONING_ENTRY_POINT_ADB, LOG_TAG_DEVICE_OWNER);
                 DevicePolicyEventLogger
@@ -7242,12 +7234,11 @@
 
     @Override
     public boolean hasDeviceOwner() {
-        enforceDeviceOwnerOrManageUsers();
-        return mOwners.hasDeviceOwner();
-    }
+        final CallerIdentity caller = getCallerIdentity();
+        Preconditions.checkCallAuthorization(
+                isCallerDeviceOwner(caller.getUid()) || canManageUsers(caller));
 
-    boolean isDeviceOwner(ActiveAdmin admin) {
-        return isDeviceOwner(admin.info.getComponent(), admin.getUserHandle().getIdentifier());
+        return mOwners.hasDeviceOwner();
     }
 
     public boolean isDeviceOwner(ComponentName who, int userId) {
@@ -7415,20 +7406,20 @@
     @Override
     public void clearDeviceOwner(String packageName) {
         Objects.requireNonNull(packageName, "packageName is null");
-        final int callingUid = mInjector.binderGetCallingUid();
-        if (!isCallingFromPackage(packageName, callingUid)) {
-            throw new SecurityException("Invalid packageName");
-        }
+
+        final CallerIdentity caller = getCallerIdentity(packageName);
+        Preconditions.checkCallAuthorization(isCallingFromPackage(packageName, caller.getUid()),
+                "Invalid packageName");
+
         synchronized (getLockObject()) {
             final ComponentName deviceOwnerComponent = mOwners.getDeviceOwnerComponent();
-            final int deviceOwnerUserId = mOwners.getDeviceOwnerUserId();
-            if (!mOwners.hasDeviceOwner()
-                    || !deviceOwnerComponent.getPackageName().equals(packageName)
-                    || (deviceOwnerUserId != UserHandle.getUserId(callingUid))) {
-                throw new SecurityException(
-                        "clearDeviceOwner can only be called by the device owner");
-            }
-            enforceUserUnlocked(deviceOwnerUserId);
+            final int deviceOwnerUserId = caller.getUserId();
+            Preconditions.checkCallAuthorization(isCallerDeviceOwner(caller.getUid())
+                    && deviceOwnerComponent.getPackageName().equals(packageName),
+                    "clearDeviceOwner can only be called by the device owner");
+            Preconditions.checkState(mUserManager.isUserUnlocked(deviceOwnerUserId),
+                    "User must be running and unlocked");
+
             DevicePolicyData policy = getUserData(deviceOwnerUserId);
             if (policy.mPasswordTokenHandle != 0) {
                 mLockPatternUtils.removeEscrowToken(policy.mPasswordTokenHandle, deviceOwnerUserId);
@@ -7513,16 +7504,13 @@
                     + " as profile owner for user " + userHandle);
             return false;
         }
-        if (who == null
-                || !isPackageInstalledForUser(who.getPackageName(), userHandle)) {
-            throw new IllegalArgumentException("Component " + who
-                    + " not installed for userId:" + userHandle);
-        }
+        Objects.requireNonNull(who, "ComponentName is null");
+        Preconditions.checkArgument(isPackageInstalledForUser(who.getPackageName(), userHandle),
+                String.format("Component %s not installed for userId: %d", who, userHandle));
 
-        final boolean hasIncompatibleAccountsOrNonAdb =
-                hasIncompatibleAccountsOrNonAdbNoLock(userHandle, who);
+        final CallerIdentity caller = getCallerIdentity();
         synchronized (getLockObject()) {
-            enforceCanSetProfileOwnerLocked(who, userHandle, hasIncompatibleAccountsOrNonAdb);
+            enforceCanSetProfileOwnerLocked(caller, userHandle);
 
             final ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
             if (admin == null || getUserData(userHandle).mRemovingAdmins.contains(who)) {
@@ -7540,7 +7528,7 @@
                 return false;
             }
 
-            if (isAdb()) {
+            if (isAdb(caller)) {
                 // Log profile owner provisioning was started using adb.
                 MetricsLogger.action(mContext, PROVISIONING_ENTRY_POINT_ADB, LOG_TAG_PROFILE_OWNER);
                 DevicePolicyEventLogger
@@ -7573,6 +7561,47 @@
         }
     }
 
+    /**
+     * The profile owner can only be set by adb or an app with the MANAGE_PROFILE_AND_DEVICE_OWNERS
+     * permission.
+     * The profile owner can only be set before the user setup phase has completed,
+     * except for:
+     * - SYSTEM_UID
+     * - adb unless hasIncompatibleAccountsOrNonAdb is true.
+     */
+    private void enforceCanSetProfileOwnerLocked(CallerIdentity caller, int userHandle) {
+        UserInfo info = getUserInfo(userHandle);
+        Preconditions.checkArgument(info != null,
+                String.format("Attempted to set profile owner for invalid userId: %d", userHandle));
+        Preconditions.checkState(!info.isGuest(), "Cannot set a profile owner on a guest");
+        Preconditions.checkState(!mOwners.hasProfileOwner(userHandle),
+                "Trying to set the profile owner, but profile owner is already set.");
+        Preconditions.checkState(
+                !mOwners.hasDeviceOwner() || mOwners.getDeviceOwnerUserId() != userHandle,
+                "Trying to set the profile owner, but the user already has a device owner.");
+
+
+        boolean hasUserSetupCompleted = mIsWatch || hasUserSetupCompleted(userHandle);
+        if (isAdb(caller)) {
+            Preconditions.checkState(!hasUserSetupCompleted
+                            || !hasIncompatibleAccountsOrNonAdbNoLock(userHandle, caller),
+                    "Not allowed to set the profile owner because there are already some accounts"
+                            + " on the profile");
+            return;
+        }
+        Preconditions.checkCallAuthorization(
+                hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+        if (hasUserSetupCompleted) {
+            Preconditions.checkState(isSystemUid(caller),
+                    "Cannot set the profile owner on a user which is already set-up");
+            if (!mIsWatch) {
+                Preconditions.checkState(isDefaultSupervisor(caller),
+                        String.format("Unable to set non-default profile owner post-setup %s",
+                                caller.getUserHandle()));
+            }
+        }
+    }
+
     private void toggleBackupServiceActive(int userId, boolean makeActive) {
         long ident = mInjector.binderClearCallingIdentity();
         try {
@@ -7599,8 +7628,9 @@
         final CallerIdentity caller = getCallerIdentity(who);
         final int userId = caller.getUserId();
         Preconditions.checkCallingUser(!isManagedProfile(userId));
+        Preconditions.checkState(mUserManager.isUserUnlocked(userId),
+                "User must be running and unlocked");
 
-        enforceUserUnlocked(userId);
         synchronized (getLockObject()) {
             // Check if this is the profile owner who is calling
             final ActiveAdmin admin =
@@ -7733,28 +7763,24 @@
                     + userHandle);
             return;
         }
-
-        if (userHandle != mOwners.getDeviceOwnerUserId() && !mOwners.hasProfileOwner(userHandle)
-                && getManagedUserId(userHandle) == -1) {
-            // No managed device, user or profile, so setting provisioning state makes no sense.
-            throw new IllegalStateException("Not allowed to change provisioning state unless a "
-                      + "device or profile owner is set.");
-        }
+        final CallerIdentity caller = getCallerIdentity();
+        Preconditions.checkState(userHandle == mOwners.getDeviceOwnerUserId()
+                        || hasProfileOwner(userHandle) || isManagedProfile(caller.getUserId()),
+                "Not allowed to change provisioning state unless "
+                        + "a device or profile owner is set.");
 
         synchronized (getLockObject()) {
             boolean transitionCheckNeeded = true;
 
             // Calling identity/permission checks.
-            if (isAdb()) {
+            if (isAdb(caller)) {
                 // ADB shell can only move directly from un-managed to finalized as part of directly
                 // setting profile-owner or device-owner.
-                if (getUserProvisioningState(userHandle) !=
-                        DevicePolicyManager.STATE_USER_UNMANAGED
-                        || newState != DevicePolicyManager.STATE_USER_SETUP_FINALIZED) {
-                    throw new IllegalStateException("Not allowed to change provisioning state "
-                            + "unless current provisioning state is unmanaged, and new state is "
-                            + "finalized.");
-                }
+                Preconditions.checkState(getUserProvisioningState(userHandle)
+                                == DevicePolicyManager.STATE_USER_UNMANAGED
+                                && newState == DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
+                        "Not allowed to change provisioning state unless current provisioning "
+                                + "state is unmanaged, and new state is finalized.");
                 transitionCheckNeeded = false;
             } else {
                 Preconditions.checkCallAuthorization(
@@ -7990,7 +8016,7 @@
 
     @Override
     public boolean checkDeviceIdentifierAccess(String packageName, int pid, int uid) {
-        ensureCallerIdentityMatchesIfNotSystem(packageName, pid, uid);
+        enforceCallerIdentityMatchesIfNotSystem(packageName, pid, uid);
 
         // Verify that the specified packages matches the provided uid.
         if (!doesPackageMatchUid(packageName, uid)) {
@@ -8054,16 +8080,16 @@
         return true;
     }
 
-    private void ensureCallerIdentityMatchesIfNotSystem(String packageName, int pid, int uid) {
+    private void enforceCallerIdentityMatchesIfNotSystem(String packageName, int pid, int uid) {
         // If the caller is not a system app then it should only be able to check its own device
         // identifier access.
-        int callingUid = mInjector.binderGetCallingUid();
         int callingPid = mInjector.binderGetCallingPid();
-        if (UserHandle.getAppId(callingUid) >= Process.FIRST_APPLICATION_UID
-                && (callingUid != uid || callingPid != pid)) {
-            String message = String.format(
-                    "Calling uid %d, pid %d cannot check device identifier access for package %s "
-                            + "(uid=%d, pid=%d)", callingUid, callingPid, packageName, uid, pid);
+        final CallerIdentity caller = getCallerIdentity();
+        if (UserHandle.getAppId(caller.getUid()) >= Process.FIRST_APPLICATION_UID
+                && (caller.getUid() != uid || callingPid != pid)) {
+            String message = String.format("Calling uid %d, pid %d cannot check device identifier "
+                    + "access for package %s (uid=%d, pid=%d)",
+                    caller.getUid(), callingPid, packageName, uid, pid);
             Log.w(LOG_TAG, message);
             throw new SecurityException(message);
         }
@@ -8101,83 +8127,18 @@
     }
 
     /**
-     * The profile owner can only be set by adb or an app with the MANAGE_PROFILE_AND_DEVICE_OWNERS
-     * permission.
-     * The profile owner can only be set before the user setup phase has completed,
-     * except for:
-     * - SYSTEM_UID
-     * - adb unless hasIncompatibleAccountsOrNonAdb is true.
-     */
-    private void enforceCanSetProfileOwnerLocked(@Nullable ComponentName owner, int userHandle,
-            boolean hasIncompatibleAccountsOrNonAdb) {
-        UserInfo info = getUserInfo(userHandle);
-        if (info == null) {
-            // User doesn't exist.
-            throw new IllegalArgumentException(
-                    "Attempted to set profile owner for invalid userId: " + userHandle);
-        }
-        if (info.isGuest()) {
-            throw new IllegalStateException("Cannot set a profile owner on a guest");
-        }
-        if (mOwners.hasProfileOwner(userHandle)) {
-            throw new IllegalStateException("Trying to set the profile owner, but profile owner "
-                    + "is already set.");
-        }
-        if (mOwners.hasDeviceOwner() && mOwners.getDeviceOwnerUserId() == userHandle) {
-            throw new IllegalStateException("Trying to set the profile owner, but the user "
-                    + "already has a device owner.");
-        }
-        if (isAdb()) {
-            if ((mIsWatch || hasUserSetupCompleted(userHandle))
-                    && hasIncompatibleAccountsOrNonAdb) {
-                throw new IllegalStateException("Not allowed to set the profile owner because "
-                        + "there are already some accounts on the profile");
-            }
-            return;
-        }
-        Preconditions.checkCallAuthorization(
-                hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
-
-        if ((mIsWatch || hasUserSetupCompleted(userHandle))) {
-            if (!isCallerWithSystemUid()) {
-                throw new IllegalStateException("Cannot set the profile owner on a user which is "
-                        + "already set-up");
-            }
-
-            if (!mIsWatch) {
-                // Only the default supervision profile owner can be set as profile owner after SUW
-                final String supervisor = mContext.getResources().getString(
-                        com.android.internal.R.string
-                                .config_defaultSupervisionProfileOwnerComponent);
-                if (supervisor == null) {
-                    throw new IllegalStateException("Unable to set profile owner post-setup, no"
-                            + "default supervisor profile owner defined");
-                }
-
-                final ComponentName supervisorComponent = ComponentName.unflattenFromString(
-                        supervisor);
-                if (!owner.equals(supervisorComponent)) {
-                    throw new IllegalStateException("Unable to set non-default profile owner"
-                            + " post-setup " + owner);
-                }
-            }
-        }
-    }
-
-    /**
      * The Device owner can only be set by adb or an app with the MANAGE_PROFILE_AND_DEVICE_OWNERS
      * permission.
      */
-    private void enforceCanSetDeviceOwnerLocked(@Nullable ComponentName owner,
-            @UserIdInt int userId,
-            boolean hasIncompatibleAccountsOrNonAdb) {
-        if (!isAdb()) {
+    private void enforceCanSetDeviceOwnerLocked(CallerIdentity caller, int userId) {
+        if (!isAdb(caller)) {
             Preconditions.checkCallAuthorization(
                     hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
         }
 
         final int code = checkDeviceOwnerProvisioningPreConditionLocked(
-                owner, userId, isAdb(), hasIncompatibleAccountsOrNonAdb);
+                caller.getComponentName(), userId, isAdb(caller),
+                hasIncompatibleAccountsOrNonAdbNoLock(userId, caller));
         if (code != CODE_OK) {
             throw new IllegalStateException(computeProvisioningErrorString(code, userId));
         }
@@ -8212,21 +8173,6 @@
 
     }
 
-    private void enforceUserUnlocked(int userId) {
-        // Since we're doing this operation on behalf of an app, we only
-        // want to use the actual "unlocked" state.
-        Preconditions.checkState(mUserManager.isUserUnlocked(userId),
-                "User must be running and unlocked");
-    }
-
-    private void enforceUserUnlocked(@UserIdInt int userId, boolean parent) {
-        if (parent) {
-            enforceUserUnlocked(getProfileParentId(userId));
-        } else {
-            enforceUserUnlocked(userId);
-        }
-    }
-
     private boolean canManageUsers(CallerIdentity caller) {
         return isSystemUid(caller) || isRootUid(caller)
                 || hasCallingOrSelfPermission(permission.MANAGE_USERS);
@@ -8259,42 +8205,6 @@
                 || hasCallingOrSelfPermission(permission.INTERACT_ACROSS_USERS);
     }
 
-    private void enforceDeviceOwnerOrManageUsers() {
-        synchronized (getLockObject()) {
-            if (getActiveAdminWithPolicyForUidLocked(null, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER,
-                    mInjector.binderGetCallingUid()) != null) {
-                return;
-            }
-        }
-        Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity()));
-    }
-
-    private void enforceProfileOwnerOrSystemUser() {
-        synchronized (getLockObject()) {
-            if (getActiveAdminWithPolicyForUidLocked(null,
-                    DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, mInjector.binderGetCallingUid())
-                            != null) {
-                return;
-            }
-        }
-        Preconditions.checkState(isCallerWithSystemUid(),
-                "Only profile owner, device owner and system may call this method.");
-    }
-
-    private void enforceProfileOwnerOrFullCrossUsersPermission(CallerIdentity caller,
-            int userId) {
-        if (userId == caller.getUserId()) {
-            synchronized (getLockObject()) {
-                if (getActiveAdminWithPolicyForUidLocked(null,
-                        DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, caller.getUid()) != null) {
-                    // Device Owner/Profile Owner may access the user it runs on.
-                    return;
-                }
-            }
-        }
-        Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userId));
-    }
-
     private boolean canUserUseLockTaskLocked(int userId) {
         if (isUserAffiliatedWithDeviceLocked(userId)) {
             return true;
@@ -8318,34 +8228,22 @@
         return true;
     }
 
-    private void enforceCanCallLockTaskLocked(ComponentName who) {
-        getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
-        final int userId =  mInjector.userHandleGetCallingUserId();
-        if (!canUserUseLockTaskLocked(userId)) {
-            throw new SecurityException("User " + userId + " is not allowed to use lock task");
-        }
-    }
-
     private void ensureCallerPackage(@Nullable String packageName) {
+        final CallerIdentity caller = getCallerIdentity();
         if (packageName == null) {
-            enforceSystemCaller("omit package name");
+            Preconditions.checkCallAuthorization(isSystemUid(caller),
+                    "Only the system can omit package name");
         } else {
-            final int callingUid = mInjector.binderGetCallingUid();
-            final int userId = mInjector.userHandleGetCallingUserId();
             try {
                 final ApplicationInfo ai = mIPackageManager.getApplicationInfo(
-                        packageName, 0, userId);
-                Preconditions.checkState(ai.uid == callingUid, "Unmatching package name");
+                        packageName, 0, caller.getUserId());
+                Preconditions.checkState(ai.uid == caller.getUid(), "Unmatching package name");
             } catch (RemoteException e) {
                 // Shouldn't happen
             }
         }
     }
 
-    private boolean isCallerWithSystemUid() {
-        return UserHandle.isSameApp(mInjector.binderGetCallingUid(), Process.SYSTEM_UID);
-    }
-
     private boolean isSystemUid(CallerIdentity caller) {
         return UserHandle.isSameApp(caller.getUid(), Process.SYSTEM_UID);
     }
@@ -8533,10 +8431,9 @@
         final CallerIdentity caller = getCallerIdentity(admin);
         Preconditions.checkCallAuthorization(isDeviceOwner(caller)
                 || (parent && isProfileOwnerOfOrganizationOwnedDevice(caller)));
-        if (parent) {
-            mInjector.binderWithCleanCallingIdentity(() -> enforcePackageIsSystemPackage(
-                    packageName, getProfileParentId(mInjector.userHandleGetCallingUserId())));
-        }
+        mInjector.binderWithCleanCallingIdentity(() -> Preconditions.checkArgument(!parent
+                        || isSystemPackage(packageName, getProfileParentId(caller.getUserId())),
+                "The provided package is not a system package"));
 
         mInjector.binderWithCleanCallingIdentity(() ->
                 SmsApplication.setDefaultApplication(packageName, mContext));
@@ -8562,7 +8459,7 @@
 
     @Override
     public boolean isCallerApplicationRestrictionsManagingPackage(String callerPackage) {
-        return isCallerDelegate(callerPackage, mInjector.binderGetCallingUid(),
+        return isCallerDelegate(callerPackage, getCallerIdentity().getUid(),
                 DELEGATION_APP_RESTRICTIONS);
     }
 
@@ -8677,7 +8574,9 @@
 
     @Override
     public ComponentName getRestrictionsProvider(int userHandle) {
-        enforceSystemCaller("query the permission provider");
+        Preconditions.checkCallAuthorization(isSystemUid(getCallerIdentity()),
+                "Only the system can query the permission provider");
+
         synchronized (getLockObject()) {
             DevicePolicyData userData = getUserData(userHandle);
             return userData != null ? userData.mRestrictionsProvider : null;
@@ -8945,7 +8844,9 @@
         }
         Objects.requireNonNull(who, "ComponentName is null");
         Preconditions.checkStringNotEmpty(packageName, "packageName is null");
-        enforceSystemCaller("query if an accessibility service is disabled by admin");
+
+        Preconditions.checkCallAuthorization(isSystemUid(getCallerIdentity()),
+                "Only the system can query if an accessibility service is disabled by admin");
 
         synchronized (getLockObject()) {
             ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
@@ -9065,7 +8966,9 @@
         }
         Objects.requireNonNull(who, "ComponentName is null");
         Preconditions.checkStringNotEmpty(packageName, "packageName is null");
-        enforceSystemCaller("query if an input method is disabled by admin");
+
+        Preconditions.checkCallAuthorization(isSystemUid(getCallerIdentity()),
+                "Only the system can query if an input method is disabled by admin");
 
         synchronized (getLockObject()) {
             ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
@@ -9122,9 +9025,10 @@
         if (!mHasFeature) {
             return true;
         }
-
         Preconditions.checkStringNotEmpty(packageName, "packageName is null or empty");
-        enforceSystemCaller("query if a notification listener service is permitted");
+
+        Preconditions.checkCallAuthorization(isSystemUid(getCallerIdentity()),
+                "Only the system can query if a notification listener service is permitted");
 
         synchronized (getLockObject()) {
             ActiveAdmin profileOwner = getProfileOwnerAdminLocked(userId);
@@ -9137,12 +9041,6 @@
         }
     }
 
-    private void enforceSystemCaller(String action) {
-        if (!isCallerWithSystemUid()) {
-            throw new SecurityException("Only the system can " + action);
-        }
-    }
-
     private void maybeSendAdminEnabledBroadcastLocked(int userHandle) {
         DevicePolicyData policyData = getUserData(userHandle);
         if (policyData.mAdminBroadcastPending) {
@@ -9172,14 +9070,14 @@
             ComponentName profileOwner, PersistableBundle adminExtras, int flags) {
         Objects.requireNonNull(admin, "admin is null");
         Objects.requireNonNull(profileOwner, "profileOwner is null");
-        if (!admin.getPackageName().equals(profileOwner.getPackageName())) {
-            throw new IllegalArgumentException("profileOwner " + profileOwner + " and admin "
-                    + admin + " are not in the same package");
-        }
-        // Only allow the system user to use this method
-        if (!mInjector.binderGetCallingUserHandle().isSystem()) {
-            throw new SecurityException("createAndManageUser was called from non-system user");
-        }
+        Preconditions.checkArgument(admin.getPackageName().equals(profileOwner.getPackageName()),
+                String.format("profileOwner %s and admin %s are not in the same package",
+                        profileOwner, admin));
+
+        final CallerIdentity caller = getCallerIdentity(admin);
+        Preconditions.checkCallAuthorization(caller.getUserHandle().isSystem(),
+                "createAndManageUser was called from non-system user");
+
         final boolean ephemeral = (flags & DevicePolicyManager.MAKE_USER_EPHEMERAL) != 0;
         final boolean demo = (flags & DevicePolicyManager.MAKE_USER_DEMO) != 0
                 && UserManager.isDeviceInDemoMode(mContext);
@@ -9189,13 +9087,12 @@
         // Create user.
         UserHandle user = null;
         synchronized (getLockObject()) {
-            getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+            Preconditions.checkCallAuthorization(isDeviceOwner(caller));
 
-            final int callingUid = mInjector.binderGetCallingUid();
             final long id = mInjector.binderClearCallingIdentity();
             try {
-                targetSdkVersion = mInjector.getPackageManagerInternal().getUidTargetSdkVersion(
-                        callingUid);
+                targetSdkVersion = mInjector.getPackageManagerInternal()
+                        .getUidTargetSdkVersion(caller.getUid());
 
                 // Return detail error code for checks inside
                 // UserManagerService.createUserInternalUnchecked.
@@ -9723,7 +9620,8 @@
                 // API cannot be used to leak if certain non-system package exists in the person
                 // profile.
                 mInjector.binderWithCleanCallingIdentity(() ->
-                        enforcePackageIsSystemPackage(packageName, userId));
+                        Preconditions.checkArgument(isSystemPackage(packageName, userId),
+                        "The provided package is not a system package"));
             }
             result = mInjector.binderWithCleanCallingIdentity(() -> mIPackageManager
                     .setApplicationHiddenSettingAsUser(packageName, hidden, userId));
@@ -9754,7 +9652,8 @@
                         && isManagedProfile(caller.getUserId()));
                 // Ensure the package provided is a system package.
                 mInjector.binderWithCleanCallingIdentity(() ->
-                        enforcePackageIsSystemPackage(packageName, userId));
+                        Preconditions.checkArgument(isSystemPackage(packageName, userId),
+                                "The provided package is not a system package"));
             }
 
             return mInjector.binderWithCleanCallingIdentity(
@@ -9762,16 +9661,12 @@
         }
     }
 
-    private void enforcePackageIsSystemPackage(String packageName, int userId)
+    private boolean isSystemPackage(String packageName, int userId)
             throws RemoteException {
-        boolean isSystem;
         try {
-            isSystem = isSystemApp(mIPackageManager, packageName, userId);
+            return isSystemApp(mIPackageManager, packageName, userId);
         } catch (IllegalArgumentException e) {
-            isSystem = false;
-        }
-        if (!isSystem) {
-            throw new IllegalArgumentException("The provided package is not a system package");
+            return false;
         }
     }
 
@@ -10320,10 +10215,12 @@
         Objects.requireNonNull(who, "ComponentName is null");
         Objects.requireNonNull(packages, "packages is null");
 
+        final CallerIdentity caller = getCallerIdentity(who);
         synchronized (getLockObject()) {
-            enforceCanCallLockTaskLocked(who);
-            final int userHandle = mInjector.userHandleGetCallingUserId();
-            setLockTaskPackagesLocked(userHandle, new ArrayList<>(Arrays.asList(packages)));
+            Preconditions.checkCallAuthorization((isDeviceOwner(caller) || isProfileOwner(caller))
+                            && canUserUseLockTaskLocked(caller.getUserId()),
+                    String.format("User %d is not allowed to use lock task", caller.getUserId()));
+            setLockTaskPackagesLocked(caller.getUserId(), new ArrayList<>(Arrays.asList(packages)));
         }
     }
 
@@ -10340,10 +10237,12 @@
     public String[] getLockTaskPackages(ComponentName who) {
         Objects.requireNonNull(who, "ComponentName is null");
 
-        final int userHandle = mInjector.binderGetCallingUserHandle().getIdentifier();
+        final CallerIdentity caller = getCallerIdentity(who);
         synchronized (getLockObject()) {
-            enforceCanCallLockTaskLocked(who);
-            final List<String> packages = getUserData(userHandle).mLockTaskPackages;
+            Preconditions.checkCallAuthorization((isDeviceOwner(caller) || isProfileOwner(caller))
+                            && canUserUseLockTaskLocked(caller.getUserId()),
+                    String.format("User %d is not allowed to use lock task", caller.getUserId()));
+            final List<String> packages = getUserData(caller.getUserId()).mLockTaskPackages;
             return packages.toArray(new String[packages.size()]);
         }
     }
@@ -10359,7 +10258,6 @@
     @Override
     public void setLockTaskFeatures(ComponentName who, int flags) {
         Objects.requireNonNull(who, "ComponentName is null");
-
         // Throw if Overview is used without Home.
         boolean hasHome = (flags & LOCK_TASK_FEATURE_HOME) != 0;
         boolean hasOverview = (flags & LOCK_TASK_FEATURE_OVERVIEW) != 0;
@@ -10369,10 +10267,12 @@
         Preconditions.checkArgument(hasHome || !hasNotification,
             "Cannot use LOCK_TASK_FEATURE_NOTIFICATIONS without LOCK_TASK_FEATURE_HOME");
 
-        final int userHandle = mInjector.userHandleGetCallingUserId();
+        final CallerIdentity caller = getCallerIdentity(who);
         synchronized (getLockObject()) {
-            enforceCanCallLockTaskLocked(who);
-            setLockTaskFeaturesLocked(userHandle, flags);
+            Preconditions.checkCallAuthorization((isDeviceOwner(caller) || isProfileOwner(caller))
+                            && canUserUseLockTaskLocked(caller.getUserId()),
+                    String.format("User %d is not allowed to use lock task", caller.getUserId()));
+            setLockTaskFeaturesLocked(caller.getUserId(), flags);
         }
     }
 
@@ -10386,10 +10286,13 @@
     @Override
     public int getLockTaskFeatures(ComponentName who) {
         Objects.requireNonNull(who, "ComponentName is null");
-        final int userHandle = mInjector.userHandleGetCallingUserId();
+
+        final CallerIdentity caller = getCallerIdentity(who);
         synchronized (getLockObject()) {
-            enforceCanCallLockTaskLocked(who);
-            return getUserData(userHandle).mLockTaskFeatures;
+            Preconditions.checkCallAuthorization((isDeviceOwner(caller) || isProfileOwner(caller))
+                            && canUserUseLockTaskLocked(caller.getUserId()),
+                    String.format("User %d is not allowed to use lock task", caller.getUserId()));
+            return getUserData(caller.getUserId()).mLockTaskFeatures;
         }
     }
 
@@ -10420,7 +10323,9 @@
 
     @Override
     public void notifyLockTaskModeChanged(boolean isEnabled, String pkg, int userHandle) {
-        enforceSystemCaller("call notifyLockTaskModeChanged");
+        Preconditions.checkCallAuthorization(isSystemUid(getCallerIdentity()),
+                "Only the system can notify lock task mode changed");
+
         synchronized (getLockObject()) {
             final DevicePolicyData policy = getUserData(userHandle);
 
@@ -11394,13 +11299,13 @@
     @Override
     public Intent createAdminSupportIntent(String restriction) {
         Objects.requireNonNull(restriction);
-        final int uid = mInjector.binderGetCallingUid();
-        final int userId = UserHandle.getUserId(uid);
+
+        final CallerIdentity caller = getCallerIdentity();
         Intent intent = null;
         if (DevicePolicyManager.POLICY_DISABLE_CAMERA.equals(restriction) ||
                 DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE.equals(restriction)) {
             synchronized (getLockObject()) {
-                final DevicePolicyData policy = getUserData(userId);
+                final DevicePolicyData policy = getUserData(caller.getUserId());
                 final int N = policy.mAdminList.size();
                 for (int i = 0; i < N; i++) {
                     final ActiveAdmin admin = policy.mAdminList.get(i);
@@ -11408,7 +11313,8 @@
                                 DevicePolicyManager.POLICY_DISABLE_CAMERA.equals(restriction)) ||
                         (admin.disableScreenCapture && DevicePolicyManager
                                 .POLICY_DISABLE_SCREEN_CAPTURE.equals(restriction))) {
-                        intent = createShowAdminSupportIntent(admin.info.getComponent(), userId);
+                        intent = createShowAdminSupportIntent(admin.info.getComponent(),
+                                caller.getUserId());
                         break;
                     }
                 }
@@ -11425,7 +11331,8 @@
             }
         } else {
             // if valid, |restriction| can only be a user restriction
-            intent = mLocalService.createUserRestrictionSupportIntent(userId, restriction);
+            intent = mLocalService.createUserRestrictionSupportIntent(
+                    caller.getUserId(), restriction);
         }
         if (intent != null) {
             intent.putExtra(DevicePolicyManager.EXTRA_RESTRICTION, restriction);
@@ -11558,7 +11465,9 @@
 
     @Override
     public void clearSystemUpdatePolicyFreezePeriodRecord() {
-        enforceShell("clearSystemUpdatePolicyFreezePeriodRecord");
+        Preconditions.checkCallAuthorization(isAdb(getCallerIdentity()),
+                "Non-shell user attempted to call clearSystemUpdatePolicyFreezePeriodRecord");
+
         synchronized (getLockObject()) {
             // Print out current record to help diagnosed CTS failures
             Slog.i(LOG_TAG, "Clear freeze period record: "
@@ -11570,7 +11479,8 @@
     }
 
     /**
-     * Checks if the caller of the method is the device owner app.
+     * Checks if the caller of the method is the device owner app. This method should only be called
+     * if not componentName is available.
      *
      * @param callerUid UID of the caller.
      * @return true if the caller is the device owner app
@@ -11586,26 +11496,47 @@
             }
             final String deviceOwnerPackageName = mOwners.getDeviceOwnerComponent()
                     .getPackageName();
-                try {
-                    String[] pkgs = mInjector.getIPackageManager().getPackagesForUid(callerUid);
+            try {
+                String[] pkgs = mInjector.getIPackageManager().getPackagesForUid(callerUid);
+                if (pkgs != null) {
                     for (String pkg : pkgs) {
                         if (deviceOwnerPackageName.equals(pkg)) {
                             return true;
                         }
                     }
-                } catch (RemoteException e) {
-                    return false;
                 }
+            } catch (RemoteException e) {
+                return false;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Checks if the caller of the method is the profile owner. This method should only be called
+     * if not componentName is available.
+     *
+     * @param callerUid UID of the caller.
+     * @return true if the caller is the profile owner
+     */
+    private boolean isCallerProfileOwner(int callerUid) {
+        final int userId = UserHandle.getUserId(callerUid);
+        for (ActiveAdmin admin : getUserData(userId).mAdminList) {
+            if (admin.getUid() == callerUid && isProfileOwner(admin.info.getComponent(), userId)) {
+                return true;
+            }
         }
         return false;
     }
 
     @Override
     public void notifyPendingSystemUpdate(@Nullable SystemUpdateInfo info) {
-        mContext.enforceCallingOrSelfPermission(permission.NOTIFY_PENDING_SYSTEM_UPDATE,
+        final CallerIdentity caller = getCallerIdentity();
+        Preconditions.checkCallAuthorization(
+                hasCallingOrSelfPermission(permission.NOTIFY_PENDING_SYSTEM_UPDATE),
                 "Only the system update service can broadcast update information");
 
-        if (UserHandle.getCallingUserId() != UserHandle.USER_SYSTEM) {
+        if (!caller.getUserHandle().isSystem()) {
             Slog.w(LOG_TAG, "Only the system update service in the system user " +
                     "can broadcast update information.");
             return;
@@ -11833,12 +11764,12 @@
     public boolean isProvisioningAllowed(String action, String packageName) {
         Objects.requireNonNull(packageName);
 
-        final int callingUid = mInjector.binderGetCallingUid();
+        final CallerIdentity caller = getCallerIdentity();
         final long ident = mInjector.binderClearCallingIdentity();
         try {
             final int uidForPackage = mInjector.getPackageManager().getPackageUidAsUser(
-                    packageName, UserHandle.getUserId(callingUid));
-            Preconditions.checkArgument(callingUid == uidForPackage,
+                    packageName, caller.getUserId());
+            Preconditions.checkArgument(caller.getUid() == uidForPackage,
                     "Caller uid doesn't match the one for the provided package.");
         } catch (NameNotFoundException e) {
             throw new IllegalArgumentException("Invalid package provided " + packageName, e);
@@ -12149,17 +12080,18 @@
             return;
         }
         Objects.requireNonNull(who, "ComponentName is null");
-        final int userHandle = mInjector.userHandleGetCallingUserId();
+
+        final CallerIdentity caller = getCallerIdentity();
         synchronized (getLockObject()) {
-            ActiveAdmin admin = getActiveAdminForUidLocked(who, mInjector.binderGetCallingUid());
+            ActiveAdmin admin = getActiveAdminForUidLocked(who, caller.getUid());
             if (!TextUtils.equals(admin.shortSupportMessage, message)) {
                 admin.shortSupportMessage = message;
-                saveSettingsLocked(userHandle);
+                saveSettingsLocked(caller.getUserId());
             }
         }
         DevicePolicyEventLogger
                 .createEvent(DevicePolicyEnums.SET_SHORT_SUPPORT_MESSAGE)
-                .setAdmin(who)
+                .setAdmin(caller.getComponentName())
                 .write();
     }
 
@@ -12169,8 +12101,9 @@
             return null;
         }
         Objects.requireNonNull(who, "ComponentName is null");
+
         synchronized (getLockObject()) {
-            ActiveAdmin admin = getActiveAdminForUidLocked(who, mInjector.binderGetCallingUid());
+            ActiveAdmin admin = getActiveAdminForUidLocked(who, getCallerIdentity().getUid());
             return admin.shortSupportMessage;
         }
     }
@@ -12181,17 +12114,18 @@
             return;
         }
         Objects.requireNonNull(who, "ComponentName is null");
-        final int userHandle = mInjector.userHandleGetCallingUserId();
+
+        final CallerIdentity caller = getCallerIdentity();
         synchronized (getLockObject()) {
-            ActiveAdmin admin = getActiveAdminForUidLocked(who, mInjector.binderGetCallingUid());
+            ActiveAdmin admin = getActiveAdminForUidLocked(who, caller.getUid());
             if (!TextUtils.equals(admin.longSupportMessage, message)) {
                 admin.longSupportMessage = message;
-                saveSettingsLocked(userHandle);
+                saveSettingsLocked(caller.getUserId());
             }
         }
         DevicePolicyEventLogger
                 .createEvent(DevicePolicyEnums.SET_LONG_SUPPORT_MESSAGE)
-                .setAdmin(who)
+                .setAdmin(caller.getComponentName())
                 .write();
     }
 
@@ -12201,8 +12135,9 @@
             return null;
         }
         Objects.requireNonNull(who, "ComponentName is null");
+
         synchronized (getLockObject()) {
-            ActiveAdmin admin = getActiveAdminForUidLocked(who, mInjector.binderGetCallingUid());
+            ActiveAdmin admin = getActiveAdminForUidLocked(who, getCallerIdentity().getUid());
             return admin.longSupportMessage;
         }
     }
@@ -12213,7 +12148,9 @@
             return null;
         }
         Objects.requireNonNull(who, "ComponentName is null");
-        enforceSystemCaller("query support message for user");
+
+        Preconditions.checkCallAuthorization(isSystemUid(getCallerIdentity()),
+                "Only the system can query support message for user");
 
         synchronized (getLockObject()) {
             ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
@@ -12230,7 +12167,9 @@
             return null;
         }
         Objects.requireNonNull(who, "ComponentName is null");
-        enforceSystemCaller("query support message for user");
+
+        Preconditions.checkCallAuthorization(isSystemUid(getCallerIdentity()),
+                "Only the system can query support message for user");
 
         synchronized (getLockObject()) {
             ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
@@ -12357,7 +12296,10 @@
         if (!mHasFeature) {
             return null;
         }
-        enforceDeviceOwnerOrManageUsers();
+        final CallerIdentity caller = getCallerIdentity();
+        Preconditions.checkCallAuthorization(
+                isCallerDeviceOwner(caller.getUid()) || canManageUsers(caller));
+
         synchronized (getLockObject()) {
             final ActiveAdmin deviceOwnerAdmin = getDeviceOwnerAdminLocked();
             return deviceOwnerAdmin == null ? null : deviceOwnerAdmin.organizationName;
@@ -12454,12 +12396,13 @@
     @Override
     public boolean isMeteredDataDisabledPackageForUser(ComponentName who,
             String packageName, int userId) {
-        Objects.requireNonNull(who);
-
         if (!mHasFeature) {
             return false;
         }
-        enforceSystemCaller("query restricted pkgs for a specific user");
+        Objects.requireNonNull(who, "ComponentName is null");
+
+        Preconditions.checkCallAuthorization(isSystemUid(getCallerIdentity()),
+                "Only the system can query restricted pkgs for a specific user");
 
         synchronized (getLockObject()) {
             final ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userId);
@@ -12472,32 +12415,27 @@
 
     @Override
     public void markProfileOwnerOnOrganizationOwnedDevice(ComponentName who, int userId) {
+        if (!mHasFeature) {
+            return;
+        }
         // As the caller is the system, it must specify the component name of the profile owner
         // as a sanity / safety check.
         Objects.requireNonNull(who);
 
-        if (!mHasFeature) {
-            return;
-        }
-
+        final CallerIdentity caller = getCallerIdentity();
         // Only adb or system apps with the right permission can mark a profile owner on
         // organization-owned device.
-        if (!(isAdb() || hasCallingPermission(permission.MARK_DEVICE_ORGANIZATION_OWNED))) {
-            throw new SecurityException(
-                    "Only the system can mark a profile owner of organization-owned device.");
-        }
-
-        if (isAdb()) {
-            if (hasIncompatibleAccountsOrNonAdbNoLock(userId, who)) {
-                throw new SecurityException(
-                        "Can only be called from ADB if the device has no accounts.");
-            }
+        Preconditions.checkCallAuthorization(isAdb(caller)
+                        || hasCallingPermission(permission.MARK_DEVICE_ORGANIZATION_OWNED),
+                "Only the system can mark a profile owner of organization-owned device.");
+        if (isAdb(caller)) {
+            Preconditions.checkCallAuthorization(
+                    !hasIncompatibleAccountsOrNonAdbNoLock(userId, caller),
+                    "Can only be called from ADB if the device has no accounts.");
         } else {
-            if (hasUserSetupCompleted(UserHandle.USER_SYSTEM)) {
-                throw new IllegalStateException(
-                        "Cannot mark profile owner as managing an organization-owned device after"
-                                + " set-up");
-            }
+            Preconditions.checkState(!hasUserSetupCompleted(UserHandle.USER_SYSTEM),
+                    "Cannot mark profile owner as managing an organization-owned device after "
+                            + "set-up");
         }
 
         // Grant access under lock.
@@ -12716,13 +12654,13 @@
         if (!mHasFeature) {
             return false;
         }
+        final CallerIdentity caller = getCallerIdentityOptionalAdmin(admin);
 
         synchronized (getLockObject()) {
-            if (!isCallerWithSystemUid()) {
-                Objects.requireNonNull(admin);
-                final CallerIdentity caller = getCallerIdentity(admin);
-                Preconditions.checkCallAuthorization(
-                        isProfileOwnerOfOrganizationOwnedDevice(caller) || isDeviceOwner(caller));
+            if (!isSystemUid(caller)) {
+                Objects.requireNonNull(admin, "ComponentName is null");
+                Preconditions.checkCallAuthorization(isDeviceOwner(caller)
+                        || isProfileOwnerOfOrganizationOwnedDevice(caller));
             }
             return mInjector.securityLogGetLoggingEnabledProperty();
         }
@@ -12806,19 +12744,13 @@
 
     @Override
     public long forceSecurityLogs() {
-        enforceShell("forceSecurityLogs");
-        if (!mInjector.securityLogGetLoggingEnabledProperty()) {
-            throw new IllegalStateException("logging is not available");
-        }
-        return mSecurityLogMonitor.forceLogs();
-    }
+        final CallerIdentity caller = getCallerIdentity();
+        Preconditions.checkCallAuthorization(isAdb(caller),
+                "Non-shell user attempted to call forceSecurityLogs");
+        Preconditions.checkState(mInjector.securityLogGetLoggingEnabledProperty(),
+                "logging is not available");
 
-    private void enforceCallerSystemUserHandle() {
-        final int callingUid = mInjector.binderGetCallingUid();
-        final int userId = UserHandle.getUserId(callingUid);
-        if (userId != UserHandle.USER_SYSTEM) {
-            throw new SecurityException("Caller has to be in user 0");
-        }
+        return mSecurityLogMonitor.forceLogs();
     }
 
     @Override
@@ -12838,22 +12770,21 @@
         Preconditions.checkArgument(!TextUtils.isEmpty(packageName));
 
         final CallerIdentity caller = getCallerIdentity();
+        final int userId = caller.getUserId();
         Preconditions.checkCallAuthorization(
                 hasCallingOrSelfPermission(permission.MANAGE_DEVICE_ADMINS));
-
-        final int userId = caller.getUserId();
-        enforceUserUnlocked(userId);
+        Preconditions.checkState(mUserManager.isUserUnlocked(userId),
+                "User must be running and unlocked");
 
         final ComponentName profileOwner = getProfileOwner(userId);
-        if (profileOwner != null && packageName.equals(profileOwner.getPackageName())) {
-            throw new IllegalArgumentException("Cannot uninstall a package with a profile owner");
-        }
+        Preconditions.checkArgument(
+                profileOwner == null || !packageName.equals(profileOwner.getPackageName()),
+                "Cannot uninstall a package with a profile owner");
 
         final ComponentName deviceOwner = getDeviceOwnerComponent(/* callingUserOnly= */ false);
-        if (getDeviceOwnerUserId() == userId && deviceOwner != null
-                && packageName.equals(deviceOwner.getPackageName())) {
-            throw new IllegalArgumentException("Cannot uninstall a package with a device owner");
-        }
+        Preconditions.checkArgument(deviceOwner == null || getDeviceOwnerUserId() != userId
+                || !packageName.equals(deviceOwner.getPackageName()),
+                "Cannot uninstall a package with a device owner");
 
         final Pair<String, Integer> packageUserPair = new Pair<>(packageName, userId);
         synchronized (getLockObject()) {
@@ -13004,22 +12935,24 @@
      */
     @Override
     public void forceUpdateUserSetupComplete() {
+        final CallerIdentity caller = getCallerIdentity();
+
         Preconditions.checkCallAuthorization(
                 hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
-        enforceCallerSystemUserHandle();
+        Preconditions.checkCallAuthorization(caller.getUserHandle().isSystem(),
+                "Caller has to be in user 0");
 
         // no effect if it's called from user build
         if (!mInjector.isBuildDebuggable()) {
             return;
         }
-        final int userId = UserHandle.USER_SYSTEM;
         boolean isUserCompleted = mInjector.settingsSecureGetIntForUser(
-                Settings.Secure.USER_SETUP_COMPLETE, 0, userId) != 0;
-        DevicePolicyData policy = getUserData(userId);
+                Settings.Secure.USER_SETUP_COMPLETE, 0, caller.getUserId()) != 0;
+        DevicePolicyData policy = getUserData(caller.getUserId());
         policy.mUserSetupComplete = isUserCompleted;
         mStateCache.setDeviceProvisioned(isUserCompleted);
         synchronized (getLockObject()) {
-            saveSettingsLocked(userId);
+            saveSettingsLocked(caller.getUserId());
         }
     }
 
@@ -13174,9 +13107,8 @@
      *
      * DO NOT CALL IT WITH THE DPMS LOCK HELD.
      */
-    private boolean hasIncompatibleAccountsOrNonAdbNoLock(
-            int userId, @Nullable ComponentName owner) {
-        if (!isAdb()) {
+    private boolean hasIncompatibleAccountsOrNonAdbNoLock(int userId, CallerIdentity caller) {
+        if (!isAdb(caller)) {
             return true;
         }
         wtfIfInLock();
@@ -13188,7 +13120,8 @@
                 return false;
             }
             synchronized (getLockObject()) {
-                if (owner == null || !isAdminTestOnlyLocked(owner, userId)) {
+                if (caller.getComponentName() == null
+                        || !isAdminTestOnlyLocked(caller.getComponentName(), userId)) {
                     Log.w(LOG_TAG,
                             "Non test-only owner can't be installed with existing accounts.");
                     return true;
@@ -13231,9 +13164,8 @@
         }
     }
 
-    private boolean isAdb() {
-        final int callingUid = mInjector.binderGetCallingUid();
-        return callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID;
+    private boolean isAdb(CallerIdentity caller) {
+        return isShellUid(caller) || isRootUid(caller);
     }
 
     @Override
@@ -13295,11 +13227,13 @@
 
     @Override
     public long forceNetworkLogs() {
-        enforceShell("forceNetworkLogs");
+        Preconditions.checkCallAuthorization(isAdb(getCallerIdentity()),
+                "Non-shell user attempted to call forceNetworkLogs");
+
         synchronized (getLockObject()) {
-            if (!isNetworkLoggingEnabledInternalLocked()) {
-                throw new IllegalStateException("logging is not available");
-            }
+            Preconditions.checkState(isNetworkLoggingEnabledInternalLocked(),
+                    "logging is not available");
+
             if (mNetworkLogger != null) {
                 return mInjector.binderWithCleanCallingIdentity(
                         () -> mNetworkLogger.forceBatchFinalization());
@@ -13499,19 +13433,28 @@
 
     @Override
     public long getLastSecurityLogRetrievalTime() {
-        enforceDeviceOwnerOrManageUsers();
+        final CallerIdentity caller = getCallerIdentity();
+        Preconditions.checkCallAuthorization(
+                isCallerDeviceOwner(caller.getUid()) || canManageUsers(caller));
+
         return getUserData(UserHandle.USER_SYSTEM).mLastSecurityLogRetrievalTime;
      }
 
     @Override
     public long getLastBugReportRequestTime() {
-        enforceDeviceOwnerOrManageUsers();
+        final CallerIdentity caller = getCallerIdentity();
+        Preconditions.checkCallAuthorization(
+                isCallerDeviceOwner(caller.getUid()) || canManageUsers(caller));
+
         return getUserData(UserHandle.USER_SYSTEM).mLastBugReportRequestTime;
      }
 
     @Override
     public long getLastNetworkLogRetrievalTime() {
-        enforceDeviceOwnerOrManageUsers();
+        final CallerIdentity caller = getCallerIdentity();
+        Preconditions.checkCallAuthorization(
+                isCallerDeviceOwner(caller.getUid()) || canManageUsers(caller));
+
         return getUserData(UserHandle.USER_SYSTEM).mLastNetworkLogsRetrievalTime;
     }
 
@@ -13591,16 +13534,18 @@
         if (!mHasFeature || !mLockPatternUtils.hasSecureLockScreen()) {
             return false;
         }
+        Objects.requireNonNull(admin);
         Objects.requireNonNull(token);
-        synchronized (getLockObject()) {
-            final int userHandle = mInjector.userHandleGetCallingUserId();
-            getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
 
-            DevicePolicyData policy = getUserData(userHandle);
+        final CallerIdentity caller = getCallerIdentity(admin);
+        Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller));
+
+        synchronized (getLockObject()) {
+            DevicePolicyData policy = getUserData(caller.getUserId());
             if (policy.mPasswordTokenHandle != 0) {
                 final String password = passwordOrNull != null ? passwordOrNull : "";
                 return resetPasswordInternal(password, policy.mPasswordTokenHandle, token,
-                        flags, mInjector.binderGetCallingUid());
+                        flags, caller.getUid());
             } else {
                 Slog.w(LOG_TAG, "No saved token handle");
             }
@@ -13610,15 +13555,21 @@
 
     @Override
     public boolean isCurrentInputMethodSetByOwner() {
-        enforceProfileOwnerOrSystemUser();
-        return getUserData(mInjector.userHandleGetCallingUserId()).mCurrentInputMethodSet;
+        final CallerIdentity caller = getCallerIdentity();
+        Preconditions.checkCallAuthorization(isCallerDeviceOwner(caller.getUid())
+                || isCallerProfileOwner(caller.getUid()) || isSystemUid(caller));
+
+        return getUserData(caller.getUserId()).mCurrentInputMethodSet;
     }
 
     @Override
     public StringParceledListSlice getOwnerInstalledCaCerts(@NonNull UserHandle user) {
         final int userId = user.getIdentifier();
         final CallerIdentity caller = getCallerIdentity();
-        enforceProfileOwnerOrFullCrossUsersPermission(caller, userId);
+        Preconditions.checkCallAuthorization(isCallerDeviceOwner(caller.getUid())
+                || isCallerProfileOwner(caller.getUid())
+                || hasFullCrossUsersPermission(caller, userId));
+
         synchronized (getLockObject()) {
             return new StringParceledListSlice(
                     new ArrayList<>(getUserData(userId).mOwnerInstalledCaCerts));
@@ -14505,14 +14456,12 @@
         }
         Preconditions.checkStringNotEmpty(packageName, "Package name is empty");
 
-        final int callingUid = mInjector.binderGetCallingUid();
-        final int callingUserId = mInjector.userHandleGetCallingUserId();
-        if (!isCallingFromPackage(packageName, callingUid)) {
-            throw new SecurityException("Input package name doesn't align with actual "
-                    + "calling package.");
-        }
+        final CallerIdentity caller = getCallerIdentity(packageName);
+        Preconditions.checkCallAuthorization(isCallingFromPackage(packageName, caller.getUid()),
+                "Input package name doesn't align with actual calling package.");
+
         return mInjector.binderWithCleanCallingIdentity(() -> {
-            final int workProfileUserId = getManagedUserId(callingUserId);
+            final int workProfileUserId = getManagedUserId(caller.getUserId());
             if (workProfileUserId < 0) {
                 return false;
             }
@@ -14996,7 +14945,9 @@
 
     @Override
     public boolean canProfileOwnerResetPasswordWhenLocked(int userId) {
-        enforceSystemCaller("call canProfileOwnerResetPasswordWhenLocked");
+        Preconditions.checkCallAuthorization(isSystemUid(getCallerIdentity()),
+                "Only the system can query profile owner can reset password when locked");
+
         synchronized (getLockObject()) {
             final ActiveAdmin poAdmin = getProfileOwnerAdminLocked(userId);
             if (poAdmin == null
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index bbcb312..5f145f3 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -2135,6 +2135,11 @@
     return binder::Status::ok();
 }
 
+binder::Status IncrementalService::DataLoaderStub::reportStreamHealth(MountId mountId,
+                                                                      int newStatus) {
+    return binder::Status::ok();
+}
+
 bool IncrementalService::DataLoaderStub::isHealthParamsValid() const {
     return mHealthCheckParams.blockedTimeoutMs > 0 &&
             mHealthCheckParams.blockedTimeoutMs < mHealthCheckParams.unhealthyTimeoutMs;
diff --git a/services/incremental/IncrementalService.h b/services/incremental/IncrementalService.h
index d820417..504c02a 100644
--- a/services/incremental/IncrementalService.h
+++ b/services/incremental/IncrementalService.h
@@ -200,6 +200,7 @@
 
     private:
         binder::Status onStatusChanged(MountId mount, int newStatus) final;
+        binder::Status reportStreamHealth(MountId mount, int newStatus) final;
 
         sp<content::pm::IDataLoader> getDataLoader();
 
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java
index 63ad53b..2a9c394 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java
@@ -160,7 +160,7 @@
         assertThat(playbackDevice.getActiveSource().logicalAddress).isEqualTo(
                 playbackDevice.mAddress);
         assertThat(playbackDevice.getActiveSource().physicalAddress).isEqualTo(mPhysicalAddress);
-        assertThat(playbackDevice.mIsActiveSource).isTrue();
+        assertThat(playbackDevice.isActiveSource()).isTrue();
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
index 415ae07..74fd683 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
@@ -30,10 +30,15 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import android.content.Context;
 import android.hardware.hdmi.HdmiDeviceInfo;
 import android.hardware.hdmi.HdmiPortInfo;
 import android.media.AudioManager;
+import android.os.Handler;
+import android.os.IPowerManager;
+import android.os.IThermalService;
 import android.os.Looper;
+import android.os.PowerManager;
 import android.os.test.TestLooper;
 import android.platform.test.annotations.Presubmit;
 
@@ -47,6 +52,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 import java.util.ArrayList;
 
@@ -81,8 +88,17 @@
     private HdmiPortInfo[] mHdmiPortInfo;
     private boolean mWokenUp;
 
+    @Mock private IPowerManager mIPowerManagerMock;
+    @Mock private IThermalService mIThermalServiceMock;
+
     @Before
     public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        Context context = InstrumentationRegistry.getTargetContext();
+        mMyLooper = mTestLooper.getLooper();
+        PowerManager powerManager = new PowerManager(context, mIPowerManagerMock,
+                mIThermalServiceMock, new Handler(mMyLooper));
         mHdmiControlService =
             new HdmiControlService(InstrumentationRegistry.getTargetContext()) {
                 @Override
@@ -166,6 +182,11 @@
                             return defVal;
                     }
                 }
+
+                @Override
+                PowerManager getPowerManager() {
+                    return powerManager;
+                }
             };
 
         mHdmiControlService.setHdmiCecVolumeControlEnabled(true);
@@ -174,11 +195,6 @@
         mHdmiCecLocalDeviceAudioSystem = new HdmiCecLocalDeviceAudioSystem(mHdmiControlService);
         mHdmiCecLocalDevicePlayback = new HdmiCecLocalDevicePlayback(mHdmiControlService) {
             @Override
-            void setIsActiveSource(boolean on) {
-                mIsActiveSource = on;
-            }
-
-            @Override
             protected int getPreferredAddress() {
                 return ADDR_PLAYBACK_1;
             }
@@ -827,4 +843,68 @@
 
         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(unexpected);
     }
+
+    @Test
+    public void setActiveSource_localDevice_playback() {
+        mHdmiControlService.setActiveSource(mHdmiCecLocalDevicePlayback.mAddress,
+                SELF_PHYSICAL_ADDRESS,
+                "HdmiControlServiceTest");
+
+        assertThat(mHdmiControlService.getLocalActiveSource().logicalAddress).isEqualTo(
+                mHdmiCecLocalDevicePlayback.mAddress);
+        assertThat(mHdmiControlService.getLocalActiveSource().physicalAddress).isEqualTo(
+                SELF_PHYSICAL_ADDRESS);
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
+        assertThat(mHdmiCecLocalDeviceAudioSystem.isActiveSource()).isFalse();
+    }
+
+    @Test
+    public void setActiveSource_localDevice_audio() {
+        mHdmiControlService.setActiveSource(mHdmiCecLocalDeviceAudioSystem.mAddress,
+                SELF_PHYSICAL_ADDRESS,
+                "HdmiControlServiceTest");
+
+        assertThat(mHdmiControlService.getLocalActiveSource().logicalAddress).isEqualTo(
+                mHdmiCecLocalDeviceAudioSystem.mAddress);
+        assertThat(mHdmiControlService.getLocalActiveSource().physicalAddress).isEqualTo(
+                SELF_PHYSICAL_ADDRESS);
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
+        assertThat(mHdmiCecLocalDeviceAudioSystem.isActiveSource()).isTrue();
+    }
+
+    @Test
+    public void setActiveSource_remoteDevice() {
+        mHdmiControlService.setActiveSource(Constants.ADDR_TV, 0x0000, "HdmiControlServiceTest");
+
+        assertThat(mHdmiControlService.getLocalActiveSource().logicalAddress).isEqualTo(
+                Constants.ADDR_TV);
+        assertThat(mHdmiControlService.getLocalActiveSource().physicalAddress).isEqualTo(0x000);
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
+        assertThat(mHdmiCecLocalDeviceAudioSystem.isActiveSource()).isFalse();
+    }
+
+    @Test
+    public void setActiveSource_nonCecDevice() {
+        mHdmiControlService.setActiveSource(Constants.ADDR_INVALID, 0x1234,
+                "HdmiControlServiceTest");
+
+        assertThat(mHdmiControlService.getLocalActiveSource().logicalAddress).isEqualTo(
+                Constants.ADDR_INVALID);
+        assertThat(mHdmiControlService.getLocalActiveSource().physicalAddress).isEqualTo(0x1234);
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
+        assertThat(mHdmiCecLocalDeviceAudioSystem.isActiveSource()).isFalse();
+    }
+
+    @Test
+    public void setActiveSource_unknown() {
+        mHdmiControlService.setActiveSource(Constants.ADDR_INVALID,
+                Constants.INVALID_PHYSICAL_ADDRESS, "HdmiControlServiceTest");
+
+        assertThat(mHdmiControlService.getLocalActiveSource().logicalAddress).isEqualTo(
+                Constants.ADDR_INVALID);
+        assertThat(mHdmiControlService.getLocalActiveSource().physicalAddress).isEqualTo(
+                Constants.INVALID_PHYSICAL_ADDRESS);
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
+        assertThat(mHdmiCecLocalDeviceAudioSystem.isActiveSource()).isFalse();
+    }
 }
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 498ebf4..7cbf571 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
@@ -17,6 +17,7 @@
 
 import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM;
 import static com.android.server.hdmi.Constants.ADDR_BROADCAST;
+import static com.android.server.hdmi.Constants.ADDR_INVALID;
 import static com.android.server.hdmi.Constants.ADDR_TV;
 import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
 
@@ -266,106 +267,197 @@
     @Test
     public void handleRoutingChange_otherDevice_None() {
         mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
-            HdmiProperties.power_state_change_on_active_source_lost_values.NONE;
-        mHdmiCecLocalDevicePlayback.setIsActiveSource(true);
+                HdmiProperties.power_state_change_on_active_source_lost_values.NONE;
+        mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
+                mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
         mStandby = false;
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000, 0x5000);
         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue();
-        assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse();
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo(
+                0x5000);
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(
+                ADDR_INVALID);
+        assertThat(mStandby).isFalse();
+    }
+
+    @Test
+    public void handleRoutingChange_sameDevice_None_ActiveSource() {
+        mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
+                HdmiProperties.power_state_change_on_active_source_lost_values.NONE;
+        mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
+                mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
+        mStandby = false;
+        HdmiCecMessage message =
+                HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000,
+                        mPlaybackPhysicalAddress);
+        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo(
+                mPlaybackPhysicalAddress);
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(
+                mPlaybackLogicalAddress);
+        assertThat(mStandby).isFalse();
+    }
+
+    @Test
+    public void handleRoutingChange_sameDevice_None_InactiveSource() {
+        mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
+                HdmiProperties.power_state_change_on_active_source_lost_values.NONE;
+        mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
+                "HdmiCecLocalDevicePlaybackTest");
+        mStandby = false;
+        HdmiCecMessage message =
+                HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000,
+                        mPlaybackPhysicalAddress);
+        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo(
+                mPlaybackPhysicalAddress);
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(
+                ADDR_INVALID);
         assertThat(mStandby).isFalse();
     }
 
     @Test
     public void handleRoutingChange_otherDevice_StandbyNow() {
         mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
-            HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW;
-        mHdmiCecLocalDevicePlayback.setIsActiveSource(true);
+                HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW;
+        mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
+                mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
         mStandby = false;
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000, 0x5000);
         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue();
-        assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse();
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
         assertThat(mStandby).isTrue();
     }
 
     @Test
     public void handleRoutingChange_otherDevice_StandbyNow_InactiveSource() {
         mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
-            HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW;
-        mHdmiCecLocalDevicePlayback.setIsActiveSource(false);
+                HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW;
+        mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
+                "HdmiCecLocalDevicePlaybackTest");
         mStandby = false;
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000, 0x5000);
         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue();
-        assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse();
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
         assertThat(mStandby).isFalse();
     }
 
     @Test
     public void handleRoutingChange_sameDevice_StandbyNow_ActiveSource() {
         mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
-            HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW;
-        mHdmiCecLocalDevicePlayback.setIsActiveSource(true);
+                HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW;
+        mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
+                mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
         mStandby = false;
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000,
                         mPlaybackPhysicalAddress);
         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue();
-        assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
         assertThat(mStandby).isFalse();
     }
 
     @Test
     public void handleRoutingInformation_otherDevice_None() {
         mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
-            HdmiProperties.power_state_change_on_active_source_lost_values.NONE;
-        mHdmiCecLocalDevicePlayback.setIsActiveSource(true);
+                HdmiProperties.power_state_change_on_active_source_lost_values.NONE;
+        mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
+                mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
+        mStandby = false;
+        HdmiCecMessage message = HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, 0x5000);
+        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo(
+                0x5000);
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(
+                ADDR_INVALID);
+        assertThat(mStandby).isFalse();
+    }
+
+    @Test
+    public void handleRoutingInformation_sameDevice_None_ActiveSource() {
+        mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
+                HdmiProperties.power_state_change_on_active_source_lost_values.NONE;
+        mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
+                mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
         mStandby = false;
         HdmiCecMessage message =
-                HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, 0x5000);
+                HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV,
+                        mPlaybackPhysicalAddress);
         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue();
-        assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse();
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo(
+                mPlaybackPhysicalAddress);
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(
+                mPlaybackLogicalAddress);
+        assertThat(mStandby).isFalse();
+    }
+
+    @Test
+    public void handleRoutingInformation_sameDevice_None_InactiveSource() {
+        mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
+                HdmiProperties.power_state_change_on_active_source_lost_values.NONE;
+        mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
+                "HdmiCecLocalDevicePlaybackTest");
+        mStandby = false;
+        HdmiCecMessage message =
+                HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV,
+                        mPlaybackPhysicalAddress);
+        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo(
+                mPlaybackPhysicalAddress);
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(
+                ADDR_INVALID);
         assertThat(mStandby).isFalse();
     }
 
     @Test
     public void handleRoutingInformation_otherDevice_StandbyNow() {
         mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
-            HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW;
-        mHdmiCecLocalDevicePlayback.setIsActiveSource(true);
+                HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW;
+        mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
+                mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
         mStandby = false;
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, 0x5000);
         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue();
-        assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse();
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
         assertThat(mStandby).isTrue();
     }
 
     @Test
     public void handleRoutingInformation_otherDevice_StandbyNow_InactiveSource() {
         mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
-            HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW;
-        mHdmiCecLocalDevicePlayback.setIsActiveSource(false);
+                HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW;
+        mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
+                "HdmiCecLocalDevicePlaybackTest");
         mStandby = false;
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, 0x5000);
         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue();
-        assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse();
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
         assertThat(mStandby).isFalse();
     }
 
     @Test
     public void handleRoutingInformation_sameDevice_StandbyNow_ActiveSource() {
         mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
-            HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW;
-        mHdmiCecLocalDevicePlayback.setIsActiveSource(true);
+                HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW;
+        mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
+                mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
         mStandby = false;
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV,
                         mPlaybackPhysicalAddress);
         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue();
-        assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
         assertThat(mStandby).isFalse();
     }
 
@@ -430,7 +522,8 @@
         mHdmiCecLocalDevicePlayback.mService.writeStringSetting(
                 Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP,
                 HdmiControlManager.SEND_STANDBY_ON_SLEEP_TO_TV);
-        mHdmiCecLocalDevicePlayback.setIsActiveSource(false);
+        mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
+                "HdmiCecLocalDevicePlaybackTest");
         mHdmiCecLocalDevicePlayback.setAutoDeviceOff(true);
         mHdmiCecLocalDevicePlayback.onStandby(false, HdmiControlService.STANDBY_SCREEN_OFF);
         mTestLooper.dispatchAll();
@@ -449,7 +542,8 @@
         mHdmiCecLocalDevicePlayback.mService.writeStringSetting(
                 Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP,
                 HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST);
-        mHdmiCecLocalDevicePlayback.setIsActiveSource(false);
+        mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
+                "HdmiCecLocalDevicePlaybackTest");
         mHdmiCecLocalDevicePlayback.setAutoDeviceOff(true);
         mHdmiCecLocalDevicePlayback.onStandby(false, HdmiControlService.STANDBY_SCREEN_OFF);
         mTestLooper.dispatchAll();
@@ -468,7 +562,8 @@
         mHdmiCecLocalDevicePlayback.mService.writeStringSetting(
                 Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP,
                 HdmiControlManager.SEND_STANDBY_ON_SLEEP_NONE);
-        mHdmiCecLocalDevicePlayback.setIsActiveSource(false);
+        mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
+                "HdmiCecLocalDevicePlaybackTest");
         mHdmiCecLocalDevicePlayback.setAutoDeviceOff(true);
         mHdmiCecLocalDevicePlayback.onStandby(false, HdmiControlService.STANDBY_SCREEN_OFF);
         mTestLooper.dispatchAll();
@@ -487,7 +582,8 @@
         mHdmiCecLocalDevicePlayback.mService.writeStringSetting(
                 Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP,
                 HdmiControlManager.SEND_STANDBY_ON_SLEEP_TO_TV);
-        mHdmiCecLocalDevicePlayback.setIsActiveSource(true);
+        mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
+                mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
         mHdmiCecLocalDevicePlayback.setAutoDeviceOff(true);
         mHdmiCecLocalDevicePlayback.onStandby(false, HdmiControlService.STANDBY_SCREEN_OFF);
         mTestLooper.dispatchAll();
@@ -506,7 +602,8 @@
         mHdmiCecLocalDevicePlayback.mService.writeStringSetting(
                 Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP,
                 HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST);
-        mHdmiCecLocalDevicePlayback.setIsActiveSource(true);
+        mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
+                mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
         mHdmiCecLocalDevicePlayback.setAutoDeviceOff(true);
         mHdmiCecLocalDevicePlayback.onStandby(false, HdmiControlService.STANDBY_SCREEN_OFF);
         mTestLooper.dispatchAll();
@@ -525,7 +622,8 @@
         mHdmiCecLocalDevicePlayback.mService.writeStringSetting(
                 Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP,
                 HdmiControlManager.SEND_STANDBY_ON_SLEEP_NONE);
-        mHdmiCecLocalDevicePlayback.setIsActiveSource(true);
+        mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
+                mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
         mHdmiCecLocalDevicePlayback.setAutoDeviceOff(true);
         mHdmiCecLocalDevicePlayback.onStandby(false, HdmiControlService.STANDBY_SCREEN_OFF);
         mTestLooper.dispatchAll();
@@ -549,6 +647,11 @@
         assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message)).isTrue();
         mTestLooper.dispatchAll();
         assertThat(mStandby).isFalse();
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo(
+                mPlaybackPhysicalAddress);
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(
+                mPlaybackLogicalAddress);
     }
 
     @Test
@@ -560,6 +663,11 @@
         assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message)).isTrue();
         mTestLooper.dispatchAll();
         assertThat(mStandby).isFalse();
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo(
+                0x0000);
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(
+                ADDR_TV);
     }
 
     @Test
@@ -572,6 +680,7 @@
         assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message)).isTrue();
         mTestLooper.dispatchAll();
         assertThat(mStandby).isFalse();
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
     }
 
     @Test
@@ -583,6 +692,7 @@
         assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message)).isTrue();
         mTestLooper.dispatchAll();
         assertThat(mStandby).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
     }
 
     @Test
@@ -703,7 +813,7 @@
                 mPlaybackLogicalAddress, ADDR_TV);
         mTestLooper.dispatchAll();
 
-        assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
         assertThat(mNativeWrapper.getResultMessages()).containsAllOf(pressed, released);
     }
 
@@ -723,7 +833,7 @@
                 mPlaybackLogicalAddress, ADDR_AUDIO_SYSTEM);
         mTestLooper.dispatchAll();
 
-        assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
         assertThat(mNativeWrapper.getResultMessages()).containsAllOf(pressed, released);
     }
 
@@ -742,7 +852,7 @@
                 mPlaybackLogicalAddress, ADDR_TV);
         mTestLooper.dispatchAll();
 
-        assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse();
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
         assertThat(mNativeWrapper.getResultMessages()).containsAllOf(pressed, released);
     }
 
@@ -761,7 +871,7 @@
                 mPlaybackLogicalAddress, ADDR_AUDIO_SYSTEM);
         mTestLooper.dispatchAll();
 
-        assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse();
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
         assertThat(mNativeWrapper.getResultMessages()).containsAllOf(pressed, released);
     }
 
@@ -805,21 +915,28 @@
         mHdmiCecLocalDevicePlayback.dispatchMessage(setStreamPath);
         mTestLooper.dispatchAll();
 
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo(
+                mPlaybackPhysicalAddress);
         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(
                 mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress());
-        assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
     }
 
     @Test
     public void handleSetStreamPath_otherDevice_None() {
         mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
-            HdmiProperties.power_state_change_on_active_source_lost_values.NONE;
-        mHdmiCecLocalDevicePlayback.setIsActiveSource(true);
+                HdmiProperties.power_state_change_on_active_source_lost_values.NONE;
+        mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
+                mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
         mStandby = false;
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, 0x5000);
         assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(message)).isTrue();
-        assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse();
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo(
+                0x5000);
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(
+                ADDR_INVALID);
         assertThat(mStandby).isFalse();
     }
 
@@ -827,12 +944,13 @@
     public void handleSetStreamPath_otherDevice_StandbyNow() {
         mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
             HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW;
-        mHdmiCecLocalDevicePlayback.setIsActiveSource(true);
+        mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
+                mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
         mStandby = false;
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, 0x5000);
         assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(message)).isTrue();
-        assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse();
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
         assertThat(mStandby).isTrue();
     }
 
@@ -840,12 +958,13 @@
     public void handleSetStreamPath_otherDevice_StandbyNow_InactiveSource() {
         mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
             HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW;
-        mHdmiCecLocalDevicePlayback.setIsActiveSource(false);
+        mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
+                "HdmiCecLocalDevicePlaybackTest");
         mStandby = false;
         HdmiCecMessage message =
                 HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, 0x5000);
         assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(message)).isTrue();
-        assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse();
+        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
         assertThat(mStandby).isFalse();
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceBinderAPITest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceBinderAPITest.java
index 7560a34..c4068d3 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceBinderAPITest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceBinderAPITest.java
@@ -138,11 +138,6 @@
 
         mPlaybackDevice = new HdmiCecLocalDevicePlayback(mHdmiControlService) {
             @Override
-            void setIsActiveSource(boolean on) {
-                mIsActiveSource = on;
-            }
-
-            @Override
             protected void wakeUpIfActiveSource() {}
 
             @Override
@@ -186,13 +181,13 @@
             }
         });
         assertEquals(mResult, -1);
-        assertThat(mPlaybackDevice.mIsActiveSource).isFalse();
+        assertThat(mPlaybackDevice.isActiveSource()).isFalse();
 
         mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
         mTestLooper.dispatchAll();
         assertThat(mHdmiControlService.isAddressAllocated()).isTrue();
         assertEquals(mResult, HdmiControlManager.RESULT_SUCCESS);
-        assertThat(mPlaybackDevice.mIsActiveSource).isTrue();
+        assertThat(mPlaybackDevice.isActiveSource()).isTrue();
     }
 
     @Test
@@ -207,6 +202,6 @@
             }
         });
         assertEquals(mResult, HdmiControlManager.RESULT_SUCCESS);
-        assertThat(mPlaybackDevice.mIsActiveSource).isTrue();
+        assertThat(mPlaybackDevice.isActiveSource()).isTrue();
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
index 4849dd4..2f48b5e 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
@@ -405,82 +405,6 @@
         assertThat(callback2.mVolumeControlEnabled).isTrue();
     }
 
-    @Test
-    public void setActiveSource_localDevice_playback() {
-        int physicalAddress = 0x1000;
-        mNativeWrapper.setPhysicalAddress(physicalAddress);
-
-        mHdmiControlService.setActiveSource(mMyPlaybackDevice.mAddress, physicalAddress,
-                "HdmiControlServiceTest");
-
-        assertThat(mHdmiControlService.getLocalActiveSource().logicalAddress).isEqualTo(
-                mMyPlaybackDevice.mAddress);
-        assertThat(mHdmiControlService.getLocalActiveSource().physicalAddress).isEqualTo(
-                physicalAddress);
-        assertThat(mMyPlaybackDevice.mIsActiveSource).isTrue();
-        assertThat(mMyAudioSystemDevice.mIsActiveSource).isFalse();
-    }
-
-    @Test
-    public void setActiveSource_localDevice_audio() {
-        int physicalAddress = 0x1000;
-        mNativeWrapper.setPhysicalAddress(physicalAddress);
-
-        mHdmiControlService.setActiveSource(mMyAudioSystemDevice.mAddress, physicalAddress,
-                "HdmiControlServiceTest");
-
-        assertThat(mHdmiControlService.getLocalActiveSource().logicalAddress).isEqualTo(
-                mMyAudioSystemDevice.mAddress);
-        assertThat(mHdmiControlService.getLocalActiveSource().physicalAddress).isEqualTo(
-                physicalAddress);
-        assertThat(mMyPlaybackDevice.mIsActiveSource).isFalse();
-        assertThat(mMyAudioSystemDevice.mIsActiveSource).isTrue();
-    }
-
-    @Test
-    public void setActiveSource_remoteDevice() {
-        int physicalAddress = 0x1000;
-        mNativeWrapper.setPhysicalAddress(physicalAddress);
-
-        mHdmiControlService.setActiveSource(Constants.ADDR_TV, 0x0000, "HdmiControlServiceTest");
-
-        assertThat(mHdmiControlService.getLocalActiveSource().logicalAddress).isEqualTo(
-                Constants.ADDR_TV);
-        assertThat(mHdmiControlService.getLocalActiveSource().physicalAddress).isEqualTo(0x000);
-        assertThat(mMyPlaybackDevice.mIsActiveSource).isFalse();
-        assertThat(mMyAudioSystemDevice.mIsActiveSource).isFalse();
-    }
-
-    @Test
-    public void setActiveSource_nonCecDevice() {
-        int physicalAddress = 0x1000;
-        mNativeWrapper.setPhysicalAddress(physicalAddress);
-
-        mHdmiControlService.setActiveSource(Constants.ADDR_INVALID, 0x1234,
-                "HdmiControlServiceTest");
-
-        assertThat(mHdmiControlService.getLocalActiveSource().logicalAddress).isEqualTo(
-                Constants.ADDR_INVALID);
-        assertThat(mHdmiControlService.getLocalActiveSource().physicalAddress).isEqualTo(0x1234);
-        assertThat(mMyPlaybackDevice.mIsActiveSource).isFalse();
-        assertThat(mMyAudioSystemDevice.mIsActiveSource).isFalse();
-    }
-
-    @Test
-    public void setActiveSource_unknown() {
-        int physicalAddress = 0x1000;
-        mNativeWrapper.setPhysicalAddress(physicalAddress);
-
-        mHdmiControlService.setActiveSource(Constants.ADDR_INVALID,
-                Constants.INVALID_PHYSICAL_ADDRESS, "HdmiControlServiceTest");
-
-        assertThat(mHdmiControlService.getLocalActiveSource().logicalAddress).isEqualTo(
-                Constants.ADDR_INVALID);
-        assertThat(mHdmiControlService.getLocalActiveSource().physicalAddress).isEqualTo(
-                Constants.INVALID_PHYSICAL_ADDRESS);
-        assertThat(mMyPlaybackDevice.mIsActiveSource).isFalse();
-        assertThat(mMyAudioSystemDevice.mIsActiveSource).isFalse();
-    }
 
     private static class VolumeControlFeatureCallback extends
             IHdmiCecVolumeControlFeatureListener.Stub {
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java
index c734242..6be28d9 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java
@@ -150,7 +150,7 @@
 
                     @Override
                     public void setAndBroadcastActiveSourceFromOneDeviceType(
-                            int sourceAddress, int physicalAddress) {
+                            int sourceAddress, int physicalAddress, String caller) {
                         mBroadcastActiveSource = true;
                     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java b/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
index d7eedd9..d0a5644 100644
--- a/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
+++ b/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
@@ -147,13 +147,6 @@
     }
 
     @Override
-    public SurfaceControl.Transaction deferTransactionUntilSurface(SurfaceControl sc,
-            Surface barrierSurface,
-            long frameNumber) {
-        return this;
-    }
-
-    @Override
     public SurfaceControl.Transaction reparentChildren(SurfaceControl sc,
             SurfaceControl newParent) {
         return this;
diff --git a/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl b/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl
index cf2cb4a..57055f7 100644
--- a/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl
+++ b/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl
@@ -14,6 +14,6 @@
  * limitations under the License.
  */
 
-package android.net.wifi.p2p.servicediscovery;
+package android.net.wifi.p2p.nsd;
 
 parcelable WifiP2pServiceInfo;
diff --git a/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl b/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl
index d5a1e8f..e4d28bb 100644
--- a/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl
+++ b/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl
@@ -14,6 +14,6 @@
  * limitations under the License.
  */
 
-package android.net.wifi.p2p.servicediscovery;
+package android.net.wifi.p2p.nsd;
 
 parcelable WifiP2pServiceRequest;