Merge "Device always wakes up when the bouncer shows" into tm-qpr-dev
diff --git a/core/java/android/view/InsetsFrameProvider.java b/core/java/android/view/InsetsFrameProvider.java
index 9e66f54..eb8687c 100644
--- a/core/java/android/view/InsetsFrameProvider.java
+++ b/core/java/android/view/InsetsFrameProvider.java
@@ -16,10 +16,14 @@
 
 package android.view;
 
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
+
 import android.graphics.Insets;
+import android.graphics.Rect;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.util.Arrays;
 import java.util.Objects;
 
 /**
@@ -52,7 +56,9 @@
     public static final int SOURCE_FRAME = 2;
 
     private static final int HAS_INSETS_SIZE = 1;
-    private static final int HAS_IME_INSETS_SIZE = 2;
+    private static final int HAS_INSETS_SIZE_OVERRIDE = 2;
+
+    private static Rect sTmpRect = new Rect();
 
     /**
      * The type of insets to provide.
@@ -77,29 +83,25 @@
     public Insets insetsSize = null;
 
     /**
-     * The provided frame based on the source frame. The result will be used as the insets
-     * size to IME window. Only one side should be set.
+     * If null, the size set in insetsSize will be applied to all window types. If it contains
+     * element of some types, the insets reported to the window with that types will be overridden.
      */
-    public Insets imeInsetsSize = null;
+    public InsetsSizeOverride[] insetsSizeOverrides = null;
 
     public InsetsFrameProvider(int type) {
         this(type, SOURCE_FRAME, null, null);
     }
 
     public InsetsFrameProvider(int type, Insets insetsSize) {
-        this(type, SOURCE_FRAME, insetsSize, insetsSize);
-    }
-
-    public InsetsFrameProvider(int type, Insets insetsSize, Insets imeInsetsSize) {
-        this(type, SOURCE_FRAME, insetsSize, imeInsetsSize);
+        this(type, SOURCE_FRAME, insetsSize, null);
     }
 
     public InsetsFrameProvider(int type, int source, Insets insetsSize,
-            Insets imeInsetsSize) {
+            InsetsSizeOverride[] insetsSizeOverride) {
         this.type = type;
         this.source = source;
         this.insetsSize = insetsSize;
-        this.imeInsetsSize = imeInsetsSize;
+        this.insetsSizeOverrides = insetsSizeOverride;
     }
 
     @Override
@@ -127,8 +129,8 @@
         if (insetsSize != null) {
             sb.append(", insetsSize=").append(insetsSize);
         }
-        if (imeInsetsSize != null) {
-            sb.append(", imeInsetsSize=").append(imeInsetsSize);
+        if (insetsSizeOverrides != null) {
+            sb.append(", insetsSizeOverrides=").append(Arrays.toString(insetsSizeOverrides));
         }
         sb.append("}");
         return sb.toString();
@@ -141,8 +143,8 @@
         if ((insetsSizeModified & HAS_INSETS_SIZE) != 0) {
             insetsSize = Insets.CREATOR.createFromParcel(in);
         }
-        if ((insetsSizeModified & HAS_IME_INSETS_SIZE) != 0) {
-            imeInsetsSize = Insets.CREATOR.createFromParcel(in);
+        if ((insetsSizeModified & HAS_INSETS_SIZE_OVERRIDE) != 0) {
+            insetsSizeOverrides = in.createTypedArray(InsetsSizeOverride.CREATOR);
         }
     }
 
@@ -152,8 +154,8 @@
         if (insetsSize != null) {
             insetsSizeModified |= HAS_INSETS_SIZE;
         }
-        if (imeInsetsSize != null) {
-            insetsSizeModified |= HAS_IME_INSETS_SIZE;
+        if (insetsSizeOverrides != null) {
+            insetsSizeModified |= HAS_INSETS_SIZE_OVERRIDE;
         }
         out.writeInt(insetsSizeModified);
         out.writeInt(type);
@@ -161,8 +163,8 @@
         if (insetsSize != null) {
             insetsSize.writeToParcel(out, flags);
         }
-        if (imeInsetsSize != null) {
-            imeInsetsSize.writeToParcel(out, flags);
+        if (insetsSizeOverrides != null) {
+            out.writeTypedArray(insetsSizeOverrides, flags);
         }
     }
 
@@ -177,16 +179,12 @@
         InsetsFrameProvider other = (InsetsFrameProvider) o;
         return type == other.type && source == other.source
                 && Objects.equals(insetsSize, other.insetsSize)
-                && Objects.equals(imeInsetsSize, other.imeInsetsSize);
+                && Arrays.equals(insetsSizeOverrides, other.insetsSizeOverrides);
     }
 
     @Override
     public int hashCode() {
-        int result = type;
-        result = 31 * result + source;
-        result = 31 * result + (insetsSize != null ? insetsSize.hashCode() : 0);
-        result = 31 * result + (imeInsetsSize != null ? imeInsetsSize.hashCode() : 0);
-        return result;
+        return Objects.hash(type, source, insetsSize, Arrays.hashCode(insetsSizeOverrides));
     }
 
     public static final @android.annotation.NonNull Parcelable.Creator<InsetsFrameProvider>
@@ -201,5 +199,96 @@
                     return new InsetsFrameProvider[size];
                 }
             };
+
+    public static void calculateInsetsFrame(Rect displayFrame, Rect containerBounds,
+            Rect displayCutoutSafe, Rect inOutFrame, int source, Insets insetsSize,
+            @WindowManager.LayoutParams.PrivateFlags int privateFlags) {
+        boolean extendByCutout = false;
+        if (source == InsetsFrameProvider.SOURCE_DISPLAY) {
+            inOutFrame.set(displayFrame);
+        } else if (source == InsetsFrameProvider.SOURCE_CONTAINER_BOUNDS) {
+            inOutFrame.set(containerBounds);
+        } else {
+            extendByCutout = (privateFlags & PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT) != 0;
+        }
+        if (insetsSize == null) {
+            return;
+        }
+        // Only one side of the provider shall be applied. Check in the order of left - top -
+        // right - bottom, only the first non-zero value will be applied.
+        if (insetsSize.left != 0) {
+            inOutFrame.right = inOutFrame.left + insetsSize.left;
+        } else if (insetsSize.top != 0) {
+            inOutFrame.bottom = inOutFrame.top + insetsSize.top;
+        } else if (insetsSize.right != 0) {
+            inOutFrame.left = inOutFrame.right - insetsSize.right;
+        } else if (insetsSize.bottom != 0) {
+            inOutFrame.top = inOutFrame.bottom - insetsSize.bottom;
+        } else {
+            inOutFrame.setEmpty();
+        }
+
+        if (extendByCutout) {
+            WindowLayout.extendFrameByCutout(displayCutoutSafe, displayFrame, inOutFrame, sTmpRect);
+        }
+    }
+
+    /**
+     * Class to describe the insets size to be provided to window with specific window type. If not
+     * used, same insets size will be sent as instructed in the insetsSize and source.
+     */
+    public static class InsetsSizeOverride implements Parcelable {
+        public final int windowType;
+        public Insets insetsSize;
+
+        protected InsetsSizeOverride(Parcel in) {
+            windowType = in.readInt();
+            insetsSize = in.readParcelable(null, android.graphics.Insets.class);
+        }
+
+        public InsetsSizeOverride(int type, Insets size) {
+            windowType = type;
+            insetsSize = size;
+        }
+
+        public static final Creator<InsetsSizeOverride> CREATOR =
+                new Creator<InsetsSizeOverride>() {
+            @Override
+            public InsetsSizeOverride createFromParcel(Parcel in) {
+                return new InsetsSizeOverride(in);
+            }
+
+            @Override
+            public InsetsSizeOverride[] newArray(int size) {
+                return new InsetsSizeOverride[size];
+            }
+        };
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel out, int flags) {
+            out.writeInt(windowType);
+            out.writeParcelable(insetsSize, flags);
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder(32);
+            sb.append("TypedInsetsSize: {");
+            sb.append("windowType=").append(windowType);
+            sb.append(", insetsSize=").append(insetsSize);
+            sb.append("}");
+            return sb.toString();
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(windowType, insetsSize);
+        }
+    }
 }
 
diff --git a/core/java/android/view/WindowLayout.java b/core/java/android/view/WindowLayout.java
index 0941ee8..57a0330 100644
--- a/core/java/android/view/WindowLayout.java
+++ b/core/java/android/view/WindowLayout.java
@@ -274,7 +274,7 @@
         }
 
         if (extendedByCutout) {
-            extendFrameByCutout(attrs.gravity, displayCutoutSafe, outDisplayFrame, outFrame,
+            extendFrameByCutout(displayCutoutSafe, outDisplayFrame, outFrame,
                     mTempRect);
         }
 
@@ -291,7 +291,7 @@
                 + " requestedVisibilities=" + requestedVisibilities);
     }
 
