Merge "Fix group summary suppression logic when without bubbles" into sc-dev
diff --git a/core/api/current.txt b/core/api/current.txt
index d603fa0..4f28266 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -22487,6 +22487,9 @@
     field public static final String KEY_MAX_PTS_GAP_TO_ENCODER = "max-pts-gap-to-encoder";
     field public static final String KEY_MAX_WIDTH = "max-width";
     field public static final String KEY_MIME = "mime";
+    field public static final String KEY_MPEGH_COMPATIBLE_SETS = "mpegh-compatible-sets";
+    field public static final String KEY_MPEGH_PROFILE_LEVEL_INDICATION = "mpegh-profile-level-indication";
+    field public static final String KEY_MPEGH_REFERENCE_CHANNEL_LAYOUT = "mpegh-reference-channel-layout";
     field public static final String KEY_OPERATING_RATE = "operating-rate";
     field public static final String KEY_OUTPUT_REORDER_DEPTH = "output-reorder-depth";
     field public static final String KEY_PCM_ENCODING = "pcm-encoding";
@@ -39119,6 +39122,7 @@
     field public static final String ACTION_VOICE_SEARCH_HANDS_FREE = "android.speech.action.VOICE_SEARCH_HANDS_FREE";
     field public static final String ACTION_WEB_SEARCH = "android.speech.action.WEB_SEARCH";
     field public static final String DETAILS_META_DATA = "android.speech.DETAILS";
+    field public static final String EXTRA_AUDIO_INJECT_SOURCE = "android.speech.extra.AUDIO_INJECT_SOURCE";
     field public static final String EXTRA_CALLING_PACKAGE = "calling_package";
     field public static final String EXTRA_CONFIDENCE_SCORES = "android.speech.extra.CONFIDENCE_SCORES";
     field public static final String EXTRA_LANGUAGE = "android.speech.extra.LANGUAGE";
diff --git a/core/java/android/app/AppOpsManagerInternal.java b/core/java/android/app/AppOpsManagerInternal.java
index 6af4d93..341b9c5 100644
--- a/core/java/android/app/AppOpsManagerInternal.java
+++ b/core/java/android/app/AppOpsManagerInternal.java
@@ -26,6 +26,7 @@
 import com.android.internal.app.IAppOpsCallback;
 import com.android.internal.util.function.HeptFunction;
 import com.android.internal.util.function.HexFunction;
+import com.android.internal.util.function.NonaFunction;
 import com.android.internal.util.function.OctFunction;
 import com.android.internal.util.function.QuadFunction;
 import com.android.internal.util.function.TriFunction;
@@ -101,8 +102,31 @@
                         Boolean, SyncNotedAppOp> superImpl);
 
         /**
+         * Allows overriding start operation behavior.
+         *
+         * @param token The client state.
+         * @param code The op code to start.
+         * @param uid The UID for which to note.
+         * @param packageName The package for which to note. {@code null} for system package.
+         * @param attributionTag the attribution tag.
+         * @param startIfModeDefault Whether to start the op of the mode is default.
+         * @param shouldCollectAsyncNotedOp If an {@link AsyncNotedAppOp} should be collected
+         * @param message The message in the async noted op
+         * @param shouldCollectMessage whether to collect messages
+         * @param superImpl The super implementation.
+         * @return The app op note result.
+         */
+        SyncNotedAppOp startOperation(IBinder token, int code, int uid,
+                @Nullable String packageName, @Nullable String attributionTag,
+                boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp,
+                @Nullable String message, boolean shouldCollectMessage, @NonNull NonaFunction<
+                        IBinder, Integer, Integer, String, String, Boolean, Boolean, String,
+                        Boolean, SyncNotedAppOp> superImpl);
+
+        /**
          * Allows overriding start proxy operation behavior.
          *
+         * @param token The client state.
          * @param code The op code to start.
          * @param attributionSource The permission identity of the caller.
          * @param startIfModeDefault Whether to start the op of the mode is default.
diff --git a/core/java/android/speech/RecognizerIntent.java b/core/java/android/speech/RecognizerIntent.java
index 3b5a6d5..22ccd23 100644
--- a/core/java/android/speech/RecognizerIntent.java
+++ b/core/java/android/speech/RecognizerIntent.java
@@ -16,8 +16,6 @@
 
 package android.speech;
 
-import java.util.ArrayList;
-
 import android.app.Activity;
 import android.content.ActivityNotFoundException;
 import android.content.BroadcastReceiver;
@@ -28,6 +26,8 @@
 import android.content.pm.ResolveInfo;
 import android.os.Bundle;
 
+import java.util.ArrayList;
+
 /**
  * Constants for supporting speech recognition through starting an {@link Intent}
  */
@@ -39,7 +39,14 @@
      * is set by anyone but the system process, it should be overridden by the voice search
      * implementation.
      */
-    public final static String EXTRA_CALLING_PACKAGE = "calling_package";
+    public static final String EXTRA_CALLING_PACKAGE = "calling_package";
+
+    /**
+     * The extra key used in an intent which is providing an already opened audio source for the
+     * RecognitionService to use.
+     */
+    public static final String EXTRA_AUDIO_INJECT_SOURCE =
+            "android.speech.extra.AUDIO_INJECT_SOURCE";
 
     private RecognizerIntent() {
         // Not for instantiating.
diff --git a/core/java/android/text/format/DateFormat.java b/core/java/android/text/format/DateFormat.java
index 00ff687..537dffc 100755
--- a/core/java/android/text/format/DateFormat.java
+++ b/core/java/android/text/format/DateFormat.java
@@ -268,7 +268,8 @@
         DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance(locale);
         boolean allowDuplicateFields = !CompatChanges.isChangeEnabled(
                 DISALLOW_DUPLICATE_FIELD_IN_SKELETON);
-        return dtpg.getBestPattern(skeleton, allowDuplicateFields);
+        return dtpg.getBestPattern(skeleton, DateTimePatternGenerator.MATCH_NO_OPTIONS,
+                allowDuplicateFields);
     }
 
     /**
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 2d5279f..b4e4ae1 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -344,6 +344,7 @@
         <permission name="android.permission.ACTIVITY_EMBEDDING"/>
         <permission name="android.permission.FORCE_STOP_PACKAGES"/>
         <permission name="android.permission.GET_APP_OPS_STATS"/>
+        <permission name="android.permission.WATCH_APPOPS"/>
         <permission name="android.permission.INSTALL_DYNAMIC_SYSTEM"/>
         <permission name="android.permission.INSTALL_LOCATION_PROVIDER"/>
         <permission name="android.permission.INSTALL_PACKAGES"/>
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index 29fa09d..895cd3e 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -23,6 +23,7 @@
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
 import android.animation.ValueAnimator;
+import android.annotation.ColorInt;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -960,9 +961,11 @@
         float radius = getComputedRadius();
         RippleAnimationSession.AnimationProperties<Float, Paint> properties;
         RippleShader shader = new RippleShader();
-        final int color = mMaskColorFilter == null
+        // Grab the color for the current state and cut the alpha channel in
+        // half so that the ripple and background together yield full alpha.
+        final int color = clampAlpha(mMaskColorFilter == null
                 ? mState.mColor.getColorForState(getState(), Color.BLACK)
-                : mMaskColorFilter.getColor();
+                : mMaskColorFilter.getColor());
         final int effectColor = mState.mEffectColor.getColorForState(getState(), Color.MAGENTA);
         shader.setColor(color, effectColor);
         shader.setOrigin(cx, cy);
@@ -984,6 +987,13 @@
         return properties;
     }
 
+    private int clampAlpha(@ColorInt int color) {
+        if (Color.alpha(color) > 128) {
+            return  (color & 0x00FFFFFF) | 0x80000000;
+        }
+        return color;
+    }
+
     private boolean shouldUseCanvasProps(Canvas c) {
         return !mForceSoftware && c.isHardwareAccelerated();
     }
@@ -1194,10 +1204,7 @@
 
         // Grab the color for the current state and cut the alpha channel in
         // half so that the ripple and background together yield full alpha.
-        int color = mState.mColor.getColorForState(getState(), Color.BLACK);
-        if (Color.alpha(color) > 128) {
-            color = (color & 0x00FFFFFF) | 0x80000000;
-        }
+        final int color = clampAlpha(mState.mColor.getColorForState(getState(), Color.BLACK));
         final Paint p = mRipplePaint;
 
         if (mMaskColorFilter != null) {
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index 50a326e..9bf0db5 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -109,6 +109,15 @@
  * <tr><td>{@link #KEY_ENCODER_DELAY}</td><td>Integer</td><td>optional, the number of frames to trim from the start of the decoded audio stream.</td></tr>
  * <tr><td>{@link #KEY_ENCODER_PADDING}</td><td>Integer</td><td>optional, the number of frames to trim from the end of the decoded audio stream.</td></tr>
  * <tr><td>{@link #KEY_FLAC_COMPRESSION_LEVEL}</td><td>Integer</td><td><b>encoder-only</b>, optional, if content is FLAC audio, specifies the desired compression level.</td></tr>
+ * <tr><td>{@link #KEY_MPEGH_PROFILE_LEVEL_INDICATION}</td><td>Integer</td>
+ *     <td><b>decoder-only</b>, optional, if content is MPEG-H audio,
+ *         specifies the profile and level of the stream.</td></tr>
+ * <tr><td>{@link #KEY_MPEGH_COMPATIBLE_SETS}</td><td>ByteBuffer</td>
+ *     <td><b>decoder-only</b>, optional, if content is MPEG-H audio,
+ *         specifies the compatible sets (profile and level) of the stream.</td></tr>
+ * <tr><td>{@link #KEY_MPEGH_REFERENCE_CHANNEL_LAYOUT}</td>
+ *     <td>Integer</td><td><b>decoder-only</b>, optional, if content is MPEG-H audio,
+ *         specifies the preferred reference channel layout of the stream.</td></tr>
  * </table>
  *
  * Subtitle formats have the following keys:
@@ -867,6 +876,30 @@
     public static final String KEY_FLAC_COMPRESSION_LEVEL = "flac-compression-level";
 
     /**
+     * A key describing the MPEG-H stream profile-level indication.
+     *
+     * See ISO_IEC_23008-3;2019 MHADecoderConfigurationRecord mpegh3daProfileLevelIndication.
+     */
+    public static final String KEY_MPEGH_PROFILE_LEVEL_INDICATION =
+            "mpegh-profile-level-indication";
+
+    /**
+     * A key describing the MPEG-H stream compatible sets.
+     *
+     * See FDAmd_2 of ISO_IEC_23008-3;2019 MHAProfileAndLevelCompatibilitySetBox.
+     */
+    public static final String KEY_MPEGH_COMPATIBLE_SETS = "mpegh-compatible-sets";
+
+    /**
+     * A key describing the MPEG-H stream reference channel layout.
+     *
+     * See ISO_IEC_23008-3;2019 MHADecoderConfigurationRecord referenceChannelLayout
+     * and ISO_IEC_23001‐8 ChannelConfiguration value.
+     */
+    public static final String KEY_MPEGH_REFERENCE_CHANNEL_LAYOUT =
+            "mpegh-reference-channel-layout";
+
+    /**
      * A key describing the encoding complexity.
      * The associated value is an integer.  These values are device and codec specific,
      * but lower values generally result in faster and/or less power-hungry encoding.
diff --git a/packages/Connectivity/framework/src/android/net/NetworkRequest.java b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
index 90aac0e..194b8ff 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkRequest.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
@@ -220,6 +220,10 @@
         public Builder(@NonNull final NetworkRequest request) {
             Objects.requireNonNull(request);
             mNetworkCapabilities = request.networkCapabilities;
+            // If the caller constructed the builder from a request, it means the user
+            // might explicitly want the capabilities from the request. Thus, the NOT_VCN_MANAGED
+            // capabilities should not be touched later.
+            mModifiedNotVcnManaged = true;
         }
 
         /**
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index ad6de9f..6c5b230 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -300,6 +300,7 @@
     <uses-permission android:name="android.permission.COMPANION_APPROVE_WIFI_CONNECTIONS" />
 
     <uses-permission android:name="android.permission.MANAGE_APPOPS" />
+    <uses-permission android:name="android.permission.WATCH_APPOPS" />
 
     <!-- Permission required for IncrementalLogCollectionTest -->
     <uses-permission android:name="android.permission.LOADER_USAGE_STATS" />
diff --git a/packages/SystemUI/plugin/Android.bp b/packages/SystemUI/plugin/Android.bp
index f415da8..9f02fdb 100644
--- a/packages/SystemUI/plugin/Android.bp
+++ b/packages/SystemUI/plugin/Android.bp
@@ -32,6 +32,7 @@
     ],
 
     static_libs: [
+        "androidx.annotation_annotation",
         "PluginCoreLib",
         "SystemUI-sensors",
         "SystemUIAnimationLib",
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
index 46237148..d1383eb 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
@@ -15,13 +15,14 @@
 package com.android.systemui.plugins.qs;
 
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.content.Context;
 import android.graphics.drawable.Drawable;
 import android.metrics.LogMaker;
 import android.service.quicksettings.Tile;
 import android.view.View;
 
+import androidx.annotation.Nullable;
+
 import com.android.internal.logging.InstanceId;
 import com.android.systemui.plugins.annotations.DependsOn;
 import com.android.systemui.plugins.annotations.ProvidesInterface;
@@ -56,8 +57,19 @@
 
     QSIconView createTileView(Context context);
 
-    void click();
-    void secondaryClick();
+    /**
+     * The tile was clicked.
+     *
+     * @param view The view that was clicked.
+     */
+    void click(@Nullable View view);
+
+    /**
+     * The tile secondary click was triggered.
+     *
+     * @param view The view that was clicked.
+     */
+    void secondaryClick(@Nullable View view);
 
     /**
      * The tile was long clicked.
diff --git a/packages/SystemUI/res/drawable/volume_background.xml b/packages/SystemUI/res/drawable/volume_background.xml
new file mode 100644
index 0000000..66f1d0d
--- /dev/null
+++ b/packages/SystemUI/res/drawable/volume_background.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 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
+  -->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+    <item>
+        <shape>
+            <size android:width="@dimen/volume_dialog_panel_width" />
+            <solid android:color="?androidprv:attr/colorSurface" />
+            <corners android:radius="@dimen/volume_dialog_panel_width_half"/>
+        </shape>
+    </item>
+</layer-list>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/volume_row_seekbar.xml b/packages/SystemUI/res/drawable/volume_row_seekbar.xml
index a845e73..7ce1ba3 100644
--- a/packages/SystemUI/res/drawable/volume_row_seekbar.xml
+++ b/packages/SystemUI/res/drawable/volume_row_seekbar.xml
@@ -9,7 +9,6 @@
   ~      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.
@@ -19,38 +18,24 @@
      and a bottom-aligned icon) and a progress layer (with an accent-colored round rect and icon)
      that moves up and down with the progress value. -->
 <layer-list xmlns:android="http://schemas.android.com/apk/res/android"
-            android:paddingMode="stack" >
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+    android:paddingMode="stack" >
     <item android:id="@android:id/background"
         android:gravity="center_vertical|fill_horizontal">
-        <layer-list>
-            <item android:id="@+id/volume_seekbar_background_solid">
-                <shape>
-                    <size android:height="@dimen/volume_dialog_slider_width" />
-                    <solid android:color="?android:attr/colorBackgroundFloating" />
-                    <corners android:radius="@dimen/volume_dialog_slider_corner_radius" />
-                </shape>
-            </item>
-            <item
-                android:id="@+id/volume_seekbar_background_icon"
-                android:gravity="center_vertical|left"
-                android:height="@dimen/rounded_slider_icon_size"
-                android:width="@dimen/rounded_slider_icon_size"
-                android:left="@dimen/rounded_slider_icon_inset">
-                <rotate
-                    android:fromDegrees="-270"
-                    android:toDegrees="-270">
-                    <!-- A placeholder drawable is required here - it'll be replaced in code. -->
-                    <com.android.systemui.util.AlphaTintDrawableWrapper
-                        android:drawable="@drawable/ic_volume_media"
-                        android:tint="?android:attr/colorAccent" />
-                </rotate>
-            </item>
-        </layer-list>
+        <inset
+            android:insetLeft="@dimen/rounded_slider_track_inset"
+            android:insetRight="@dimen/rounded_slider_track_inset" >
+            <shape>
+                <size android:height="@dimen/volume_dialog_track_width" />
+                <corners android:radius="@dimen/volume_dialog_track_corner_radius" />
+                <solid android:color="?androidprv:attr/colorAccentSecondaryVariant" />
+            </shape>
+        </inset>
     </item>
     <item android:id="@android:id/progress"
-          android:gravity="center_vertical|fill_horizontal">
-            <com.android.systemui.util.RoundedCornerProgressDrawable
-                android:drawable="@drawable/volume_row_seekbar_progress"
+        android:gravity="center_vertical|fill_horizontal">
+        <com.android.systemui.util.RoundedCornerProgressDrawable
+            android:drawable="@drawable/volume_row_seekbar_progress"
             />
     </item>
 </layer-list>
diff --git a/packages/SystemUI/res/drawable/volume_row_seekbar_progress.xml b/packages/SystemUI/res/drawable/volume_row_seekbar_progress.xml
index ef20236..4f97ca4 100644
--- a/packages/SystemUI/res/drawable/volume_row_seekbar_progress.xml
+++ b/packages/SystemUI/res/drawable/volume_row_seekbar_progress.xml
@@ -18,12 +18,13 @@
 <!-- Progress drawable for volume row SeekBars. This is the accent-colored round rect that moves up
      and down as the progress value changes. -->
 <layer-list xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:autoMirrored="true">
     <item android:id="@+id/volume_seekbar_progress_solid">
         <shape>
-            <size android:height="@dimen/volume_dialog_panel_width" />
+            <size android:height="@dimen/volume_dialog_slider_width" />
             <solid android:color="?android:attr/colorAccent" />
-            <corners android:radius="@dimen/volume_dialog_panel_width_half"/>
+            <corners android:radius="@dimen/volume_dialog_slider_corner_radius"/>
         </shape>
     </item>
     <item
@@ -38,7 +39,7 @@
             <!-- A placeholder drawable is required here - it'll be replaced in code. -->
             <com.android.systemui.util.AlphaTintDrawableWrapper
                 android:drawable="@drawable/ic_volume_media"
-                android:tint="?android:attr/colorBackgroundFloating" />
+                android:tint="?androidprv:attr/colorAccentPrimaryVariant" />
         </rotate>
     </item>
 </layer-list>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/controls_fullscreen.xml b/packages/SystemUI/res/layout/controls_fullscreen.xml
index 1b2d2e2..7fd029c 100644
--- a/packages/SystemUI/res/layout/controls_fullscreen.xml
+++ b/packages/SystemUI/res/layout/controls_fullscreen.xml
@@ -20,8 +20,7 @@
     android:id="@+id/control_detail_root"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:orientation="vertical"
-    android:background="@android:color/black">
+    android:orientation="vertical">
 
   <com.android.systemui.globalactions.MinHeightScrollView
       android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index 6aac5a3..a39006c 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -16,114 +16,119 @@
 <FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:sysui="http://schemas.android.com/apk/res-auto"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:id="@+id/volume_dialog_container"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:gravity="right"
     android:layout_gravity="right"
-    android:paddingRight="@dimen/volume_dialog_stream_padding"
     android:clipToPadding="false"
-    android:background="@android:color/transparent"
     android:theme="@style/volume_dialog_theme">
 
     <!-- right-aligned to be physically near volume button -->
     <LinearLayout
         android:id="@+id/volume_dialog"
-        android:minWidth="@dimen/volume_dialog_panel_width"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:gravity="right"
         android:layout_gravity="right"
-        android:background="@android:color/transparent"
-        android:paddingRight="@dimen/volume_dialog_panel_transparent_padding_right"
-        android:paddingLeft="@dimen/volume_dialog_panel_transparent_padding"
+        android:layout_marginRight="@dimen/volume_dialog_panel_transparent_padding_right"
         android:orientation="vertical"
         android:clipToPadding="false"
         android:clipChildren="false">
 
-        <include layout="@layout/volume_ringer_drawer" />
-
-        <FrameLayout
-            android:visibility="gone"
-            android:id="@+id/ringer"
-            android:layout_width="@dimen/volume_dialog_ringer_size"
-            android:layout_height="@dimen/volume_dialog_ringer_size"
-            android:layout_marginBottom="@dimen/volume_dialog_spacer"
-            android:gravity="right"
-            android:layout_gravity="right"
-            android:translationZ="@dimen/volume_dialog_elevation"
-            android:clipToPadding="false"
-            android:background="@drawable/rounded_bg_full">
-            <com.android.keyguard.AlphaOptimizedImageButton
-                android:id="@+id/ringer_icon"
-                style="@style/VolumeButtons"
-                android:background="@drawable/rounded_ripple"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:scaleType="fitCenter"
-                android:padding="@dimen/volume_dialog_ringer_icon_padding"
-                android:tint="?android:attr/textColorPrimary"
-                android:layout_gravity="center"
-                android:soundEffectsEnabled="false" />
-
-            <include layout="@layout/volume_dnd_icon"
-                     android:layout_width="match_parent"
-                     android:layout_height="wrap_content"
-                     android:layout_marginRight="@dimen/volume_dialog_stream_padding"
-                     android:layout_marginTop="6dp"/>
-        </FrameLayout>
 
         <LinearLayout
-            android:id="@+id/main"
-            android:minWidth="@dimen/volume_dialog_panel_width"
+            android:id="@+id/volume_dialog_ringer_and_rows_container"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:gravity="right"
-            android:layout_gravity="right"
             android:orientation="vertical"
+            android:padding="7dp"
             android:clipChildren="false"
-            android:clipToPadding="false" >
+            android:background="@drawable/volume_background">
+
+            <include layout="@layout/volume_ringer_drawer" />
+
+            <FrameLayout
+                android:visibility="gone"
+                android:id="@+id/ringer"
+                android:layout_width="@dimen/volume_dialog_ringer_size"
+                android:layout_height="@dimen/volume_dialog_ringer_size"
+                android:layout_marginBottom="@dimen/volume_dialog_spacer"
+                android:gravity="right"
+                android:layout_gravity="right"
+                android:translationZ="@dimen/volume_dialog_elevation"
+                android:clipToPadding="false"
+                android:background="@drawable/rounded_bg_full">
+                <com.android.keyguard.AlphaOptimizedImageButton
+                    android:id="@+id/ringer_icon"
+                    style="@style/VolumeButtons"
+                    android:background="@drawable/rounded_ripple"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:scaleType="fitCenter"
+                    android:padding="@dimen/volume_dialog_ringer_icon_padding"
+                    android:tint="?android:attr/textColorPrimary"
+                    android:layout_gravity="center"
+                    android:soundEffectsEnabled="false" />
+
+                <include layout="@layout/volume_dnd_icon"
+                         android:layout_width="match_parent"
+                         android:layout_height="wrap_content"
+                         android:layout_marginRight="@dimen/volume_dialog_stream_padding"
+                         android:layout_marginTop="6dp"/>
+            </FrameLayout>
+
             <LinearLayout
-                android:id="@+id/volume_dialog_rows"
+                android:id="@+id/main"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:minWidth="@dimen/volume_dialog_panel_width"
-                android:gravity="center"
-                android:orientation="horizontal"
-                android:layout_marginTop="@dimen/volume_row_slider_padding_start">
-                    <!-- volume rows added and removed here! :-) -->
+                android:gravity="right"
+                android:layout_gravity="right"
+                android:orientation="vertical"
+                android:clipChildren="false"
+                android:clipToPadding="false" >
+                <LinearLayout
+                    android:id="@+id/volume_dialog_rows"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:gravity="center"
+                    android:orientation="horizontal"
+                    android:layout_marginTop="@dimen/volume_row_slider_padding_start">
+                        <!-- volume rows added and removed here! :-) -->
+                </LinearLayout>
+                <FrameLayout
+                    android:id="@+id/settings_container"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content">
+                    <com.android.keyguard.AlphaOptimizedImageButton
+                        android:id="@+id/settings"
+                        android:src="@drawable/horizontal_ellipsis"
+                        android:layout_width="@dimen/volume_dialog_tap_target_size"
+                        android:layout_height="@dimen/volume_dialog_tap_target_size"
+                        android:layout_gravity="center"
+                        android:contentDescription="@string/accessibility_volume_settings"
+                        android:background="@drawable/ripple_drawable_20dp"
+                        android:tint="?androidprv:attr/colorAccent"
+                        android:soundEffectsEnabled="false" />
+                </FrameLayout>
             </LinearLayout>
-            <FrameLayout
-                android:id="@+id/settings_container"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content">
-                <com.android.keyguard.AlphaOptimizedImageButton
-                    android:id="@+id/settings"
-                    android:src="@drawable/horizontal_ellipsis"
-                    android:layout_width="@dimen/volume_dialog_tap_target_size"
-                    android:layout_height="@dimen/volume_dialog_tap_target_size"
-                    android:layout_gravity="center"
-                    android:contentDescription="@string/accessibility_volume_settings"
-                    android:background="@drawable/ripple_drawable_20dp"
-                    android:tint="?android:attr/colorBackgroundFloating"
-                    android:soundEffectsEnabled="false" />
-            </FrameLayout>
+
         </LinearLayout>
 
         <FrameLayout
             android:id="@+id/odi_captions"
             android:layout_width="@dimen/volume_dialog_caption_size"
             android:layout_height="@dimen/volume_dialog_caption_size"
-            android:layout_marginTop="@dimen/volume_dialog_spacer"
+            android:layout_marginTop="@dimen/volume_dialog_row_margin_bottom"
             android:gravity="right"
-            android:layout_gravity="right"
+            android:layout_gravity="center"
             android:clipToPadding="false"
-            android:background="@drawable/rounded_bg_full">
+            android:background="@drawable/volume_background">
             <com.android.systemui.volume.CaptionsToggleImageButton
                 android:id="@+id/odi_captions_icon"
                 android:src="@drawable/ic_volume_odi_captions_disabled"
                 style="@style/VolumeButtons"
-                android:background="@drawable/rounded_ripple"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
                 android:tint="?android:attr/colorAccent"
@@ -131,7 +136,6 @@
                 android:soundEffectsEnabled="false"
                 sysui:optedOut="false"/>
         </FrameLayout>
-
     </LinearLayout>
 
     <ViewStub
diff --git a/packages/SystemUI/res/layout/volume_dialog_row.xml b/packages/SystemUI/res/layout/volume_dialog_row.xml
index 1d5bca9..446c7eb 100644
--- a/packages/SystemUI/res/layout/volume_dialog_row.xml
+++ b/packages/SystemUI/res/layout/volume_dialog_row.xml
@@ -17,7 +17,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:tag="row"
     android:layout_height="wrap_content"
-    android:layout_width="@dimen/volume_dialog_panel_width"
+    android:layout_width="@dimen/volume_dialog_slider_width"
     android:clipChildren="false"
     android:clipToPadding="false"
     android:translationZ="@dimen/volume_dialog_elevation"
@@ -25,7 +25,7 @@
 
     <LinearLayout
         android:layout_height="wrap_content"
-        android:layout_width="@dimen/volume_dialog_panel_width"
+        android:layout_width="@dimen/volume_dialog_slider_width"
         android:gravity="center"
         android:layout_gravity="center"
         android:orientation="vertical" >
@@ -54,7 +54,9 @@
                 android:layout_width="@dimen/volume_row_slider_height"
                 android:layout_height="match_parent"
                 android:layout_gravity="center"
-                android:thumb="@android:color/transparent"
+                android:thumb="@null"
+                android:splitTrack="false"
+                android:progressDrawable="@drawable/volume_row_seekbar"
                 android:rotation="270" />
         </FrameLayout>
 
diff --git a/packages/SystemUI/res/layout/volume_ringer_drawer.xml b/packages/SystemUI/res/layout/volume_ringer_drawer.xml
index d6e1782..9d14ac4 100644
--- a/packages/SystemUI/res/layout/volume_ringer_drawer.xml
+++ b/packages/SystemUI/res/layout/volume_ringer_drawer.xml
@@ -60,7 +60,7 @@
                     android:layout_width="@dimen/volume_ringer_drawer_icon_size"
                     android:layout_height="@dimen/volume_ringer_drawer_icon_size"
                     android:layout_gravity="center"
-                    android:tint="?android:attr/colorAccent"
+                    android:tint="?android:attr/textColorPrimary"
                     android:src="@drawable/ic_volume_ringer_vibrate" />
 
             </FrameLayout>
@@ -77,7 +77,7 @@
                     android:layout_width="@dimen/volume_ringer_drawer_icon_size"
                     android:layout_height="@dimen/volume_ringer_drawer_icon_size"
                     android:layout_gravity="center"
-                    android:tint="?android:attr/colorAccent"
+                    android:tint="?android:attr/textColorPrimary"
                     android:src="@drawable/ic_volume_ringer_mute" />
 
             </FrameLayout>
@@ -94,7 +94,7 @@
                     android:layout_width="@dimen/volume_ringer_drawer_icon_size"
                     android:layout_height="@dimen/volume_ringer_drawer_icon_size"
                     android:layout_gravity="center"
-                    android:tint="?android:attr/colorAccent"
+                    android:tint="?android:attr/textColorPrimary"
                     android:src="@drawable/ic_volume_ringer" />
 
             </FrameLayout>
@@ -118,7 +118,7 @@
             android:layout_width="@dimen/volume_ringer_drawer_icon_size"
             android:layout_height="@dimen/volume_ringer_drawer_icon_size"
             android:layout_gravity="center"
-            android:tint="?android:attr/colorBackgroundFloating"
+            android:tint="?android:attr/textColorPrimaryInverse"
             android:src="@drawable/ic_volume_media" />
 
     </FrameLayout>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 238b9e6..0577d46e 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -461,29 +461,33 @@
     <!-- The width of the panel that holds the quick settings. -->
     <dimen name="qs_panel_width">@dimen/notification_panel_width</dimen>
 
-    <dimen name="volume_dialog_panel_transparent_padding_right">4dp</dimen>
+    <dimen name="volume_dialog_panel_transparent_padding_right">8dp</dimen>
 
     <dimen name="volume_dialog_panel_transparent_padding">20dp</dimen>
 
     <dimen name="volume_dialog_stream_padding">12dp</dimen>
 
-    <dimen name="volume_dialog_panel_width">64dp</dimen>
+    <dimen name="volume_dialog_panel_width">56dp</dimen>
 
-    <dimen name="volume_dialog_panel_width_half">32dp</dimen>
+    <dimen name="volume_dialog_panel_width_half">28dp</dimen>
+
+    <dimen name="volume_dialog_slider_width">42dp</dimen>
+
+    <dimen name="volume_dialog_slider_corner_radius">21dp</dimen>
 
     <dimen name="volume_dialog_slider_height">116dp</dimen>
 
-    <dimen name="volume_dialog_slider_width">@dimen/volume_dialog_panel_width</dimen>
+    <dimen name="volume_dialog_track_width">4dp</dimen>
 
-    <dimen name="volume_dialog_slider_corner_radius">@dimen/volume_dialog_panel_width_half</dimen>
+    <dimen name="volume_dialog_track_corner_radius">2dp</dimen>
 
-    <dimen name="volume_dialog_ringer_size">64dp</dimen>
+    <dimen name="volume_dialog_ringer_size">42dp</dimen>
 
     <dimen name="volume_dialog_ringer_icon_padding">20dp</dimen>
 
-    <dimen name="volume_dialog_caption_size">64dp</dimen>
+    <dimen name="volume_dialog_caption_size">56dp</dimen>
 
-    <dimen name="volume_dialog_tap_target_size">48dp</dimen>
+    <dimen name="volume_dialog_tap_target_size">42dp</dimen>
 
     <dimen name="volume_dialog_spacer">4dp</dimen>
 
@@ -504,8 +508,8 @@
     <dimen name="volume_tool_tip_arrow_corner_radius">2dp</dimen>
 
     <!-- Size of each item in the ringer selector drawer. -->
-    <dimen name="volume_ringer_drawer_item_size">64dp</dimen>
-    <dimen name="volume_ringer_drawer_item_size_half">32dp</dimen>
+    <dimen name="volume_ringer_drawer_item_size">42dp</dimen>
+    <dimen name="volume_ringer_drawer_item_size_half">21dp</dimen>
 
     <!-- Size of the icon inside each item in the ringer selector drawer. -->
     <dimen name="volume_ringer_drawer_icon_size">24dp</dimen>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 43c4465..885227b 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -678,9 +678,9 @@
         <item name="android:windowActivityTransitions">true</item>
         <item name="android:windowContentTransitions">false</item>
         <item name="android:windowIsTranslucent">false</item>
-        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:windowBackground">@android:color/black</item>
         <item name="android:windowAnimationStyle">@null</item>
-        <item name="android:statusBarColor">@*android:color/transparent</item>
+        <item name="android:statusBarColor">@android:color/black</item>
         <item name="wallpaperTextColor">@*android:color/primary_text_material_dark</item>
     </style>
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
index 925c9eb..e40f293 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
@@ -210,7 +210,7 @@
         final String spec = CustomTile.toSpec(tile);
         for (TileRecord record : mRecords) {
             if (record.tile.getTileSpec().equals(spec)) {
-                record.tile.click();
+                record.tile.click(null /* view */);
                 break;
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFlagsModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFlagsModule.java
index a1e1d64..6fa44eb 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFlagsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFlagsModule.java
@@ -34,6 +34,7 @@
     String RBC_AVAILABLE = "rbc_available";
     String PM_LITE_ENABLED = "pm_lite";
     String PM_LITE_SETTING = "sysui_pm_lite";