-    public static void extendFrameByCutout(int gravity, Rect displayCutoutSafe,
+    public static void extendFrameByCutout(Rect displayCutoutSafe,
             Rect displayFrame, Rect inOutFrame, Rect tempRect) {
         if (displayCutoutSafe.contains(inOutFrame)) {
             return;
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index 25445ab..ac4c2ea 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -404,9 +404,10 @@
             try {
                 root.setView(view, wparams, panelParentView, userId);
             } catch (RuntimeException e) {
+                final int viewIndex = findViewLocked(view, false);
                 // BadTokenException or InvalidDisplayException, clean up.
-                if (index >= 0) {
-                    removeViewLocked(index, true);
+                if (viewIndex >= 0) {
+                    removeViewLocked(viewIndex, true);
                 }
                 throw e;
             }
diff --git a/core/jni/android_graphics_BLASTBufferQueue.cpp b/core/jni/android_graphics_BLASTBufferQueue.cpp
index 4af28ea..1520ea5 100644
--- a/core/jni/android_graphics_BLASTBufferQueue.cpp
+++ b/core/jni/android_graphics_BLASTBufferQueue.cpp
@@ -41,7 +41,12 @@
 
 static JNIEnv* getenv(JavaVM* vm) {
     JNIEnv* env;
-    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+    auto result = vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
+    if (result == JNI_EDETACHED) {
+        if (vm->AttachCurrentThreadAsDaemon(&env, nullptr) != JNI_OK) {
+            LOG_ALWAYS_FATAL("Failed to AttachCurrentThread!");
+        }
+    } else if (result != JNI_OK) {
         LOG_ALWAYS_FATAL("Failed to get JNIEnv for JavaVM: %p", vm);
     }
     return env;
@@ -60,28 +65,22 @@
     }
 
     ~TransactionHangCallbackWrapper() {
-        if (mTransactionHangObject) {
-            getenv()->DeleteGlobalRef(mTransactionHangObject);
+        if (mTransactionHangObject != nullptr) {
+            getenv(mVm)->DeleteGlobalRef(mTransactionHangObject);
             mTransactionHangObject = nullptr;
         }
     }
 
     void onTransactionHang(bool isGpuHang) {
         if (mTransactionHangObject) {
-            getenv()->CallVoidMethod(mTransactionHangObject,
-                                     gTransactionHangCallback.onTransactionHang, isGpuHang);
+            getenv(mVm)->CallVoidMethod(mTransactionHangObject,
+                                        gTransactionHangCallback.onTransactionHang, isGpuHang);
         }
     }
 
 private:
     JavaVM* mVm;
     jobject mTransactionHangObject;
-
-    JNIEnv* getenv() {
-        JNIEnv* env;
-        mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
-        return env;
-    }
 };
 
 static jlong nativeCreate(JNIEnv* env, jclass clazz, jstring jName,
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index 92ac389..505ef30 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -578,7 +578,7 @@
     optional WindowStateProto pending_control_target = 6;
     optional WindowStateProto fake_control_target = 7;
     optional .android.view.SurfaceControlProto captured_leash = 8;
-    optional .android.graphics.RectProto ime_overridden_frame = 9;
+    optional .android.graphics.RectProto ime_overridden_frame = 9 [deprecated=true];
     optional bool is_leash_ready_for_dispatching = 10;
     optional bool client_visible = 11;
     optional bool server_visible = 12;
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 6706e4e..f01e2e8 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -577,12 +577,6 @@
       "group": "WM_ERROR",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
-    "-1521427940": {
-      "message": "commitVisibility: %s: visible=%b mVisibleRequested=%b",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
     "-1517908912": {
       "message": "requestScrollCapture: caught exception dispatching to window.token=%s",
       "level": "WARN",
@@ -1513,6 +1507,12 @@
       "group": "WM_DEBUG_FOCUS_LIGHT",
       "at": "com\/android\/server\/wm\/DisplayContent.java"
     },
+    "-636553602": {
+      "message": "commitVisibility: %s: visible=%b visibleRequested=%b, isInTransition=%b, runningAnimation=%b, caller=%s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_APP_TRANSITIONS",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "-635082269": {
       "message": "******** booted=%b msg=%b haveBoot=%b haveApp=%b haveWall=%b wallEnabled=%b haveKeyguard=%b",
       "level": "INFO",
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
index 3f518c7..e0ad9cb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
@@ -23,6 +23,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 
 import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG;
+import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -541,7 +542,8 @@
             // Notify the recent tasks that a task has been removed
             mRecentTasks.ifPresent(recentTasks -> recentTasks.onTaskRemoved(taskInfo));
 
-            if (appearedInfo.getLeash() != null) {
+            if (!ENABLE_SHELL_TRANSITIONS && (appearedInfo.getLeash() != null)) {
+                // Preemptively clean up the leash only if shell transitions are not enabled
                 appearedInfo.getLeash().release();
             }
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/animation/PhysicsAnimator.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/animation/PhysicsAnimator.kt
index b483fe0..312af4f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/animation/PhysicsAnimator.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/animation/PhysicsAnimator.kt
@@ -829,8 +829,12 @@
 
     /** Cancels all in progress animations on all properties. */
     fun cancel() {
-        cancelAction(flingAnimations.keys)
-        cancelAction(springAnimations.keys)
+        if (flingAnimations.size > 0) {
+            cancelAction(flingAnimations.keys)
+        }
+        if (springAnimations.size > 0) {
+            cancelAction(springAnimations.keys)
+        }
     }
 
     /** Cancels in progress animations on the provided properties only. */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/README.txt b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/README.txt
deleted file mode 100644
index 1cd69ed..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/README.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-The dagger modules in this directory can be included by the host SysUI using the Shell library for
-explicity injection of Shell components. Apps using this library are not required to use these
-dagger modules for setup, but it is recommended for them to include them as needed.
-
-The modules are currently inherited as such:
-
-+- WMShellBaseModule (common shell features across SysUI)
-   |
-   +- WMShellModule (handheld)
-   |
-   +- TvPipModule (tv pip)
-      |
-      +- TvWMShellModule (tv)
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/README.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/README.md
new file mode 100644
index 0000000..73a7348
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/README.md
@@ -0,0 +1,18 @@
+# Window Manager Shell Readme
+
+The following docs present more detail about the implementation of the WMShell library (in no
+particular order):
+
+1) [What is the Shell](overview.md)
+2) [Integration with SystemUI & Launcher](sysui.md)
+3) [Usage of Dagger](dagger.md)
+4) [Threading model in the Shell](threading.md)
+5) [Making changes in the Shell](changes.md)
+6) [Extending the Shell for Products/OEMs](extending.md)
+7) [Debugging in the Shell](debugging.md)
+8) [Testing in the Shell](testing.md)
+
+Todo
+- Per-feature docs
+- Feature flagging
+- Best practices
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/changes.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/changes.md
new file mode 100644
index 0000000..f4e2f20
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/changes.md
@@ -0,0 +1,73 @@
+# Making changes in the Shell
+
+---
+
+## Code reviews
+
+In addition to the individual reviewers who are most familiar with the changes you are making,
+please also add [wm-code-reviewers@google.com](http://g/wm-code-reviewers) to keep other WM folks
+in the loop.
+
+## Adding new code
+
+### Internal Shell utility classes
+If the new component is used only within the WMShell library, then there are no special
+considerations, go ahead and add it (in the `com.android.wm.shell.common` package for example)
+and make sure the appropriate [unit tests](testing.md) are added.
+
+### Internal Shell components
+If the new component is to be used by other components/features within the Shell library, then
+you can create an appropriate package for this component to add your new code. The current
+pattern is to have a single `<Component name>Controller` that handles the initialization of the
+component.
+
+As mentioned in the [Dagger usage](dagger.md) docs, you need to determine whether it should go into:
+- `WMShellBaseModule` for components that other base & product components will depend on
+- or `WMShellModule`, `TvWmShellModule`, etc. for product specific components that no base
+  components depend on
+
+### SysUI accessible components
+In addition to doing the above, you will also need to provide an interface for calling to SysUI
+from the Shell and vice versa.  The current pattern is to have a parallel `Optional<Component name>`
+interface that the `<Component name>Controller` implements and handles on the main Shell thread.
+
+In addition, because components accessible to SysUI injection are explicitly listed, you'll have to
+add an appropriate method in `WMComponent` to get the interface and update the `Builder` in
+`SysUIComponent` to take the interface so it can be injected in SysUI code.  The binding between
+the two is done in `SystemUIFactory#init()` which will need to be updated as well.
+
+### Launcher accessible components
+Because Launcher is not a part of SystemUI and is a separate process, exposing controllers to
+Launcher requires a new AIDL interface to be created and implemented by the controller.  The
+implementation of the stub interface in the controller otherwise behaves similar to the interface
+to SysUI where it posts the work to the main Shell thread.
+
+### Component initialization
+To initialize the component:
+- On the Shell side, update `ShellInitImpl` to get a signal to initialize when the SysUI is started
+- On the SysUI side, update `WMShell` to setup any bindings for the component that depend on
+  SysUI code
+
+### General Do's & Dont's
+Do:
+- Do add unit tests for all new components
+- Do keep controllers simple and break them down as needed
+
+Don't:
+- **Don't** do initialization in the constructor, only do initialization in the init callbacks.
+  Otherwise it complicates the building of the dependency graph.
+- **Don't** create dependencies from base-module components on specific features (the base module
+  is intended for use with all products)
+  - Try adding a mechanism to register and listen for changes from the base module component instead
+- **Don't** add blocking synchronous calls in the SysUI interface between Shell & SysUI
+  - Try adding a push-mechanism to share data, or an async callback to request data
+
+### Exposing shared code for use in Launcher
+Launcher doesn't currently build against the Shell library, but needs to have access to some shared
+AIDL interfaces and constants.  Currently, all AIDL files, and classes under the
+`com.android.wm.shell.util` package are automatically built into the `SystemUISharedLib` that
+Launcher uses.
+
+If the new code doesn't fall into those categories, they can be added explicitly in the Shell's
+[Android.bp](frameworks/base/libs/WindowManager/Shell/Android.bp) file under the
+`wm_shell_util-sources` filegroup.
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/dagger.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/dagger.md
new file mode 100644
index 0000000..6c01d96
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/dagger.md
@@ -0,0 +1,50 @@
+# Usage of Dagger in the Shell library
+
+---
+
+## Dependencies
+
+Dagger is not required to use the Shell library, but it has a lot of obvious benefits:
+
+- Not having to worry about how to instantiate all the dependencies of a class, especially as
+  dependencies evolve (ie. product controller depends on base controller)
+- Can create boundaries within the same app to encourage better code modularity
+
+As such, the Shell also tries to provide some reasonable out-of-the-box modules for use with Dagger.
+
+## Modules
+
+All the Dagger related code in the Shell can be found in the `com.android.wm.shell.dagger` package,
+this is intentional as it keeps the "magic" in a single location.  The explicit nature of how
+components in the shell are provided is as a result a bit more verbose, but it makes it easy for
+developers to jump into a few select files and understand how different components are provided
+(especially as products override components).
+
+The module dependency tree looks a bit like:
+- [WMShellConcurrencyModule](frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellConcurrencyModule.java)
+  (provides threading-related components)
+  - [WMShellBaseModule](frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java)
+    (provides components that are likely common to all products, ie. DisplayController,
+    Transactions, etc.)
+    - [WMShellModule](frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java)
+      (phone/tablet specific components only)
+    - [TvPipModule](frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java)
+      (PIP specific components for TV)
+      - [TvWMShellModule](frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvWMShellModule.java)
+        (TV specific components only)
+  - etc.
+
+Ideally features could be abstracted out into their own modules and included as needed by each
+product.
+
+## Overriding base components
+
+In some rare cases, there are base components that can change behavior depending on which
+product it runs on.  If there are hooks that can be added to the component, that is the
+preferable approach.
+
+The alternative is to use the [@DynamicOverride](frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/DynamicOverride.java)
+annotation to allow the product module to provide an implementation that the base module can
+reference.  This is most useful if the existence of the entire component is controlled by the
+product and the override implementation is optional (there is a default implementation).  More
+details can be found in the class's javadoc.
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/debugging.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/debugging.md
new file mode 100644
index 0000000..52f0c42
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/debugging.md
@@ -0,0 +1,69 @@
+# Debugging in the Shell
+
+---
+
+## Logging & ProtoLogs
+
+The interactions in the Shell can be pretty complicated, so having good logging is crucial to
+debugging problems that arise (especially in dogfood).  The Shell uses the same efficient Protolog
+mechanism as WM Core, which can be enabled at runtime on debug devices.
+
+**TLDR**&nbsp; Don’t use Logs or Slogs except for error cases, Protologs are much more flexible,
+easy to add and easy to use
+
+### Adding a new ProtoLog
+Update `ShellProtoLogGroup` to include a new log group (ie. NEW_FEATURE) for the content you want to
+log.  ProtoLog log calls mirror Log.v/d/e(), and take a format message and arguments:
+```java
+ProtoLog.v(NEW_FEATURE, "Test log w/ params: %d %s", 1, “a”)
+```
+This code itself will not compile by itself, but the `protologtool` will preprocess the file when
+building to check the log state (is enabled) before printing the print format style log.
+
+**Notes**
+- ProtoLogs currently only work from soong builds (ie. via make/mp). We need to reimplement the
+  tool for use with SysUI-studio
+- Non-text ProtoLogs are not currently supported with the Shell library (you can't view them with
+  traces in Winscope)
+
+### Enabling ProtoLog command line logging
+Run these commands to enable protologs for both WM Core and WM Shell to print to logcat.
+```shell
+adb shell wm logging enable-text NEW_FEATURE
+adb shell wm logging disable-text NEW_FEATURE
+```
+
+## Winscope Tracing
+
+The Winscope tool is extremely useful in determining what is happening on-screen in both
+WindowManager and SurfaceFlinger.  Follow [go/winscope](http://go/winscope-help) to learn how to
+use the tool.
+
+In addition, there is limited preliminary support for Winscope tracing componetns in the Shell,
+which involves adding trace fields to [wm_shell_trace.proto](frameworks/base/libs/WindowManager/Shell/proto/wm_shell_trace.proto)
+file and ensure it is updated as a part of `WMShell#writeToProto`.
+
+Tracing can be started via the shell command (to be added to the Winscope tool as needed):
+```shell
+adb shell cmd statusbar tracing start
+adb shell cmd statusbar tracing stop
+```
+
+## Dumps
+
+Because the Shell library is built as a part of SystemUI, dumping the state is currently done as a
+part of dumping the SystemUI service.  Dumping the Shell specific data can be done by specifying the
+WMShell SysUI service:
+
+```shell
+adb shell dumpsys activity service SystemUIService WMShell
+```
+
+If information should be added to the dump, make updates to:
+- `WMShell` if you are dumping SysUI state
+- `ShellCommandHandler` if you are dumping Shell state
+
+## Debugging in Android Studio
+
+If you are using the [go/sysui-studio](http://go/sysui-studio) project, then you can debug Shell
+code directly from Android Studio like any other app.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/extending.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/extending.md
new file mode 100644
index 0000000..061ae00e
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/extending.md
@@ -0,0 +1,13 @@
+# Extending the Shell for Products/OEMs
+
+---
+
+## General Do's & Dont's
+
+Do:
+- &nbsp;
+
+Don't
+- **Don't** override classes provided by WMShellBaseModule, it makes it difficult to make
+  simple changes to the Shell library base modules which are shared by all products
+  - If possible add mechanisms to modify the base class behavior
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/overview.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/overview.md
new file mode 100644
index 0000000..a88ef6a
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/overview.md
@@ -0,0 +1,58 @@
+# What is the WindowManager Shell
+
+---
+
+## Motivation
+
+The primary motivation for the WindowManager Shell (WMShell) library is to effectively scale
+WindowManager by making it easy&trade; and safe to create windowing features to fit the needs of
+various Android products and form factors.
+
+To achieve this, WindowManager separates the policy of managing windows (WMCore) from the
+presentation of surfaces (WMShell) and provides a minimal interface boundary for the two to
+communicate.
+
+## Who is using the library?
+
+Currently, the WMShell library is used to drive the windowing experience on handheld
+(phones & tablets), TV, Auto, Arc++, and Wear to varying degrees.
+
+## Where does the code live
+
+The core WMShell library code is currently located in the [frameworks/base/libs/WindowManager/Shell](frameworks/base/libs/WindowManager/Shell)
+directory and is included as a part dependency of the host SystemUI apk.
+
+## How do I build the Shell library
+
+The library can be built directly by running (using [go/makepush](http://go/makepush)):
+```shell
+mp :WindowManager-Shell
+```
+But this is mainly useful for inspecting the contents of the library or verifying it builds. The
+various targets can be found in the Shell library's [Android.bp](frameworks/base/libs/WindowManager/Shell/Android.bp)
+file.
+
+Normally, you would build it as a part of the host SystemUI, for example via commandline:
+```shell
+# Phone SystemUI variant
+mp sysuig
+# Building Shell & SysUI changes along w/ framework changes
+mp core services sysuig
+```
+
+Or preferably, if you are making WMShell/SysUI only changes (no other framework changes), then
+building via [go/sysui-studio](http://go/sysui-studio) allows for very quick iteration (one click
+build and push of SysUI in < 30s).
+
+If you are making framework changes and are using `aidegen` to set up your platform IDE, make sure
+to include the appropriate directories to build, for example:
+```shell
+# frameworks/base will include base/libs/WindowManager/Shell and base/packages/SystemUI
+aidegen frameworks/base \
+    vendor/<oem>/packages/SystemUI \
+    ...
+```
+
+## Other useful links
+- [go/o-o-summit-20](go/o-o-summit-20) (Video presentations from the WM team)
+- [go/o-o-summit-21](go/o-o-summit-21)
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/sysui.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/sysui.md
new file mode 100644
index 0000000..68f970f
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/sysui.md
@@ -0,0 +1,55 @@
+# Shell & SystemUI
+
+---
+
+## Setup
+
+The SystemUI of various products depend on and build against the WM Shell library. To ensure
+that we don't inadvertently build dependencies between the Shell library and one particular
+product (ie. handheld SysUI), we deliberately separate the initialization of the WM Shell
+component from the SysUI component when set up through Dagger.
+
+**TLDR**&nbsp; Initialize everything as needed in the WM component scope and export only well
+defined interfaces to SysUI.
+
+## Initialization
+
+There are more details in the Dagger docs, but the general overview of the SysUI/Shell
+initialization flow is such:
+
+1) SysUI Global scope is initialize (see `GlobalModule` and its included modules)
+2) WM Shell scope is initialized, for example
+   1) On phones: `WMComponent` includes `WMShellModule` which includes `WMShellBaseModule`
+      (common to all SysUI)
+   2) On TVs: `TvWMComponent` includes `TvWMShellModule` which includes `WMShellBaseModule`
+   3) etc.
+3) SysUI explicitly passes interfaces provided from the `WMComponent` to `SysUIComponent` via
+   the `SysUIComponent#Builder`, then builds the SysUI scoped components
+4) `WMShell` is the SystemUI “service” (in the SysUI scope) that initializes with the app after the
+SystemUI part of the dependency graph has been created. It contains the binding code between the
+interfaces provided by the Shell and the rest of SystemUI.
+5) SysUI can inject the interfaces into its own components
+
+More detail can be found in [go/wm-sysui-dagger](http://go/wm-sysui-dagger).
+
+## Interfaces to Shell components
+
+Within the same process, the WM Shell components can be running on a different thread than the main
+SysUI thread (disabled on certain products).  This introduces challenges where we have to be
+careful about how SysUI calls into the Shell and vice versa.
+
+As a result, we enforce explicit interfaces between SysUI and Shell components, and the
+implementations of the interfaces on each side need to post to the right thread before it calls
+into other code.
+
+For example, you might have:
+1) (Shell) ShellFeature interface to be used from SysUI
+2) (Shell) ShellFeatureController handles logic, implements ShellFeature interface and posts to
+   main Shell thread
+3) SysUI application init injects Optional<ShellFeature> as an interface to SysUI to call
+4) (SysUI) SysUIFeature depends on ShellFeature interface
+5) (SysUI) SysUIFeature injects Optional<ShellFeature>, and sets up a callback for the Shell to
+   call, and the callback posts to the main SysUI thread
+
+Adding an interface to a Shell component may seem like a lot of boiler plate, but is currently
+necessary to maintain proper threading and logic isolation.
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/testing.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/testing.md
new file mode 100644
index 0000000..8a80333
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/testing.md
@@ -0,0 +1,49 @@
+# Testing
+
+---
+
+## Unit tests
+
+New WM Shell unit tests can be added to the
+[Shell/tests/unittest](frameworks/base/libs/WindowManager/Shell/tests/unittest) directory, and can
+be run via command line using `atest`:
+```shell
+atest WMShellUnitTests
+```
+
+If you use the SysUI Studio project, you can run and debug tests directly in the source files
+(click on the little arrows next to the test class or test method).
+
+These unit tests are run as a part of WindowManager presubmit, and the dashboards for these unit
+tests tests can be found at [go/wm-tests](http://go/wm-tests).
+
+This [GCL file](http://go/wm-unit-tests-gcl) configures the tests being run on the server.
+
+## Flicker tests
+
+Flicker tests are tests that perform actions and make assertions on the state in Window Manager
+and SurfaceFlinger traces captured during the run.
+
+New WM Shell Flicker tests can be added to the
+[Shell/tests/flicker](frameworks/base/libs/WindowManager/Shell/tests/flicker) directory, and can
+be run via command line using `atest`:
+```shell
+atest WMShellFlickerTests
+```
+
+**Note**: Currently Flicker tests can only be run from the commandline and not via SysUI Studio
+
+A subset of the flicker tests tests are run as a part of WindowManager presubmit, and the
+dashboards for these tests tests can be found at [go/wm-tests-flicker](http://go/wm-tests-flicker).
+
+## CTS tests
+
+Some windowing features also have CTS tests to ensure consistent behavior across OEMs.  For example:
+- Picture-in-Picture:
+  [PinnedStackTests](cts/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java)
+- etc.
+
+These can also be run via commandline only using `atest`, for example:
+```shell
+atest PinnedStackTests
+```
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/threading.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/threading.md
new file mode 100644
index 0000000..eac74889
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/threading.md
@@ -0,0 +1,83 @@
+# Threading
+
+---
+
+## Boundaries
+
+```text
+                                    Thread boundary
+                                          |
+                                WM Shell  | SystemUI
+                                          |
+                                          |
+FeatureController <-> FeatureInterface <--|--> WMShell <-> SysUI
+       |          (^post to shell thread) |            (^post to main thread)
+      ...                                 |
+       |                                  |
+ OtherControllers                         |
+```
+
+## Threads
+
+We currently have multiple threads in use in the Shell library depending on the configuration by
+the product.
+- SysUI main thread (standard main thread)
+- `ShellMainThread` (only used if the resource `config_enableShellMainThread` is set true
+  (ie. phones))
+  - This falls back to the SysUI main thread otherwise
+  - **Note**:
+    - This thread runs with `THREAD_PRIORITY_DISPLAY` priority since so many windowing-critical
+      components depend on it
+    - This is also the UI thread for almost all UI created by the Shell
+    - The Shell main thread Handler (and the Executor that wraps it) is async, so
+      messages/runnables used via this Handler are handled immediately if there is no sync
+      messages prior to it in the queue.
+- `ShellBackgroundThread` (for longer running tasks where we don't want to block the shell main
+  thread)
+  - This is always another thread even if config_enableShellMainThread is not set true
+  - **Note**:
+    - This thread runs with `THREAD_PRIORITY_BACKGROUND` priority
+- `ShellAnimationThread` (currently only used for Transitions and Splitscreen, but potentially all
+  animations could be offloaded here)
+- `ShellSplashScreenThread` (only for use with splashscreens)
+
+## Dagger setup
+
+The threading-related components are provided by the [WMShellConcurrencyModule](frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellConcurrencyModule.java),
+for example, the Executors and Handlers for the various threads that are used.  You can request
+an executor of the necessary type by using the appropriate annotation for each of the threads (ie.
+`@ShellMainThread Executor`) when injecting into your Shell component.
+
+To get the SysUI main thread, you can use the `@Main` annotation.
+
+## Best practices
+
+### Components
+- Don't do initialization in the Shell component constructors
+  - If the host SysUI is not careful, it may construct the WMComponent dependencies on the main
+    thread, and this reduces the likelihood that components will intiailize on the wrong thread
+    in such cases
+- Be careful of using CountDownLatch and other blocking synchronization mechanisms in Shell code
+  - If the Shell main thread is not a separate thread, this will cause a deadlock
+- Callbacks, Observers, Listeners to any non-shell component should post onto main Shell thread
+  - This includes Binder calls, SysUI calls, BroadcastReceivers, etc. Basically any API that
+    takes a runnable should either be registered with the right Executor/Handler or posted to
+    the main Shell thread manually
+- Since everything in the Shell runs on the main Shell thread, you do **not** need to explicitly
+  `synchronize` your code (unless you are trying to prevent reentrantcy, but that can also be
+  done in other ways)
+
+### Handlers/Executors
+- You generally **never** need to create Handlers explicitly, instead inject `@ShellMainThread
+  ShellExecutor` instead
+  - This is a common pattern to defer logic in UI code, but the Handler created wraps the Looper
+    that is currently running, which can be wrong (see above for initialization vs construction)
+- That said, sometimes Handlers are necessary because Framework API only takes Handlers or you
+  want to dedupe multiple messages
+  - In such cases inject `@ShellMainThread Handler` or use view.getHandler() which should be OK
+    assuming that the view root was initialized on the main Shell thread
+- **Never use Looper.getMainLooper()**
+  - It's likely going to be wrong, you can inject `@Main ShellExecutor` to get the SysUI main thread
+
+### Testing
+- You can use a `TestShellExecutor` to control the processing of messages
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
index f1e2323..3dd0032 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
@@ -26,11 +26,13 @@
 import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCREEN;
 import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_MULTI_WINDOW;
 import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_PIP;
+import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.mock;
@@ -146,6 +148,7 @@
 
     @Test
     public void testTaskLeashReleasedAfterVanished() throws RemoteException {
+        assumeFalse(ENABLE_SHELL_TRANSITIONS);
         RunningTaskInfo taskInfo = createTaskInfo(1, WINDOWING_MODE_MULTI_WINDOW);
         SurfaceControl taskLeash = new SurfaceControl.Builder(new SurfaceSession())
                 .setName("task").build();
diff --git a/packages/SystemUI/res/drawable/qs_battery_saver_icon_off.xml b/packages/SystemUI/res/drawable/qs_battery_saver_icon_off.xml
new file mode 100644
index 0000000..7b9f23d
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_battery_saver_icon_off.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 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.
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="183"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_0_G_D_0_P_0"
+                        android:pathData=" M3.67 -8 C3.67,-8 2,-8 2,-8 C2,-8 2,-10 2,-10 C2,-10 -2,-10 -2,-10 C-2,-10 -2,-8 -2,-8 C-2,-8 -3.67,-8 -3.67,-8 C-4.4,-8 -5,-7.4 -5,-6.67 C-5,-6.67 -5,8.66 -5,8.66 C-5,9.4 -4.4,10 -3.67,10 C-3.67,10 3.66,10 3.66,10 C4.4,10 5,9.4 5,8.67 C5,8.67 5,-6.67 5,-6.67 C5,-7.4 4.4,-8 3.67,-8c "
+                        android:strokeAlpha="1"
+                        android:strokeColor="#ffffff"
+                        android:strokeLineCap="round"
+                        android:strokeLineJoin="round"
+                        android:strokeWidth="2" />
+                    <path
+                        android:name="_R_G_L_0_G_D_1_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M2 -10 C2,-10 2,-7 2,-7 C2,-7 -2,-7 -2,-7 C-2,-7 -2,-10 -2,-10 C-2,-10 2,-10 2,-10c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_2_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M3 2 C3,2 1,2 1,2 C1,2 1,4 1,4 C1,4 -1,4 -1,4 C-1,4 -1,2 -1,2 C-1,2 -3,2 -3,2 C-3,2 -3,0 -3,0 C-3,0 -1,0 -1,0 C-1,0 -1,-2 -1,-2 C-1,-2 1,-2 1,-2 C1,-2 1,0 1,0 C1,0 3,0 3,0 C3,0 3,2 3,2c " />
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_battery_saver_icon_on.xml b/packages/SystemUI/res/drawable/qs_battery_saver_icon_on.xml
new file mode 100644
index 0000000..5e4af39
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_battery_saver_icon_on.xml
@@ -0,0 +1,636 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 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.
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_4_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="317"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="0"
+                    android:valueFrom="1"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="83"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="317"
+                    android:valueFrom="1"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_4_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="417"
+                    android:pathData="M 0,0.875C 0,-0.9690000000000001 0,-8.344000000000001 0,-10.188"
+                    android:propertyName="translateXY"
+                    android:propertyXName="translateX"
+                    android:propertyYName="translateY"
+                    android:startOffset="0">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c1,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_4_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="417"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="112"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c1,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_3_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="250"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="83"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="250"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="217"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="333"
+                    android:valueFrom="1"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="83"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="550"
+                    android:valueFrom="1"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_3_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="83"
+                    android:pathData="M -0.875,9C -0.854,6.156000000000001 -0.896,11.844 -0.875,9"
+                    android:propertyName="translateXY"
+                    android:propertyXName="translateX"
+                    android:propertyYName="translateY"
+                    android:startOffset="0">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="550"
+                    android:pathData="M -0.875,9C -0.854,6.156000000000001 -0.771,-5.218 -0.75,-8.062"
+                    android:propertyName="translateXY"
+                    android:propertyXName="translateX"
+                    android:propertyYName="translateY"
+                    android:startOffset="83">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_3_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="83"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="67"
+                    android:valueTo="67"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="550"
+                    android:propertyName="rotation"
+                    android:startOffset="83"
+                    android:valueFrom="67"
+                    android:valueTo="192"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_2_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="417"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="83"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="417"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="267"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="500"
+                    android:valueFrom="1"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="83"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="767"
+                    android:valueFrom="1"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_2_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="250"
+                    android:pathData="M 2.125,9.375C 2.146,6.468999999999999 2.104,12.281 2.125,9.375"
+                    android:propertyName="translateXY"
+                    android:propertyXName="translateX"
+                    android:propertyYName="translateY"
+                    android:startOffset="0">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="600"
+                    android:pathData="M 2.125,9.375C 2.146,6.468999999999999 2.229,-5.155999999999999 2.25,-8.062"
+                    android:propertyName="translateXY"
+                    android:propertyXName="translateX"
+                    android:propertyYName="translateY"
+                    android:startOffset="250">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_2_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="250"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="28"
+                    android:valueTo="28"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="600"
+                    android:propertyName="rotation"
+                    android:startOffset="250"
+                    android:valueFrom="28"
+                    android:valueTo="153"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_1_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="533"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="83"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="533"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="250"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="617"
+                    android:valueFrom="1"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="83"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="867"
+                    android:valueFrom="1"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_1_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="350"
+                    android:pathData="M -2,10C -2,6.99 -2,13.01 -2,10"
+                    android:propertyName="translateXY"
+                    android:propertyXName="translateX"
+                    android:propertyYName="translateY"
+                    android:startOffset="0">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="600"
+                    android:pathData="M -2,10C -2,6.99 -2,-5.052 -2,-8.062"
+                    android:propertyName="translateXY"
+                    android:propertyXName="translateX"
+                    android:propertyYName="translateY"
+                    android:startOffset="350">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_1_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="350"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="28"
+                    android:valueTo="28"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="600"
+                    android:propertyName="rotation"
+                    android:startOffset="350"
+                    android:valueFrom="28"
+                    android:valueTo="153"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="883"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="83"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="883"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="667"
+                    android:pathData="M 0,11.5C 0,9.729 0,13.271 0,11.5"
+                    android:propertyName="translateXY"
+                    android:propertyXName="translateX"
+                    android:propertyYName="translateY"
+                    android:startOffset="0">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="667"
+                    android:pathData="M 0,11.5C 0,9.729 0,2.646 0,0.875"
+                    android:propertyName="translateXY"
+                    android:propertyXName="translateX"
+                    android:propertyYName="translateY"
+                    android:startOffset="667">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="667"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="-48"
+                    android:valueTo="-48"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="667"
+                    android:propertyName="rotation"
+                    android:startOffset="667"
+                    android:valueFrom="-48"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="1350"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_5_G"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_5_G_D_0_P_0"
+                        android:pathData=" M3.67 -8 C3.67,-8 2,-8 2,-8 C2,-8 2,-10 2,-10 C2,-10 -2,-10 -2,-10 C-2,-10 -2,-8 -2,-8 C-2,-8 -3.67,-8 -3.67,-8 C-4.4,-8 -5,-7.4 -5,-6.67 C-5,-6.67 -5,8.66 -5,8.66 C-5,9.4 -4.4,10 -3.67,10 C-3.67,10 3.66,10 3.66,10 C4.4,10 5,9.4 5,8.67 C5,8.67 5,-6.67 5,-6.67 C5,-7.4 4.4,-8 3.67,-8c "
+                        android:strokeAlpha="1"
+                        android:strokeColor="#ffffff"
+                        android:strokeLineCap="round"
+                        android:strokeLineJoin="round"
+                        android:strokeWidth="2" />
+                    <path
+                        android:name="_R_G_L_5_G_D_1_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M2 -10 C2,-10 2,-7 2,-7 C2,-7 -2,-7 -2,-7 C-2,-7 -2,-10 -2,-10 C-2,-10 2,-10 2,-10c " />
+                </group>
+                <group
+                    android:name="_R_G_L_4_G_N_6_T_0"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <group
+                        android:name="_R_G_L_4_G_T_1"
+                        android:rotation="0"
+                        android:translateX="0"
+                        android:translateY="0.875">
+                        <group
+                            android:name="_R_G_L_4_G"
+                            android:translateY="-0.875">
+                            <path
+                                android:name="_R_G_L_4_G_D_0_P_0"
+                                android:fillAlpha="1"
+                                android:fillColor="#ffffff"
+                                android:fillType="nonZero"
+                                android:pathData=" M3 2 C3,2 1,2 1,2 C1,2 1,4 1,4 C1,4 -1,4 -1,4 C-1,4 -1,2 -1,2 C-1,2 -3,2 -3,2 C-3,2 -3,0 -3,0 C-3,0 -1,0 -1,0 C-1,0 -1,-2 -1,-2 C-1,-2 1,-2 1,-2 C1,-2 1,0 1,0 C1,0 3,0 3,0 C3,0 3,2 3,2c " />
+                        </group>
+                    </group>
+                </group>
+                <group
+                    android:name="_R_G_L_3_G_N_6_T_0"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <group
+                        android:name="_R_G_L_3_G_T_1"
+                        android:rotation="67"
+                        android:scaleX="0.7"
+                        android:scaleY="0.7"
+                        android:translateX="-0.875"
+                        android:translateY="9">
+                        <group
+                            android:name="_R_G_L_3_G"
+                            android:translateY="-0.875">
+                            <path
+                                android:name="_R_G_L_3_G_D_0_P_0"
+                                android:fillAlpha="0"
+                                android:fillColor="#ffffff"
+                                android:fillType="nonZero"
+                                android:pathData=" M3 2 C3,2 1,2 1,2 C1,2 1,4 1,4 C1,4 -1,4 -1,4 C-1,4 -1,2 -1,2 C-1,2 -3,2 -3,2 C-3,2 -3,0 -3,0 C-3,0 -1,0 -1,0 C-1,0 -1,-2 -1,-2 C-1,-2 1,-2 1,-2 C1,-2 1,0 1,0 C1,0 3,0 3,0 C3,0 3,2 3,2c " />
+                        </group>
+                    </group>
+                </group>
+                <group
+                    android:name="_R_G_L_2_G_N_6_T_0"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <group
+                        android:name="_R_G_L_2_G_T_1"
+                        android:rotation="28"
+                        android:scaleX="0.85"
+                        android:scaleY="0.85"
+                        android:translateX="2.125"
+                        android:translateY="9.375">
+                        <group
+                            android:name="_R_G_L_2_G"
+                            android:translateY="-0.875">
+                            <path
+                                android:name="_R_G_L_2_G_D_0_P_0"
+                                android:fillAlpha="0"
+                                android:fillColor="#ffffff"
+                                android:fillType="nonZero"
+                                android:pathData=" M3 2 C3,2 1,2 1,2 C1,2 1,4 1,4 C1,4 -1,4 -1,4 C-1,4 -1,2 -1,2 C-1,2 -3,2 -3,2 C-3,2 -3,0 -3,0 C-3,0 -1,0 -1,0 C-1,0 -1,-2 -1,-2 C-1,-2 1,-2 1,-2 C1,-2 1,0 1,0 C1,0 3,0 3,0 C3,0 3,2 3,2c " />
+                        </group>
+                    </group>
+                </group>
+                <group
+                    android:name="_R_G_L_1_G_N_6_T_0"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <group
+                        android:name="_R_G_L_1_G_T_1"
+                        android:rotation="28"
+                        android:scaleX="0.55"
+                        android:scaleY="0.55"
+                        android:translateX="-2"
+                        android:translateY="10">
+                        <group
+                            android:name="_R_G_L_1_G"
+                            android:translateY="-0.875">
+                            <path
+                                android:name="_R_G_L_1_G_D_0_P_0"
+                                android:fillAlpha="0"
+                                android:fillColor="#ffffff"
+                                android:fillType="nonZero"
+                                android:pathData=" M3 2 C3,2 1,2 1,2 C1,2 1,4 1,4 C1,4 -1,4 -1,4 C-1,4 -1,2 -1,2 C-1,2 -3,2 -3,2 C-3,2 -3,0 -3,0 C-3,0 -1,0 -1,0 C-1,0 -1,-2 -1,-2 C-1,-2 1,-2 1,-2 C1,-2 1,0 1,0 C1,0 3,0 3,0 C3,0 3,2 3,2c " />
+                        </group>
+                    </group>
+                </group>
+                <group
+                    android:name="_R_G_L_0_G_N_6_T_0"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <group
+                        android:name="_R_G_L_0_G_T_1"
+                        android:rotation="-48"
+                        android:translateX="0"
+                        android:translateY="11.5">
+                        <group
+                            android:name="_R_G_L_0_G"
+                            android:translateY="-0.875">
+                            <path
+                                android:name="_R_G_L_0_G_D_0_P_0"
+                                android:fillAlpha="0"
+                                android:fillColor="#ffffff"
+                                android:fillType="nonZero"
+                                android:pathData=" M3 2 C3,2 1,2 1,2 C1,2 1,4 1,4 C1,4 -1,4 -1,4 C-1,4 -1,2 -1,2 C-1,2 -3,2 -3,2 C-3,2 -3,0 -3,0 C-3,0 -1,0 -1,0 C-1,0 -1,-2 -1,-2 C-1,-2 1,-2 1,-2 C1,-2 1,0 1,0 C1,0 3,0 3,0 C3,0 3,2 3,2c " />
+                        </group>
+                    </group>
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_mic_access_off.xml b/packages/SystemUI/res/drawable/qs_mic_access_off.xml
new file mode 100644
index 0000000..63a9444
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_mic_access_off.xml
@@ -0,0 +1,212 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 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
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_0_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="167"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M5.05 4.43 C3.98,5.25 3.08,5.53 2.53,5.73 C2.26,5.81 1.98,5.87 1.7,5.9 C1.7,5.9 1.7,9 1.7,9 C1.7,9 -0.3,9 -0.3,9 C-0.3,9 -0.3,5.9 -0.3,5.9 C-2.02,5.65 -3.44,4.88 -4.59,3.59 C-5.73,2.3 -6.3,0.77 -6.3,-1 C-6.3,-1 -4.3,-1 -4.3,-1 C-4.3,0.38 -3.81,1.56 -2.84,2.54 C-1.86,3.51 -0.68,4 0.7,4 C0.88,4 1.06,3.99 1.23,3.96 C1.39,3.94 2.58,3.77 3.61,2.99 C3.61,2.99 5.05,4.43 5.05,4.43c "
+                    android:valueTo="M5.02 4.5 C3.59,5.47 2.79,5.64 2.53,5.73 C2.26,5.81 1.98,5.87 1.7,5.9 C1.7,5.9 1.7,9 1.7,9 C1.7,9 -0.3,9 -0.3,9 C-0.3,9 -0.3,5.9 -0.3,5.9 C-2.02,5.65 -3.44,4.88 -4.59,3.59 C-5.73,2.3 -6.3,0.77 -6.3,-1 C-6.3,-1 -4.3,-1 -4.3,-1 C-4.3,0.38 -3.81,1.56 -2.84,2.54 C-1.86,3.51 -0.68,4 0.7,4 C0.88,4 1.06,3.99 1.23,3.96 C1.39,3.94 2.53,3.83 3.58,3.07 C3.58,3.07 5.02,4.5 5.02,4.5c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_1_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="44"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M2.31 1.86 C2.31,1.86 1.01,0.55 0.75,0.31 C1.7,0.27 1.7,-0.7 1.7,-0.7 C1.7,-0.7 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-0.66 -0.29,-0.66 C-0.29,-0.66 -2.31,-2.67 -2.31,-2.67 C-2.31,-2.67 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.7,-0.33 3.64,-0.03 C3.51,0.52 3.23,1.19 2.31,1.86c "
+                    android:valueTo="M2.86 1.48 C2.86,1.48 1.58,0.21 1.39,0.03 C1.77,-0.26 1.7,-1.03 1.7,-1.03 C1.7,-1.03 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-1.51 -0.29,-1.51 C-0.29,-1.51 -2.31,-3.5 -2.31,-3.5 C-2.31,-3.5 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.68,-0.44 3.65,-0.17 C3.61,0.19 3.36,1.05 2.86,1.48c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="39"
+                    android:propertyName="pathData"
+                    android:startOffset="44"
+                    android:valueFrom="M2.86 1.48 C2.86,1.48 1.58,0.21 1.39,0.03 C1.77,-0.26 1.7,-1.03 1.7,-1.03 C1.7,-1.03 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-1.51 -0.29,-1.51 C-0.29,-1.51 -2.31,-3.5 -2.31,-3.5 C-2.31,-3.5 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.68,-0.44 3.65,-0.17 C3.61,0.19 3.36,1.05 2.86,1.48c "
+                    android:valueTo="M3.12 0.99 C3.12,0.99 1.83,-0.26 1.71,-0.38 C1.72,-0.81 1.7,-1.31 1.7,-1.31 C1.7,-1.31 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-2.26 -0.29,-2.26 C-0.29,-2.26 -2.31,-4.23 -2.31,-4.23 C-2.31,-4.23 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.67,-0.54 3.66,-0.3 C3.63,0.12 3.38,0.7 3.12,0.99c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="83"
+                    android:propertyName="pathData"
+                    android:startOffset="83"
+                    android:valueFrom="M3.12 0.99 C3.12,0.99 1.83,-0.26 1.71,-0.38 C1.72,-0.81 1.7,-1.31 1.7,-1.31 C1.7,-1.31 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-2.26 -0.29,-2.26 C-0.29,-2.26 -2.31,-4.23 -2.31,-4.23 C-2.31,-4.23 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.67,-0.54 3.66,-0.3 C3.63,0.12 3.38,0.7 3.12,0.99c "
+                    android:valueTo="M3.5 -0.05 C3.5,-0.05 1.7,-1.85 1.7,-1.85 C1.7,-1.85 1.7,-1.92 1.7,-1.92 C1.7,-1.92 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.3,-3.85 -0.3,-3.85 C-0.3,-3.85 -2.3,-5.85 -2.3,-5.85 C-2.3,-5.85 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.68,-0.65 3.64,-0.5 C3.6,-0.35 3.55,-0.2 3.5,-0.05c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_2_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="167"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M5.04 4.45 C5.04,4.45 3.59,3.02 3.59,3.02 C4.82,1.94 5.31,0.96 5.53,0.3 C5.64,-0.12 5.7,-0.55 5.7,-1 C5.7,-1 7.7,-1 7.7,-1 C7.7,-0.27 7.59,0.43 7.38,1.09 C7.16,1.75 6.51,3.17 5.04,4.45c "
+                    android:valueTo="M6.45 2.95 C6.45,2.95 5,1.5 5,1.5 C5.23,1.12 5.41,0.72 5.53,0.3 C5.64,-0.12 5.7,-0.55 5.7,-1 C5.7,-1 7.7,-1 7.7,-1 C7.7,-0.27 7.59,0.43 7.38,1.09 C7.16,1.75 6.85,2.37 6.45,2.95c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_3_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="67"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M-0.29 -0.71 C-0.29,-0.42 -0.19,-0.19 0,0.01 C0.19,0.2 0.43,0.29 0.71,0.29 C0.76,0.31 0.75,0.31 0.78,0.3 C1.14,0.67 1.92,1.43 2.34,1.85 C2.03,2.04 1.55,2.29 0.71,2.29 C0.55,2.29 0.39,2.28 0.23,2.26 C-0.4,2.17 -0.94,1.89 -1.41,1.42 C-1.89,0.94 -2.18,0.37 -2.26,-0.28 C-2.28,-0.42 -2.29,-0.56 -2.29,-0.71 C-2.29,-0.71 -2.31,-2.72 -2.31,-2.72 C-2.31,-2.72 -0.29,-0.71 -0.29,-0.71c "
+                    android:valueTo="M-0.29 -0.71 C-0.29,-0.42 -0.19,-0.19 0,0.01 C0.19,0.2 0.43,0.29 0.71,0.29 C0.76,0.31 0.75,0.31 0.78,0.3 C1.14,0.67 1.92,1.43 2.34,1.85 C2.03,2.04 1.55,2.29 0.71,2.29 C0.55,2.29 0.39,2.28 0.23,2.26 C-0.4,2.17 -0.94,1.89 -1.41,1.42 C-1.89,0.94 -2.18,0.37 -2.26,-0.28 C-2.28,-0.42 -2.29,-0.56 -2.29,-0.71 C-2.29,-0.71 -2.31,-2.72 -2.31,-2.72 C-2.31,-2.72 -0.29,-0.71 -0.29,-0.71c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="100"
+                    android:propertyName="pathData"
+                    android:startOffset="67"
+                    android:valueFrom="M-0.29 -0.71 C-0.29,-0.42 -0.19,-0.19 0,0.01 C0.19,0.2 0.43,0.29 0.71,0.29 C0.76,0.31 0.75,0.31 0.78,0.3 C1.14,0.67 1.92,1.43 2.34,1.85 C2.03,2.04 1.55,2.29 0.71,2.29 C0.55,2.29 0.39,2.28 0.23,2.26 C-0.4,2.17 -0.94,1.89 -1.41,1.42 C-1.89,0.94 -2.18,0.37 -2.26,-0.28 C-2.28,-0.42 -2.29,-0.56 -2.29,-0.71 C-2.29,-0.71 -2.31,-2.72 -2.31,-2.72 C-2.31,-2.72 -0.29,-0.71 -0.29,-0.71c "
+                    android:valueTo="M-0.29 -0.71 C-0.29,-0.42 -0.19,-0.19 0,0.01 C0.19,0.2 0.43,0.29 0.71,0.29 C0.76,0.31 0.75,0.31 0.78,0.3 C1.14,0.67 1.92,1.43 2.34,1.85 C2.03,2.04 1.55,2.29 0.71,2.29 C0.55,2.29 0.39,2.28 0.23,2.26 C0.09,2.2 -0.55,1.45 -1.02,0.98 C-1.5,0.5 -2.23,-0.14 -2.26,-0.28 C-2.28,-0.42 -2.29,-0.56 -2.29,-0.71 C-2.29,-0.71 -2.31,-2.72 -2.31,-2.72 C-2.31,-2.72 -0.29,-0.71 -0.29,-0.71c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_4_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="17"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_4_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="250"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M-9.89 -7.81 C-9.89,-7.81 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 -8.49,-9.21 -8.49,-9.21 C-8.49,-9.21 -9.89,-7.81 -9.89,-7.81c "
+                    android:valueTo="M8.5 10.6 C8.5,10.6 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 9.9,9.2 9.9,9.2 C9.9,9.2 8.5,10.6 8.5,10.6c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="267"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_0_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#edf2eb"
+                        android:fillType="nonZero"
+                        android:pathData=" M5.05 4.43 C3.98,5.25 3.08,5.53 2.53,5.73 C2.26,5.81 1.98,5.87 1.7,5.9 C1.7,5.9 1.7,9 1.7,9 C1.7,9 -0.3,9 -0.3,9 C-0.3,9 -0.3,5.9 -0.3,5.9 C-2.02,5.65 -3.44,4.88 -4.59,3.59 C-5.73,2.3 -6.3,0.77 -6.3,-1 C-6.3,-1 -4.3,-1 -4.3,-1 C-4.3,0.38 -3.81,1.56 -2.84,2.54 C-1.86,3.51 -0.68,4 0.7,4 C0.88,4 1.06,3.99 1.23,3.96 C1.39,3.94 2.58,3.77 3.61,2.99 C3.61,2.99 5.05,4.43 5.05,4.43c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_1_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#edf2eb"
+                        android:fillType="nonZero"
+                        android:pathData=" M2.31 1.86 C2.31,1.86 1.01,0.55 0.75,0.31 C1.7,0.27 1.7,-0.7 1.7,-0.7 C1.7,-0.7 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-0.66 -0.29,-0.66 C-0.29,-0.66 -2.31,-2.67 -2.31,-2.67 C-2.31,-2.67 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.7,-0.33 3.64,-0.03 C3.51,0.52 3.23,1.19 2.31,1.86c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_2_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#edf2eb"
+                        android:fillType="nonZero"
+                        android:pathData=" M5.04 4.45 C5.04,4.45 3.59,3.02 3.59,3.02 C4.82,1.94 5.31,0.96 5.53,0.3 C5.64,-0.12 5.7,-0.55 5.7,-1 C5.7,-1 7.7,-1 7.7,-1 C7.7,-0.27 7.59,0.43 7.38,1.09 C7.16,1.75 6.51,3.17 5.04,4.45c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_3_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#edf2eb"
+                        android:fillType="nonZero"
+                        android:pathData=" M-0.29 -0.71 C-0.29,-0.42 -0.19,-0.19 0,0.01 C0.19,0.2 0.43,0.29 0.71,0.29 C0.76,0.31 0.75,0.31 0.78,0.3 C1.14,0.67 1.92,1.43 2.34,1.85 C2.03,2.04 1.55,2.29 0.71,2.29 C0.55,2.29 0.39,2.28 0.23,2.26 C-0.4,2.17 -0.94,1.89 -1.41,1.42 C-1.89,0.94 -2.18,0.37 -2.26,-0.28 C-2.28,-0.42 -2.29,-0.56 -2.29,-0.71 C-2.29,-0.71 -2.31,-2.72 -2.31,-2.72 C-2.31,-2.72 -0.29,-0.71 -0.29,-0.71c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_4_P_0"
+                        android:fillAlpha="0"
+                        android:fillColor="#edf2eb"
+                        android:fillType="nonZero"
+                        android:pathData=" M-9.89 -7.81 C-9.89,-7.81 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 -8.49,-9.21 -8.49,-9.21 C-8.49,-9.21 -9.89,-7.81 -9.89,-7.81c " />
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_mic_access_on.xml b/packages/SystemUI/res/drawable/qs_mic_access_on.xml
new file mode 100644
index 0000000..b485f06
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_mic_access_on.xml
@@ -0,0 +1,212 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 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
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_0_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="250"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M5.02 4.5 C3.59,5.47 2.79,5.64 2.53,5.73 C2.26,5.81 1.98,5.87 1.7,5.9 C1.7,5.9 1.7,9 1.7,9 C1.7,9 -0.3,9 -0.3,9 C-0.3,9 -0.3,5.9 -0.3,5.9 C-2.02,5.65 -3.44,4.88 -4.59,3.59 C-5.73,2.3 -6.3,0.77 -6.3,-1 C-6.3,-1 -4.3,-1 -4.3,-1 C-4.3,0.38 -3.81,1.56 -2.84,2.54 C-1.86,3.51 -0.68,4 0.7,4 C0.88,4 1.06,3.99 1.23,3.96 C1.39,3.94 2.53,3.83 3.58,3.07 C3.58,3.07 5.02,4.5 5.02,4.5c "
+                    android:valueTo="M5.05 4.43 C3.98,5.25 3.08,5.53 2.53,5.73 C2.26,5.81 1.98,5.87 1.7,5.9 C1.7,5.9 1.7,9 1.7,9 C1.7,9 -0.3,9 -0.3,9 C-0.3,9 -0.3,5.9 -0.3,5.9 C-2.02,5.65 -3.44,4.88 -4.59,3.59 C-5.73,2.3 -6.3,0.77 -6.3,-1 C-6.3,-1 -4.3,-1 -4.3,-1 C-4.3,0.38 -3.81,1.56 -2.84,2.54 C-1.86,3.51 -0.68,4 0.7,4 C0.88,4 1.06,3.99 1.23,3.96 C1.39,3.94 2.58,3.77 3.61,2.99 C3.61,2.99 5.05,4.43 5.05,4.43c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_1_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="125"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M3.5 -0.05 C3.5,-0.05 1.7,-1.85 1.7,-1.85 C1.7,-1.85 1.7,-1.92 1.7,-1.92 C1.7,-1.92 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.3,-3.85 -0.3,-3.85 C-0.3,-3.85 -2.3,-5.85 -2.3,-5.85 C-2.3,-5.85 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.68,-0.65 3.64,-0.5 C3.6,-0.35 3.55,-0.2 3.5,-0.05c "
+                    android:valueTo="M3.12 0.99 C3.12,0.99 1.83,-0.26 1.71,-0.38 C1.72,-0.81 1.7,-1.31 1.7,-1.31 C1.7,-1.31 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-2.26 -0.29,-2.26 C-0.29,-2.26 -2.31,-4.23 -2.31,-4.23 C-2.31,-4.23 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.67,-0.54 3.66,-0.3 C3.63,0.12 3.38,0.7 3.12,0.99c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="58"
+                    android:propertyName="pathData"
+                    android:startOffset="125"
+                    android:valueFrom="M3.12 0.99 C3.12,0.99 1.83,-0.26 1.71,-0.38 C1.72,-0.81 1.7,-1.31 1.7,-1.31 C1.7,-1.31 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-2.26 -0.29,-2.26 C-0.29,-2.26 -2.31,-4.23 -2.31,-4.23 C-2.31,-4.23 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.67,-0.54 3.66,-0.3 C3.63,0.12 3.38,0.7 3.12,0.99c "
+                    android:valueTo="M2.86 1.48 C2.86,1.48 1.58,0.21 1.39,0.03 C1.77,-0.26 1.7,-1.03 1.7,-1.03 C1.7,-1.03 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-1.51 -0.29,-1.51 C-0.29,-1.51 -2.31,-3.5 -2.31,-3.5 C-2.31,-3.5 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.68,-0.44 3.65,-0.17 C3.61,0.19 3.36,1.05 2.86,1.48c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="67"
+                    android:propertyName="pathData"
+                    android:startOffset="183"
+                    android:valueFrom="M2.86 1.48 C2.86,1.48 1.58,0.21 1.39,0.03 C1.77,-0.26 1.7,-1.03 1.7,-1.03 C1.7,-1.03 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-1.51 -0.29,-1.51 C-0.29,-1.51 -2.31,-3.5 -2.31,-3.5 C-2.31,-3.5 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.68,-0.44 3.65,-0.17 C3.61,0.19 3.36,1.05 2.86,1.48c "
+                    android:valueTo="M2.42 1.81 C2.42,1.81 1.16,0.52 0.9,0.28 C1.7,0.14 1.7,-0.7 1.7,-0.7 C1.7,-0.7 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-0.66 -0.29,-0.66 C-0.29,-0.66 -2.31,-2.67 -2.31,-2.67 C-2.31,-2.67 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.7,-0.33 3.64,-0.03 C3.58,0.27 3.22,1.2 2.42,1.81c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_2_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="250"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M6.45 2.95 C6.45,2.95 5,1.5 5,1.5 C5.23,1.12 5.41,0.72 5.53,0.3 C5.64,-0.12 5.7,-0.55 5.7,-1 C5.7,-1 7.7,-1 7.7,-1 C7.7,-0.27 7.59,0.43 7.38,1.09 C7.16,1.75 6.85,2.37 6.45,2.95c "
+                    android:valueTo="M5.04 4.43 C5.04,4.43 3.59,2.98 3.59,2.98 C4.61,2.09 5.41,0.72 5.53,0.3 C5.64,-0.12 5.7,-0.55 5.7,-1 C5.7,-1 7.7,-1 7.7,-1 C7.7,-0.27 7.59,0.43 7.38,1.09 C7.16,1.75 6.19,3.44 5.04,4.43c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_3_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="250"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M-0.29 -0.71 C-0.29,-0.42 -0.19,-0.19 0,0.01 C0.19,0.2 0.43,0.29 0.71,0.29 C0.76,0.31 0.75,0.31 0.78,0.3 C1.14,0.67 1.92,1.43 2.34,1.85 C2.03,2.04 1.55,2.29 0.71,2.29 C0.55,2.29 0.39,2.28 0.23,2.26 C0.09,2.2 -0.55,1.45 -1.02,0.98 C-1.5,0.5 -2.23,-0.14 -2.26,-0.28 C-2.28,-0.42 -2.29,-0.56 -2.29,-0.71 C-2.29,-0.71 -2.31,-2.72 -2.31,-2.72 C-2.31,-2.72 -0.29,-0.71 -0.29,-0.71c "
+                    android:valueTo="M-0.29 -0.71 C-0.29,-0.42 -0.19,-0.19 0,0.01 C0.19,0.2 0.43,0.29 0.71,0.29 C0.76,0.31 0.75,0.31 0.78,0.3 C1.14,0.67 1.92,1.43 2.34,1.85 C2.03,2.04 1.55,2.29 0.71,2.29 C0.55,2.29 0.39,2.28 0.23,2.26 C-0.4,2.17 -0.94,1.89 -1.41,1.42 C-1.89,0.94 -2.18,0.37 -2.26,-0.28 C-2.28,-0.42 -2.29,-0.56 -2.29,-0.71 C-2.29,-0.71 -2.31,-2.72 -2.31,-2.72 C-2.31,-2.72 -0.29,-0.71 -0.29,-0.71c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_4_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="400"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="0"
+                    android:valueFrom="1"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="17"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="400"
+                    android:valueFrom="1"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_4_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="167"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M8.5 10.6 C8.5,10.6 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 9.9,9.2 9.9,9.2 C9.9,9.2 8.5,10.6 8.5,10.6c "
+                    android:valueTo="M8.5 10.6 C8.5,10.6 8.51,10.6 8.51,10.6 C8.51,10.6 9.91,9.2 9.91,9.2 C9.91,9.2 9.9,9.2 9.9,9.2 C9.9,9.2 8.5,10.6 8.5,10.6c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="433"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_0_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M5.02 4.5 C3.59,5.47 2.79,5.64 2.53,5.73 C2.26,5.81 1.98,5.87 1.7,5.9 C1.7,5.9 1.7,9 1.7,9 C1.7,9 -0.3,9 -0.3,9 C-0.3,9 -0.3,5.9 -0.3,5.9 C-2.02,5.65 -3.44,4.88 -4.59,3.59 C-5.73,2.3 -6.3,0.77 -6.3,-1 C-6.3,-1 -4.3,-1 -4.3,-1 C-4.3,0.38 -3.81,1.56 -2.84,2.54 C-1.86,3.51 -0.68,4 0.7,4 C0.88,4 1.06,3.99 1.23,3.96 C1.39,3.94 2.53,3.83 3.58,3.07 C3.58,3.07 5.02,4.5 5.02,4.5c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_1_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M3.5 -0.05 C3.5,-0.05 1.7,-1.85 1.7,-1.85 C1.7,-1.85 1.7,-1.92 1.7,-1.92 C1.7,-1.92 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.3,-3.85 -0.3,-3.85 C-0.3,-3.85 -2.3,-5.85 -2.3,-5.85 C-2.3,-5.85 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.68,-0.65 3.64,-0.5 C3.6,-0.35 3.55,-0.2 3.5,-0.05c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_2_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M6.45 2.95 C6.45,2.95 5,1.5 5,1.5 C5.23,1.12 5.41,0.72 5.53,0.3 C5.64,-0.12 5.7,-0.55 5.7,-1 C5.7,-1 7.7,-1 7.7,-1 C7.7,-0.27 7.59,0.43 7.38,1.09 C7.16,1.75 6.85,2.37 6.45,2.95c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_3_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M-0.29 -0.71 C-0.29,-0.42 -0.19,-0.19 0,0.01 C0.19,0.2 0.43,0.29 0.71,0.29 C0.76,0.31 0.75,0.31 0.78,0.3 C1.14,0.67 1.92,1.43 2.34,1.85 C2.03,2.04 1.55,2.29 0.71,2.29 C0.55,2.29 0.39,2.28 0.23,2.26 C0.09,2.2 -0.55,1.45 -1.02,0.98 C-1.5,0.5 -2.23,-0.14 -2.26,-0.28 C-2.28,-0.42 -2.29,-0.56 -2.29,-0.71 C-2.29,-0.71 -2.31,-2.72 -2.31,-2.72 C-2.31,-2.72 -0.29,-0.71 -0.29,-0.71c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_4_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M8.5 10.6 C8.5,10.6 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 9.9,9.2 9.9,9.2 C9.9,9.2 8.5,10.6 8.5,10.6c " />
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/screenshot_edit_background.xml b/packages/SystemUI/res/drawable/screenshot_edit_background.xml
index ff5c62e..a1185a2 100644
--- a/packages/SystemUI/res/drawable/screenshot_edit_background.xml
+++ b/packages/SystemUI/res/drawable/screenshot_edit_background.xml
@@ -17,7 +17,7 @@
 <!-- Long screenshot edit FAB background -->
 <ripple xmlns:android="http://schemas.android.com/apk/res/android"
         xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
-        android:color="?android:textColorPrimary">
+        android:color="@color/overlay_button_ripple">
     <item android:id="@android:id/background">
         <shape android:shape="rectangle">
             <solid android:color="?androidprv:attr/colorAccentPrimary"/>
diff --git a/packages/SystemUI/res/layout/brightness_mirror_container.xml b/packages/SystemUI/res/layout/brightness_mirror_container.xml
index ac90db3..1bf45aa 100644
--- a/packages/SystemUI/res/layout/brightness_mirror_container.xml
+++ b/packages/SystemUI/res/layout/brightness_mirror_container.xml
@@ -23,7 +23,6 @@
     android:background="@drawable/brightness_mirror_background"
     android:layout_gravity="center_vertical"
     android:layout_margin="8dp"
-    android:padding="@dimen/rounded_slider_background_padding"
     android:gravity="center"
     android:visibility="invisible">
 
diff --git a/packages/SystemUI/res/layout/media_output_dialog.xml b/packages/SystemUI/res/layout/media_output_dialog.xml
index 1efb479..eb43853 100644
--- a/packages/SystemUI/res/layout/media_output_dialog.xml
+++ b/packages/SystemUI/res/layout/media_output_dialog.xml
@@ -89,8 +89,7 @@
             android:id="@+id/list_result"
             android:scrollbars="vertical"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:overScrollMode="never"/>
+            android:layout_height="wrap_content"/>
     </LinearLayout>
 
     <LinearLayout
diff --git a/packages/SystemUI/screenshot/Android.bp b/packages/SystemUI/screenshot/Android.bp
index a79fd9040d..601e92f 100644
--- a/packages/SystemUI/screenshot/Android.bp
+++ b/packages/SystemUI/screenshot/Android.bp
@@ -26,11 +26,7 @@
     manifest: "AndroidManifest.xml",
 
     srcs: [
-        // All files in this library should be in Kotlin besides some exceptions.
         "src/**/*.kt",
-
-        // This file was forked from google3, so exceptionally it can be in Java.
-        "src/com/android/systemui/testing/screenshot/DynamicColorsTestUtils.java",
     ],
 
     resource_dirs: [
diff --git a/packages/SystemUI/screenshot/AndroidManifest.xml b/packages/SystemUI/screenshot/AndroidManifest.xml
index 3b703be..a405836 100644
--- a/packages/SystemUI/screenshot/AndroidManifest.xml
+++ b/packages/SystemUI/screenshot/AndroidManifest.xml
@@ -23,6 +23,4 @@
             android:exported="true"
             android:theme="@style/Theme.SystemUI.Screenshot" />
     </application>
-
-    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
 </manifest>
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/Bitmap.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/Bitmap.kt
new file mode 100644
index 0000000..3d26cda
--- /dev/null
+++ b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/Bitmap.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.testing.screenshot
+
+import android.graphics.Bitmap
+import android.graphics.Canvas
+import android.os.Build
+import android.view.View
+import platform.test.screenshot.matchers.MSSIMMatcher
+import platform.test.screenshot.matchers.PixelPerfectMatcher
+
+/** Draw this [View] into a [Bitmap]. */
+fun View.drawIntoBitmap(): Bitmap {
+    val bitmap =
+        Bitmap.createBitmap(
+            measuredWidth,
+            measuredHeight,
+            Bitmap.Config.ARGB_8888,
+        )
+    val canvas = Canvas(bitmap)
+    draw(canvas)
+    return bitmap
+}
+
+/**
+ * The [BitmapMatcher][platform.test.screenshot.matchers.BitmapMatcher] that should be used for
+ * screenshot *unit* tests.
+ */
+val UnitTestBitmapMatcher =
+    if (Build.CPU_ABI == "x86_64") {
+        // Different CPU architectures can sometimes end up rendering differently, so we can't do
+        // pixel-perfect matching on different architectures using the same golden. Given that our
+        // presubmits are run on cf_x86_64_phone, our goldens should be perfectly matched on the
+        // x86_64 architecture and use the Structural Similarity Index on others.
+        // TODO(b/237511747): Run our screenshot presubmit tests on arm64 instead so that we can
+        // do pixel perfect matching both at presubmit time and at development time with actual
+        // devices.
+        PixelPerfectMatcher()
+    } else {
+        MSSIMMatcher()
+    }
+
+/**
+ * The [BitmapMatcher][platform.test.screenshot.matchers.BitmapMatcher] that should be used for
+ * screenshot *unit* tests.
+ *
+ * We use the Structural Similarity Index for integration tests because they usually contain
+ * additional information and noise that shouldn't break the test.
+ */
+val IntegrationTestBitmapMatcher = MSSIMMatcher()
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/DynamicColorsTestUtils.java b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/DynamicColorsTestUtils.java
deleted file mode 100644
index 96ec4c5..0000000
--- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/DynamicColorsTestUtils.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.testing.screenshot;
-
-import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
-
-import android.app.UiAutomation;
-import android.content.Context;
-import android.provider.Settings;
-import android.util.Log;
-
-import androidx.annotation.ColorInt;
-import androidx.annotation.ColorRes;
-import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
-import androidx.core.content.ContextCompat;
-import androidx.test.espresso.Espresso;
-import androidx.test.espresso.IdlingRegistry;
-import androidx.test.espresso.IdlingResource;
-
-import org.json.JSONObject;
-import org.junit.function.ThrowingRunnable;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/*
- * Note: This file was forked from
- * google3/third_party/java_src/android_libs/material_components/screenshot_tests/java/android/
- * support/design/scuba/color/DynamicColorsTestUtils.java.
- */
-
-/** Utility that helps change the dynamic system colors for testing. */
-@RequiresApi(32)
-public class DynamicColorsTestUtils {
-
-    private static final String TAG = DynamicColorsTestUtils.class.getSimpleName();
-
-    private static final String THEME_CUSTOMIZATION_KEY = "theme_customization_overlay_packages";
-    private static final String THEME_CUSTOMIZATION_SYSTEM_PALETTE_KEY =
-            "android.theme.customization.system_palette";
-
-    private static final int ORANGE_SYSTEM_SEED_COLOR = 0xA66800;
-    private static final int ORANGE_EXPECTED_SYSTEM_ACCENT1_600_COLOR = -8235756;
-
-    private DynamicColorsTestUtils() {
-    }
-
-    /**
-     * Update system dynamic colors (e.g., android.R.color.system_accent1_600) based on an orange
-     * seed color, and then wait for the change to propagate to the app by comparing
-     * android.R.color.system_accent1_600 to the expected orange value.
-     */
-    public static void updateSystemColorsToOrange() {
-        updateSystemColors(ORANGE_SYSTEM_SEED_COLOR, ORANGE_EXPECTED_SYSTEM_ACCENT1_600_COLOR);
-    }
-
-    /**
-     * Update system dynamic colors (e.g., android.R.color.system_accent1_600) based on the provided
-     * {@code seedColor}, and then wait for the change to propagate to the app by comparing
-     * android.R.color.system_accent1_600 to {@code expectedSystemAccent1600}.
-     */
-    public static void updateSystemColors(
-            @ColorInt int seedColor, @ColorInt int expectedSystemAccent1600) {
-        Context context = getInstrumentation().getTargetContext();
-
-        int actualSystemAccent1600 =
-                ContextCompat.getColor(context, android.R.color.system_accent1_600);
-
-        if (expectedSystemAccent1600 == actualSystemAccent1600) {
-            String expectedColorString = Integer.toHexString(expectedSystemAccent1600);
-            Log.d(
-                    TAG,
-                    "Skipped updating system colors since system_accent1_600 is already equal to "
-                            + "expected: "
-                            + expectedColorString);
-            return;
-        }
-
-        updateSystemColors(seedColor);
-    }
-
-    /**
-     * Update system dynamic colors (e.g., android.R.color.system_accent1_600) based on the provided
-     * {@code seedColor}, and then wait for the change to propagate to the app by checking
-     * android.R.color.system_accent1_600 for any change.
-     */
-    public static void updateSystemColors(@ColorInt int seedColor) {
-        Context context = getInstrumentation().getTargetContext();
-
-        // Initialize system color idling resource with original system_accent1_600 value.
-        ColorChangeIdlingResource systemColorIdlingResource =
-                new ColorChangeIdlingResource(context, android.R.color.system_accent1_600);
-
-        // Update system theme color setting to trigger fabricated resource overlay.
-        runWithShellPermissionIdentity(
-                () ->
-                        Settings.Secure.putString(
-                                context.getContentResolver(),
-                                THEME_CUSTOMIZATION_KEY,
-                                buildThemeCustomizationString(seedColor)));
-
-        // Wait for system color update to propagate to app.
-        IdlingRegistry idlingRegistry = IdlingRegistry.getInstance();
-        idlingRegistry.register(systemColorIdlingResource);
-        Espresso.onIdle();
-        idlingRegistry.unregister(systemColorIdlingResource);
-
-        Log.d(TAG,
-                Settings.Secure.getString(context.getContentResolver(), THEME_CUSTOMIZATION_KEY));
-    }
-
-    private static String buildThemeCustomizationString(@ColorInt int seedColor) {
-        String seedColorHex = Integer.toHexString(seedColor);
-        Map<String, String> themeCustomizationMap = new HashMap<>();
-        themeCustomizationMap.put(THEME_CUSTOMIZATION_SYSTEM_PALETTE_KEY, seedColorHex);
-        return new JSONObject(themeCustomizationMap).toString();
-    }
-
-    private static void runWithShellPermissionIdentity(@NonNull ThrowingRunnable runnable) {
-        UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
-        uiAutomation.adoptShellPermissionIdentity();
-        try {
-            runnable.run();
-        } catch (Throwable e) {
-            throw new RuntimeException(e);
-        } finally {
-            uiAutomation.dropShellPermissionIdentity();
-        }
-    }
-
-    private static class ColorChangeIdlingResource implements IdlingResource {
-
-        private final Context mContext;
-        private final int mColorResId;
-        private final int mInitialColorInt;
-
-        private ResourceCallback mResourceCallback;
-        private boolean mIdleNow;
-
-        ColorChangeIdlingResource(Context context, @ColorRes int colorResId) {
-            this.mContext = context;
-            this.mColorResId = colorResId;
-            this.mInitialColorInt = ContextCompat.getColor(context, colorResId);
-        }
-
-        @Override
-        public String getName() {
-            return ColorChangeIdlingResource.class.getName();
-        }
-
-        @Override
-        public boolean isIdleNow() {
-            if (mIdleNow) {
-                return true;
-            }
-
-            int currentColorInt = ContextCompat.getColor(mContext, mColorResId);
-
-            String initialColorString = Integer.toHexString(mInitialColorInt);
-            String currentColorString = Integer.toHexString(currentColorInt);
-            Log.d(TAG, String.format("Initial=%s, Current=%s", initialColorString,
-                    currentColorString));
-
-            mIdleNow = currentColorInt != mInitialColorInt;
-            Log.d(TAG, String.format("idleNow=%b", mIdleNow));
-
-            if (mIdleNow) {
-                mResourceCallback.onTransitionToIdle();
-            }
-            return mIdleNow;
-        }
-
-        @Override
-        public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
-            this.mResourceCallback = resourceCallback;
-        }
-    }
-}
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestRule.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestRule.kt
deleted file mode 100644
index 564901c..0000000
--- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestRule.kt
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.testing.screenshot
-
-import android.app.UiModeManager
-import android.content.Context
-import android.graphics.Bitmap
-import android.graphics.Canvas
-import android.os.Build
-import android.os.UserHandle
-import android.view.Display
-import android.view.View
-import android.view.WindowManagerGlobal
-import androidx.test.platform.app.InstrumentationRegistry
-import org.junit.rules.TestRule
-import org.junit.runner.Description
-import org.junit.runners.model.Statement
-import platform.test.screenshot.GoldenImagePathManager
-import platform.test.screenshot.PathConfig
-import platform.test.screenshot.PathElementNoContext
-import platform.test.screenshot.ScreenshotTestRule
-import platform.test.screenshot.matchers.MSSIMMatcher
-import platform.test.screenshot.matchers.PixelPerfectMatcher
-
-/**
- * A base rule for screenshot diff tests.
- *
- * This rules takes care of setting up the activity according to [testSpec] by:
- * - emulating the display size and density.
- * - setting the dark/light mode.
- * - setting the system (Material You) colors to a fixed value.
- *
- * @see ComposeScreenshotTestRule
- * @see ViewScreenshotTestRule
- */
-class ScreenshotTestRule(private val testSpec: ScreenshotTestSpec) : TestRule {
-    private var currentDisplay: DisplaySpec? = null
-    private var currentGoldenIdentifier: String? = null
-
-    private val pathConfig =
-        PathConfig(
-            PathElementNoContext("model", isDir = true) {
-                currentDisplay?.name ?: error("currentDisplay is null")
-            },
-        )
-    private val matcher = if (shouldUsePerfectMatching()) {
-        PixelPerfectMatcher()
-    } else {
-        MSSIMMatcher()
-    }
-
-    private val screenshotRule =
-        ScreenshotTestRule(
-            SystemUIGoldenImagePathManager(
-                pathConfig,
-                currentGoldenIdentifier = {
-                    currentGoldenIdentifier ?: error("currentGoldenIdentifier is null")
-                },
-            )
-        )
-
-    private fun shouldUsePerfectMatching(): Boolean {
-        // Different CPU architectures can sometimes end up rendering differently, so we can't do
-        // pixel-perfect matching on different architectures using the same golden. Given that our
-        // presubmits are run on cf_x86_64_phone, our goldens should be perfectly matched on the
-        // x86_64 architecture and use the Structural Similarity Index on others.
-        // TODO(b/237511747): Run our screenshot presubmit tests on arm64 instead so that we can
-        // do pixel perfect matching both at presubmit time and at development time with actual
-        // devices.
-        return Build.CPU_ABI == "x86_64"
-    }
-
-    override fun apply(base: Statement, description: Description): Statement {
-        // The statement which call beforeTest() before running the test and afterTest() afterwards.
-        val statement =
-            object : Statement() {
-                override fun evaluate() {
-                    try {
-                        beforeTest()
-                        base.evaluate()
-                    } finally {
-                        afterTest()
-                    }
-                }
-            }
-
-        return screenshotRule.apply(statement, description)
-    }
-
-    private fun beforeTest() {
-        // Update the system colors to a fixed color, so that tests don't depend on the host device
-        // extracted colors. Note that we don't restore the default device colors at the end of the
-        // test because changing the colors (and waiting for them to be applied) is costly and makes
-        // the screenshot tests noticeably slower.
-        DynamicColorsTestUtils.updateSystemColorsToOrange()
-
-        // Emulate the display size and density.
-        val display = testSpec.display
-        val density = display.densityDpi
-        val wm = WindowManagerGlobal.getWindowManagerService()
-        val (width, height) = getEmulatedDisplaySize()
-        wm.setForcedDisplayDensityForUser(Display.DEFAULT_DISPLAY, density, UserHandle.myUserId())
-        wm.setForcedDisplaySize(Display.DEFAULT_DISPLAY, width, height)
-
-        // Force the dark/light theme.
-        val uiModeManager =
-            InstrumentationRegistry.getInstrumentation()
-                .targetContext
-                .getSystemService(Context.UI_MODE_SERVICE) as UiModeManager
-        uiModeManager.setApplicationNightMode(
-            if (testSpec.isDarkTheme) {
-                UiModeManager.MODE_NIGHT_YES
-            } else {
-                UiModeManager.MODE_NIGHT_NO
-            }
-        )
-    }
-
-    private fun afterTest() {
-        // Reset the density and display size.
-        val wm = WindowManagerGlobal.getWindowManagerService()
-        wm.clearForcedDisplayDensityForUser(Display.DEFAULT_DISPLAY, UserHandle.myUserId())
-        wm.clearForcedDisplaySize(Display.DEFAULT_DISPLAY)
-
-        // Reset the dark/light theme.
-        val uiModeManager =
-            InstrumentationRegistry.getInstrumentation()
-                .targetContext
-                .getSystemService(Context.UI_MODE_SERVICE) as UiModeManager
-        uiModeManager.setApplicationNightMode(UiModeManager.MODE_NIGHT_AUTO)
-    }
-
-    /**
-     * Compare the content of [view] with the golden image identified by [goldenIdentifier] in the
-     * context of [testSpec].
-     */
-    fun screenshotTest(goldenIdentifier: String, view: View) {
-        val bitmap = drawIntoBitmap(view)
-
-        // Compare bitmap against golden asset.
-        val isDarkTheme = testSpec.isDarkTheme
-        val isLandscape = testSpec.isLandscape
-        val identifierWithSpec = buildString {
-            append(goldenIdentifier)
-            if (isDarkTheme) append("_dark")
-            if (isLandscape) append("_landscape")
-        }
-
-        // TODO(b/230832101): Provide a way to pass a PathConfig and override the file name on
-        // device to assertBitmapAgainstGolden instead?
-        currentDisplay = testSpec.display
-        currentGoldenIdentifier = goldenIdentifier
-        screenshotRule.assertBitmapAgainstGolden(bitmap, identifierWithSpec, matcher)
-        currentDisplay = null
-        currentGoldenIdentifier = goldenIdentifier
-    }
-
-    /** Draw [view] into a [Bitmap]. */
-    private fun drawIntoBitmap(view: View): Bitmap {
-        val bitmap =
-            Bitmap.createBitmap(
-                view.measuredWidth,
-                view.measuredHeight,
-                Bitmap.Config.ARGB_8888,
-            )
-        val canvas = Canvas(bitmap)
-        view.draw(canvas)
-        return bitmap
-    }
-
-    /** Get the emulated display size for [testSpec]. */
-    private fun getEmulatedDisplaySize(): Pair<Int, Int> {
-        val display = testSpec.display
-        val isPortraitNaturalPosition = display.width < display.height
-        return if (testSpec.isLandscape) {
-            if (isPortraitNaturalPosition) {
-                display.height to display.width
-            } else {
-                display.width to display.height
-            }
-        } else {
-            if (isPortraitNaturalPosition) {
-                display.width to display.height
-            } else {
-                display.height to display.width
-            }
-        }
-    }
-}
-
-private class SystemUIGoldenImagePathManager(
-    pathConfig: PathConfig,
-    private val currentGoldenIdentifier: () -> String,
-) :
-    GoldenImagePathManager(
-        appContext = InstrumentationRegistry.getInstrumentation().context,
-        deviceLocalPath =
-            InstrumentationRegistry.getInstrumentation()
-                .targetContext
-                .filesDir
-                .absolutePath
-                .toString() + "/sysui_screenshots",
-        pathConfig = pathConfig,
-    ) {
-    // This string is appended to all actual/expected screenshots on the device. We append the
-    // golden identifier so that our pull_golden.py scripts can map a screenshot on device to its
-    // asset (and automatically update it, if necessary).
-    override fun toString() = currentGoldenIdentifier()
-}
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestSpec.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestSpec.kt
deleted file mode 100644
index 7fc6245..0000000
--- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestSpec.kt
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.testing.screenshot
-
-/** The specification of a device display to be used in a screenshot test. */
-data class DisplaySpec(
-    val name: String,
-    val width: Int,
-    val height: Int,
-    val densityDpi: Int,
-)
-
-/** The specification of a screenshot diff test. */
-class ScreenshotTestSpec(
-    val display: DisplaySpec,
-    val isDarkTheme: Boolean = false,
-    val isLandscape: Boolean = false,
-) {
-    companion object {
-        /**
-         * Return a list of [ScreenshotTestSpec] for each of the [displays].
-         *
-         * If [isDarkTheme] is null, this will create a spec for both light and dark themes, for
-         * each of the orientation.
-         *
-         * If [isLandscape] is null, this will create a spec for both portrait and landscape, for
-         * each of the light/dark themes.
-         */
-        fun forDisplays(
-            vararg displays: DisplaySpec,
-            isDarkTheme: Boolean? = null,
-            isLandscape: Boolean? = null,
-        ): List<ScreenshotTestSpec> {
-            return displays.flatMap { display ->
-                buildList {
-                    fun addDisplay(isLandscape: Boolean) {
-                        if (isDarkTheme != true) {
-                            add(ScreenshotTestSpec(display, isDarkTheme = false, isLandscape))
-                        }
-
-                        if (isDarkTheme != false) {
-                            add(ScreenshotTestSpec(display, isDarkTheme = true, isLandscape))
-                        }
-                    }
-
-                    if (isLandscape != true) {
-                        addDisplay(isLandscape = false)
-                    }
-
-                    if (isLandscape != false) {
-                        addDisplay(isLandscape = true)
-                    }
-                }
-            }
-        }
-    }
-
-    override fun toString(): String = buildString {
-        // This string is appended to PNGs stored in the device, so let's keep it simple.
-        append(display.name)
-        if (isDarkTheme) append("_dark")
-        if (isLandscape) append("_landscape")
-    }
-}
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/SystemUIGoldenImagePathManager.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/SystemUIGoldenImagePathManager.kt
new file mode 100644
index 0000000..cbab0a7
--- /dev/null
+++ b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/SystemUIGoldenImagePathManager.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.testing.screenshot
+
+import androidx.test.platform.app.InstrumentationRegistry
+import platform.test.screenshot.GoldenImagePathManager
+import platform.test.screenshot.PathConfig
+
+/** A [GoldenImagePathManager] that should be used for all SystemUI screenshot tests. */
+class SystemUIGoldenImagePathManager(
+    pathConfig: PathConfig,
+) :
+    GoldenImagePathManager(
+        appContext = InstrumentationRegistry.getInstrumentation().context,
+        deviceLocalPath =
+            InstrumentationRegistry.getInstrumentation()
+                .targetContext
+                .filesDir
+                .absolutePath
+                .toString() + "/sysui_screenshots",
+        pathConfig = pathConfig,
+    ) {
+    override fun toString(): String {
+        // This string is appended to all actual/expected screenshots on the device, so make sure
+        // it is a static value.
+        return "SystemUIGoldenImagePathManager"
+    }
+}
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt
index 6a80c48..3209c8b 100644
--- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt
+++ b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.android.systemui.testing.screenshot
 
 import android.app.Activity
@@ -11,21 +27,35 @@
 import org.junit.rules.TestRule
 import org.junit.runner.Description
 import org.junit.runners.model.Statement
+import platform.test.screenshot.DeviceEmulationRule
+import platform.test.screenshot.DeviceEmulationSpec
+import platform.test.screenshot.MaterialYouColorsRule
+import platform.test.screenshot.ScreenshotTestRule
+import platform.test.screenshot.getEmulatedDevicePathConfig
 
-/** A rule for View screenshot diff tests. */
-class ViewScreenshotTestRule(testSpec: ScreenshotTestSpec) : TestRule {
+/** A rule for View screenshot diff unit tests. */
+class ViewScreenshotTestRule(emulationSpec: DeviceEmulationSpec) : TestRule {
+    private val colorsRule = MaterialYouColorsRule()
+    private val deviceEmulationRule = DeviceEmulationRule(emulationSpec)
+    private val screenshotRule =
+        ScreenshotTestRule(
+            SystemUIGoldenImagePathManager(getEmulatedDevicePathConfig(emulationSpec))
+        )
     private val activityRule = ActivityScenarioRule(ScreenshotActivity::class.java)
-    private val screenshotRule = ScreenshotTestRule(testSpec)
-
-    private val delegate = RuleChain.outerRule(screenshotRule).around(activityRule)
+    private val delegateRule =
+        RuleChain.outerRule(colorsRule)
+            .around(deviceEmulationRule)
+            .around(screenshotRule)
+            .around(activityRule)
+    private val matcher = UnitTestBitmapMatcher
 
     override fun apply(base: Statement, description: Description): Statement {
-        return delegate.apply(base, description)
+        return delegateRule.apply(base, description)
     }
 
     /**
      * Compare the content of the view provided by [viewProvider] with the golden image identified
-     * by [goldenIdentifier] in the context of [testSpec].
+     * by [goldenIdentifier] in the context of [emulationSpec].
      */
     fun screenshotTest(
         goldenIdentifier: String,
@@ -46,13 +76,17 @@
             // Check that the content is what we expected.
             val content = activity.requireViewById<ViewGroup>(android.R.id.content)
             assertEquals(1, content.childCount)
-            screenshotRule.screenshotTest(goldenIdentifier, content.getChildAt(0))
+            screenshotRule.assertBitmapAgainstGolden(
+                content.getChildAt(0).drawIntoBitmap(),
+                goldenIdentifier,
+                matcher
+            )
         }
     }
 
     /**
      * Compare the content of the dialog provided by [dialogProvider] with the golden image
-     * identified by [goldenIdentifier] in the context of [testSpec].
+     * identified by [goldenIdentifier] in the context of [emulationSpec].
      */
     fun dialogScreenshotTest(
         goldenIdentifier: String,
@@ -81,7 +115,11 @@
             // Check that the content is what we expected.
             val dialog = dialog ?: error("dialog is null")
             try {
-                screenshotRule.screenshotTest(goldenIdentifier, dialog.window.decorView)
+                screenshotRule.assertBitmapAgainstGolden(
+                    dialog.window.decorView.drawIntoBitmap(),
+                    goldenIdentifier,
+                    matcher,
+                )
             } finally {
                 dialog.dismiss()
             }
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index 2dade21..b05582e 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -18,7 +18,6 @@
 
 import android.app.ActivityThread;
 import android.content.Context;
-import android.content.res.AssetManager;
 import android.content.res.Resources;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -29,7 +28,6 @@
 import com.android.systemui.dagger.GlobalRootComponent;
 import com.android.systemui.dagger.SysUIComponent;
 import com.android.systemui.dagger.WMComponent;
-import com.android.systemui.navigationbar.gestural.BackGestureTfClassifierProvider;
 import com.android.systemui.screenshot.ScreenshotNotificationSmartActionsProvider;
 import com.android.wm.shell.dagger.WMShellConcurrencyModule;
 import com.android.wm.shell.transition.ShellTransitions;
@@ -251,13 +249,4 @@
                         Context context, Executor executor, Handler uiHandler) {
         return new ScreenshotNotificationSmartActionsProvider();
     }
-
-    /**
-     * Creates an instance of BackGestureTfClassifierProvider.
-     * This method is overridden in vendor specific implementation of Sys UI.
-     */
-    public BackGestureTfClassifierProvider createBackGestureTfClassifierProvider(
-            AssetManager am, String modelName) {
-        return new BackGestureTfClassifierProvider();
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java
index 3f78f97..1fa9ac5 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java
@@ -74,6 +74,7 @@
         }
         mEditText.setText(clip.getItemAt(0).getText());
         mEditText.requestFocus();
+        mEditText.setSelection(0);
         mSensitive = clip.getDescription().getExtras() != null
                 && clip.getDescription().getExtras()
                 .getBoolean(ClipDescription.EXTRA_IS_SENSITIVE);
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
index afc58ef..4096ed4 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
@@ -42,6 +42,7 @@
 import android.content.pm.LauncherApps;
 import android.content.pm.PackageManager;
 import android.content.pm.ShortcutManager;
+import android.content.res.AssetManager;
 import android.content.res.Resources;
 import android.hardware.SensorManager;
 import android.hardware.SensorPrivacyManager;
@@ -91,6 +92,7 @@
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.util.LatencyTracker;
 import com.android.systemui.Prefs;
+import com.android.systemui.dagger.qualifiers.Application;
 import com.android.systemui.dagger.qualifiers.DisplayId;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dagger.qualifiers.TestHarness;
@@ -405,6 +407,12 @@
     }
 
     @Provides
+    @Application
+    static AssetManager provideAssetManager(@Application Context context) {
+        return context.getAssets();
+    }
+
+    @Provides
     @Singleton
     static RoleManager provideRoleManager(Context context) {
         return context.getSystemService(RoleManager.class);
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
index 4e48a52..c4fca60 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
@@ -35,6 +35,7 @@
 import com.android.systemui.dock.DockManagerImpl;
 import com.android.systemui.doze.DozeHost;
 import com.android.systemui.media.dagger.MediaModule;
+import com.android.systemui.navigationbar.gestural.GestureModule;
 import com.android.systemui.plugins.qs.QSFactory;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.power.EnhancedEstimates;
@@ -94,6 +95,7 @@
  * SystemUI code that variants of SystemUI _must_ include to function correctly.
  */
 @Module(includes = {
+        GestureModule.class,
         MediaModule.class,
         PowerModule.class,
         QSModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index 3039d9d..bd6a5fc 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -59,7 +59,6 @@
 import com.android.internal.policy.GestureNavigationSettingsObserver;
 import com.android.internal.util.LatencyTracker;
 import com.android.systemui.R;
-import com.android.systemui.SystemUIFactory;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.flags.FeatureFlags;
@@ -96,6 +95,7 @@
 import java.util.function.Consumer;
 
 import javax.inject.Inject;
+import javax.inject.Provider;
 
 /**
  * Utility class to handle edge swipes for back gesture
@@ -196,6 +196,8 @@
     private final Region mExcludeRegion = new Region();
     private final Region mUnrestrictedExcludeRegion = new Region();
     private final LatencyTracker mLatencyTracker;
+    private final Provider<BackGestureTfClassifierProvider>
+            mBackGestureTfClassifierProviderProvider;
     private final FeatureFlags mFeatureFlags;
 
     // The left side edge width where touch down is allowed
@@ -316,6 +318,7 @@
             Optional<Pip> pipOptional,
             FalsingManager falsingManager,
             LatencyTracker latencyTracker,
+            Provider<BackGestureTfClassifierProvider> backGestureTfClassifierProviderProvider,
             FeatureFlags featureFlags) {
         super(broadcastDispatcher);
         mContext = context;
@@ -333,6 +336,7 @@
         mPipOptional = pipOptional;
         mFalsingManager = falsingManager;
         mLatencyTracker = latencyTracker;
+        mBackGestureTfClassifierProviderProvider = backGestureTfClassifierProviderProvider;
         mFeatureFlags = featureFlags;
         ComponentName recentsComponentName = ComponentName.unflattenFromString(
                 context.getString(com.android.internal.R.string.config_recentsComponentName));
@@ -612,10 +616,7 @@
         }
 
         if (newState) {
-            String mlModelName = DeviceConfig.getString(DeviceConfig.NAMESPACE_SYSTEMUI,
-                    SystemUiDeviceConfigFlags.BACK_GESTURE_ML_MODEL_NAME, "backgesture");
-            mBackGestureTfClassifierProvider = SystemUIFactory.getInstance()
-                    .createBackGestureTfClassifierProvider(mContext.getAssets(), mlModelName);
+            mBackGestureTfClassifierProvider = mBackGestureTfClassifierProviderProvider.get();
             mMLModelThreshold = DeviceConfig.getFloat(DeviceConfig.NAMESPACE_SYSTEMUI,
                     SystemUiDeviceConfigFlags.BACK_GESTURE_ML_MODEL_THRESHOLD, 0.9f);
             if (mBackGestureTfClassifierProvider.isActive()) {
@@ -1007,6 +1008,8 @@
         private final Optional<Pip> mPipOptional;
         private final FalsingManager mFalsingManager;
         private final LatencyTracker mLatencyTracker;
+        private final Provider<BackGestureTfClassifierProvider>
+                mBackGestureTfClassifierProviderProvider;
         private final FeatureFlags mFeatureFlags;
 
         @Inject
@@ -1024,6 +1027,8 @@
                        Optional<Pip> pipOptional,
                        FalsingManager falsingManager,
                        LatencyTracker latencyTracker,
+                       Provider<BackGestureTfClassifierProvider>
+                               backGestureTfClassifierProviderProvider,
                        FeatureFlags featureFlags) {
             mOverviewProxyService = overviewProxyService;
             mSysUiState = sysUiState;
@@ -1039,6 +1044,7 @@
             mPipOptional = pipOptional;
             mFalsingManager = falsingManager;
             mLatencyTracker = latencyTracker;
+            mBackGestureTfClassifierProviderProvider = backGestureTfClassifierProviderProvider;
             mFeatureFlags = featureFlags;
         }
 
@@ -1060,6 +1066,7 @@
                     mPipOptional,
                     mFalsingManager,
                     mLatencyTracker,
+                    mBackGestureTfClassifierProviderProvider,
                     mFeatureFlags);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/GestureModule.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/GestureModule.java
new file mode 100644
index 0000000..f98496d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/GestureModule.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.navigationbar.gestural;
+
+import dagger.Module;
+import dagger.Provides;
+
+/**
+ *
+ */
+@Module
+public interface GestureModule {
+    /** */
+    @Provides
+    static BackGestureTfClassifierProvider providsBackGestureTfClassifierProvider() {
+        return new BackGestureTfClassifierProvider();
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
index 1004fca..ee49b29 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
@@ -57,8 +57,6 @@
     private boolean mCharging;
     private boolean mPluggedIn;
 
-    private Icon mIcon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_battery_saver);
-
     @Inject
     public BatterySaverTile(
             QSHost host,
@@ -145,7 +143,9 @@
     protected void handleUpdateState(BooleanState state, Object arg) {
         state.state = mPluggedIn ? Tile.STATE_UNAVAILABLE
                 : mPowerSave ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
-        state.icon = mIcon;
+        state.icon = ResourceIcon.get(mPowerSave
+                ? R.drawable.qs_battery_saver_icon_on
+                : R.drawable.qs_battery_saver_icon_off);
         state.label = mContext.getString(R.string.battery_detail_switch_title);
         state.secondaryLabel = "";
         state.contentDescription = state.label;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/MicrophoneToggleTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/MicrophoneToggleTile.java
index f4f0b2c..e547095 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/MicrophoneToggleTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/MicrophoneToggleTile.java
@@ -72,9 +72,9 @@
     @Override
     public @DrawableRes int getIconRes(boolean isBlocked) {
         if (isBlocked) {
-            return com.android.internal.R.drawable.ic_mic_blocked;
+            return R.drawable.qs_mic_access_off;
         } else {
-            return com.android.internal.R.drawable.ic_mic_allowed;
+            return R.drawable.qs_mic_access_on;
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index 7d53abf..eb2ee9d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -2693,7 +2693,8 @@
     @Override
     public void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancelAction,
             boolean afterKeyguardGone) {
-        if (mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_ASLEEP
+        if (!action.willRunAnimationOnKeyguard()
+                && mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_ASLEEP
                 && mKeyguardStateController.canDismissLockScreen()
                 && !mStatusBarStateController.leaveOpenOnKeyguardHide()
                 && mDozeServiceHost.isPulsing()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
index 5bd20ff..a29ba91 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
@@ -68,6 +68,7 @@
             mBrightnessMirror.setVisibility(View.INVISIBLE);
         });
         mVisibilityCallback = visibilityCallback;
+        updateResources();
     }
 
     public void showMirror() {
diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
index 9a19d8d..36a49af 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
@@ -35,6 +35,7 @@
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.dock.DockManagerImpl;
 import com.android.systemui.doze.DozeHost;
+import com.android.systemui.navigationbar.gestural.GestureModule;
 import com.android.systemui.plugins.qs.QSFactory;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.power.EnhancedEstimates;
@@ -87,6 +88,7 @@
  * overridden by the System UI implementation.
  */
 @Module(includes = {
+            GestureModule.class,
             PowerModule.class,
             QSModule.class,
             VolumeModule.class,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt
index 3d9205e..95e7ad9f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt
@@ -24,15 +24,19 @@
 import android.view.View
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
+import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingManagerFake
 import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.qs.QSTile
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.qs.QSHost
 import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.tileimpl.QSTileImpl
 import com.android.systemui.statusbar.policy.BatteryController
 import com.android.systemui.util.settings.FakeSettings
 import com.android.systemui.util.settings.SecureSettings
+import com.google.common.truth.Truth.assertThat
 import org.junit.Assert.assertEquals
 import org.junit.Before
 import org.junit.Test
@@ -77,6 +81,7 @@
     fun setUp() {
         MockitoAnnotations.initMocks(this)
         testableLooper = TestableLooper.get(this)
+        `when`(qsHost.context).thenReturn(mContext)
         `when`(qsHost.userContext).thenReturn(userContext)
         `when`(userContext.userId).thenReturn(USER)
 
@@ -133,4 +138,26 @@
         tile.handleSetListening(false)
         verify(batteryController).clearLastPowerSaverStartView()
     }
+
+    @Test
+    fun testIcon_whenBatterySaverDisabled_isOffState() {
+        val state = QSTile.BooleanState()
+        tile.onPowerSaveChanged(false)
+
+        tile.handleUpdateState(state, /* arg= */ null)
+
+        assertThat(state.icon)
+                .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_battery_saver_icon_off))
+    }
+
+    @Test
+    fun testIcon_whenBatterySaverEnabled_isOnState() {
+        val state = QSTile.BooleanState()
+        tile.onPowerSaveChanged(true)
+
+        tile.handleUpdateState(state, /* arg= */ null)
+
+        assertThat(state.icon)
+                .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_battery_saver_icon_on))
+    }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt
new file mode 100644
index 0000000..1ab601c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles
+
+import android.os.Handler
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.MetricsLogger
+import com.android.internal.logging.UiEventLogger
+import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.classifier.FalsingManagerFake
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.qs.QSTile
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.qs.QSHost
+import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController
+import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+import org.mockito.Mockito.`when` as whenever
+
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@SmallTest
+class MicrophoneToggleTileTest : SysuiTestCase() {
+    companion object {
+        /* isBlocked */
+        const val MICROPHONE_TOGGLE_ENABLED: Boolean = false
+        const val MICROPHONE_TOGGLE_DISABLED: Boolean = true
+    }
+
+    @Mock
+    private lateinit var host: QSHost
+    @Mock
+    private lateinit var metricsLogger: MetricsLogger
+    @Mock
+    private lateinit var statusBarStateController: StatusBarStateController
+    @Mock
+    private lateinit var activityStarter: ActivityStarter
+    @Mock
+    private lateinit var qsLogger: QSLogger
+    @Mock
+    private lateinit var privacyController: IndividualSensorPrivacyController
+    @Mock
+    private lateinit var keyguardStateController: KeyguardStateController
+
+    private lateinit var testableLooper: TestableLooper
+    private lateinit var tile: MicrophoneToggleTile
+    private val uiEventLogger: UiEventLogger = UiEventLoggerFake()
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        testableLooper = TestableLooper.get(this)
+        whenever(host.context).thenReturn(mContext)
+        whenever(host.uiEventLogger).thenReturn(uiEventLogger)
+
+        tile = MicrophoneToggleTile(host,
+                testableLooper.looper,
+                Handler(testableLooper.looper),
+                metricsLogger,
+                FalsingManagerFake(),
+                statusBarStateController,
+                activityStarter,
+                qsLogger,
+                privacyController,
+                keyguardStateController)
+    }
+
+    @Test
+    fun testIcon_whenMicrophoneAccessEnabled_isOnState() {
+        val state = QSTile.BooleanState()
+
+        tile.handleUpdateState(state, MICROPHONE_TOGGLE_ENABLED)
+
+        assertThat(state.icon).isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_mic_access_on))
+    }
+
+    @Test
+    fun testIcon_whenMicrophoneAccessDisabled_isOffState() {
+        val state = QSTile.BooleanState()
+
+        tile.handleUpdateState(state, MICROPHONE_TOGGLE_DISABLED)
+
+        assertThat(state.icon).isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_mic_access_off))
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewControllerTest.kt
index 7e245fc..7982bc0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewControllerTest.kt
@@ -37,94 +37,94 @@
 import com.android.systemui.statusbar.window.StatusBarWindowStateController
 import com.android.systemui.tuner.TunerService
 import com.google.common.truth.Truth.assertThat
+import java.util.Optional
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentCaptor
 import org.mockito.ArgumentMatchers
 import org.mockito.Mock
-import org.mockito.MockitoAnnotations
 import org.mockito.Mockito.anyFloat
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
-import java.util.Optional
 import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoAnnotations
 
 @RunWith(AndroidTestingRunner::class)
 @RunWithLooper(setAsMainLooper = true)
 @SmallTest
 class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
-    private lateinit var mController: NotificationShadeWindowViewController
-
     @Mock
-    private lateinit var mView: NotificationShadeWindowView
+    private lateinit var view: NotificationShadeWindowView
     @Mock
-    private lateinit var mTunerService: TunerService
+    private lateinit var tunserService: TunerService
     @Mock
-    private lateinit var mStatusBarStateController: SysuiStatusBarStateController
+    private lateinit var sysuiStatusBarStateController: SysuiStatusBarStateController
     @Mock
-    private lateinit var mCentralSurfaces: CentralSurfaces
+    private lateinit var centralSurfaces: CentralSurfaces
     @Mock
-    private lateinit var mDockManager: DockManager
+    private lateinit var dockManager: DockManager
     @Mock
-    private lateinit var mNotificationPanelViewController: NotificationPanelViewController
+    private lateinit var notificationPanelViewController: NotificationPanelViewController
     @Mock
-    private lateinit var mNotificationShadeDepthController: NotificationShadeDepthController
+    private lateinit var notificationShadeDepthController: NotificationShadeDepthController
     @Mock
-    private lateinit var mNotificationShadeWindowController: NotificationShadeWindowController
+    private lateinit var notificationShadeWindowController: NotificationShadeWindowController
     @Mock
-    private lateinit var mKeyguardUnlockAnimationController: KeyguardUnlockAnimationController
+    private lateinit var keyguardUnlockAnimationController: KeyguardUnlockAnimationController
     @Mock
-    private lateinit var mAmbientState: AmbientState
+    private lateinit var ambientState: AmbientState
     @Mock
     private lateinit var stackScrollLayoutController: NotificationStackScrollLayoutController
     @Mock
-    private lateinit var mStatusBarKeyguardViewManager: StatusBarKeyguardViewManager
+    private lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager
     @Mock
-    private lateinit var mStatusBarWindowStateController: StatusBarWindowStateController
+    private lateinit var statusBarWindowStateController: StatusBarWindowStateController
     @Mock
-    private lateinit var mLockscreenShadeTransitionController: LockscreenShadeTransitionController
+    private lateinit var lockscreenShadeTransitionController: LockscreenShadeTransitionController
     @Mock
-    private lateinit var mLockIconViewController: LockIconViewController
+    private lateinit var lockIconViewController: LockIconViewController
     @Mock
-    private lateinit var mPhoneStatusBarViewController: PhoneStatusBarViewController
+    private lateinit var phoneStatusBarViewController: PhoneStatusBarViewController
     @Mock
-    private lateinit var mLowLightClockController: LowLightClockController
+    private lateinit var lowLightClockController: LowLightClockController
 
-    private lateinit var mInteractionEventHandlerCaptor: ArgumentCaptor<InteractionEventHandler>
-    private lateinit var mInteractionEventHandler: InteractionEventHandler
+    private lateinit var interactionEventHandlerCaptor: ArgumentCaptor<InteractionEventHandler>
+    private lateinit var interactionEventHandler: InteractionEventHandler
+
+    private lateinit var underTest: NotificationShadeWindowViewController
 
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
-        whenever(mView.bottom).thenReturn(VIEW_BOTTOM)
+        whenever(view.bottom).thenReturn(VIEW_BOTTOM)
 
-        mController = NotificationShadeWindowViewController(
-            mLockscreenShadeTransitionController,
+        underTest = NotificationShadeWindowViewController(
+            lockscreenShadeTransitionController,
             FalsingCollectorFake(),
-            mTunerService,
-            mStatusBarStateController,
-            mDockManager,
-            mNotificationShadeDepthController,
-            mView,
-            mNotificationPanelViewController,
+            tunserService,
+            sysuiStatusBarStateController,
+            dockManager,
+            notificationShadeDepthController,
+            view,
+            notificationPanelViewController,
             PanelExpansionStateManager(),
             stackScrollLayoutController,
-            mStatusBarKeyguardViewManager,
-            mStatusBarWindowStateController,
-            mLockIconViewController,
-            Optional.of(mLowLightClockController),
-            mCentralSurfaces,
-            mNotificationShadeWindowController,
-            mKeyguardUnlockAnimationController,
-            mAmbientState
+            statusBarKeyguardViewManager,
+            statusBarWindowStateController,
+            lockIconViewController,
+            Optional.of(lowLightClockController),
+            centralSurfaces,
+            notificationShadeWindowController,
+            keyguardUnlockAnimationController,
+            ambientState
         )
-        mController.setupExpandedStatusBar()
+        underTest.setupExpandedStatusBar()
 
-        mInteractionEventHandlerCaptor =
+        interactionEventHandlerCaptor =
             ArgumentCaptor.forClass(InteractionEventHandler::class.java)
-        verify(mView).setInteractionEventHandler(mInteractionEventHandlerCaptor.capture())
-            mInteractionEventHandler = mInteractionEventHandlerCaptor.value
+        verify(view).setInteractionEventHandler(interactionEventHandlerCaptor.capture())
+            interactionEventHandler = interactionEventHandlerCaptor.value
     }
 
     // Note: So far, these tests only cover interactions with the status bar view controller. More
@@ -132,148 +132,148 @@
 
     @Test
     fun handleDispatchTouchEvent_nullStatusBarViewController_returnsFalse() {
-        mController.setStatusBarViewController(null)
+        underTest.setStatusBarViewController(null)
 
-        val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(downEv)
+        val returnVal = interactionEventHandler.handleDispatchTouchEvent(downEv)
 
         assertThat(returnVal).isFalse()
     }
 
     @Test
     fun handleDispatchTouchEvent_downTouchBelowView_sendsTouchToSb() {
-        mController.setStatusBarViewController(mPhoneStatusBarViewController)
+        underTest.setStatusBarViewController(phoneStatusBarViewController)
         val ev = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, VIEW_BOTTOM + 4f, 0)
-        whenever(mPhoneStatusBarViewController.sendTouchToView(ev)).thenReturn(true)
+        whenever(phoneStatusBarViewController.sendTouchToView(ev)).thenReturn(true)
 
-        val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(ev)
+        val returnVal = interactionEventHandler.handleDispatchTouchEvent(ev)
 
-        verify(mPhoneStatusBarViewController).sendTouchToView(ev)
+        verify(phoneStatusBarViewController).sendTouchToView(ev)
         assertThat(returnVal).isTrue()
     }
 
     @Test
     fun handleDispatchTouchEvent_downTouchBelowViewThenAnotherTouch_sendsTouchToSb() {
-        mController.setStatusBarViewController(mPhoneStatusBarViewController)
+        underTest.setStatusBarViewController(phoneStatusBarViewController)
         val downEvBelow = MotionEvent.obtain(
             0L, 0L, MotionEvent.ACTION_DOWN, 0f, VIEW_BOTTOM + 4f, 0
         )
-        mInteractionEventHandler.handleDispatchTouchEvent(downEvBelow)
+        interactionEventHandler.handleDispatchTouchEvent(downEvBelow)
 
         val nextEvent = MotionEvent.obtain(
             0L, 0L, MotionEvent.ACTION_MOVE, 0f, VIEW_BOTTOM + 5f, 0
         )
-        whenever(mPhoneStatusBarViewController.sendTouchToView(nextEvent)).thenReturn(true)
+        whenever(phoneStatusBarViewController.sendTouchToView(nextEvent)).thenReturn(true)
 
-        val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(nextEvent)
+        val returnVal = interactionEventHandler.handleDispatchTouchEvent(nextEvent)
 
-        verify(mPhoneStatusBarViewController).sendTouchToView(nextEvent)
+        verify(phoneStatusBarViewController).sendTouchToView(nextEvent)
         assertThat(returnVal).isTrue()
     }
 
     @Test
     fun handleDispatchTouchEvent_downAndPanelCollapsedAndInSbBoundAndSbWindowShow_sendsTouchToSb() {
-        mController.setStatusBarViewController(mPhoneStatusBarViewController)
-        whenever(mStatusBarWindowStateController.windowIsShowing()).thenReturn(true)
-        whenever(mNotificationPanelViewController.isFullyCollapsed).thenReturn(true)
-        whenever(mPhoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
+        underTest.setStatusBarViewController(phoneStatusBarViewController)
+        whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(true)
+        whenever(notificationPanelViewController.isFullyCollapsed).thenReturn(true)
+        whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
             .thenReturn(true)
-        whenever(mPhoneStatusBarViewController.sendTouchToView(downEv)).thenReturn(true)
+        whenever(phoneStatusBarViewController.sendTouchToView(downEv)).thenReturn(true)
 
-        val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(downEv)
+        val returnVal = interactionEventHandler.handleDispatchTouchEvent(downEv)
 
-        verify(mPhoneStatusBarViewController).sendTouchToView(downEv)
+        verify(phoneStatusBarViewController).sendTouchToView(downEv)
         assertThat(returnVal).isTrue()
     }
 
     @Test
     fun handleDispatchTouchEvent_panelNotCollapsed_returnsNull() {
-        mController.setStatusBarViewController(mPhoneStatusBarViewController)
-        whenever(mStatusBarWindowStateController.windowIsShowing()).thenReturn(true)
-        whenever(mPhoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
+        underTest.setStatusBarViewController(phoneStatusBarViewController)
+        whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(true)
+        whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
             .thenReturn(true)
         // Item we're testing
-        whenever(mNotificationPanelViewController.isFullyCollapsed).thenReturn(false)
+        whenever(notificationPanelViewController.isFullyCollapsed).thenReturn(false)
 
-        val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(downEv)
+        val returnVal = interactionEventHandler.handleDispatchTouchEvent(downEv)
 
-        verify(mPhoneStatusBarViewController, never()).sendTouchToView(downEv)
+        verify(phoneStatusBarViewController, never()).sendTouchToView(downEv)
         assertThat(returnVal).isNull()
     }
 
     @Test
     fun handleDispatchTouchEvent_touchNotInSbBounds_returnsNull() {
-        mController.setStatusBarViewController(mPhoneStatusBarViewController)
-        whenever(mStatusBarWindowStateController.windowIsShowing()).thenReturn(true)
-        whenever(mNotificationPanelViewController.isFullyCollapsed).thenReturn(true)
+        underTest.setStatusBarViewController(phoneStatusBarViewController)
+        whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(true)
+        whenever(notificationPanelViewController.isFullyCollapsed).thenReturn(true)
         // Item we're testing
-        whenever(mPhoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
+        whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
             .thenReturn(false)
 
-        val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(downEv)
+        val returnVal = interactionEventHandler.handleDispatchTouchEvent(downEv)
 
-        verify(mPhoneStatusBarViewController, never()).sendTouchToView(downEv)
+        verify(phoneStatusBarViewController, never()).sendTouchToView(downEv)
         assertThat(returnVal).isNull()
     }
 
     @Test
     fun handleDispatchTouchEvent_sbWindowNotShowing_noSendTouchToSbAndReturnsTrue() {
-        mController.setStatusBarViewController(mPhoneStatusBarViewController)
-        whenever(mNotificationPanelViewController.isFullyCollapsed).thenReturn(true)
-        whenever(mPhoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
+        underTest.setStatusBarViewController(phoneStatusBarViewController)
+        whenever(notificationPanelViewController.isFullyCollapsed).thenReturn(true)
+        whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
             .thenReturn(true)
         // Item we're testing
-        whenever(mStatusBarWindowStateController.windowIsShowing()).thenReturn(false)
+        whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(false)
 
-        val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(downEv)
+        val returnVal = interactionEventHandler.handleDispatchTouchEvent(downEv)
 
-        verify(mPhoneStatusBarViewController, never()).sendTouchToView(downEv)
+        verify(phoneStatusBarViewController, never()).sendTouchToView(downEv)
         assertThat(returnVal).isTrue()
     }
 
     @Test
     fun handleDispatchTouchEvent_downEventSentToSbThenAnotherEvent_sendsTouchToSb() {
-        mController.setStatusBarViewController(mPhoneStatusBarViewController)
-        whenever(mStatusBarWindowStateController.windowIsShowing()).thenReturn(true)
-        whenever(mNotificationPanelViewController.isFullyCollapsed).thenReturn(true)
-        whenever(mPhoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
+        underTest.setStatusBarViewController(phoneStatusBarViewController)
+        whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(true)
+        whenever(notificationPanelViewController.isFullyCollapsed).thenReturn(true)
+        whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
             .thenReturn(true)
 
         // Down event first
-        mInteractionEventHandler.handleDispatchTouchEvent(downEv)
+        interactionEventHandler.handleDispatchTouchEvent(downEv)
 
         // Then another event
         val nextEvent = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 0f, 0)
-        whenever(mPhoneStatusBarViewController.sendTouchToView(nextEvent)).thenReturn(true)
+        whenever(phoneStatusBarViewController.sendTouchToView(nextEvent)).thenReturn(true)
 
-        val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(nextEvent)
+        val returnVal = interactionEventHandler.handleDispatchTouchEvent(nextEvent)
 
-        verify(mPhoneStatusBarViewController).sendTouchToView(nextEvent)
+        verify(phoneStatusBarViewController).sendTouchToView(nextEvent)
         assertThat(returnVal).isTrue()
     }
 
     @Test
     fun testLowLightClockAttachedWhenExpandedStatusBarSetup() {
-        verify(mLowLightClockController).attachLowLightClockView(ArgumentMatchers.any())
+        verify(lowLightClockController).attachLowLightClockView(ArgumentMatchers.any())
     }
 
     @Test
     fun testLowLightClockShownWhenDozing() {
-        mController.setDozing(true)
-        verify(mLowLightClockController).showLowLightClock(true)
+        underTest.setDozing(true)
+        verify(lowLightClockController).showLowLightClock(true)
     }
 
     @Test
     fun testLowLightClockDozeTimeTickCalled() {
-        mController.dozeTimeTick()
-        verify(mLowLightClockController).dozeTimeTick()
+        underTest.dozeTimeTick()
+        verify(lowLightClockController).dozeTimeTick()
     }
 
     @Test
     fun testLowLightClockHiddenWhenNotDozing() {
-        mController.setDozing(true)
-        verify(mLowLightClockController).showLowLightClock(true)
-        mController.setDozing(false)
-        verify(mLowLightClockController).showLowLightClock(false)
+        underTest.setDozing(true)
+        verify(lowLightClockController).showLowLightClock(true)
+        underTest.setDozing(false)
+        verify(lowLightClockController).showLowLightClock(false)
     }
 }
 
diff --git a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
index 1af8ad3..84707a8 100644
--- a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
+++ b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
@@ -398,18 +398,7 @@
         final IBinder.DeathRecipient mDeathRecipient;
 
         private final RemoteCallbackList<IPredictionCallback> mCallbacks =
-                new RemoteCallbackList<IPredictionCallback>() {
-                    @Override
-                    public void onCallbackDied(IPredictionCallback callback) {
-                        if (DEBUG) {
-                            Slog.d(TAG, "Binder died for session Id=" + mSessionId
-                                    + " and callback=" + callback.asBinder());
-                        }
-                        if (mCallbacks.getRegisteredCallbackCount() == 0) {
-                            destroy();
-                        }
-                    }
-                };
+                new RemoteCallbackList<>();
 
         AppPredictionSessionInfo(
                 @NonNull final AppPredictionSessionId id,
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index d4155d1..867be24 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -224,6 +224,7 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
+import static com.android.server.wm.WindowManagerService.sEnableShellTransitions;
 import static com.android.server.wm.WindowState.LEGACY_POLICY_VISIBILITY;
 import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN;
 
@@ -3149,15 +3150,10 @@
         mWillCloseOrEnterPip = willCloseOrEnterPip;
     }
 
-    /**
-     * Returns whether this {@link ActivityRecord} is considered closing. Conditions are either
-     * 1. Is this app animating and was requested to be hidden
-     * 2. App is delayed closing since it might enter PIP.
-     */
-    boolean isClosingOrEnteringPip() {
-        return (isAnimating(TRANSITION | PARENTS, ANIMATION_TYPE_APP_TRANSITION)
-                && !mVisibleRequested) || mWillCloseOrEnterPip;
+    boolean willCloseOrEnterPip() {
+        return mWillCloseOrEnterPip;
     }
+
     /**
      * @return Whether AppOps allows this package to enter picture-in-picture.
      */
@@ -5272,12 +5268,19 @@
         }
 
         final int windowsCount = mChildren.size();
+        // With Shell-Transition, the activity will running a transition when it is visible.
+        // It won't be included when fromTransition is true means the call from finishTransition.
+        final boolean runningAnimation = sEnableShellTransitions ? visible
+                : isAnimating(PARENTS, ANIMATION_TYPE_APP_TRANSITION);
         for (int i = 0; i < windowsCount; i++) {
-            mChildren.get(i).onAppVisibilityChanged(visible, isAnimating(PARENTS,
-                    ANIMATION_TYPE_APP_TRANSITION));
+            mChildren.get(i).onAppVisibilityChanged(visible, runningAnimation);
         }
         setVisible(visible);
         setVisibleRequested(visible);
+        ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "commitVisibility: %s: visible=%b"
+                        + " visibleRequested=%b, isInTransition=%b, runningAnimation=%b, caller=%s",
+                this, isVisible(), mVisibleRequested, isInTransition(), runningAnimation,
+                Debug.getCallers(5));
         if (!visible) {
             stopFreezingScreen(true, true);
         } else {
@@ -5300,9 +5303,6 @@
             task.dispatchTaskInfoChangedIfNeeded(false /* force */);
             task = task.getParent().asTask();
         }
-        ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
-                "commitVisibility: %s: visible=%b mVisibleRequested=%b", this,
-                isVisible(), mVisibleRequested);
         final DisplayContent displayContent = getDisplayContent();
         displayContent.getInputMonitor().setUpdateInputWindowsNeededLw();
         if (performLayout) {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 288777b..124b8a6 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1362,7 +1362,7 @@
 
     void setInsetProvider(@InternalInsetsType int type, WindowContainer win,
             @Nullable TriConsumer<DisplayFrames, WindowContainer, Rect> frameProvider) {
-        setInsetProvider(type, win, frameProvider, null /* imeFrameProvider */);
+        setInsetProvider(type, win, frameProvider, null /* overrideFrameProviders */);
     }
 
     /**
@@ -1371,15 +1371,18 @@
      * @param type The type of inset this window provides.
      * @param win The window.
      * @param frameProvider Function to compute the frame, or {@code null} if the just the frame of
-     *                      the window should be taken.
-     * @param imeFrameProvider Function to compute the frame when dispatching insets to the IME, or
-     *                         {@code null} if the normal frame should be taken.
+     *                      the window should be taken. Only for non-WindowState providers, nav bar
+     *                      and status bar.
+     * @param overrideFrameProviders Functions to compute the frame when dispatching insets to the
+     *                               given window types, or {@code null} if the normal frame should
+     *                               be taken.
      */
     void setInsetProvider(@InternalInsetsType int type, WindowContainer win,
             @Nullable TriConsumer<DisplayFrames, WindowContainer, Rect> frameProvider,
-            @Nullable TriConsumer<DisplayFrames, WindowContainer, Rect> imeFrameProvider) {
+            @Nullable SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>>
+                    overrideFrameProviders) {
         mInsetsStateController.getSourceProvider(type).setWindowContainer(win, frameProvider,
-                imeFrameProvider);
+                overrideFrameProviders);
     }
 
     InsetsStateController getInsetsStateController() {
@@ -3865,7 +3868,7 @@
             mAtmService.onImeWindowSetOnDisplayArea(imePid, mImeWindowsContainer);
         }
         mInsetsStateController.getSourceProvider(ITYPE_IME).setWindowContainer(win,
-                mDisplayPolicy.getImeSourceFrameProvider(), null /* imeFrameProvider */);
+                mDisplayPolicy.getImeSourceFrameProvider(), null);
         computeImeTarget(true /* updateImeTarget */);
         updateImeControlTarget();
     }
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 95f7618..98a51a9 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -46,9 +46,9 @@
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
@@ -1156,7 +1156,7 @@
                 break;
             case TYPE_NAVIGATION_BAR:
                 mNavigationBar = win;
-                mDisplayContent.setInsetProvider(ITYPE_NAVIGATION_BAR, win,
+                final TriConsumer<DisplayFrames, WindowContainer, Rect> navFrameProvider =
                         (displayFrames, windowContainer, inOutFrame) -> {
                             if (!mNavButtonForcedVisible) {
                                 final LayoutParams lp =
@@ -1166,19 +1166,22 @@
                                         if (provider.type != ITYPE_NAVIGATION_BAR) {
                                             continue;
                                         }
-                                        calculateInsetsFrame(displayFrames, win, inOutFrame,
-                                                provider.source, provider.insetsSize,
-                                                lp.privateFlags, lp.gravity
-                                        );
+                                        InsetsFrameProvider.calculateInsetsFrame(
+                                                displayFrames.mUnrestricted,
+                                                win.getBounds(), displayFrames.mDisplayCutoutSafe,
+                                                inOutFrame, provider.source,
+                                                provider.insetsSize, lp.privateFlags);
                                     }
                                 }
                                 inOutFrame.inset(win.mGivenContentInsets);
                             }
-                        },
-
-                        (displayFrames, windowContainer, inOutFrame) -> {
-                            // For IME, we don't modify the frame.
-                        });
+                        };
+                final SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>> imeOverride =
+                        new SparseArray<>();
+                // For IME, we don't modify the frame.
+                imeOverride.put(TYPE_INPUT_METHOD, null);
+                mDisplayContent.setInsetProvider(ITYPE_NAVIGATION_BAR, win,
+                        navFrameProvider, imeOverride);
 
                 mDisplayContent.setInsetProvider(ITYPE_BOTTOM_MANDATORY_GESTURES, win,
                         (displayFrames, windowContainer, inOutFrame) -> {
@@ -1246,25 +1249,48 @@
                                             final LayoutParams lp =
                                                     win.mAttrs.forRotation(displayFrames.mRotation);
                                             final InsetsFrameProvider ifp =
-                                                    lp.providedInsets[index];
-                                            calculateInsetsFrame(displayFrames, windowContainer,
-                                                    inOutFrame, ifp.source, ifp.insetsSize,
-                                                    lp.privateFlags, lp.gravity);
+                                                    win.mAttrs.forRotation(displayFrames.mRotation)
+                                                            .providedInsets[index];
+                                            InsetsFrameProvider.calculateInsetsFrame(
+                                                    displayFrames.mUnrestricted,
+                                                    windowContainer.getBounds(),
+                                                    displayFrames.mDisplayCutoutSafe,
+                                                    inOutFrame, ifp.source,
+                                                    ifp.insetsSize, lp.privateFlags);
                                         } : null;
-                        final TriConsumer<DisplayFrames, WindowContainer, Rect> imeFrameProvider =
-                                provider.imeInsetsSize != null
-                                        ? (displayFrames, windowContainer, inOutFrame) -> {
-                                            inOutFrame.inset(win.mGivenContentInsets);
-                                            final LayoutParams lp =
-                                                    win.mAttrs.forRotation(displayFrames.mRotation);
-                                            final InsetsFrameProvider ifp =
-                                                    lp.providedInsets[index];
-                                            calculateInsetsFrame(displayFrames, windowContainer,
-                                                    inOutFrame, ifp.source, ifp.imeInsetsSize,
-                                                    lp.privateFlags, lp.gravity);
-                                        } : null;
+                        final InsetsFrameProvider.InsetsSizeOverride[] overrides =
+                                provider.insetsSizeOverrides;
+                        final SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>>
+                                overrideProviders;
+                        if (overrides != null) {
+                            overrideProviders = new SparseArray<>();
+                            for (int j = overrides.length - 1; j >= 0; j--) {
+                                final int overrideIndex = j;
+                                final TriConsumer<DisplayFrames, WindowContainer, Rect>
+                                        overrideFrameProvider =
+                                                (displayFrames, windowContainer, inOutFrame) -> {
+                                                    final LayoutParams lp =
+                                                            win.mAttrs.forRotation(
+                                                                    displayFrames.mRotation);
+                                                    final InsetsFrameProvider ifp =
+                                                            win.mAttrs.providedInsets[index];
+                                                    InsetsFrameProvider.calculateInsetsFrame(
+                                                            displayFrames.mUnrestricted,
+                                                            windowContainer.getBounds(),
+                                                            displayFrames.mDisplayCutoutSafe,
+                                                            inOutFrame, ifp.source,
+                                                            ifp.insetsSizeOverrides[
+                                                                    overrideIndex].insetsSize,
+                                                            lp.privateFlags);
+                                                };
+                                overrideProviders.put(overrides[j].windowType,
+                                        overrideFrameProvider);
+                            }
+                        } else {
+                            overrideProviders = null;
+                        }
                         mDisplayContent.setInsetProvider(provider.type, win, frameProvider,
-                                imeFrameProvider);
+                                overrideProviders);
                         mInsetsSourceWindowsExceptIme.add(win);
                     }
                 }
@@ -1272,40 +1298,6 @@
         }
     }
 
-    private void calculateInsetsFrame(DisplayFrames df, WindowContainer container, Rect inOutFrame,
-            int source, Insets insetsSize, @LayoutParams.PrivateFlags int privateFlags,
-            int windowGravity) {
-        boolean extendByCutout = false;
-        if (source == InsetsFrameProvider.SOURCE_DISPLAY) {
-            inOutFrame.set(df.mUnrestricted);
-        } else if (source == InsetsFrameProvider.SOURCE_CONTAINER_BOUNDS) {
-            inOutFrame.set(container.getBounds());
-        } else {
-            extendByCutout = (privateFlags & PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT) != 0;
-        }
-        if (insetsSize == null) {
-            return;
-        }
-        // Only one side of the provider shall be applied. Check in the order of left - top -
-        // right - bottom, only the first non-zero value will be applied.
-        if (insetsSize.left != 0) {
-            inOutFrame.right = inOutFrame.left + insetsSize.left;
-        } else if (insetsSize.top != 0) {
-            inOutFrame.bottom = inOutFrame.top + insetsSize.top;
-        } else if (insetsSize.right != 0) {
-            inOutFrame.left = inOutFrame.right - insetsSize.right;
-        } else if (insetsSize.bottom != 0) {
-            inOutFrame.top = inOutFrame.bottom - insetsSize.bottom;
-        } else {
-            inOutFrame.setEmpty();
-        }
-
-        if (extendByCutout) {
-            WindowLayout.extendFrameByCutout(windowGravity, df.mDisplayCutoutSafe,
-                    df.mUnrestricted, inOutFrame, sTmpRect);
-        }
-    }
-
     @WindowManagerPolicy.AltBarPosition
     private int getAltBarPosition(WindowManager.LayoutParams params) {
         switch (params.gravity) {
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index 0d4cfa3..3e6e06a 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -234,7 +234,7 @@
     //
     private static boolean isImeLayeringTarget(@NonNull InsetsControlTarget target,
             @NonNull InsetsControlTarget dcTarget) {
-        return !dcTarget.getWindow().isClosing() && target == dcTarget;
+        return !isImeTargetWindowClosing(dcTarget.getWindow()) && target == dcTarget;
     }
 
     private static boolean isAboveImeLayeringTarget(@NonNull InsetsControlTarget target,
@@ -256,7 +256,14 @@
         final InsetsControlTarget target = mDisplayContent.getImeTarget(IME_TARGET_CONTROL);
         return target == mImeRequester
                 && (mImeRequester.getWindow() == null
-                || !mImeRequester.getWindow().isClosing());
+                || !isImeTargetWindowClosing(mImeRequester.getWindow()));
+    }
+
+    private static boolean isImeTargetWindowClosing(@NonNull WindowState win) {
+        return win.mAnimatingExit || win.mActivityRecord != null
+                && (win.mActivityRecord.isInTransition()
+                    && !win.mActivityRecord.isVisibleRequested()
+                    || win.mActivityRecord.willCloseOrEnterPip());
     }
 
     private boolean isTargetChangedWithinActivity(InsetsControlTarget target) {
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index ee1ff2c..620a56d 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -289,7 +289,7 @@
         // contains all insets types.
         final InsetsState originalState = mDisplayContent.getInsetsPolicy()
                 .enforceInsetsPolicyForTarget(type, WINDOWING_MODE_FULLSCREEN, alwaysOnTop,
-                        mStateController.getRawInsetsState());
+                        attrs.type, mStateController.getRawInsetsState());
         InsetsState state = adjustVisibilityForTransientTypes(originalState);
         return adjustInsetsForRoundedCorners(token, state, state == originalState);
     }