+    int PM_LITE_SETTING_DEFAULT = 1;
 
     /** */
     @Provides
@@ -47,6 +48,7 @@
     @SysUISingleton
     @Named(PM_LITE_ENABLED)
     static boolean isPMLiteEnabled(FeatureFlags featureFlags, GlobalSettings globalSettings) {
-        return featureFlags.isPMLiteEnabled() && globalSettings.getInt(PM_LITE_SETTING, 0) != 0;
+        return featureFlags.isPMLiteEnabled()
+                && globalSettings.getInt(PM_LITE_SETTING, PM_LITE_SETTING_DEFAULT) != 0;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
index 1699a34..10eea82 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
@@ -40,10 +40,12 @@
 import android.text.format.DateUtils;
 import android.util.Log;
 import android.view.IWindowManager;
+import android.view.View;
 import android.view.WindowManagerGlobal;
 import android.widget.Switch;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -311,7 +313,7 @@
     }
 
     @Override
-    protected void handleClick() {
+    protected void handleClick(@Nullable View view) {
         if (mTile.getState() == Tile.STATE_UNAVAILABLE) {
             return;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
index 7e72f1a..c973e8c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
@@ -170,7 +170,7 @@
 
     @Override
     public void init(QSTile tile) {
-        init(v -> tile.click(), v -> tile.secondaryClick(), view -> {
+        init(v -> tile.click(this), v -> tile.secondaryClick(this), view -> {
             tile.longClick(this);
             return true;
         });
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
index ba69dd5..5ff785d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
@@ -31,7 +31,6 @@
 
 import android.annotation.CallSuper;
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.drawable.Drawable;
@@ -46,6 +45,7 @@
 import android.util.SparseArray;
 import android.view.View;
 
+import androidx.annotation.Nullable;
 import androidx.lifecycle.Lifecycle;
 import androidx.lifecycle.LifecycleOwner;
 import androidx.lifecycle.LifecycleRegistry;
@@ -135,8 +135,10 @@
      * Handles clicks by the user.
      *
      * Calls to the controller should be made here to set the new state of the device.
+     *
+     * @param view The view that was clicked.
      */
-    abstract protected void handleClick();
+    protected abstract void handleClick(@Nullable View view);
 
     /**
      * Update state of the tile based on device state
@@ -272,7 +274,7 @@
         mHandler.sendEmptyMessage(H.REMOVE_CALLBACKS);
     }
 
-    public void click() {
+    public void click(@Nullable View view) {
         mMetricsLogger.write(populate(new LogMaker(ACTION_QS_CLICK).setType(TYPE_ACTION)
                 .addTaggedData(FIELD_STATUS_BAR_STATE,
                         mStatusBarStateController.getState())));
@@ -280,11 +282,11 @@
                 getInstanceId());
         mQSLogger.logTileClick(mTileSpec, mStatusBarStateController.getState(), mState.state);
         if (!mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
-            mHandler.sendEmptyMessage(H.CLICK);
+            mHandler.obtainMessage(H.CLICK, view).sendToTarget();
         }
     }
 
-    public void secondaryClick() {
+    public void secondaryClick(@Nullable View view) {
         mMetricsLogger.write(populate(new LogMaker(ACTION_QS_SECONDARY_CLICK).setType(TYPE_ACTION)
                 .addTaggedData(FIELD_STATUS_BAR_STATE,
                         mStatusBarStateController.getState())));
@@ -292,7 +294,7 @@
                 getInstanceId());
         mQSLogger.logTileSecondaryClick(mTileSpec, mStatusBarStateController.getState(),
                 mState.state);
-        mHandler.sendEmptyMessage(H.SECONDARY_CLICK);
+        mHandler.obtainMessage(H.SECONDARY_CLICK, view).sendToTarget();
     }
 
     @Override
@@ -370,10 +372,12 @@
      * Handles secondary click on the tile.
      *
      * Defaults to {@link QSTileImpl#handleClick}
+     *
+     * @param view The view that was clicked.
      */
-    protected void handleSecondaryClick() {
+    protected void handleSecondaryClick(@Nullable View view) {
         // Default to normal click.
-        handleClick();
+        handleClick(view);
     }
 
     /**
@@ -616,11 +620,11 @@
                                 mContext, mEnforcedAdmin);
                         mActivityStarter.postStartActivityDismissingKeyguard(intent, 0);
                     } else {
-                        handleClick();
+                        handleClick((View) msg.obj);
                     }
                 } else if (msg.what == SECONDARY_CLICK) {
                     name = "handleSecondaryClick";
-                    handleSecondaryClick();
+                    handleSecondaryClick((View) msg.obj);
                 } else if (msg.what == LONG_CLICK) {
                     name = "handleLongClick";
                     handleLongClick((View) msg.obj);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
index 07abb90..22cd6f8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
@@ -29,8 +29,11 @@
 import android.service.quicksettings.Tile;
 import android.sysprop.TelephonyProperties;
 import android.telephony.TelephonyManager;
+import android.view.View;
 import android.widget.Switch;
 
+import androidx.annotation.Nullable;
+
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
@@ -92,7 +95,7 @@
     }
 
     @Override
-    public void handleClick() {
+    public void handleClick(@Nullable View view) {
         boolean airplaneModeEnabled = mState.value;
         MetricsLogger.action(mContext, getMetricsCategory(), !airplaneModeEnabled);
         if (!airplaneModeEnabled && TelephonyProperties.in_ecm_mode().orElse(false)) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt
index 2945c6b..c2a6255 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt
@@ -9,9 +9,11 @@
 import android.service.quicksettings.Tile
 import android.text.TextUtils
 import android.text.format.DateFormat
+import android.view.View
 import androidx.annotation.VisibleForTesting
 import com.android.internal.logging.MetricsLogger
 import com.android.systemui.R
+import com.android.systemui.animation.ActivityLaunchAnimator
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.plugins.ActivityStarter
@@ -73,14 +75,15 @@
         }
     }
 
-    private fun startDefaultSetAlarm() {
-        mActivityStarter.postStartActivityDismissingKeyguard(defaultIntent, 0)
-    }
-
-    override fun handleClick() {
-        lastAlarmInfo?.showIntent?.let {
-                mActivityStarter.postStartActivityDismissingKeyguard(it)
-        } ?: startDefaultSetAlarm()
+    override fun handleClick(view: View?) {
+        val animationController = view?.let { ActivityLaunchAnimator.Controller.fromView(it) }
+        val pendingIntent = lastAlarmInfo?.showIntent
+        if (pendingIntent != null) {
+            mActivityStarter.postStartActivityDismissingKeyguard(pendingIntent, animationController)
+        } else {
+            mActivityStarter.postStartActivityDismissingKeyguard(defaultIntent, 0,
+                    animationController)
+        }
     }
 
     override fun handleUpdateState(state: QSTile.State, arg: Any?) {
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 49d3ff9..e3024fa 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
@@ -20,8 +20,11 @@
 import android.os.Looper;
 import android.provider.Settings.Secure;
 import android.service.quicksettings.Tile;
+import android.view.View;
 import android.widget.Switch;
 
+import androidx.annotation.Nullable;
+
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -120,7 +123,7 @@
     }
 
     @Override
-    protected void handleClick() {
+    protected void handleClick(@Nullable View view) {
         if (getState().state == Tile.STATE_UNAVAILABLE) {
             return;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 56df4d8..65b6617 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -16,7 +16,6 @@
 
 package com.android.systemui.qs.tiles;
 
-import android.annotation.Nullable;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothClass;
 import android.bluetooth.BluetoothDevice;
@@ -33,6 +32,8 @@
 import android.view.ViewGroup;
 import android.widget.Switch;
 
+import androidx.annotation.Nullable;
+
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settingslib.Utils;
@@ -96,7 +97,7 @@
     }
 
     @Override
-    protected void handleClick() {
+    protected void handleClick(@Nullable View view) {
         // Secondary clicks are header clicks, just toggle.
         final boolean isEnabled = mState.value;
         // Immediately enter transient enabling state when turning bluetooth on.
@@ -110,7 +111,7 @@
     }
 
     @Override
-    protected void handleSecondaryClick() {
+    protected void handleSecondaryClick(@Nullable View view) {
         if (!mController.canConfigBluetooth()) {
             mActivityStarter.postStartActivityDismissingKeyguard(
                     new Intent(Settings.ACTION_BLUETOOTH_SETTINGS), 0);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index d78dbae9..4b13015 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -33,6 +33,8 @@
 import android.view.WindowManager.LayoutParams;
 import android.widget.Button;
 
+import androidx.annotation.Nullable;
+
 import com.android.internal.app.MediaRouteDialogPresenter;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -137,17 +139,12 @@
     }
 
     @Override
-    protected void handleSecondaryClick() {
-        handleClick();
+    protected void handleLongClick(@Nullable View view) {
+        handleClick(view);
     }
 
     @Override
-    protected void handleLongClick(View view) {
-        handleClick();
-    }
-
-    @Override
-    protected void handleClick() {
+    protected void handleClick(@Nullable View view) {
         if (getState().state == Tile.STATE_UNAVAILABLE) {
             return;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 8cc6ff2..8e886e8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -37,6 +37,8 @@
 import android.view.WindowManager.LayoutParams;
 import android.widget.Switch;
 
+import androidx.annotation.Nullable;
+
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settingslib.net.DataUsageController;
@@ -116,7 +118,7 @@
     }
 
     @Override
-    protected void handleClick() {
+    protected void handleClick(@Nullable View view) {
         if (getState().state == Tile.STATE_UNAVAILABLE) {
             return;
         }
@@ -157,7 +159,7 @@
     }
 
     @Override
-    protected void handleSecondaryClick() {
+    protected void handleSecondaryClick(@Nullable View view) {
         if (mDataController.isMobileDataSupported()) {
             showDetail(true);
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
index ca7cf83..5e502cc 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -23,8 +23,11 @@
 import android.provider.Settings;
 import android.provider.Settings.Secure;
 import android.service.quicksettings.Tile;
+import android.view.View;
 import android.widget.Switch;
 
+import androidx.annotation.Nullable;
+
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
@@ -115,7 +118,7 @@
     }
 
     @Override
-    protected void handleClick() {
+    protected void handleClick(@Nullable View view) {
         mSetting.setValue(mState.value ? 0 : 1);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
index 61376f0..5a11ff8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
@@ -20,8 +20,11 @@
 import android.os.Looper;
 import android.provider.Settings;
 import android.service.quicksettings.Tile;
+import android.view.View;
 import android.widget.Switch;
 
+import androidx.annotation.Nullable;
+
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.Prefs;
@@ -73,7 +76,7 @@
         return new Intent(Settings.ACTION_DATA_SAVER_SETTINGS);
     }
     @Override
-    protected void handleClick() {
+    protected void handleClick(@Nullable View view) {
         if (mState.value
                 || Prefs.getBoolean(mContext, Prefs.Key.QS_DATA_SAVER_DIALOG_SHOWN, false)) {
             // Do it right away.
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
index a2c7633..2168b1f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
@@ -22,8 +22,10 @@
 import android.os.Looper
 import android.provider.Settings
 import android.service.quicksettings.Tile
+import android.view.View
 import com.android.internal.logging.MetricsLogger
 import com.android.systemui.R
+import com.android.systemui.animation.ActivityLaunchAnimator
 import com.android.systemui.controls.ControlsServiceInfo
 import com.android.systemui.controls.dagger.ControlsComponent
 import com.android.systemui.controls.dagger.ControlsComponent.Visibility.AVAILABLE
@@ -96,16 +98,19 @@
         super.handleDestroy()
     }
 
-    override fun handleClick() {
+    override fun handleClick(view: View?) {
         if (state.state == Tile.STATE_ACTIVE) {
             mUiHandler.post {
-                mHost.collapsePanels()
                 val i = Intent().apply {
                     component = ComponentName(mContext, ControlsActivity::class.java)
                     addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
                     putExtra(ControlsUiController.EXTRA_ANIMATE, true)
                 }
-                mContext.startActivity(i)
+
+                val animationController = view?.let {
+                    ActivityLaunchAnimator.Controller.fromView(it)
+                }
+                mActivityStarter.startActivity(i, true /* dismissShade */, animationController)
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 4b96cf3..e896c7c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -45,6 +45,8 @@
 import android.widget.Switch;
 import android.widget.Toast;
 
+import androidx.annotation.Nullable;
+
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settingslib.notification.EnableZenModeDialog;
@@ -137,7 +139,7 @@
     }
 
     @Override
-    protected void handleClick() {
+    protected void handleClick(@Nullable View view) {
         // Zen is currently on
         if (mState.value) {
             mController.setZen(ZEN_MODE_OFF, null, TAG);
@@ -191,7 +193,7 @@
     }
 
     @Override
-    protected void handleSecondaryClick() {
+    protected void handleSecondaryClick(@Nullable View view) {
         if (mController.isVolumeRestricted()) {
             // Collapse the panels, so the user can see the toast.
             mHost.collapsePanels();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
index b7cb615..c0065a0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -25,6 +25,8 @@
 import android.view.View;
 import android.widget.Switch;
 
+import androidx.annotation.Nullable;
+
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
@@ -93,7 +95,7 @@
     }
 
     @Override
-    protected void handleClick() {
+    protected void handleClick(@Nullable View view) {
         if (ActivityManager.isUserAMonkey()) {
             return;
         }
@@ -108,8 +110,8 @@
     }
 
     @Override
-    protected void handleLongClick(View view) {
-        handleClick();
+    protected void handleLongClick(@Nullable View view) {
+        handleClick(view);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index 4e0f634..34f2b63 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -16,7 +16,6 @@
 
 package com.android.systemui.qs.tiles;
 
-import android.annotation.Nullable;
 import android.content.Intent;
 import android.os.Handler;
 import android.os.Looper;
@@ -24,8 +23,11 @@
 import android.provider.Settings;
 import android.service.quicksettings.Tile;
 import android.util.Log;
+import android.view.View;
 import android.widget.Switch;
 
+import androidx.annotation.Nullable;
+
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
@@ -105,7 +107,7 @@
     }
 
     @Override
-    protected void handleClick() {
+    protected void handleClick(@Nullable View view) {
         final boolean isEnabled = mState.value;
         if (!isEnabled && mDataSaverController.isDataSaverEnabled()) {
             return;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
index 1a17e61..5dcbf49 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
@@ -29,8 +29,11 @@
 import android.text.Html;
 import android.text.TextUtils;
 import android.util.Log;
+import android.view.View;
 import android.widget.Switch;
 
+import androidx.annotation.Nullable;
+
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settingslib.graph.SignalDrawable;
@@ -110,7 +113,7 @@
     }
 
     @Override
-    protected void handleClick() {
+    protected void handleClick(@Nullable View view) {
         mActivityStarter.postStartActivityDismissingKeyguard(INTERNET_PANEL, 0);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index 830a1fd..6a018f6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -22,8 +22,11 @@
 import android.os.UserManager;
 import android.provider.Settings;
 import android.service.quicksettings.Tile;
+import android.view.View;
 import android.widget.Switch;
 
+import androidx.annotation.Nullable;
+
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
@@ -83,7 +86,7 @@
     }
 
     @Override
-    protected void handleClick() {
+    protected void handleClick(@Nullable View view) {
         if (mKeyguard.isMethodSecure() && mKeyguard.isShowing()) {
             mActivityStarter.postQSRunnableDismissingKeyguard(() -> {
                 final boolean wasEnabled = mState.value;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
index 6ac2f9ae..cd2e27a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
@@ -27,8 +27,11 @@
 import android.os.Looper;
 import android.provider.Settings;
 import android.service.quicksettings.Tile;
+import android.view.View;
 import android.widget.Switch;
 
+import androidx.annotation.Nullable;
+
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
@@ -111,7 +114,7 @@
     }
 
     @Override
-    protected void handleClick() {
+    protected void handleClick(@Nullable View view) {
         if (getAdapter() == null) {
             return;
         }
@@ -123,11 +126,6 @@
     }
 
     @Override
-    protected void handleSecondaryClick() {
-        handleClick();
-    }
-
-    @Override
     public CharSequence getTileLabel() {
         return mContext.getString(R.string.quick_settings_nfc_label);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
index 5369086..81813db 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
@@ -18,7 +18,6 @@
 
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_QS_MODE;
 
-import android.annotation.Nullable;
 import android.content.Intent;
 import android.hardware.display.ColorDisplayManager;
 import android.hardware.display.NightDisplayListener;
@@ -29,8 +28,10 @@
 import android.service.quicksettings.Tile;
 import android.text.TextUtils;
 import android.util.Log;
+import android.view.View;
 import android.widget.Switch;
 
+import androidx.annotation.Nullable;
 import androidx.annotation.StringRes;
 
 import com.android.internal.logging.MetricsLogger;
@@ -107,7 +108,7 @@
     }
 
     @Override
-    protected void handleClick() {
+    protected void handleClick(@Nullable View view) {
         // Enroll in forced auto mode if eligible.
         if ("1".equals(Settings.Global.getString(mContext.getContentResolver(),
                 Settings.Global.NIGHT_DISPLAY_FORCED_AUTO_MODE_AVAILABLE))
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
index 6f19276..ff830bc 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
@@ -30,12 +30,15 @@
 import android.service.quickaccesswallet.WalletCard;
 import android.service.quicksettings.Tile;
 import android.util.Log;
+import android.view.View;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.R;
+import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.ActivityStarter;
@@ -117,21 +120,25 @@
     }
 
     @Override
-    protected void handleClick() {
+    protected void handleClick(@Nullable View view) {
+        ActivityLaunchAnimator.Controller animationController =
+                view == null ? null : ActivityLaunchAnimator.Controller.fromView(view);
+
         mUiHandler.post(() -> {
-            mHost.collapsePanels();
             if (mHasCard) {
                 Intent intent = new Intent(mContext, WalletActivity.class)
                         .setAction(Intent.ACTION_VIEW)
                         .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
-                mContext.startActivity(intent);
+                mActivityStarter.startActivity(intent, true /* dismissShade */,
+                        animationController);
             } else {
                 if (mQuickAccessWalletClient.createWalletIntent() == null) {
                     Log.w(TAG, "Could not get intent of the wallet app.");
                     return;
                 }
                 mActivityStarter.postStartActivityDismissingKeyguard(
-                        mQuickAccessWalletClient.createWalletIntent(), /* delay= */ 0);
+                        mQuickAccessWalletClient.createWalletIntent(), /* delay= */ 0,
+                        animationController);
             }
         });
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java
index 44eeaf4..6921ad5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java
@@ -23,8 +23,11 @@
 import android.os.Looper;
 import android.provider.Settings;
 import android.service.quicksettings.Tile;
+import android.view.View;
 import android.widget.Switch;
 
+import androidx.annotation.Nullable;
+
 import com.android.internal.R;
 import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.R.drawable;
@@ -92,7 +95,7 @@
     }
 
     @Override
-    protected void handleClick() {
+    protected void handleClick(@Nullable View view) {
         mReduceBrightColorsController.setReduceBrightColorsActivated(!mState.value);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
index 173cc05..0bbb5bd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
@@ -23,8 +23,11 @@
 import android.os.Looper;
 import android.provider.Settings;
 import android.service.quicksettings.Tile;
+import android.view.View;
 import android.widget.Switch;
 
+import androidx.annotation.Nullable;
+
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
@@ -77,7 +80,7 @@
     }
 
     @Override
-    protected void handleClick() {
+    protected void handleClick(@Nullable View view) {
         final boolean newState = !mState.value;
         mController.setRotationLocked(!newState);
         refreshState(newState);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
index 6845dc5..a4148ee 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
@@ -22,8 +22,11 @@
 import android.service.quicksettings.Tile;
 import android.text.TextUtils;
 import android.util.Log;
+import android.view.View;
 import android.widget.Switch;
 
+import androidx.annotation.Nullable;
+
 import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.R;
 import com.android.systemui.dagger.qualifiers.Background;
@@ -80,7 +83,7 @@
     }
 
     @Override
-    protected void handleClick() {
+    protected void handleClick(@Nullable View view) {
         if (mController.isStarting()) {
             cancelCountdown();
         } else if (mController.isRecording()) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyToggleTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyToggleTile.java
index 5d2d6f8..3d9c272 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyToggleTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyToggleTile.java
@@ -21,9 +21,11 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.service.quicksettings.Tile;
+import android.view.View;
 import android.widget.Switch;
 
 import androidx.annotation.DrawableRes;
+import androidx.annotation.Nullable;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.R;
@@ -82,7 +84,7 @@
     }
 
     @Override
-    protected void handleClick() {
+    protected void handleClick(@Nullable View view) {
         if (mKeyguard.isMethodSecure() && mKeyguard.isShowing()) {
             mActivityStarter.postQSRunnableDismissingKeyguard(() -> {
                 mSensorPrivacyController.setSensorBlocked(getSensorId(),
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java
index 0ef5bc8..596d8f0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java
@@ -24,8 +24,11 @@
 import android.provider.Settings;
 import android.service.quicksettings.Tile;
 import android.text.TextUtils;
+import android.view.View;
 import android.widget.Switch;
 
+import androidx.annotation.Nullable;
+
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.systemui.R;
@@ -101,7 +104,7 @@
     }
 
     @Override
-    protected void handleClick() {
+    protected void handleClick(@Nullable View view) {
         if (getState().state == Tile.STATE_UNAVAILABLE) {
             return;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java
index 2590f37..e110a64 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java
@@ -22,6 +22,9 @@
 import android.os.Looper;
 import android.provider.Settings;
 import android.util.Pair;
+import android.view.View;
+
+import androidx.annotation.Nullable;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -78,7 +81,7 @@
     }
 
     @Override
-    protected void handleClick() {
+    protected void handleClick(@Nullable View view) {
         showDetail(true);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 86ea50c..efac141 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -30,6 +30,8 @@
 import android.view.ViewGroup;
 import android.widget.Switch;
 
+import androidx.annotation.Nullable;
+
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settingslib.wifi.AccessPoint;
@@ -129,7 +131,7 @@
     }
 
     @Override
-    protected void handleClick() {
+    protected void handleClick(@Nullable View view) {
         // Secondary clicks are header clicks, just toggle.
         mState.copyTo(mStateBeforeClick);
         boolean wifiEnabled = mState.value;
@@ -148,7 +150,7 @@
     }
 
     @Override
-    protected void handleSecondaryClick() {
+    protected void handleSecondaryClick(@Nullable View view) {
         if (!mWifiController.canConfigWifi()) {
             mActivityStarter.postStartActivityDismissingKeyguard(
                     new Intent(Settings.ACTION_WIFI_SETTINGS), 0);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
index c88a002..ef2c1c9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
@@ -21,8 +21,11 @@
 import android.os.Looper;
 import android.provider.Settings;
 import android.service.quicksettings.Tile;
+import android.view.View;
 import android.widget.Switch;
 
+import androidx.annotation.Nullable;
+
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
@@ -75,7 +78,7 @@
     }
 
     @Override
-    public void handleClick() {
+    public void handleClick(@Nullable View view) {
         mProfileController.setWorkModeEnabled(!mState.value);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
index 0b6a5c9..d925a93 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
@@ -6,7 +6,6 @@
 import com.android.systemui.statusbar.NotificationShadeDepthController
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer
-import com.android.systemui.statusbar.phone.NotificationPanelViewController
 import com.android.systemui.statusbar.phone.NotificationShadeWindowViewController
 import kotlin.math.ceil
 import kotlin.math.max
@@ -14,7 +13,6 @@
 /** A provider of [NotificationLaunchAnimatorController]. */
 class NotificationLaunchAnimatorControllerProvider(
     private val notificationShadeWindowViewController: NotificationShadeWindowViewController,
-    private val notificationPanelViewController: NotificationPanelViewController,
     private val notificationListContainer: NotificationListContainer,
     private val depthController: NotificationShadeDepthController
 ) {
@@ -23,7 +21,6 @@
     ): NotificationLaunchAnimatorController {
         return NotificationLaunchAnimatorController(
             notificationShadeWindowViewController,
-            notificationPanelViewController,
             notificationListContainer,
             depthController,
             notification
@@ -38,7 +35,6 @@
  */
 class NotificationLaunchAnimatorController(
     private val notificationShadeWindowViewController: NotificationShadeWindowViewController,
-    private val notificationPanelViewController: NotificationPanelViewController,
     private val notificationListContainer: NotificationListContainer,
     private val depthController: NotificationShadeDepthController,
     private val notification: ExpandableNotificationRow
@@ -97,7 +93,6 @@
     }
 
     override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
-        notificationPanelViewController.setLaunchingNotification(true)
         notification.isExpandAnimationRunning = true
         notificationListContainer.setExpandingNotification(notification)
 
@@ -108,7 +103,6 @@
     override fun onLaunchAnimationEnd(isExpandingFullyAbove: Boolean) {
         InteractionJankMonitor.getInstance().end(InteractionJankMonitor.CUJ_NOTIFICATION_APP_START)
 
-        notificationPanelViewController.setLaunchingNotification(false)
         notification.isExpandAnimationRunning = false
         notificationShadeWindowViewController.setExpandAnimationRunning(false)
         notificationListContainer.setExpandingNotification(null)
@@ -118,7 +112,6 @@
     private fun applyParams(params: ExpandAnimationParameters?) {
         notification.applyExpandAnimationParams(params)
         notificationListContainer.applyExpandAnimationParams(params)
-        notificationPanelViewController.applyExpandAnimationParams(params)
         depthController.notificationLaunchAnimationParams = params
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 6c65bb4..40680dc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -122,7 +122,6 @@
 import com.android.systemui.statusbar.notification.AnimatableProperty;
 import com.android.systemui.statusbar.notification.ConversationNotificationManager;
 import com.android.systemui.statusbar.notification.DynamicPrivacyController;
-import com.android.systemui.statusbar.notification.ExpandAnimationParameters;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
 import com.android.systemui.statusbar.notification.PropertyAnimator;
@@ -183,7 +182,7 @@
     private static final int FLING_HIDE = 2;
     private static final long ANIMATION_DELAY_ICON_FADE_IN =
             ActivityLaunchAnimator.ANIMATION_DURATION - CollapsedStatusBarFragment.FADE_IN_DURATION
-                    - CollapsedStatusBarFragment.FADE_IN_DELAY - 16;
+                    - CollapsedStatusBarFragment.FADE_IN_DELAY - 48;
 
     private final DozeParameters mDozeParameters;
     private final OnHeightChangedListener mOnHeightChangedListener = new OnHeightChangedListener();
@@ -444,7 +443,7 @@
     private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
     private boolean mUserSetupComplete;
     private int mQsNotificationTopPadding;
-    private boolean mHideIconsDuringNotificationLaunch = true;
+    private boolean mHideIconsDuringLaunchAnimation = true;
     private int mStackScrollerMeasuringPass;
     private ArrayList<Consumer<ExpandableNotificationRow>>
             mTrackingHeadsUpListeners =
@@ -3112,8 +3111,8 @@
     }
 
     public boolean hideStatusBarIconsWhenExpanded() {
-        if (mLaunchingNotification) {
-            return mHideIconsDuringNotificationLaunch;
+        if (mIsLaunchAnimationRunning) {
+            return mHideIconsDuringLaunchAnimation;
         }
         if (mHeadsUpAppearanceController != null
                 && mHeadsUpAppearanceController.shouldBeVisible()) {
@@ -3242,14 +3241,11 @@
         mKeyguardBottomArea.setUserSetupComplete(userSetupComplete);
     }
 
-    public void applyExpandAnimationParams(ExpandAnimationParameters params) {
-        if (params == null) {
-            return;
-        }
-
-        boolean hideIcons = params.getProgress(ANIMATION_DELAY_ICON_FADE_IN, 100) == 0.0f;
-        if (hideIcons != mHideIconsDuringNotificationLaunch) {
-            mHideIconsDuringNotificationLaunch = hideIcons;
+    public void applyLaunchAnimationProgress(float linearProgress) {
+        boolean hideIcons = ActivityLaunchAnimator.getProgress(linearProgress,
+                ANIMATION_DELAY_ICON_FADE_IN, 100) == 0.0f;
+        if (hideIcons != mHideIconsDuringLaunchAnimation) {
+            mHideIconsDuringLaunchAnimation = hideIcons;
             if (!hideIcons) {
                 mCommandQueue.recomputeDisableFlags(mDisplayId, true /* animate */);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
index a80e270..064086a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
@@ -83,7 +83,7 @@
     private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
     private boolean mPanelUpdateWhenAnimatorEnds;
     private boolean mVibrateOnOpening;
-    protected boolean mLaunchingNotification;
+    protected boolean mIsLaunchAnimationRunning;
     private int mFixedDuration = NO_FIXED_DURATION;
     protected ArrayList<PanelExpansionListener> mExpansionListeners = new ArrayList<>();
 
@@ -830,7 +830,7 @@
     }
 
     public boolean isCollapsing() {
-        return mClosing || mLaunchingNotification;
+        return mClosing || mIsLaunchAnimationRunning;
     }
 
     public boolean isTracking() {
@@ -1130,8 +1130,8 @@
         mHeadsUpManager = headsUpManager;
     }
 
-    public void setLaunchingNotification(boolean launchingNotification) {
-        mLaunchingNotification = launchingNotification;
+    public void setIsLaunchAnimationRunning(boolean running) {
+        mIsLaunchAnimationRunning = running;
     }
 
     public void collapseWithDuration(int animationDuration) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 0e99d3a..026072b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -1386,7 +1386,6 @@
         mActivityLaunchAnimator = new ActivityLaunchAnimator(mContext);
         mNotificationAnimationProvider = new NotificationLaunchAnimatorControllerProvider(
                 mNotificationShadeWindowViewController,
-                mNotificationPanelViewController,
                 mStackScrollerController.getNotificationListContainer(),
                 mNotificationShadeDepthControllerLazy.get()
         );
@@ -1600,6 +1599,10 @@
         return mNotificationShadeWindowViewController;
     }
 
+    public NotificationPanelViewController getNotificationPanelViewController() {
+        return mNotificationPanelViewController;
+    }
+
     protected ViewGroup getBouncerContainer() {
         return mNotificationShadeWindowView;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLaunchAnimatorController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLaunchAnimatorController.kt
index 2f52158..4a56020 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLaunchAnimatorController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLaunchAnimatorController.kt
@@ -20,6 +20,7 @@
 
     override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
         delegate.onLaunchAnimationStart(isExpandingFullyAbove)
+        statusBar.notificationPanelViewController.setIsLaunchAnimationRunning(true)
         if (!isExpandingFullyAbove) {
             statusBar.collapsePanelWithDuration(ActivityLaunchAnimator.ANIMATION_DURATION.toInt())
         }
@@ -28,6 +29,16 @@
     override fun onLaunchAnimationEnd(isExpandingFullyAbove: Boolean) {
         delegate.onLaunchAnimationEnd(isExpandingFullyAbove)
         statusBar.onLaunchAnimationEnd(isExpandingFullyAbove)
+        statusBar.notificationPanelViewController.setIsLaunchAnimationRunning(false)
+    }
+
+    override fun onLaunchAnimationProgress(
+        state: ActivityLaunchAnimator.State,
+        progress: Float,
+        linearProgress: Float
+    ) {
+        delegate.onLaunchAnimationProgress(state, progress, linearProgress)
+        statusBar.notificationPanelViewController.applyLaunchAnimationProgress(linearProgress)
     }
 
     override fun onLaunchAnimationCancelled() {
diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
index 5cd3e57..08cdebd 100644
--- a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
@@ -43,6 +43,7 @@
 import android.text.format.DateUtils;
 import android.util.Log;
 import android.util.LongSparseArray;
+import android.view.View;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.Dumpable;
@@ -432,7 +433,7 @@
         }
 
         @Override
-        protected void handleClick() {
+        protected void handleClick(@Nullable View view) {
             if (dumpInProgress) return;
 
             dumpInProgress = true;
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 8459b7b..6953039 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -53,6 +53,7 @@
 import android.content.res.TypedArray;
 import android.graphics.Color;
 import android.graphics.PixelFormat;
+import android.graphics.Rect;
 import android.graphics.Region;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
@@ -96,6 +97,8 @@
 import android.widget.TextView;
 import android.widget.Toast;
 
+import androidx.annotation.Nullable;
+
 import com.android.internal.graphics.drawable.BackgroundBlurDrawable;
 import com.android.settingslib.Utils;
 import com.android.systemui.Dependency;
@@ -162,6 +165,9 @@
     private ViewGroup mDialogRowsView;
     private ViewGroup mRinger;
 
+    @Nullable private View mRingerAndRowsContainer;
+    @Nullable private Drawable mRingerAndRowsContainerBackground;
+
     private ViewGroup mSelectedRingerContainer;
     private ImageView mSelectedRingerIcon;
 
@@ -183,6 +189,12 @@
     private ImageView mRingerDrawerIconAnimatingSelected;
     private ImageView mRingerDrawerIconAnimatingDeselected;
 
+    /**
+     * Animates the volume dialog's background drawable bounds upwards, to match the height of the
+     * expanded ringer drawer.
+     */
+    private final ValueAnimator mAnimateUpBackgroundToMatchDrawer = ValueAnimator.ofFloat(1f, 0f);
+
     private boolean mIsRingerDrawerOpen = false;
 
     private ImageButton mRingerIcon;
@@ -586,20 +598,26 @@
 
         row.anim = null;
 
+        mRingerAndRowsContainer = mDialogView.findViewById(
+                R.id.volume_dialog_ringer_and_rows_container);
+
+        if (mRingerAndRowsContainer != null) {
+            // Wait for layout so the background bounds are set, then set the background top to the
+            // ringer drawer closed position.
+            mRingerAndRowsContainer.post(() -> {
+                final LayerDrawable bgWrapper =
+                        ((LayerDrawable) mRingerAndRowsContainer.getBackground());
+
+                if (bgWrapper != null) {
+                    mRingerAndRowsContainerBackground = bgWrapper.getDrawable(0);
+                    setRingerAndRowsBackgroundTop(1f /* closedAmount */);
+                }
+            });
+        }
+
         final LayerDrawable seekbarDrawable =
                 (LayerDrawable) mContext.getDrawable(R.drawable.volume_row_seekbar);
 
-        final LayerDrawable seekbarBgDrawable =
-                (LayerDrawable) seekbarDrawable.findDrawableByLayerId(android.R.id.background);
-
-        row.sliderBgSolid = seekbarBgDrawable.findDrawableByLayerId(
-                R.id.volume_seekbar_background_solid);
-
-        final Drawable sliderBgIcon = seekbarBgDrawable.findDrawableByLayerId(
-                        R.id.volume_seekbar_background_icon);
-        row.sliderBgIcon =  sliderBgIcon != null ? (AlphaTintDrawableWrapper)
-                ((RotateDrawable) sliderBgIcon).getDrawable() : null;
-
         final LayerDrawable seekbarProgressDrawable = (LayerDrawable)
                 ((RoundedCornerProgressDrawable) seekbarDrawable.findDrawableByLayerId(
                         android.R.id.progress)).getDrawable();
@@ -679,10 +697,10 @@
                     mDialogView.getPaddingLeft(),
                     mDialogView.getPaddingTop(),
                     mDialogView.getPaddingRight(),
-                    mDialogView.getPaddingBottom() + (mRingerCount - 1) * mRingerDrawerItemSize);
+                    mDialogView.getPaddingBottom() + getRingerDrawerOpenExtraHeight());
         } else {
             mDialogView.setPadding(
-                    mDialogView.getPaddingLeft() + (mRingerCount - 1) * mRingerDrawerItemSize,
+                    mDialogView.getPaddingLeft() + getRingerDrawerOpenExtraHeight(),
                     mDialogView.getPaddingTop(),
                     mDialogView.getPaddingRight(),
                     mDialogView.getPaddingBottom());
@@ -731,6 +749,9 @@
             }
         });
         mRingerDrawerIconColorAnimator.setDuration(DRAWER_ANIMATION_DURATION_SHORT);
+
+        mAnimateUpBackgroundToMatchDrawer.addUpdateListener(valueAnimator ->
+                setRingerAndRowsBackgroundTop((float) valueAnimator.getAnimatedValue()));
     }
 
     private ImageView getDrawerIconViewForMode(int mode) {
@@ -789,14 +810,16 @@
         mRingerDrawerContainer.setAlpha(0f);
         mRingerDrawerContainer.setVisibility(VISIBLE);
 
+        final int ringerDrawerAnimationDuration = mState.ringerModeInternal == RINGER_MODE_VIBRATE
+                ? DRAWER_ANIMATION_DURATION_SHORT
+                : DRAWER_ANIMATION_DURATION;
+
         // Animate the drawer up and visible.
         mRingerDrawerContainer.animate()
                 .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
                 // Vibrate is way farther up, so give the selected ringer icon a head start if
                 // vibrate is selected.
-                .setDuration(mState.ringerModeInternal == RINGER_MODE_VIBRATE
-                        ? DRAWER_ANIMATION_DURATION_SHORT
-                        : DRAWER_ANIMATION_DURATION)
+                .setDuration(ringerDrawerAnimationDuration)
                 .setStartDelay(mState.ringerModeInternal == RINGER_MODE_VIBRATE
                         ? DRAWER_ANIMATION_DURATION - DRAWER_ANIMATION_DURATION_SHORT
                         : 0)
@@ -812,6 +835,10 @@
                 .withEndAction(() ->
                         getDrawerIconViewForMode(mState.ringerModeInternal).setVisibility(VISIBLE));
 
+        mAnimateUpBackgroundToMatchDrawer.setDuration(ringerDrawerAnimationDuration);
+        mAnimateUpBackgroundToMatchDrawer.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
+        mAnimateUpBackgroundToMatchDrawer.start();
+
         if (!isLandscape()) {
             mSelectedRingerContainer.animate()
                     .translationY(getTranslationInDrawerForRingerMode(mState.ringerModeInternal))
@@ -853,6 +880,10 @@
                     .start();
         }
 
+        mAnimateUpBackgroundToMatchDrawer.setDuration(DRAWER_ANIMATION_DURATION);
+        mAnimateUpBackgroundToMatchDrawer.setInterpolator(Interpolators.FAST_OUT_SLOW_IN_REVERSE);
+        mAnimateUpBackgroundToMatchDrawer.reverse();
+
         mSelectedRingerContainer.animate()
                 .translationX(0f)
                 .translationY(0f)
@@ -1524,7 +1555,7 @@
         }
         final ColorStateList colorTint = useActiveColoring
                 ? Utils.getColorAccent(mContext)
-                : Utils.getColorAttr(mContext, android.R.attr.colorForeground);
+                : Utils.getColorAttr(mContext, com.android.internal.R.attr.colorAccentSecondary);
         final int alpha = useActiveColoring
                 ? Color.alpha(colorTint.getDefaultColor())
                 : getAlphaAttr(android.R.attr.secondaryContentAlpha);
@@ -1532,18 +1563,24 @@
         final ColorStateList bgTint = Utils.getColorAttr(
                 mContext, android.R.attr.colorBackgroundFloating);
 
+        final ColorStateList inverseTextTint = Utils.getColorAttr(
+                mContext, com.android.internal.R.attr.textColorPrimaryInverse);
+
         row.sliderProgressSolid.setTintList(colorTint);
         if (row.sliderBgIcon != null) {
             row.sliderBgIcon.setTintList(colorTint);
         }
 
-        row.sliderBgSolid.setTintList(bgTint);
+        if (row.sliderBgSolid != null) {
+            row.sliderBgSolid.setTintList(bgTint);
+        }
+
         if (row.sliderProgressIcon != null) {
             row.sliderProgressIcon.setTintList(bgTint);
         }
 
         if (row.icon != null) {
-            row.icon.setImageTintList(colorTint);
+            row.icon.setImageTintList(inverseTextTint);
             row.icon.setImageAlpha(alpha);
         }
 
@@ -1682,6 +1719,28 @@
         };
     }
 
+    /**
+     * Return the height of the 1-2 extra ringer options that are made visible when the ringer
+     * drawer is opened.
+     */
+    private int getRingerDrawerOpenExtraHeight() {
+        return (mRingerCount - 1) * mRingerDrawerItemSize;
+    }
+
+    /**
+     * Sets the top of the background drawable behind the container view for the ringer icon and the
+     * volume rows, depending on whether the ringer drawer is open or closed.
+     */
+    private void setRingerAndRowsBackgroundTop(float drawerClosedAmount) {
+        if (mRingerAndRowsContainerBackground == null) {
+            return;
+        }
+
+        final Rect bounds = mRingerAndRowsContainerBackground.copyBounds();
+        bounds.top = (int) (drawerClosedAmount * getRingerDrawerOpenExtraHeight());
+        mRingerAndRowsContainerBackground.setBounds(bounds);
+    }
+
     private final VolumeDialogController.Callbacks mControllerCallbackH
             = new VolumeDialogController.Callbacks() {
         @Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
index 57e9d2b..7c73b4c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
@@ -40,7 +40,9 @@
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
 import android.util.FeatureFlagUtils;
+import android.view.View;
 
+import androidx.annotation.Nullable;
 import androidx.test.filters.SmallTest;
 
 import com.android.dx.mockito.inline.extended.ExtendedMockito;
@@ -430,7 +432,7 @@
         }
 
         @Override
-        protected void handleClick() {}
+        protected void handleClick(@Nullable View view) {}
 
         @Override
         protected void handleUpdateState(State state, Object arg) {}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java
index c35f8b6..f2f4f07 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java
@@ -34,7 +34,6 @@
 import static org.mockito.Mockito.when;
 
 import android.Manifest;
-import android.annotation.Nullable;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
@@ -49,6 +48,7 @@
 import android.util.FeatureFlagUtils;
 import android.view.View;
 
+import androidx.annotation.Nullable;
 import androidx.test.filters.SmallTest;
 
 import com.android.dx.mockito.inline.extended.ExtendedMockito;
@@ -414,10 +414,10 @@
         }
 
         @Override
-        public void click() {}
+        public void click(@Nullable View view) {}
 
         @Override
-        public void secondaryClick() {}
+        public void secondaryClick(@Nullable View view) {}
 
         @Override
         public void longClick(@Nullable View view) {}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
index 2d6ed7c..80231a4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
@@ -49,7 +49,9 @@
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
+import android.view.View;
 
+import androidx.annotation.Nullable;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.InstanceId;
@@ -124,7 +126,7 @@
 
     @Test
     public void testClick_Metrics() {
-        mTile.click();
+        mTile.click(null /* view */);
         verify(mMetricsLogger).write(argThat(new TileLogMatcher(ACTION_QS_CLICK)));
         assertEquals(1, mUiEventLoggerFake.numLogs());
         UiEventLoggerFake.FakeUiEvent event = mUiEventLoggerFake.get(0);
@@ -135,14 +137,14 @@
     public void testClick_log() {
         when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
 
-        mTile.click();
+        mTile.click(null /* view */);
         verify(mQsLogger).logTileClick(SPEC, StatusBarState.SHADE, Tile.STATE_ACTIVE);
     }
 
     @Test
     public void testClick_Metrics_Status_Bar_Status() {
         when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
-        mTile.click();
+        mTile.click(null /* view */);
         verify(mMetricsLogger).write(mLogCaptor.capture());
         assertEquals(StatusBarState.SHADE, mLogCaptor.getValue()
                 .getTaggedData(FIELD_STATUS_BAR_STATE));
@@ -151,19 +153,19 @@
     @Test
     public void testClick_falsing() {
         mFalsingManager.setFalseTap(true);
-        mTile.click();
+        mTile.click(null /* view */);
         mTestableLooper.processAllMessages();
         assertThat(mTile.mClicked).isFalse();
 
         mFalsingManager.setFalseTap(false);
-        mTile.click();
+        mTile.click(null /* view */);
         mTestableLooper.processAllMessages();
         assertThat(mTile.mClicked).isTrue();
     }
 
     @Test
     public void testSecondaryClick_Metrics() {
-        mTile.secondaryClick();
+        mTile.secondaryClick(null /* view */);
         verify(mMetricsLogger).write(argThat(new TileLogMatcher(ACTION_QS_SECONDARY_CLICK)));
         assertEquals(1, mUiEventLoggerFake.numLogs());
         UiEventLoggerFake.FakeUiEvent event = mUiEventLoggerFake.get(0);
@@ -174,14 +176,14 @@
     public void testSecondaryClick_log() {
         when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
 
-        mTile.secondaryClick();
+        mTile.secondaryClick(null /* view */);
         verify(mQsLogger).logTileSecondaryClick(SPEC, StatusBarState.SHADE, Tile.STATE_ACTIVE);
     }
 
     @Test
     public void testSecondaryClick_Metrics_Status_Bar_Status() {
         when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
-        mTile.secondaryClick();
+        mTile.secondaryClick(null /* view */);
         verify(mMetricsLogger).write(mLogCaptor.capture());
         assertEquals(StatusBarState.KEYGUARD, mLogCaptor.getValue()
                 .getTaggedData(FIELD_STATUS_BAR_STATE));
@@ -208,7 +210,7 @@
     @Test
     public void testLongClick_Metrics_Status_Bar_Status() {
         when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE_LOCKED);
-        mTile.click();
+        mTile.click(null /* view */);
         verify(mMetricsLogger).write(mLogCaptor.capture());
         assertEquals(StatusBarState.SHADE_LOCKED, mLogCaptor.getValue()
                 .getTaggedData(FIELD_STATUS_BAR_STATE));
@@ -401,7 +403,7 @@
         }
 
         @Override
-        protected void handleClick() {
+        protected void handleClick(@Nullable View view) {
             mClicked = true;
         }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AlarmTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AlarmTileTest.kt
index 9674a60..a435768 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AlarmTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AlarmTileTest.kt
@@ -122,10 +122,11 @@
     @Test
     fun testActivityStartedWhenNullNextAlarm() {
         callbackCaptor.value.onNextAlarmChanged(null)
-        tile.click()
+        tile.click(null /* view */)
 
         testableLooper.processAllMessages()
-        verify(activityStarter).postStartActivityDismissingKeyguard(tile.defaultIntent, 0)
+        verify(activityStarter).postStartActivityDismissingKeyguard(tile.defaultIntent, 0,
+                null /* animationController */)
     }
 
     @Test
@@ -141,9 +142,10 @@
     fun testActivityStartedWhenNextAlarm() {
         val alarmInfo = AlarmManager.AlarmClockInfo(1L, pendingIntent)
         callbackCaptor.value.onNextAlarmChanged(alarmInfo)
-        tile.click()
+        tile.click(null /* view */)
 
         testableLooper.processAllMessages()
-        verify(activityStarter).postStartActivityDismissingKeyguard(pendingIntent)
+        verify(activityStarter).postStartActivityDismissingKeyguard(pendingIntent,
+                null /* animationController */)
     }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java
index 7d39361..7c1a5f5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java
@@ -240,7 +240,7 @@
         when(mController.getCastDevices()).thenReturn(devices);
 
         enableWifiAndProcessMessages();
-        mCastTile.handleClick();
+        mCastTile.handleClick(null /* view */);
         mTestableLooper.processAllMessages();
 
         verify(mActivityStarter, times(1)).postQSRunnableDismissingKeyguard(any());
@@ -256,7 +256,7 @@
         when(mController.getCastDevices()).thenReturn(devices);
 
         enableWifiAndProcessMessages();
-        mCastTile.handleClick();
+        mCastTile.handleClick(null /* view */);
         mTestableLooper.processAllMessages();
 
         verify(mController, times(1)).stopCasting(same(device));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
index aa76651..51aeb15 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
@@ -28,6 +28,7 @@
 import com.android.internal.logging.MetricsLogger
 import com.android.internal.logging.UiEventLogger
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.ActivityLaunchAnimator
 import com.android.systemui.classifier.FalsingManagerFake
 import com.android.systemui.controls.ControlsServiceInfo
 import com.android.systemui.controls.controller.ControlsController
@@ -40,6 +41,7 @@
 import com.android.systemui.qs.logging.QSLogger
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.capture
+import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.settings.FakeSettings
 import com.android.systemui.util.settings.SecureSettings
 import com.google.common.truth.Truth.assertThat
@@ -47,6 +49,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.anyBoolean
 import org.mockito.Captor
 import org.mockito.Mock
 import org.mockito.Mockito.`when`
@@ -244,10 +247,11 @@
 
     @Test
     fun testNoDialogWhenUnavailable() {
-        tile.click()
+        tile.click(null /* view */)
         testableLooper.processAllMessages()
 
-        verify(spiedContext, never()).startActivity(any(Intent::class.java))
+        verify(activityStarter, never()).startActivity(any(), anyBoolean(),
+                any<ActivityLaunchAnimator.Controller>())
     }
 
     @Test
@@ -261,10 +265,11 @@
         listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo))
         testableLooper.processAllMessages()
 
-        tile.click()
+        tile.click(null /* view */)
         testableLooper.processAllMessages()
 
-        verify(spiedContext).startActivity(any(Intent::class.java))
+        verify(activityStarter).startActivity(any(), eq(true) /* dismissShade */,
+                eq(null) as ActivityLaunchAnimator.Controller?)
     }
 
     @Test
@@ -279,10 +284,11 @@
         listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo))
         testableLooper.processAllMessages()
 
-        tile.click()
+        tile.click(null /* view */)
         testableLooper.processAllMessages()
 
-        verify(spiedContext, never()).startActivity(any(Intent::class.java))
+        verify(activityStarter, never()).startActivity(any(), anyBoolean(),
+                any<ActivityLaunchAnimator.Controller>())
     }
 
     private fun createTile(): DeviceControlsTile {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
index 4bba0d0..2f28b13 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
@@ -62,6 +62,7 @@
 import com.android.internal.logging.testing.UiEventLoggerFake;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.QSTile;
@@ -186,11 +187,12 @@
         when(mQuickAccessWalletClient.createWalletIntent()).thenReturn(intent);
         setUpWalletCard(/* hasCard= */ false);
 
-        mTile.handleClick();
+        mTile.handleClick(null /* view */);
         mTestableLooper.processAllMessages();
 
         verify(mActivityStarter, times(1))
-                .postStartActivityDismissingKeyguard(eq(intent), anyInt());
+                .postStartActivityDismissingKeyguard(eq(intent), anyInt(),
+                        eq(null) /* animationController */);
     }
 
     @Test
@@ -198,7 +200,7 @@
         when(mQuickAccessWalletClient.createWalletIntent()).thenReturn(null);
         setUpWalletCard(/* hasCard= */ false);
 
-        mTile.handleClick();
+        mTile.handleClick(null /* view */);
         mTestableLooper.processAllMessages();
 
         verifyZeroInteractions(mActivityStarter);
@@ -208,10 +210,11 @@
     public void testHandleClick_hasCards_startWalletActivity() {
         setUpWalletCard(/* hasCard= */ true);
 
-        mTile.handleClick();
+        mTile.handleClick(null /* view */);
         mTestableLooper.processAllMessages();
 
-        verify(mSpiedContext).startActivity(mIntentCaptor.capture());
+        verify(mActivityStarter).startActivity(mIntentCaptor.capture(), eq(true) /* dismissShade */,
+                (ActivityLaunchAnimator.Controller) eq(null));
 
         Intent nextStartedIntent = mIntentCaptor.getValue();
         String walletClassName = "com.android.systemui.wallet.ui.WalletActivity";
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java
index 9799514..df4908d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java
@@ -121,7 +121,7 @@
         // Validity check
         assertEquals(Tile.STATE_INACTIVE, mTile.getState().state);
 
-        mTile.handleClick();
+        mTile.handleClick(null /* view */);
 
         verify(mReduceBrightColorsController, times(1))
                 .setReduceBrightColorsActivated(eq(true));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
index 2215433..e4af21a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
@@ -106,7 +106,7 @@
         assertTrue(mTile.getState().secondaryLabel.toString().equals(
                 mContext.getString(R.string.quick_settings_screen_record_start)));
 
-        mTile.handleClick();
+        mTile.handleClick(null /* view */);
         mTestableLooper.processAllMessages();
         verify(mController, times(1)).getPromptIntent();
     }
@@ -130,7 +130,7 @@
         when(mController.isStarting()).thenReturn(true);
         when(mController.isRecording()).thenReturn(false);
 
-        mTile.handleClick();
+        mTile.handleClick(null /* view */);
 
         verify(mController, times(1)).cancelCountdown();
     }
@@ -155,7 +155,7 @@
         when(mController.isStarting()).thenReturn(false);
         when(mController.isRecording()).thenReturn(true);
 
-        mTile.handleClick();
+        mTile.handleClick(null /* view */);
 
         verify(mController, times(1)).stopRecording();
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/mockito/KotlinMockitoHelpers.kt b/packages/SystemUI/tests/src/com/android/systemui/util/mockito/KotlinMockitoHelpers.kt
index 3f095c7..bff99bf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/mockito/KotlinMockitoHelpers.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/mockito/KotlinMockitoHelpers.kt
@@ -41,6 +41,7 @@
  * Generic T is nullable because implicitly bounded by Any?.
  */
 fun <T> any(type: Class<T>): T = Mockito.any<T>(type)
+inline fun <reified T> any(): T = any(T::class.java)
 
 /**
  * Returns ArgumentCaptor.capture() as nullable type to avoid java.lang.IllegalStateException
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 7919a78..278291c 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -346,6 +346,7 @@
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.function.HeptFunction;
 import com.android.internal.util.function.HexFunction;
+import com.android.internal.util.function.NonaFunction;
 import com.android.internal.util.function.OctFunction;
 import com.android.internal.util.function.QuadFunction;
 import com.android.internal.util.function.TriFunction;
@@ -16731,6 +16732,29 @@
         }
 
         @Override
+        public SyncNotedAppOp startOperation(IBinder token, int code, int uid,
+                @Nullable String packageName, @Nullable String attributionTag,
+                boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp,
+                @Nullable String message, boolean shouldCollectMessage,
+                @NonNull NonaFunction<IBinder, Integer, Integer, String, String, Boolean,
+                        Boolean, String, Boolean, SyncNotedAppOp> superImpl) {
+            if (uid == mTargetUid && isTargetOp(code)) {
+                final int shellUid = UserHandle.getUid(UserHandle.getUserId(uid),
+                        Process.SHELL_UID);
+                final long identity = Binder.clearCallingIdentity();
+                try {
+                    return superImpl.apply(token, code, shellUid, "com.android.shell",
+                            attributionTag, startIfModeDefault, shouldCollectAsyncNotedOp, message,
+                            shouldCollectMessage);
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            }
+            return superImpl.apply(token, code, uid, packageName, attributionTag,
+                    startIfModeDefault, shouldCollectAsyncNotedOp, message, shouldCollectMessage);
+        }
+
+        @Override
         public SyncNotedAppOp startProxyOperation(IBinder token, int code,
                 @NonNull AttributionSource attributionSource, boolean startIfModeDefault,
                 boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 2a0beb8..7eaf18f 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -3509,9 +3509,19 @@
     }
 
     @Override
-    public SyncNotedAppOp startOperation(IBinder clientId, int code, int uid, String packageName,
-            String attributionTag, boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp,
+    public SyncNotedAppOp startOperation(IBinder token, int code, int uid,
+            @Nullable String packageName, @Nullable String attributionTag,
+            boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp,
             String message, boolean shouldCollectMessage) {
+        return mCheckOpsDelegateDispatcher.startOperation(token, code, uid, packageName,
+                attributionTag, startIfModeDefault, shouldCollectAsyncNotedOp, message,
+                shouldCollectMessage);
+    }
+
+    private SyncNotedAppOp startOperationImpl(@NonNull IBinder clientId, int code, int uid,
+            @Nullable String packageName, @Nullable String attributionTag,
+            boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp, @NonNull String message,
+            boolean shouldCollectMessage) {
         verifyIncomingUid(uid);
         verifyIncomingOp(code);
         verifyIncomingPackage(packageName, UserHandle.getUserId(uid));
@@ -3535,7 +3545,6 @@
         return startOperationUnchecked(clientId, code, uid, packageName, attributionTag,
                 Process.INVALID_UID, null, null, OP_FLAG_SELF, startIfModeDefault,
                 shouldCollectAsyncNotedOp, message, shouldCollectMessage, false);
-
     }
 
     @Override
@@ -6973,8 +6982,8 @@
         }
 
         public SyncNotedAppOp noteProxyOperation(int code, AttributionSource attributionSource,
-                boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
-                boolean skipProxyOperation) {
+                boolean shouldCollectAsyncNotedOp, @Nullable String message,
+                boolean shouldCollectMessage, boolean skipProxyOperation) {
             if (mPolicy != null) {
                 if (mCheckOpsDelegate != null) {
                     return mPolicy.noteProxyOperation(code, attributionSource,
@@ -7003,6 +7012,38 @@
                     AppOpsService.this::noteProxyOperationImpl);
         }
 
+        public SyncNotedAppOp startOperation(IBinder token, int code, int uid,
+                @Nullable String packageName, @NonNull String attributionTag,
+                boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp,
+                @Nullable String message, boolean shouldCollectMessage) {
+            if (mPolicy != null) {
+                if (mCheckOpsDelegate != null) {
+                    return mPolicy.startOperation(token, code, uid, packageName,
+                            attributionTag, startIfModeDefault, shouldCollectAsyncNotedOp, message,
+                            shouldCollectMessage, this::startDelegateOperationImpl);
+                } else {
+                    return mPolicy.startOperation(token, code, uid, packageName, attributionTag,
+                            startIfModeDefault, shouldCollectAsyncNotedOp, message,
+                            shouldCollectMessage, AppOpsService.this::startOperationImpl);
+                }
+            } else if (mCheckOpsDelegate != null) {
+                return startDelegateOperationImpl(token, code, uid, packageName, attributionTag,
+                        startIfModeDefault, shouldCollectAsyncNotedOp, message,
+                        shouldCollectMessage);
+            }
+            return startOperationImpl(token, code, uid, packageName, attributionTag,
+                    startIfModeDefault, shouldCollectAsyncNotedOp, message, shouldCollectMessage);
+        }
+
+        private SyncNotedAppOp startDelegateOperationImpl(IBinder token, int code, int uid,
+                @Nullable String packageName, @Nullable String attributionTag,
+                boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp, String message,
+                boolean shouldCollectMessage) {
+            return mCheckOpsDelegate.startOperation(token, code, uid, packageName, attributionTag,
+                    startIfModeDefault, shouldCollectAsyncNotedOp, message, shouldCollectMessage,
+                    AppOpsService.this::startOperationImpl);
+        }
+
         public SyncNotedAppOp startProxyOperation(IBinder clientId, int code,
                 @NonNull AttributionSource attributionSource, boolean startIfModeDefault,
                 boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 614e488..21595c4 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -243,8 +243,7 @@
     volatile private PowerManager.WakeLock mSyncManagerWakeLock;
     volatile private boolean mDataConnectionIsConnected = false;
     volatile private boolean mStorageIsLow = false;
-    volatile private boolean mDeviceIsIdle = false;
-    volatile private boolean mReportedSyncActive = false;
+    private volatile int mNextJobIdOffset = 0;
 
     private final NotificationManager mNotificationMgr;
     private final IBatteryStats mBatteryStats;
@@ -264,17 +263,17 @@
 
     protected final SyncAdaptersCache mSyncAdapters;
 
-    private final Random mRand;
-
     private final SyncLogger mLogger;
 
     private boolean isJobIdInUseLockedH(int jobId, List<JobInfo> pendingJobs) {
-        for (JobInfo job: pendingJobs) {
+        for (int i = 0, size = pendingJobs.size(); i < size; i++) {
+            JobInfo job = pendingJobs.get(i);
             if (job.getId() == jobId) {
                 return true;
             }
         }
-        for (ActiveSyncContext asc: mActiveSyncContexts) {
+        for (int i = 0, size = mActiveSyncContexts.size(); i < size; i++) {
+            ActiveSyncContext asc = mActiveSyncContexts.get(i);
             if (asc.mSyncOperation.jobId == jobId) {
                 return true;
             }
@@ -283,19 +282,28 @@
     }
 
     private int getUnusedJobIdH() {
-        int newJobId;
-        do {
-            newJobId = MIN_SYNC_JOB_ID + mRand.nextInt(MAX_SYNC_JOB_ID - MIN_SYNC_JOB_ID);
-        } while (isJobIdInUseLockedH(newJobId,
-                mJobSchedulerInternal.getSystemScheduledPendingJobs()));
-        return newJobId;
+        final int maxNumSyncJobIds = MAX_SYNC_JOB_ID - MIN_SYNC_JOB_ID;
+        final List<JobInfo> pendingJobs = mJobSchedulerInternal.getSystemScheduledPendingJobs();
+        for (int i = 0; i < maxNumSyncJobIds; ++i) {
+            int newJobId = MIN_SYNC_JOB_ID + ((mNextJobIdOffset + i) % maxNumSyncJobIds);
+            if (!isJobIdInUseLockedH(newJobId, pendingJobs)) {
+                mNextJobIdOffset = (mNextJobIdOffset + i + 1) % maxNumSyncJobIds;
+                return newJobId;
+            }
+        }
+        // We've used all 10,000 intended job IDs.... We're probably in a world of pain right now :/
+        Slog.wtf(TAG, "All " + maxNumSyncJobIds + " possible sync job IDs are taken :/");
+        mNextJobIdOffset = (mNextJobIdOffset + 1) % maxNumSyncJobIds;
+        return MIN_SYNC_JOB_ID + mNextJobIdOffset;
     }
 
     private List<SyncOperation> getAllPendingSyncs() {
         verifyJobScheduler();
         List<JobInfo> pendingJobs = mJobSchedulerInternal.getSystemScheduledPendingJobs();
-        List<SyncOperation> pendingSyncs = new ArrayList<SyncOperation>(pendingJobs.size());
-        for (JobInfo job: pendingJobs) {
+        final int numJobs = pendingJobs.size();
+        final List<SyncOperation> pendingSyncs = new ArrayList<>(numJobs);
+        for (int i = 0; i < numJobs; ++i) {
+            final JobInfo job = pendingJobs.get(i);
             SyncOperation op = SyncOperation.maybeCreateFromJobExtras(job.getExtras());
             if (op != null) {
                 pendingSyncs.add(op);
@@ -637,7 +645,6 @@
             }
         }, mSyncHandler);
 
-        mRand = new Random(System.currentTimeMillis());
         mConstants = new SyncManagerConstants(context);
 
         IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
@@ -2184,8 +2191,6 @@
             pw.println();
         }
         pw.print("Memory low: "); pw.println(mStorageIsLow);
-        pw.print("Device idle: "); pw.println(mDeviceIsIdle);
-        pw.print("Reported active: "); pw.println(mReportedSyncActive);
         pw.print("Clock valid: "); pw.println(mSyncStorageEngine.isClockValid());
 
         final AccountAndUser[] accounts = AccountManagerService.getSingleton().getAllAccounts();
@@ -3265,7 +3270,8 @@
                 removeStaleAccounts();
 
                 AccountAndUser[] accounts = mRunningAccounts;
-                for (ActiveSyncContext currentSyncContext : mActiveSyncContexts) {
+                for (int i = 0, size = mActiveSyncContexts.size(); i < size; i++) {
+                    ActiveSyncContext currentSyncContext = mActiveSyncContexts.get(i);
                     if (!containsAccountAndUser(accounts,
                             currentSyncContext.mSyncOperation.target.account,
                             currentSyncContext.mSyncOperation.target.userId)) {
@@ -3277,7 +3283,8 @@
 
                 if (syncTargets != null) {
                     // On account add, check if there are any settings to be restored.
-                    for (AccountAndUser aau : mRunningAccounts) {
+                    for (int i = 0, length = mRunningAccounts.length; i < length; i++) {
+                        AccountAndUser aau = mRunningAccounts[i];
                         if (!containsAccountAndUser(oldAccounts, aau.account, aau.userId)) {
                             if (Log.isLoggable(TAG, Log.DEBUG)) {
                                 Log.d(TAG, "Account " + aau.account
@@ -3294,7 +3301,8 @@
             // Cancel all jobs from non-existent accounts.
             AccountAndUser[] allAccounts = AccountManagerService.getSingleton().getAllAccounts();
             List<SyncOperation> ops = getAllPendingSyncs();
-            for (SyncOperation op: ops) {
+            for (int i = 0, opsSize = ops.size(); i < opsSize; i++) {
+                SyncOperation op = ops.get(i);
                 if (!containsAccountAndUser(allAccounts, op.target.account, op.target.userId)) {
                     mLogger.log("canceling: ", op);
                     cancelJob(op, "updateRunningAccountsH()");
diff --git a/services/core/java/com/android/server/policy/AppOpsPolicy.java b/services/core/java/com/android/server/policy/AppOpsPolicy.java
index ca7406b..622b758 100644
--- a/services/core/java/com/android/server/policy/AppOpsPolicy.java
+++ b/services/core/java/com/android/server/policy/AppOpsPolicy.java
@@ -37,11 +37,11 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Log;
-import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.function.HeptFunction;
 import com.android.internal.util.function.HexFunction;
+import com.android.internal.util.function.NonaFunction;
 import com.android.internal.util.function.OctFunction;
 import com.android.internal.util.function.QuadFunction;
 import com.android.internal.util.function.TriFunction;
@@ -166,7 +166,7 @@
             boolean shouldCollectAsyncNotedOp, @Nullable String message,
             boolean shouldCollectMessage, boolean skipProxyOperation, @NonNull HexFunction<Integer,
                     AttributionSource, Boolean, String, Boolean, Boolean,
-            SyncNotedAppOp> superImpl) {
+                    SyncNotedAppOp> superImpl) {
         return superImpl.apply(resolveDatasourceOp(code, attributionSource.getUid(),
                 attributionSource.getPackageName(), attributionSource.getAttributionTag()),
                 attributionSource, shouldCollectAsyncNotedOp, message, shouldCollectMessage,
@@ -174,6 +174,17 @@
     }
 
     @Override
+    public SyncNotedAppOp startOperation(IBinder token, int code, int uid,
+            @Nullable String packageName, @Nullable String attributionTag,
+            boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp, String message,
+            boolean shouldCollectMessage, @NonNull NonaFunction<IBinder, Integer, Integer, String,
+                    String, Boolean, Boolean, String, Boolean, SyncNotedAppOp> superImpl) {
+        return superImpl.apply(token, resolveDatasourceOp(code, uid, packageName, attributionTag),
+                uid, packageName, attributionTag, startIfModeDefault, shouldCollectAsyncNotedOp,
+                message, shouldCollectMessage);
+    }
+
+    @Override
     public SyncNotedAppOp startProxyOperation(IBinder token, int code,
             @NonNull AttributionSource attributionSource, boolean startIfModeDefault,
             boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 8b9fc0f..2343970 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -5069,6 +5069,7 @@
                         + "320000:5000,640000:5000,1280000:5000,1800000:5000",
                 "mms:default_randomization=2000,5000,10000,20000,40000,80000:5000,160000:5000,"
                         + "320000:5000,640000:5000,1280000:5000,1800000:5000",
+                "ims:max_retries=10, 5000, 5000, 5000",
                 "others:max_retries=3, 5000, 5000, 5000"});
         sDefaults.putLong(KEY_CARRIER_DATA_CALL_APN_DELAY_DEFAULT_LONG, 20000);
         sDefaults.putLong(KEY_CARRIER_DATA_CALL_APN_DELAY_FASTER_LONG, 3000);