@@ -351,12 +351,13 @@
      * @param type the inset type provided by the target
      * @param windowingMode the windowing mode of the target
      * @param isAlwaysOnTop is the target always on top
+     * @param windowType the type of the target
      * @param state the input inset state containing all the sources
      * @return The state stripped of the necessary information.
      */
     InsetsState enforceInsetsPolicyForTarget(@InternalInsetsType int type,
             @WindowConfiguration.WindowingMode int windowingMode, boolean isAlwaysOnTop,
-            InsetsState state) {
+            int windowType, InsetsState state) {
         boolean stateCopied = false;
 
         if (type != ITYPE_INVALID) {
@@ -377,21 +378,20 @@
             if (type == ITYPE_STATUS_BAR || type == ITYPE_CLIMATE_BAR) {
                 state.removeSource(ITYPE_CAPTION_BAR);
             }
-
-            // IME needs different frames for certain cases (e.g. navigation bar in gesture nav).
-            if (type == ITYPE_IME) {
-                ArrayMap<Integer, WindowContainerInsetsSourceProvider> providers = mStateController
-                        .getSourceProviders();
-                for (int i = providers.size() - 1; i >= 0; i--) {
-                    WindowContainerInsetsSourceProvider otherProvider = providers.valueAt(i);
-                    if (otherProvider.overridesImeFrame()) {
-                        InsetsSource override =
-                                new InsetsSource(
-                                        state.getSource(otherProvider.getSource().getType()));
-                        override.setFrame(otherProvider.getImeOverrideFrame());
-                        state.addSource(override);
-                    }
+        }
+        ArrayMap<Integer, WindowContainerInsetsSourceProvider> providers = mStateController
+                .getSourceProviders();
+        for (int i = providers.size() - 1; i >= 0; i--) {
+            WindowContainerInsetsSourceProvider otherProvider = providers.valueAt(i);
+            if (otherProvider.overridesFrame(windowType)) {
+                if (!stateCopied) {
+                    state = new InsetsState(state);
+                    stateCopied = true;
                 }
+                InsetsSource override =
+                        new InsetsSource(state.getSource(otherProvider.getSource().getType()));
+                override.setFrame(otherProvider.getOverriddenFrame(windowType));
+                state.addSource(override);
             }
         }
 
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 610bf05..86a73c9 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -27,7 +27,6 @@
 import static com.android.server.wm.InsetsSourceProviderProto.FAKE_CONTROL;
 import static com.android.server.wm.InsetsSourceProviderProto.FAKE_CONTROL_TARGET;
 import static com.android.server.wm.InsetsSourceProviderProto.FRAME;
-import static com.android.server.wm.InsetsSourceProviderProto.IME_OVERRIDDEN_FRAME;
 import static com.android.server.wm.InsetsSourceProviderProto.IS_LEASH_READY_FOR_DISPATCHING;
 import static com.android.server.wm.InsetsSourceProviderProto.PENDING_CONTROL_TARGET;
 import static com.android.server.wm.InsetsSourceProviderProto.SEAMLESS_ROTATING;
@@ -41,6 +40,7 @@
 import android.graphics.Insets;
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.util.SparseArray;
 import android.util.proto.ProtoOutputStream;
 import android.view.InsetsFrameProvider;
 import android.view.InsetsSource;
@@ -78,8 +78,8 @@
 
     private @Nullable ControlAdapter mAdapter;
     private TriConsumer<DisplayFrames, WindowContainer, Rect> mFrameProvider;
-    private TriConsumer<DisplayFrames, WindowContainer, Rect> mImeFrameProvider;
-    private final Rect mImeOverrideFrame = new Rect();
+    private SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>> mOverrideFrameProviders;
+    private final SparseArray<Rect> mOverrideFrames = new SparseArray<Rect>();
     private boolean mIsLeashReadyForDispatching;
     private final Rect mSourceFrame = new Rect();
     private final Rect mLastSourceFrame = new Rect();
@@ -146,12 +146,15 @@
      * @param windowContainer The window container that links to this source.
      * @param frameProvider Based on display frame state and the window, calculates the resulting
      *                      frame that should be reported to clients.
-     * @param imeFrameProvider Based on display frame state and the window, calculates the resulting
-     *                         frame that should be reported to IME.
+     *                      This will only be used when the window container providing the insets is
+     *                      not a WindowState.
+     * @param overrideFrameProviders Based on display frame state and the window, calculates the
+     *                               resulting frame that should be reported to given window type.
      */
     void setWindowContainer(@Nullable WindowContainer windowContainer,
             @Nullable TriConsumer<DisplayFrames, WindowContainer, Rect> frameProvider,
-            @Nullable TriConsumer<DisplayFrames, WindowContainer, Rect> imeFrameProvider) {
+            @Nullable SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>>
+                    overrideFrameProviders) {
         if (mWindowContainer != null) {
             if (mControllable) {
                 mWindowContainer.setControllableInsetProvider(null);
@@ -167,8 +170,9 @@
         ProtoLog.d(WM_DEBUG_WINDOW_INSETS, "InsetsSource setWin %s for type %s",
                 windowContainer, InsetsState.typeToString(mSource.getType()));
         mWindowContainer = windowContainer;
+        // TODO: remove the frame provider for non-WindowState container.
         mFrameProvider = frameProvider;
-        mImeFrameProvider = imeFrameProvider;
+        mOverrideFrameProviders = overrideFrameProviders;
         if (windowContainer == null) {
             setServerVisible(false);
             mSource.setVisibleFrame(null);
@@ -228,10 +232,25 @@
         }
         updateSourceFrameForServerVisibility();
 
-        if (mImeFrameProvider != null) {
-            mImeOverrideFrame.set(frame);
-            mImeFrameProvider.accept(mWindowContainer.getDisplayContent().mDisplayFrames,
-                    mWindowContainer, mImeOverrideFrame);
+        if (mOverrideFrameProviders != null) {
+            for (int i = mOverrideFrameProviders.size() - 1; i >= 0; i--) {
+                final int windowType = mOverrideFrameProviders.keyAt(i);
+                final Rect overrideFrame;
+                if (mOverrideFrames.contains(windowType)) {
+                    overrideFrame = mOverrideFrames.get(windowType);
+                    overrideFrame.set(frame);
+                } else {
+                    overrideFrame = new Rect(frame);
+                }
+                final TriConsumer<DisplayFrames, WindowContainer, Rect> provider =
+                        mOverrideFrameProviders.get(windowType);
+                if (provider != null) {
+                    mOverrideFrameProviders.get(windowType).accept(
+                            mWindowContainer.getDisplayContent().mDisplayFrames, mWindowContainer,
+                            overrideFrame);
+                }
+                mOverrideFrames.put(windowType, overrideFrame);
+            }
         }
 
         if (win.mGivenVisibleInsets.left != 0 || win.mGivenVisibleInsets.top != 0
@@ -552,32 +571,30 @@
         return mClientVisible;
     }
 
-    /**
-     * @return Whether this provider uses a different frame to dispatch to the IME.
-     */
-    boolean overridesImeFrame() {
-        return mImeFrameProvider != null;
+    boolean overridesFrame(int windowType) {
+        return mOverrideFrames.contains(windowType);
     }
 
-    /**
-     * @return Rect to dispatch to the IME as frame. Only valid if {@link #overridesImeFrame()}
-     *         returns {@code true}.
-     */
-    Rect getImeOverrideFrame() {
-        return mImeOverrideFrame;
+    Rect getOverriddenFrame(int windowType) {
+        return mOverrideFrames.get(windowType);
     }
 
     public void dump(PrintWriter pw, String prefix) {
         pw.println(prefix + getClass().getSimpleName());
         prefix = prefix + "  ";
         pw.print(prefix + "mSource="); mSource.dump("", pw);
+        pw.print(prefix + "mSourceFrame=");
+        pw.println(mSourceFrame);
+        if (mOverrideFrames.size() > 0) {
+            pw.print(prefix + "mOverrideFrames=");
+            pw.println(mOverrideFrames);
+        }
         if (mControl != null) {
             pw.print(prefix + "mControl=");
             mControl.dump("", pw);
         }
         pw.print(prefix);
         pw.print("mIsLeashReadyForDispatching="); pw.print(mIsLeashReadyForDispatching);
-        pw.print(" mImeOverrideFrame="); pw.print(mImeOverrideFrame.toShortString());
         pw.println();
         if (mWindowContainer != null) {
             pw.print(prefix + "mWindowContainer=");
@@ -621,7 +638,6 @@
         if (mAdapter != null && mAdapter.mCapturedLeash != null) {
             mAdapter.mCapturedLeash.dumpDebug(proto, CAPTURED_LEASH);
         }
-        mImeOverrideFrame.dumpDebug(proto, IME_OVERRIDDEN_FRAME);
         proto.write(IS_LEASH_READY_FOR_DISPATCHING, mIsLeashReadyForDispatching);
         proto.write(CLIENT_VISIBLE, mClientVisible);
         proto.write(SERVER_VISIBLE, mServerVisible);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 46091d8..af8c4c8 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1703,7 +1703,7 @@
                 mFrozenInsetsState != null ? mFrozenInsetsState : getMergedInsetsState();
         final InsetsState insetsStateForWindow = insetsPolicy
                 .enforceInsetsPolicyForTarget(insetTypeProvidedByWindow,
-                        getWindowingMode(), isAlwaysOnTop(), rawInsetsState);
+                        getWindowingMode(), isAlwaysOnTop(), mAttrs.type, rawInsetsState);
         return insetsPolicy.adjustInsetsForWindow(this, insetsStateForWindow,
                 includeTransient);
     }
@@ -3461,10 +3461,6 @@
         return mClient.asBinder().isBinderAlive();
     }
 
-    boolean isClosing() {
-        return mAnimatingExit || (mActivityRecord != null && mActivityRecord.isClosingOrEnteringPip());
-    }
-
     void sendAppVisibilityToClients() {
         super.sendAppVisibilityToClients();
 
diff --git a/services/smartspace/java/com/android/server/smartspace/SmartspacePerUserService.java b/services/smartspace/java/com/android/server/smartspace/SmartspacePerUserService.java
index dcffc9e..f041fbd 100644
--- a/services/smartspace/java/com/android/server/smartspace/SmartspacePerUserService.java
+++ b/services/smartspace/java/com/android/server/smartspace/SmartspacePerUserService.java
@@ -334,18 +334,7 @@
         @NonNull
         private final SmartspaceConfig mSmartspaceConfig;
         private final RemoteCallbackList<ISmartspaceCallback> mCallbacks =
-                new RemoteCallbackList<ISmartspaceCallback>() {
-                    @Override
-                    public void onCallbackDied(ISmartspaceCallback callback) {
-                        if (DEBUG) {
-                            Slog.d(TAG, "Binder died for session Id=" + mSessionId
-                                    + " and callback=" + callback.asBinder());
-                        }
-                        if (mCallbacks.getRegisteredCallbackCount() == 0) {
-                            destroy();
-                        }
-                    }
-                };
+                new RemoteCallbackList<>();
 
         SmartspaceSessionInfo(
                 @NonNull final SmartspaceSessionId id,
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 40e266c..11a7c7d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -2118,7 +2118,6 @@
         final WindowState appWin2 = createWindow(null, TYPE_BASE_APPLICATION, act2, "appWin2");
         appWin2.setHasSurface(true);
         assertTrue(appWin2.canBeImeTarget());
-        doReturn(true).when(appWin1).isClosing();
         doReturn(true).when(appWin1).inTransitionSelfOrParent();
 
         // Test step 3: Verify appWin2 will be the next IME target and the IME snapshot surface will
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
index ffa21fa..6c161cf 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
@@ -27,6 +27,7 @@
 import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
@@ -44,12 +45,15 @@
 
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
+import android.util.SparseArray;
 import android.view.InsetsSourceControl;
 import android.view.InsetsState;
 import android.view.InsetsVisibilities;
 
 import androidx.test.filters.SmallTest;
 
+import com.android.internal.util.function.TriConsumer;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -269,15 +273,18 @@
     @Test
     public void testImeForDispatch() {
         final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
-        final WindowState ime = createWindow(null, TYPE_APPLICATION, "ime");
+        final WindowState ime = createWindow(null, TYPE_INPUT_METHOD, "ime");
 
         // IME cannot be the IME target.
         ime.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
 
         WindowContainerInsetsSourceProvider statusBarProvider =
                 getController().getSourceProvider(ITYPE_STATUS_BAR);
-        statusBarProvider.setWindowContainer(statusBar, null, ((displayFrames, windowState, rect) ->
+        final SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>> imeOverrideProviders =
+                new SparseArray<>();
+        imeOverrideProviders.put(TYPE_INPUT_METHOD, ((displayFrames, windowState, rect) ->
                 rect.set(0, 1, 2, 3)));
+        statusBarProvider.setWindowContainer(statusBar, null, imeOverrideProviders);
         getController().getSourceProvider(ITYPE_IME).setWindowContainer(ime, null, null);
         statusBar.setControllableInsetProvider(statusBarProvider);
         statusBar.updateSourceFrame(statusBar.getFrame());