Merge "frameworks/base - Tiramisu is now 33" into tm-dev
diff --git a/api/api.go b/api/api.go
index 94bccaa..9aac879 100644
--- a/api/api.go
+++ b/api/api.go
@@ -27,6 +27,7 @@
 const art = "art.module.public.api"
 const conscrypt = "conscrypt.module.public.api"
 const i18n = "i18n.module.public.api"
+
 var core_libraries_modules = []string{art, conscrypt, i18n}
 
 // The intention behind this soong plugin is to generate a number of "merged"
@@ -92,6 +93,8 @@
 type MergedTxtDefinition struct {
 	// "current.txt" or "removed.txt"
 	TxtFilename string
+	// Filename in the new dist dir. "android.txt" or "android-removed.txt"
+	DistFilename string
 	// The module for the non-updatable / non-module part of the api.
 	BaseTxt string
 	// The list of modules that are relevant for this merged txt.
@@ -112,7 +115,6 @@
 	if txt.Scope != "public" {
 		filename = txt.Scope + "-" + filename
 	}
-
 	props := genruleProps{}
 	props.Name = proptools.StringPtr(ctx.ModuleName() + "-" + filename)
 	props.Tools = []string{"metalava"}
@@ -126,9 +128,9 @@
 			Dest:    proptools.StringPtr(filename),
 		},
 		{
-			Targets: []string{"sdk"},
+			Targets: []string{"api_txt", "sdk"},
 			Dir:     proptools.StringPtr("apistubs/android/" + txt.Scope + "/api"),
-			Dest:    proptools.StringPtr(txt.TxtFilename),
+			Dest:    proptools.StringPtr(txt.DistFilename),
 		},
 	}
 	props.Visibility = []string{"//visibility:public"}
@@ -240,34 +242,39 @@
 	var textFiles []MergedTxtDefinition
 
 	tagSuffix := []string{".api.txt}", ".removed-api.txt}"}
+	distFilename := []string{"android.txt", "android-removed.txt"}
 	for i, f := range []string{"current.txt", "removed.txt"} {
 		textFiles = append(textFiles, MergedTxtDefinition{
-			TxtFilename: f,
-			BaseTxt:     ":non-updatable-" + f,
-			Modules:     bootclasspath,
-			ModuleTag:   "{.public" + tagSuffix[i],
-			Scope:       "public",
+			TxtFilename:  f,
+			DistFilename: distFilename[i],
+			BaseTxt:      ":non-updatable-" + f,
+			Modules:      bootclasspath,
+			ModuleTag:    "{.public" + tagSuffix[i],
+			Scope:        "public",
 		})
 		textFiles = append(textFiles, MergedTxtDefinition{
-			TxtFilename: f,
-			BaseTxt:     ":non-updatable-system-" + f,
-			Modules:     bootclasspath,
-			ModuleTag:   "{.system" + tagSuffix[i],
-			Scope:       "system",
+			TxtFilename:  f,
+			DistFilename: distFilename[i],
+			BaseTxt:      ":non-updatable-system-" + f,
+			Modules:      bootclasspath,
+			ModuleTag:    "{.system" + tagSuffix[i],
+			Scope:        "system",
 		})
 		textFiles = append(textFiles, MergedTxtDefinition{
-			TxtFilename: f,
-			BaseTxt:     ":non-updatable-module-lib-" + f,
-			Modules:     bootclasspath,
-			ModuleTag:   "{.module-lib" + tagSuffix[i],
-			Scope:       "module-lib",
+			TxtFilename:  f,
+			DistFilename: distFilename[i],
+			BaseTxt:      ":non-updatable-module-lib-" + f,
+			Modules:      bootclasspath,
+			ModuleTag:    "{.module-lib" + tagSuffix[i],
+			Scope:        "module-lib",
 		})
 		textFiles = append(textFiles, MergedTxtDefinition{
-			TxtFilename: f,
-			BaseTxt:     ":non-updatable-system-server-" + f,
-			Modules:     system_server_classpath,
-			ModuleTag:   "{.system-server" + tagSuffix[i],
-			Scope:       "system-server",
+			TxtFilename:  f,
+			DistFilename: distFilename[i],
+			BaseTxt:      ":non-updatable-system-server-" + f,
+			Modules:      system_server_classpath,
+			ModuleTag:    "{.system-server" + tagSuffix[i],
+			Scope:        "system-server",
 		})
 	}
 	for _, txt := range textFiles {
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 6e1d1cd..6bb35db 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -7917,6 +7917,8 @@
          * @hide
          */
         public MessagingStyle setShortcutIcon(@Nullable Icon conversationIcon) {
+            // TODO(b/228941516): This icon should be downscaled to avoid using too much memory,
+            // see reduceImageSizes.
             mShortcutIcon = conversationIcon;
             return this;
         }
@@ -8423,6 +8425,51 @@
             return makeMessagingView(StandardTemplateParams.VIEW_TYPE_HEADS_UP);
         }
 
+        /**
+         * @hide
+         */
+        @Override
+        public void reduceImageSizes(Context context) {
+            super.reduceImageSizes(context);
+            Resources resources = context.getResources();
+            boolean isLowRam = ActivityManager.isLowRamDeviceStatic();
+            if (mShortcutIcon != null) {
+                int maxSize = resources.getDimensionPixelSize(
+                        isLowRam ? R.dimen.notification_small_icon_size_low_ram
+                                : R.dimen.notification_small_icon_size);
+                mShortcutIcon.scaleDownIfNecessary(maxSize, maxSize);
+            }
+
+            int maxAvatarSize = resources.getDimensionPixelSize(
+                    isLowRam ? R.dimen.notification_person_icon_max_size
+                            : R.dimen.notification_person_icon_max_size_low_ram);
+            if (mUser != null && mUser.getIcon() != null) {
+                mUser.getIcon().scaleDownIfNecessary(maxAvatarSize, maxAvatarSize);
+            }
+
+            reduceMessagesIconSizes(mMessages, maxAvatarSize);
+            reduceMessagesIconSizes(mHistoricMessages, maxAvatarSize);
+        }
+
+        /**
+         * @hide
+         */
+        private static void reduceMessagesIconSizes(@Nullable List<Message> messages, int maxSize) {
+            if (messages == null) {
+                return;
+            }
+
+            for (Message message : messages) {
+                Person sender = message.mSender;
+                if (sender != null) {
+                    Icon icon = sender.getIcon();
+                    if (icon != null) {
+                        icon.scaleDownIfNecessary(maxSize, maxSize);
+                    }
+                }
+            }
+        }
+
         public static final class Message {
             /** @hide */
             public static final String KEY_TEXT = "text";
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index a476189..d9d1a08 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -782,6 +782,10 @@
     <dimen name="notification_left_icon_start">@dimen/notification_icon_circle_start</dimen>
     <!-- The alpha of a disabled notification button -->
     <item type="dimen" format="float" name="notification_action_disabled_alpha">0.5</item>
+    <!-- The maximum size of Person avatar image in MessagingStyle notifications.
+         This is bigger than displayed because listeners can use it for other displays
+         e.g. wearables. -->
+    <dimen name="notification_person_icon_max_size">144dp</dimen>
 
     <!-- The maximum size of the small notification icon on low memory devices. -->
     <dimen name="notification_small_icon_size_low_ram">@dimen/notification_small_icon_size</dimen>
@@ -795,6 +799,10 @@
     <dimen name="notification_big_picture_max_width_low_ram">294dp</dimen>
     <!-- The size of the right icon image when on low ram -->
     <dimen name="notification_right_icon_size_low_ram">@dimen/notification_right_icon_size</dimen>
+    <!-- The maximum size of Person avatar image in MessagingStyle notifications.
+     This is bigger than displayed because listeners can use it for other displays
+     e.g. wearables. -->
+    <dimen name="notification_person_icon_max_size_low_ram">96dp</dimen>
     <!-- The maximum size of the grayscale icon -->
     <dimen name="notification_grayscale_icon_max_size">256dp</dimen>
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 5f14647..a9b95da 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3604,6 +3604,7 @@
   <java-symbol type="dimen" name="notification_actions_icon_drawable_size"/>
   <java-symbol type="dimen" name="notification_custom_view_max_image_height"/>
   <java-symbol type="dimen" name="notification_custom_view_max_image_width"/>
+  <java-symbol type="dimen" name="notification_person_icon_max_size" />
 
   <java-symbol type="dimen" name="notification_small_icon_size_low_ram"/>
   <java-symbol type="dimen" name="notification_big_picture_max_height_low_ram"/>
@@ -3612,6 +3613,7 @@
   <java-symbol type="dimen" name="notification_grayscale_icon_max_size"/>
   <java-symbol type="dimen" name="notification_custom_view_max_image_height_low_ram"/>
   <java-symbol type="dimen" name="notification_custom_view_max_image_width_low_ram"/>
+  <java-symbol type="dimen" name="notification_person_icon_max_size_low_ram" />
 
   <!-- Accessibility fingerprint gestures -->
   <java-symbol type="string" name="capability_title_canCaptureFingerprintGestures" />
diff --git a/core/tests/coretests/src/android/app/NotificationTest.java b/core/tests/coretests/src/android/app/NotificationTest.java
index e6d2364..a5da442 100644
--- a/core/tests/coretests/src/android/app/NotificationTest.java
+++ b/core/tests/coretests/src/android/app/NotificationTest.java
@@ -521,6 +521,70 @@
     }
 
     @Test
+    public void testBuild_ensureMessagingUserIsNotTooBig_resizesIcon() {
+        Icon hugeIcon = Icon.createWithBitmap(
+                Bitmap.createBitmap(3000, 3000, Bitmap.Config.ARGB_8888));
+        Icon hugeMessageAvatar = Icon.createWithBitmap(
+                Bitmap.createBitmap(3000, 3000, Bitmap.Config.ARGB_8888));
+        Icon hugeHistoricMessageAvatar = Icon.createWithBitmap(
+                Bitmap.createBitmap(3000, 3000, Bitmap.Config.ARGB_8888));
+
+        Notification.MessagingStyle style = new Notification.MessagingStyle(
+                new Person.Builder().setIcon(hugeIcon).setName("A User").build());
+        style.addMessage(new Notification.MessagingStyle.Message("A message", 123456,
+                new Person.Builder().setIcon(hugeMessageAvatar).setName("A Sender").build()));
+        style.addHistoricMessage(new Notification.MessagingStyle.Message("A message", 123456,
+                new Person.Builder().setIcon(hugeHistoricMessageAvatar).setName(
+                        "A Historic Sender").build()));
+        Notification notification = new Notification.Builder(mContext, "Channel").setStyle(
+                style).build();
+
+        Bitmap personIcon = style.getUser().getIcon().getBitmap();
+        assertThat(personIcon.getWidth()).isEqualTo(
+                mContext.getResources().getDimensionPixelSize(
+                        R.dimen.notification_person_icon_max_size));
+        assertThat(personIcon.getHeight()).isEqualTo(
+                mContext.getResources().getDimensionPixelSize(
+                        R.dimen.notification_person_icon_max_size));
+
+        Bitmap avatarIcon = style.getMessages().get(0).getSenderPerson().getIcon().getBitmap();
+        assertThat(avatarIcon.getWidth()).isEqualTo(
+                mContext.getResources().getDimensionPixelSize(
+                        R.dimen.notification_person_icon_max_size));
+        assertThat(avatarIcon.getHeight()).isEqualTo(
+                mContext.getResources().getDimensionPixelSize(
+                        R.dimen.notification_person_icon_max_size));
+
+        Bitmap historicAvatarIcon = style.getHistoricMessages().get(
+                0).getSenderPerson().getIcon().getBitmap();
+        assertThat(historicAvatarIcon.getWidth()).isEqualTo(
+                mContext.getResources().getDimensionPixelSize(
+                        R.dimen.notification_person_icon_max_size));
+        assertThat(historicAvatarIcon.getHeight()).isEqualTo(
+                mContext.getResources().getDimensionPixelSize(
+                        R.dimen.notification_person_icon_max_size));
+    }
+
+    @Test
+    public void testBuild_ensureMessagingShortcutIconIsNotTooBig_resizesIcon() {
+        Icon hugeIcon = Icon.createWithBitmap(
+                Bitmap.createBitmap(3000, 3000, Bitmap.Config.ARGB_8888));
+        Notification.MessagingStyle style = new Notification.MessagingStyle(
+                new Person.Builder().setName("A User").build()).setShortcutIcon(hugeIcon);
+
+        Notification notification = new Notification.Builder(mContext, "Channel").setStyle(
+                style).build();
+        Bitmap shortcutIcon = style.getShortcutIcon().getBitmap();
+
+        assertThat(shortcutIcon.getWidth()).isEqualTo(
+                mContext.getResources().getDimensionPixelSize(
+                        R.dimen.notification_small_icon_size));
+        assertThat(shortcutIcon.getHeight()).isEqualTo(
+                mContext.getResources().getDimensionPixelSize(
+                        R.dimen.notification_small_icon_size));
+    }
+
+    @Test
     public void testColors_ensureColors_dayMode_producesValidPalette() {
         Notification.Colors c = new Notification.Colors();
         boolean colorized = false;
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index c21aa2d..0318760 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -3427,6 +3427,12 @@
       "group": "WM_DEBUG_FOCUS_LIGHT",
       "at": "com\/android\/server\/wm\/WindowState.java"
     },
+    "1288920916": {
+      "message": "Error sending initial insets change to WindowContainer overlay",
+      "level": "ERROR",
+      "group": "WM_DEBUG_ANIM",
+      "at": "com\/android\/server\/wm\/WindowContainer.java"
+    },
     "1305412562": {
       "message": "Report configuration: %s %s",
       "level": "VERBOSE",
diff --git a/graphics/java/android/graphics/BLASTBufferQueue.java b/graphics/java/android/graphics/BLASTBufferQueue.java
index 7f70e1c..4b723d1 100644
--- a/graphics/java/android/graphics/BLASTBufferQueue.java
+++ b/graphics/java/android/graphics/BLASTBufferQueue.java
@@ -47,7 +47,7 @@
     /** Create a new connection with the surface flinger. */
     public BLASTBufferQueue(String name, SurfaceControl sc, int width, int height,
             @PixelFormat.Format int format) {
-        this(name, false /* updateDestinationFrame */);
+        this(name, true /* updateDestinationFrame */);
         update(sc, width, height, format);
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index 1a1cd5b..b6fb828 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -1225,12 +1225,6 @@
                 mOverflowListener.applyUpdate(update);
             }
 
-            // Collapsing? Do this first before remaining steps.
-            if (update.expandedChanged && !update.expanded) {
-                mStackView.setExpanded(false);
-                mSysuiProxy.requestNotificationShadeTopUi(false, TAG);
-            }
-
             // Do removals, if any.
             ArrayList<Pair<Bubble, Integer>> removedBubbles =
                     new ArrayList<>(update.removedBubbles);
@@ -1307,6 +1301,11 @@
                 mStackView.updateBubbleOrder(update.bubbles);
             }
 
+            if (update.expandedChanged && !update.expanded) {
+                mStackView.setExpanded(false);
+                mSysuiProxy.requestNotificationShadeTopUi(false, TAG);
+            }
+
             if (update.selectionChanged && mStackView != null) {
                 mStackView.setSelectedBubble(update.selectedBubble);
                 if (update.selectedBubble != null) {
diff --git a/omapi/java/android/se/omapi/SEService.java b/omapi/java/android/se/omapi/SEService.java
index f42ca36..306c09a 100644
--- a/omapi/java/android/se/omapi/SEService.java
+++ b/omapi/java/android/se/omapi/SEService.java
@@ -118,6 +118,16 @@
                 });
             }
         }
+
+        @Override
+        public String getInterfaceHash() {
+            return ISecureElementListener.HASH;
+        }
+
+        @Override
+        public int getInterfaceVersion() {
+            return ISecureElementListener.VERSION;
+        }
     }
     private SEListener mSEListener = new SEListener();
 
diff --git a/packages/SystemUI/res/drawable/overlay_button_background.xml b/packages/SystemUI/res/drawable/overlay_button_background.xml
index 0e8438c..c045048 100644
--- a/packages/SystemUI/res/drawable/overlay_button_background.xml
+++ b/packages/SystemUI/res/drawable/overlay_button_background.xml
@@ -18,7 +18,7 @@
      (clipboard text editor, long screenshots) -->
 <ripple xmlns:android="http://schemas.android.com/apk/res/android"
         xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
-        android:color="?android:textColorPrimary">
+        android:color="@color/overlay_button_ripple">
     <item android:id="@android:id/background">
         <inset android:insetTop="4dp" android:insetBottom="4dp">
             <shape android:shape="rectangle">
diff --git a/packages/SystemUI/res/values-night/colors.xml b/packages/SystemUI/res/values-night/colors.xml
index 3a638b1..dc2bee5 100644
--- a/packages/SystemUI/res/values-night/colors.xml
+++ b/packages/SystemUI/res/values-night/colors.xml
@@ -59,7 +59,6 @@
     <color name="global_actions_alert_text">@color/GM2_red_300</color>
 
     <!-- Floating overlay actions -->
-    <color name="overlay_button_ripple">#42FFFFFF</color>
     <color name="overlay_background_protection_start">#80000000</color> <!-- 50% black -->
 
     <!-- Media -->
diff --git a/packages/SystemUI/src/com/android/keyguard/BouncerPanelExpansionCalculator.kt b/packages/SystemUI/src/com/android/keyguard/BouncerPanelExpansionCalculator.kt
index 1b2ea3b..a08c900 100644
--- a/packages/SystemUI/src/com/android/keyguard/BouncerPanelExpansionCalculator.kt
+++ b/packages/SystemUI/src/com/android/keyguard/BouncerPanelExpansionCalculator.kt
@@ -23,7 +23,7 @@
      *  Scale the alpha/position of the host view.
      */
     @JvmStatic
-    fun getHostViewScaledExpansion(fraction: Float): Float {
+    fun showBouncerProgress(fraction: Float): Float {
         return when {
                     fraction >= 0.9f -> 1f
                     fraction < 0.6 -> 0f
@@ -35,7 +35,7 @@
      *  Scale the alpha/tint of the back scrim.
      */
     @JvmStatic
-    fun getBackScrimScaledExpansion(fraction: Float): Float {
+    fun aboutToShowBouncerProgress(fraction: Float): Float {
         return MathUtils.constrain((fraction - 0.9f) / 0.1f, 0f, 1f)
     }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java
index 8c3e066..239b4789 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java
@@ -327,7 +327,7 @@
      * @param fraction amount of the screen that should show.
      */
     public void setExpansion(float fraction) {
-        float scaledFraction = BouncerPanelExpansionCalculator.getHostViewScaledExpansion(fraction);
+        float scaledFraction = BouncerPanelExpansionCalculator.showBouncerProgress(fraction);
         mView.setAlpha(MathUtils.constrain(1 - scaledFraction, 0f, 1f));
         mView.setTranslationY(scaledFraction * mTranslationY);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/Prefs.java b/packages/SystemUI/src/com/android/systemui/Prefs.java
index ff5715c..9aa5fae 100644
--- a/packages/SystemUI/src/com/android/systemui/Prefs.java
+++ b/packages/SystemUI/src/com/android/systemui/Prefs.java
@@ -63,7 +63,6 @@
             Key.QS_WORK_ADDED,
             Key.QS_NIGHTDISPLAY_ADDED,
             Key.QS_LONG_PRESS_TOOLTIP_SHOWN_COUNT,
-            Key.SEEN_MULTI_USER,
             Key.SEEN_RINGER_GUIDANCE_COUNT,
             Key.QS_HAS_TURNED_OFF_MOBILE_DATA,
             Key.TOUCHED_RINGER_TOGGLE,
@@ -106,7 +105,6 @@
          * Settings panel.
          */
         String QS_LONG_PRESS_TOOLTIP_SHOWN_COUNT = "QsLongPressTooltipShownCount";
-        String SEEN_MULTI_USER = "HasSeenMultiUser";
         String SEEN_RINGER_GUIDANCE_COUNT = "RingerGuidanceCount";
         String QS_TILE_SPECS_REVEALED = "QsTileSpecsRevealed";
         String QS_HAS_TURNED_OFF_MOBILE_DATA = "QsHasTurnedOffMobileData";
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
index 33126b3..76c1dbc 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
@@ -145,6 +145,7 @@
         val lightRevealScrim = centralSurfaces.lightRevealScrim
         if (statusBarStateController.isDozing || biometricUnlockController.isWakeAndUnlock) {
             circleReveal?.let {
+                lightRevealScrim?.revealAmount = 0f
                 lightRevealScrim?.revealEffect = it
                 startLightRevealScrimOnKeyguardFadingAway = true
             }
@@ -168,7 +169,8 @@
                     startDelay = keyguardStateController.keyguardFadingAwayDelay
                     addUpdateListener { animator ->
                         if (lightRevealScrim.revealEffect != circleReveal) {
-                            // if something else took over the reveal, let's do nothing.
+                            // if something else took over the reveal, let's cancel ourselves
+                            cancel()
                             return@addUpdateListener
                         }
                         lightRevealScrim.revealAmount = animator.animatedValue as Float
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
index 5d131f2..f5f07c8 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
@@ -25,6 +25,7 @@
 import android.util.MathUtils;
 import android.view.MotionEvent;
 
+import com.android.keyguard.BouncerPanelExpansionCalculator;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.R;
 import com.android.systemui.animation.ActivityLaunchAnimator;
@@ -71,7 +72,7 @@
     private float mTransitionToFullShadeProgress;
     private float mLastDozeAmount;
     private long mLastUdfpsBouncerShowTime = -1;
-    private float mStatusBarExpansion;
+    private float mPanelExpansionFraction;
     private boolean mLaunchTransitionFadingAway;
     private boolean mIsLaunchingActivity;
     private float mActivityLaunchProgress;
@@ -188,7 +189,7 @@
         pw.println("mQsExpanded=" + mQsExpanded);
         pw.println("mIsBouncerVisible=" + mIsBouncerVisible);
         pw.println("mInputBouncerHiddenAmount=" + mInputBouncerHiddenAmount);
-        pw.println("mStatusBarExpansion=" + mStatusBarExpansion);
+        pw.println("mPanelExpansionFraction=" + mPanelExpansionFraction);
         pw.println("unpausedAlpha=" + mView.getUnpausedAlpha());
         pw.println("mUdfpsRequested=" + mUdfpsRequested);
         pw.println("mView.mUdfpsRequested=" + mView.mUdfpsRequested);
@@ -324,14 +325,16 @@
      */
     @Override
     public void updateAlpha() {
-        // fade icon on transitions to showing the status bar, but if mUdfpsRequested, then
-        // the keyguard is occluded by some application - so instead use the input bouncer
-        // hidden amount to determine the fade
-        float expansion = mUdfpsRequested ? mInputBouncerHiddenAmount : mStatusBarExpansion;
+        // Fade icon on transitions to showing the status bar or bouncer, but if mUdfpsRequested,
+        // then the keyguard is occluded by some application - so instead use the input bouncer
+        // hidden amount to determine the fade.
+        float expansion = mUdfpsRequested ? mInputBouncerHiddenAmount : mPanelExpansionFraction;
+
         int alpha = mShowingUdfpsBouncer ? 255
                 : (int) MathUtils.constrain(
                     MathUtils.map(.5f, .9f, 0f, 255f, expansion),
                     0f, 255f);
+
         if (!mShowingUdfpsBouncer) {
             alpha *= (1.0f - mTransitionToFullShadeProgress);
 
@@ -471,7 +474,9 @@
         @Override
         public void onPanelExpansionChanged(
                 float fraction, boolean expanded, boolean tracking) {
-            mStatusBarExpansion = fraction;
+            mPanelExpansionFraction =
+                    mKeyguardViewManager.bouncerIsInTransit() ? BouncerPanelExpansionCalculator
+                            .aboutToShowBouncerProgress(fraction) : fraction;
             updateAlpha();
         }
     };
diff --git a/packages/SystemUI/src/com/android/systemui/broadcast/ActionReceiver.kt b/packages/SystemUI/src/com/android/systemui/broadcast/ActionReceiver.kt
index 4315cb0..ca36375 100644
--- a/packages/SystemUI/src/com/android/systemui/broadcast/ActionReceiver.kt
+++ b/packages/SystemUI/src/com/android/systemui/broadcast/ActionReceiver.kt
@@ -39,6 +39,13 @@
  *
  * This class has no sync controls, so make sure to only make modifications from the background
  * thread.
+ *
+ * This class takes the following actions:
+ * * [registerAction]: action to register this receiver (with the proper filter) with [Context].
+ * * [unregisterAction]: action to unregister this receiver with [Context].
+ * * [testPendingRemovalAction]: action to check if a particular [BroadcastReceiver] registered
+ *   with [BroadcastDispatcher] has been unregistered and is pending removal. See
+ *   [PendingRemovalStore].
  */
 class ActionReceiver(
     private val action: String,
@@ -46,7 +53,8 @@
     private val registerAction: BroadcastReceiver.(IntentFilter) -> Unit,
     private val unregisterAction: BroadcastReceiver.() -> Unit,
     private val bgExecutor: Executor,
-    private val logger: BroadcastDispatcherLogger
+    private val logger: BroadcastDispatcherLogger,
+    private val testPendingRemovalAction: (BroadcastReceiver, Int) -> Boolean
 ) : BroadcastReceiver(), Dumpable {
 
     companion object {
@@ -106,7 +114,8 @@
         // Immediately return control to ActivityManager
         bgExecutor.execute {
             receiverDatas.forEach {
-                if (it.filter.matchCategories(intent.categories) == null) {
+                if (it.filter.matchCategories(intent.categories) == null &&
+                    !testPendingRemovalAction(it.receiver, userId)) {
                     it.executor.execute {
                         it.receiver.pendingResult = pendingResult
                         it.receiver.onReceive(context, intent)
diff --git a/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt b/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt
index 1c27e32..b7aebc1 100644
--- a/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt
+++ b/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt
@@ -63,13 +63,14 @@
  * Broadcast handling may be asynchronous *without* calling goAsync(), as it's running within sysui
  * and doesn't need to worry about being killed.
  */
-open class BroadcastDispatcher constructor (
+open class BroadcastDispatcher @JvmOverloads constructor (
     private val context: Context,
     private val bgLooper: Looper,
     private val bgExecutor: Executor,
     private val dumpManager: DumpManager,
     private val logger: BroadcastDispatcherLogger,
-    private val userTracker: UserTracker
+    private val userTracker: UserTracker,
+    private val removalPendingStore: PendingRemovalStore = PendingRemovalStore(logger)
 ) : Dumpable {
 
     // Only modify in BG thread
@@ -167,6 +168,7 @@
      * @param receiver The receiver to unregister. It will be unregistered for all users.
      */
     open fun unregisterReceiver(receiver: BroadcastReceiver) {
+        removalPendingStore.tagForRemoval(receiver, UserHandle.USER_ALL)
         handler.obtainMessage(MSG_REMOVE_RECEIVER, receiver).sendToTarget()
     }
 
@@ -177,13 +179,21 @@
      * @param user The user associated to the registered [receiver]. It can be [UserHandle.ALL].
      */
     open fun unregisterReceiverForUser(receiver: BroadcastReceiver, user: UserHandle) {
+        removalPendingStore.tagForRemoval(receiver, user.identifier)
         handler.obtainMessage(MSG_REMOVE_RECEIVER_FOR_USER, user.identifier, 0, receiver)
                 .sendToTarget()
     }
 
     @VisibleForTesting
     protected open fun createUBRForUser(userId: Int) =
-            UserBroadcastDispatcher(context, userId, bgLooper, bgExecutor, logger)
+            UserBroadcastDispatcher(
+                context,
+                userId,
+                bgLooper,
+                bgExecutor,
+                logger,
+                removalPendingStore
+            )
 
     override fun dump(pw: PrintWriter, args: Array<out String>) {
         pw.println("Broadcast dispatcher:")
@@ -193,6 +203,8 @@
             ipw.println("User ${receiversByUser.keyAt(index)}")
             receiversByUser.valueAt(index).dump(ipw, args)
         }
+        ipw.println("Pending removal:")
+        removalPendingStore.dump(ipw, args)
         ipw.decreaseIndent()
     }
 
@@ -223,10 +235,20 @@
                     for (it in 0 until receiversByUser.size()) {
                         receiversByUser.valueAt(it).unregisterReceiver(msg.obj as BroadcastReceiver)
                     }
+                    removalPendingStore.clearPendingRemoval(
+                        msg.obj as BroadcastReceiver,
+                        UserHandle.USER_ALL
+                    )
                 }
 
                 MSG_REMOVE_RECEIVER_FOR_USER -> {
-                    receiversByUser.get(msg.arg1)?.unregisterReceiver(msg.obj as BroadcastReceiver)
+                    val userId = if (msg.arg1 == UserHandle.USER_CURRENT) {
+                        userTracker.userId
+                    } else {
+                        msg.arg1
+                    }
+                    receiversByUser.get(userId)?.unregisterReceiver(msg.obj as BroadcastReceiver)
+                    removalPendingStore.clearPendingRemoval(msg.obj as BroadcastReceiver, userId)
                 }
                 else -> super.handleMessage(msg)
             }
diff --git a/packages/SystemUI/src/com/android/systemui/broadcast/PendingRemovalStore.kt b/packages/SystemUI/src/com/android/systemui/broadcast/PendingRemovalStore.kt
new file mode 100644
index 0000000..ebf4983
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/broadcast/PendingRemovalStore.kt
@@ -0,0 +1,58 @@
+package com.android.systemui.broadcast
+
+import android.content.BroadcastReceiver
+import android.os.UserHandle
+import android.util.SparseSetArray
+import androidx.annotation.GuardedBy
+import com.android.systemui.Dumpable
+import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger
+import com.android.systemui.util.indentIfPossible
+import java.io.PrintWriter
+
+/**
+ * Store information about requests for unregistering receivers from [BroadcastDispatcher], before
+ * they have been completely removed from the system.
+ *
+ * This helps make unregistering a receiver a *sync* operation.
+ */
+class PendingRemovalStore(
+    private val logger: BroadcastDispatcherLogger
+) : Dumpable {
+    @GuardedBy("pendingRemoval")
+    private val pendingRemoval: SparseSetArray<BroadcastReceiver> = SparseSetArray()
+
+    fun tagForRemoval(broadcastReceiver: BroadcastReceiver, userId: Int) {
+        logger.logTagForRemoval(userId, broadcastReceiver)
+        synchronized(pendingRemoval) {
+            pendingRemoval.add(userId, broadcastReceiver)
+        }
+    }
+
+    fun isPendingRemoval(broadcastReceiver: BroadcastReceiver, userId: Int): Boolean {
+        return synchronized(pendingRemoval) {
+            pendingRemoval.contains(userId, broadcastReceiver) ||
+                pendingRemoval.contains(UserHandle.USER_ALL, broadcastReceiver)
+        }
+    }
+
+    fun clearPendingRemoval(broadcastReceiver: BroadcastReceiver, userId: Int) {
+        synchronized(pendingRemoval) {
+            pendingRemoval.remove(userId, broadcastReceiver)
+        }
+        logger.logClearedAfterRemoval(userId, broadcastReceiver)
+    }
+
+    override fun dump(pw: PrintWriter, args: Array<out String>) {
+        synchronized(pendingRemoval) {
+            pw.indentIfPossible {
+                val size = pendingRemoval.size()
+                for (i in 0 until size) {
+                    val user = pendingRemoval.keyAt(i)
+                    print(user)
+                    print("->")
+                    println(pendingRemoval.get(user))
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt b/packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt
index 24ce238..6b15188 100644
--- a/packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt
+++ b/packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt
@@ -20,12 +20,12 @@
 import android.content.Context
 import android.os.Handler
 import android.os.Looper
-import android.os.Message
 import android.os.UserHandle
 import android.util.ArrayMap
 import android.util.ArraySet
 import android.util.Log
 import androidx.annotation.VisibleForTesting
+import androidx.annotation.WorkerThread
 import com.android.internal.util.Preconditions
 import com.android.systemui.Dumpable
 import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger
@@ -34,8 +34,6 @@
 import java.util.concurrent.Executor
 import java.util.concurrent.atomic.AtomicInteger
 
-private const val MSG_REGISTER_RECEIVER = 0
-private const val MSG_UNREGISTER_RECEIVER = 1
 private const val TAG = "UserBroadcastDispatcher"
 private const val DEBUG = false
 
@@ -50,7 +48,8 @@
     private val userId: Int,
     private val bgLooper: Looper,
     private val bgExecutor: Executor,
-    private val logger: BroadcastDispatcherLogger
+    private val logger: BroadcastDispatcherLogger,
+    private val removalPendingStore: PendingRemovalStore
 ) : Dumpable {
 
     companion object {
@@ -60,16 +59,6 @@
         val index = AtomicInteger(0)
     }
 
-    private val bgHandler = object : Handler(bgLooper) {
-        override fun handleMessage(msg: Message) {
-            when (msg.what) {
-                MSG_REGISTER_RECEIVER -> handleRegisterReceiver(msg.obj as ReceiverData, msg.arg1)
-                MSG_UNREGISTER_RECEIVER -> handleUnregisterReceiver(msg.obj as BroadcastReceiver)
-                else -> Unit
-            }
-        }
-    }
-
     // Used for key in actionsToActionsReceivers
     internal data class ReceiverProperties(
         val action: String,
@@ -77,6 +66,8 @@
         val permission: String?
     )
 
+    private val bgHandler = Handler(bgLooper)
+
     // Only modify in BG thread
     @VisibleForTesting
     internal val actionsToActionsReceivers = ArrayMap<ReceiverProperties, ActionReceiver>()
@@ -92,19 +83,21 @@
     /**
      * Register a [ReceiverData] for this user.
      */
+    @WorkerThread
     fun registerReceiver(receiverData: ReceiverData, flags: Int) {
-        bgHandler.obtainMessage(MSG_REGISTER_RECEIVER, flags, 0, receiverData).sendToTarget()
+        handleRegisterReceiver(receiverData, flags)
     }
 
     /**
      * Unregister a given [BroadcastReceiver] for this user.
      */
+    @WorkerThread
     fun unregisterReceiver(receiver: BroadcastReceiver) {
-        bgHandler.obtainMessage(MSG_UNREGISTER_RECEIVER, receiver).sendToTarget()
+        handleUnregisterReceiver(receiver)
     }
 
     private fun handleRegisterReceiver(receiverData: ReceiverData, flags: Int) {
-        Preconditions.checkState(bgHandler.looper.isCurrentThread,
+        Preconditions.checkState(bgLooper.isCurrentThread,
                 "This method should only be called from BG thread")
         if (DEBUG) Log.w(TAG, "Register receiver: ${receiverData.receiver}")
         receiverToActions
@@ -151,12 +144,13 @@
                     }
                 },
                 bgExecutor,
-                logger
+                logger,
+                removalPendingStore::isPendingRemoval
         )
     }
 
     private fun handleUnregisterReceiver(receiver: BroadcastReceiver) {
-        Preconditions.checkState(bgHandler.looper.isCurrentThread,
+        Preconditions.checkState(bgLooper.isCurrentThread,
                 "This method should only be called from BG thread")
         if (DEBUG) Log.w(TAG, "Unregister receiver: $receiver")
         receiverToActions.getOrDefault(receiver, mutableSetOf()).forEach {
diff --git a/packages/SystemUI/src/com/android/systemui/broadcast/logging/BroadcastDispatcherLogger.kt b/packages/SystemUI/src/com/android/systemui/broadcast/logging/BroadcastDispatcherLogger.kt
index 8da6519..5b3a982 100644
--- a/packages/SystemUI/src/com/android/systemui/broadcast/logging/BroadcastDispatcherLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/broadcast/logging/BroadcastDispatcherLogger.kt
@@ -87,6 +87,26 @@
         })
     }
 
+    fun logTagForRemoval(user: Int, receiver: BroadcastReceiver) {
+        val receiverString = receiver.toString()
+        log(DEBUG, {
+            int1 = user
+            str1 = receiverString
+        }, {
+            "Receiver $str1 tagged for removal from user $int1"
+        })
+    }
+
+    fun logClearedAfterRemoval(user: Int, receiver: BroadcastReceiver) {
+        val receiverString = receiver.toString()
+        log(DEBUG, {
+            int1 = user
+            str1 = receiverString
+        }, {
+            "Receiver $str1 has been completely removed for user $int1"
+        })
+    }
+
     fun logReceiverUnregistered(user: Int, receiver: BroadcastReceiver) {
         val receiverString = receiver.toString()
         log(INFO, {
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
index fb1af8b..74949d0 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
@@ -16,7 +16,7 @@
 
 package com.android.systemui.dreams;
 
-import static com.android.keyguard.BouncerPanelExpansionCalculator.getBackScrimScaledExpansion;
+import static com.android.keyguard.BouncerPanelExpansionCalculator.aboutToShowBouncerProgress;
 import static com.android.keyguard.BouncerPanelExpansionCalculator.getDreamAlphaScaledExpansion;
 import static com.android.keyguard.BouncerPanelExpansionCalculator.getDreamYPositionScaledExpansion;
 import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
@@ -217,19 +217,19 @@
 
         mBlurUtils.applyBlur(mView.getViewRootImpl(),
                 (int) mBlurUtils.blurRadiusOfRatio(
-                        1 - getBackScrimScaledExpansion(bouncerHideAmount)), false);
+                        1 - aboutToShowBouncerProgress(bouncerHideAmount)), false);
     }
 
     private static float getAlpha(int position, float expansion) {
         return Interpolators.LINEAR_OUT_SLOW_IN.getInterpolation(
                 position == POSITION_TOP ? getDreamAlphaScaledExpansion(expansion)
-                        : getBackScrimScaledExpansion(expansion + 0.03f));
+                        : aboutToShowBouncerProgress(expansion + 0.03f));
     }
 
     private float getTranslationY(int position, float expansion) {
         final float fraction = Interpolators.LINEAR_OUT_SLOW_IN.getInterpolation(
                 position == POSITION_TOP ? getDreamYPositionScaledExpansion(expansion)
-                        : getBackScrimScaledExpansion(expansion + 0.03f));
+                        : aboutToShowBouncerProgress(expansion + 0.03f));
         return MathUtils.lerp(-mDreamOverlayMaxTranslationY, 0, fraction);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index f87f81e..a64b670 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -610,7 +610,7 @@
             view.setVisibility((View.VISIBLE));
         }
         float alpha = mQSPanelController.bouncerInTransit()
-                ? BouncerPanelExpansionCalculator.getBackScrimScaledExpansion(progress)
+                ? BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(progress)
                 : ShadeInterpolation.getContentAlpha(progress);
         view.setAlpha(alpha);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt
index 9a932ba..270bdc7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt
@@ -11,6 +11,7 @@
 import android.graphics.PorterDuffXfermode
 import android.graphics.RadialGradient
 import android.graphics.Shader
+import android.os.Trace
 import android.util.AttributeSet
 import android.util.MathUtils.lerp
 import android.view.View
@@ -222,6 +223,8 @@
 
                 revealEffect.setRevealAmountOnScrim(value, this)
                 updateScrimOpaque()
+                Trace.traceCounter(Trace.TRACE_TAG_APP, "light_reveal_amount",
+                        (field * 100).toInt())
                 invalidate()
             }
         }
@@ -355,8 +358,8 @@
     }
 
     override fun onDraw(canvas: Canvas?) {
-        if (canvas == null || revealGradientWidth <= 0 || revealGradientHeight <= 0
-            || revealAmount == 0f) {
+        if (canvas == null || revealGradientWidth <= 0 || revealGradientHeight <= 0 ||
+            revealAmount == 0f) {
             if (revealAmount < 1f) {
                 canvas?.drawColor(revealGradientEndColor)
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
index c77b0d6..5e81b5d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -4404,8 +4404,7 @@
                 @Override
                 public void onDozeAmountChanged(float linear, float eased) {
                     if (mFeatureFlags.isEnabled(Flags.LOCKSCREEN_ANIMATIONS)
-                            && !(mLightRevealScrim.getRevealEffect() instanceof CircleReveal)
-                            && !mBiometricUnlockController.isWakeAndUnlock()) {
+                            && !(mLightRevealScrim.getRevealEffect() instanceof CircleReveal)) {
                         mLightRevealScrim.setRevealAmount(1f - linear);
                     }
                 }
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 518a918..d492c57 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
@@ -797,7 +797,7 @@
             mExpandedFraction = Math.min(1f,
                     maxPanelHeight == 0 ? 0 : mExpandedHeight / maxPanelHeight);
             mAmbientState.setExpansionFraction(mStatusBarKeyguardViewManager.bouncerIsInTransit()
-                    ? BouncerPanelExpansionCalculator.getBackScrimScaledExpansion(mExpandedFraction)
+                    ? BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(mExpandedFraction)
                     : mExpandedFraction);
             onHeightUpdated(mExpandedHeight);
             updatePanelExpansionAndVisibility();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index fd6503a..cc2ff3f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -790,7 +790,7 @@
 
             if (mBouncerHiddenFraction != KeyguardBouncer.EXPANSION_HIDDEN) {
                 final float interpolatedFraction =
-                        BouncerPanelExpansionCalculator.getBackScrimScaledExpansion(
+                        BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(
                                 mBouncerHiddenFraction);
                 mBehindAlpha = MathUtils.lerp(mDefaultScrimAlpha, mBehindAlpha,
                         interpolatedFraction);
@@ -1076,7 +1076,7 @@
     private float getInterpolatedFraction() {
         if (mStatusBarKeyguardViewManager.bouncerIsInTransit()) {
             return BouncerPanelExpansionCalculator
-                    .getBackScrimScaledExpansion(mPanelExpansionFraction);
+                    .aboutToShowBouncerProgress(mPanelExpansionFraction);
         }
         return ShadeInterpolation.getNotificationScrimAlpha(mPanelExpansionFraction);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
index ea935be..935f87d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
@@ -17,6 +17,7 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.keyguard.KeyguardViewMediator
 import com.android.systemui.keyguard.WakefulnessLifecycle
+import com.android.systemui.statusbar.CircleReveal
 import com.android.systemui.statusbar.LightRevealScrim
 import com.android.systemui.statusbar.StatusBarState
 import com.android.systemui.statusbar.StatusBarStateControllerImpl
@@ -85,7 +86,9 @@
         duration = LIGHT_REVEAL_ANIMATION_DURATION
         interpolator = Interpolators.LINEAR
         addUpdateListener {
-            lightRevealScrim.revealAmount = it.animatedValue as Float
+            if (lightRevealScrim.revealEffect !is CircleReveal) {
+                lightRevealScrim.revealAmount = it.animatedValue as Float
+            }
             if (lightRevealScrim.isScrimAlmostOccludes &&
                     interactionJankMonitor.isInstrumenting(CUJ_SCREEN_OFF)) {
                 // ends the instrument when the scrim almost occludes the screen.
@@ -95,9 +98,9 @@
         }
         addListener(object : AnimatorListenerAdapter() {
             override fun onAnimationCancel(animation: Animator?) {
-                lightRevealScrim.revealAmount = 1f
-                lightRevealAnimationPlaying = false
-                interactionJankMonitor.cancel(CUJ_SCREEN_OFF)
+                if (lightRevealScrim.revealEffect !is CircleReveal) {
+                    lightRevealScrim.revealAmount = 1f
+                }
             }
 
             override fun onAnimationEnd(animation: Animator?) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index 846e07f..a3f01c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -64,8 +64,6 @@
 import com.android.settingslib.utils.ThreadUtils;
 import com.android.systemui.Dumpable;
 import com.android.systemui.GuestResumeSessionReceiver;
-import com.android.systemui.Prefs;
-import com.android.systemui.Prefs.Key;
 import com.android.systemui.R;
 import com.android.systemui.SystemUISecondaryUserService;
 import com.android.systemui.animation.DialogLaunchAnimator;
@@ -84,6 +82,7 @@
 import com.android.systemui.statusbar.phone.SystemUIDialog;
 import com.android.systemui.telephony.TelephonyListenerManager;
 import com.android.systemui.user.CreateUserActivity;
+import com.android.systemui.util.settings.GlobalSettings;
 import com.android.systemui.util.settings.SecureSettings;
 
 import java.io.PrintWriter;
@@ -144,6 +143,7 @@
     // When false, there won't be any visual affordance to add a new user from the keyguard even if
     // the user is unlocked
     private boolean mAddUsersFromLockScreen;
+    private boolean mUserSwitcherEnabled;
     @VisibleForTesting
     boolean mPauseRefreshUsers;
     private int mSecondaryUser = UserHandle.USER_NULL;
@@ -160,6 +160,7 @@
     private FalsingManager mFalsingManager;
     private View mView;
     private String mCreateSupervisedUserPackage;
+    private GlobalSettings mGlobalSettings;
 
     @Inject
     public UserSwitcherController(Context context,
@@ -177,6 +178,7 @@
             FalsingManager falsingManager,
             TelephonyListenerManager telephonyListenerManager,
             SecureSettings secureSettings,
+            GlobalSettings globalSettings,
             @Background Executor bgExecutor,
             @LongRunning Executor longRunningExecutor,
             @Main Executor uiExecutor,
@@ -194,6 +196,7 @@
         mFalsingManager = falsingManager;
         mInteractionJankMonitor = interactionJankMonitor;
         mLatencyTracker = latencyTracker;
+        mGlobalSettings = globalSettings;
         mGuestResumeSessionReceiver = new GuestResumeSessionReceiver(
                 this, mUserTracker, mUiEventLogger, secureSettings);
         mBgExecutor = bgExecutor;
@@ -237,8 +240,10 @@
             @Override
             public void onChange(boolean selfChange) {
                 mSimpleUserSwitcher = shouldUseSimpleUserSwitcher();
-                mAddUsersFromLockScreen = Settings.Global.getInt(mContext.getContentResolver(),
-                        Settings.Global.ADD_USERS_WHEN_LOCKED, 0) != 0;
+                mAddUsersFromLockScreen = mGlobalSettings.getIntForUser(
+                        Settings.Global.ADD_USERS_WHEN_LOCKED, 0, UserHandle.USER_SYSTEM) != 0;
+                mUserSwitcherEnabled = mGlobalSettings.getIntForUser(
+                        Settings.Global.USER_SWITCHER_ENABLED, 0, UserHandle.USER_SYSTEM) != 0;
                 refreshUsers(UserHandle.USER_NULL);
             };
         };
@@ -246,6 +251,9 @@
                 Settings.Global.getUriFor(SIMPLE_USER_SWITCHER_GLOBAL_SETTING), true,
                 mSettingsObserver);
         mContext.getContentResolver().registerContentObserver(
+                Settings.Global.getUriFor(Settings.Global.USER_SWITCHER_ENABLED), true,
+                mSettingsObserver);
+        mContext.getContentResolver().registerContentObserver(
                 Settings.Global.getUriFor(Settings.Global.ADD_USERS_WHEN_LOCKED), true,
                 mSettingsObserver);
         mContext.getContentResolver().registerContentObserver(
@@ -314,6 +322,10 @@
             for (UserInfo info : infos) {
                 boolean isCurrent = currentId == info.id;
                 boolean switchToEnabled = canSwitchUsers || isCurrent;
+                if (!mUserSwitcherEnabled && !info.isPrimary()) {
+                    continue;
+                }
+
                 if (info.isEnabled()) {
                     if (info.isGuest()) {
                         // Tapping guest icon triggers remove and a user switch therefore
@@ -340,9 +352,6 @@
                     }
                 }
             }
-            if (records.size() > 1 || guestRecord != null) {
-                Prefs.putBoolean(mContext, Key.SEEN_MULTI_USER, true);
-            }
 
             if (guestRecord == null) {
                 if (mGuestUserAutoCreated) {
@@ -411,12 +420,14 @@
     }
 
     boolean canCreateGuest(boolean hasExistingGuest) {
-        return (currentUserCanCreateUsers() || anyoneCanCreateUsers())
+        return mUserSwitcherEnabled
+                && (currentUserCanCreateUsers() || anyoneCanCreateUsers())
                 && !hasExistingGuest;
     }
 
     boolean canCreateUser() {
-        return (currentUserCanCreateUsers() || anyoneCanCreateUsers())
+        return mUserSwitcherEnabled
+                && (currentUserCanCreateUsers() || anyoneCanCreateUsers())
                 && mUserManager.canAddMoreUsers(UserManager.USER_TYPE_FULL_SECONDARY);
     }
 
@@ -1034,8 +1045,8 @@
     private boolean shouldUseSimpleUserSwitcher() {
         int defaultSimpleUserSwitcher = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_expandLockScreenUserSwitcher) ? 1 : 0;
-        return Settings.Global.getInt(mContext.getContentResolver(),
-                SIMPLE_USER_SWITCHER_GLOBAL_SETTING, defaultSimpleUserSwitcher) != 0;
+        return mGlobalSettings.getIntForUser(SIMPLE_USER_SWITCHER_GLOBAL_SETTING,
+                defaultSimpleUserSwitcher, UserHandle.USER_SYSTEM) != 0;
     }
 
     public void startActivity(Intent intent) {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/BouncerPanelExpansionCalculatorTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/BouncerPanelExpansionCalculatorTest.kt
index 6266bf1..f8fdd8d 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/BouncerPanelExpansionCalculatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/BouncerPanelExpansionCalculatorTest.kt
@@ -29,29 +29,29 @@
 class BouncerPanelExpansionCalculatorTest : SysuiTestCase() {
     @Test
     fun testGetHostViewScaledExpansion() {
-        assertThat(BouncerPanelExpansionCalculator.getHostViewScaledExpansion(1f))
+        assertThat(BouncerPanelExpansionCalculator.showBouncerProgress(1f))
                 .isEqualTo(1f)
-        assertThat(BouncerPanelExpansionCalculator.getHostViewScaledExpansion(0.9f))
+        assertThat(BouncerPanelExpansionCalculator.showBouncerProgress(0.9f))
                 .isEqualTo(1f)
-        assertThat(BouncerPanelExpansionCalculator.getHostViewScaledExpansion(0.59f))
+        assertThat(BouncerPanelExpansionCalculator.showBouncerProgress(0.59f))
                 .isEqualTo(0f)
-        assertThat(BouncerPanelExpansionCalculator.getHostViewScaledExpansion(0f))
+        assertThat(BouncerPanelExpansionCalculator.showBouncerProgress(0f))
                 .isEqualTo(0f)
         assertEquals(BouncerPanelExpansionCalculator
-                .getHostViewScaledExpansion(0.8f), 2f / 3f, 0.01f)
+                .showBouncerProgress(0.8f), 2f / 3f, 0.01f)
     }
 
     @Test
     fun testGetBackScrimScaledExpansion() {
-        assertThat(BouncerPanelExpansionCalculator.getBackScrimScaledExpansion(1f))
+        assertThat(BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(1f))
                 .isEqualTo(1f)
         assertEquals(BouncerPanelExpansionCalculator
-                .getBackScrimScaledExpansion(0.95f), 1f / 2f, 0.01f)
-        assertThat(BouncerPanelExpansionCalculator.getBackScrimScaledExpansion(0.9f))
+                .aboutToShowBouncerProgress(0.95f), 1f / 2f, 0.01f)
+        assertThat(BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(0.9f))
                 .isEqualTo(0f)
-        assertThat(BouncerPanelExpansionCalculator.getBackScrimScaledExpansion(0.5f))
+        assertThat(BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(0.5f))
                 .isEqualTo(0f)
-        assertThat(BouncerPanelExpansionCalculator.getBackScrimScaledExpansion(0f))
+        assertThat(BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(0f))
                 .isEqualTo(0f)
     }
 
@@ -63,9 +63,9 @@
                 .getKeyguardClockScaledExpansion(0.8f), 1f / 3f, 0.01f)
         assertThat(BouncerPanelExpansionCalculator.getKeyguardClockScaledExpansion(0.7f))
                 .isEqualTo(0f)
-        assertThat(BouncerPanelExpansionCalculator.getBackScrimScaledExpansion(0.5f))
+        assertThat(BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(0.5f))
                 .isEqualTo(0f)
-        assertThat(BouncerPanelExpansionCalculator.getBackScrimScaledExpansion(0f))
+        assertThat(BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(0f))
                 .isEqualTo(0f)
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/broadcast/ActionReceiverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/broadcast/ActionReceiverTest.kt
index e95eb4e..f5990be 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/broadcast/ActionReceiverTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/broadcast/ActionReceiverTest.kt
@@ -42,6 +42,7 @@
 import org.mockito.Captor
 import org.mockito.Mock
 import org.mockito.Mockito
+import org.mockito.Mockito.`when`
 import org.mockito.Mockito.mock
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
@@ -81,6 +82,8 @@
     @Mock
     private lateinit var unregisterFunction: BroadcastReceiver.() -> Unit
     @Mock
+    private lateinit var isPendingRemovalFunction: (BroadcastReceiver, Int) -> Boolean
+    @Mock
     private lateinit var receiver1: BroadcastReceiver
     @Mock
     private lateinit var receiver2: BroadcastReceiver
@@ -98,13 +101,16 @@
         MockitoAnnotations.initMocks(this)
         executor = FakeExecutor(FakeSystemClock())
 
+        `when`(isPendingRemovalFunction(any(), anyInt())).thenReturn(false)
+
         actionReceiver = ActionReceiver(
                 ACTION1,
                 USER.identifier,
                 registerFunction,
                 unregisterFunction,
                 executor,
-                logger
+                logger,
+                isPendingRemovalFunction
         )
     }
 
@@ -249,6 +255,20 @@
         verify(logger).logBroadcastDispatched(anyInt(), eq(ACTION1), sameNotNull(receiver1))
     }
 
+    @Test
+    fun testBroadcastNotDispatchingOnPendingRemoval() {
+        `when`(isPendingRemovalFunction(receiver1, USER.identifier)).thenReturn(true)
+
+        val receiverData = ReceiverData(receiver1, IntentFilter(ACTION1), directExecutor, USER)
+
+        actionReceiver.addReceiverData(receiverData)
+
+        val intent = Intent(ACTION1)
+        actionReceiver.onReceive(mContext, intent)
+        executor.runAllReady()
+        verify(receiver1, never()).onReceive(any(), eq(intent))
+    }
+
     @Test(expected = IllegalStateException::class)
     fun testBroadcastWithWrongAction_throwsException() {
         actionReceiver.onReceive(mContext, Intent(ACTION2))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
index a1d1933..7795d2c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
@@ -41,6 +41,8 @@
 import org.mockito.Captor
 import org.mockito.Mock
 import org.mockito.Mockito.`when`
+import org.mockito.Mockito.anyInt
+import org.mockito.Mockito.inOrder
 import org.mockito.Mockito.mock
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
@@ -85,6 +87,8 @@
     private lateinit var logger: BroadcastDispatcherLogger
     @Mock
     private lateinit var userTracker: UserTracker
+    @Mock
+    private lateinit var removalPendingStore: PendingRemovalStore
 
     private lateinit var executor: Executor
 
@@ -108,6 +112,7 @@
                 mock(DumpManager::class.java),
                 logger,
                 userTracker,
+                removalPendingStore,
                 mapOf(0 to mockUBRUser0, 1 to mockUBRUser1))
 
         // These should be valid filters
@@ -325,6 +330,57 @@
         broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter)
     }
 
+    @Test
+    fun testTaggedReceiverForRemovalImmediately_allUsers() {
+        broadcastDispatcher.unregisterReceiver(broadcastReceiver)
+
+        verify(removalPendingStore).tagForRemoval(broadcastReceiver, UserHandle.USER_ALL)
+        verify(removalPendingStore, never()).clearPendingRemoval(eq(broadcastReceiver), anyInt())
+    }
+
+    @Test
+    fun testTaggedReceiverForRemovalImmediately_singleUser() {
+        val user = 0
+        broadcastDispatcher.unregisterReceiverForUser(broadcastReceiver, UserHandle.of(user))
+
+        verify(removalPendingStore).tagForRemoval(broadcastReceiver, user)
+        verify(removalPendingStore, never()).clearPendingRemoval(eq(broadcastReceiver), anyInt())
+    }
+
+    @Test
+    fun testUnregisterReceiverClearsPendingRemovalAfterRemoving_allUsers() {
+        broadcastDispatcher.registerReceiver(broadcastReceiver, intentFilter, null, user0)
+        broadcastDispatcher.registerReceiver(broadcastReceiver, intentFilter, null, user1)
+
+        broadcastDispatcher.unregisterReceiver(broadcastReceiver)
+
+        testableLooper.processAllMessages()
+
+        val inOrderUser0 = inOrder(mockUBRUser0, removalPendingStore)
+        inOrderUser0.verify(mockUBRUser0).unregisterReceiver(broadcastReceiver)
+        inOrderUser0.verify(removalPendingStore)
+            .clearPendingRemoval(broadcastReceiver, UserHandle.USER_ALL)
+
+        val inOrderUser1 = inOrder(mockUBRUser1, removalPendingStore)
+        inOrderUser1.verify(mockUBRUser1).unregisterReceiver(broadcastReceiver)
+        inOrderUser1.verify(removalPendingStore)
+            .clearPendingRemoval(broadcastReceiver, UserHandle.USER_ALL)
+    }
+
+    @Test
+    fun testUnregisterReceiverclearPendingRemovalAfterRemoving_singleUser() {
+        broadcastDispatcher.registerReceiver(broadcastReceiver, intentFilter, null, user1)
+
+        broadcastDispatcher.unregisterReceiverForUser(broadcastReceiver, user1)
+
+        testableLooper.processAllMessages()
+
+        val inOrderUser1 = inOrder(mockUBRUser1, removalPendingStore)
+        inOrderUser1.verify(mockUBRUser1).unregisterReceiver(broadcastReceiver)
+        inOrderUser1.verify(removalPendingStore)
+            .clearPendingRemoval(broadcastReceiver, user1.identifier)
+    }
+
     private fun setUserMock(mockContext: Context, user: UserHandle) {
         `when`(mockContext.user).thenReturn(user)
         `when`(mockContext.userId).thenReturn(user.identifier)
@@ -337,8 +393,17 @@
         dumpManager: DumpManager,
         logger: BroadcastDispatcherLogger,
         userTracker: UserTracker,
+        removalPendingStore: PendingRemovalStore,
         var mockUBRMap: Map<Int, UserBroadcastDispatcher>
-    ) : BroadcastDispatcher(context, bgLooper, executor, dumpManager, logger, userTracker) {
+    ) : BroadcastDispatcher(
+        context,
+        bgLooper,
+        executor,
+        dumpManager,
+        logger,
+        userTracker,
+        removalPendingStore
+    ) {
         override fun createUBRForUser(userId: Int): UserBroadcastDispatcher {
             return mockUBRMap.getOrDefault(userId, mock(UserBroadcastDispatcher::class.java))
         }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/broadcast/PendingRemovalStoreTest.kt b/packages/SystemUI/tests/src/com/android/systemui/broadcast/PendingRemovalStoreTest.kt
new file mode 100644
index 0000000..43d2cb8
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/broadcast/PendingRemovalStoreTest.kt
@@ -0,0 +1,81 @@
+package com.android.systemui.broadcast
+
+import android.content.BroadcastReceiver
+import android.os.UserHandle
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class PendingRemovalStoreTest : SysuiTestCase() {
+
+    @Mock
+    private lateinit var logger: BroadcastDispatcherLogger
+    @Mock
+    private lateinit var receiverOne: BroadcastReceiver
+    @Mock
+    private lateinit var receiverTwo: BroadcastReceiver
+
+    private lateinit var store: PendingRemovalStore
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+
+        store = PendingRemovalStore(logger)
+    }
+
+    @Test
+    fun testTagForRemoval_logged() {
+        val user = 10
+        store.tagForRemoval(receiverOne, 10)
+
+        verify(logger).logTagForRemoval(user, receiverOne)
+    }
+
+    @Test
+    fun testClearedPendingRemoval_logged() {
+        val user = UserHandle.USER_ALL
+        store.clearPendingRemoval(receiverOne, user)
+
+        verify(logger).logClearedAfterRemoval(user, receiverOne)
+    }
+
+    @Test
+    fun testTaggedReceiverMarkedAsPending_specificUser() {
+        val user = 10
+        store.tagForRemoval(receiverOne, user)
+
+        assertThat(store.isPendingRemoval(receiverOne, user)).isTrue()
+        assertThat(store.isPendingRemoval(receiverOne, user + 1)).isFalse()
+        assertThat(store.isPendingRemoval(receiverOne, UserHandle.USER_ALL)).isFalse()
+    }
+
+    @Test
+    fun testTaggedReceiverMarkedAsPending_allUsers() {
+        val user = 10
+        store.tagForRemoval(receiverOne, UserHandle.USER_ALL)
+
+        assertThat(store.isPendingRemoval(receiverOne, user)).isTrue()
+        assertThat(store.isPendingRemoval(receiverOne, user + 1)).isTrue()
+        assertThat(store.isPendingRemoval(receiverOne, UserHandle.USER_ALL)).isTrue()
+    }
+
+    @Test
+    fun testOnlyBlockCorrectReceiver() {
+        val user = 10
+        store.tagForRemoval(receiverOne, user)
+
+        assertThat(store.isPendingRemoval(receiverOne, user)).isTrue()
+        assertThat(store.isPendingRemoval(receiverTwo, user)).isFalse()
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/broadcast/UserBroadcastDispatcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/broadcast/UserBroadcastDispatcherTest.kt
index 116b81d..39e4467 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/broadcast/UserBroadcastDispatcherTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/broadcast/UserBroadcastDispatcherTest.kt
@@ -68,6 +68,8 @@
     private lateinit var mockContext: Context
     @Mock
     private lateinit var logger: BroadcastDispatcherLogger
+    @Mock
+    private lateinit var removalPendingStore: PendingRemovalStore
 
     private lateinit var testableLooper: TestableLooper
     private lateinit var userBroadcastDispatcher: UserBroadcastDispatcher
@@ -84,7 +86,13 @@
         fakeExecutor = FakeExecutor(FakeSystemClock())
 
         userBroadcastDispatcher = object : UserBroadcastDispatcher(
-                mockContext, USER_ID, testableLooper.looper, mock(Executor::class.java), logger) {
+                mockContext,
+                USER_ID,
+                testableLooper.looper,
+                mock(Executor::class.java),
+                logger,
+                removalPendingStore
+        ) {
             override fun createActionReceiver(
                 action: String,
                 permission: String?,
@@ -216,7 +224,8 @@
                 USER_ID,
                 testableLooper.looper,
                 fakeExecutor,
-                logger
+                logger,
+                removalPendingStore
         )
         uBR.registerReceiver(
                 ReceiverData(
@@ -243,7 +252,8 @@
             USER_ID,
             testableLooper.looper,
             fakeExecutor,
-            logger
+            logger,
+            removalPendingStore
         )
         uBR.registerReceiver(
             ReceiverData(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
index 6453c20..d70467d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
@@ -177,7 +177,7 @@
 
         final float bouncerHideAmount = 0.05f;
         final float scaledFraction =
-                BouncerPanelExpansionCalculator.getBackScrimScaledExpansion(bouncerHideAmount);
+                BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(bouncerHideAmount);
 
         bouncerExpansionCaptor.getValue().onExpansionChanged(bouncerHideAmount);
         verify(mBlurUtils).blurRadiusOfRatio(1 - scaledFraction);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index 829445e..f5d19e2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -214,7 +214,7 @@
 
         assertThat(mQsFragmentView.getAlpha())
                 .isEqualTo(
-                        BouncerPanelExpansionCalculator.getBackScrimScaledExpansion(
+                        BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(
                                 transitionProgress));
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index 509fa3b..69d7932 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -1244,11 +1244,11 @@
 
         float expansion = 0.8f;
         float expectedAlpha =
-                BouncerPanelExpansionCalculator.getBackScrimScaledExpansion(expansion);
+                BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(expansion);
         assertAlphaAfterExpansion(mNotificationsScrim, expectedAlpha, expansion);
 
         expansion = 0.2f;
-        expectedAlpha = BouncerPanelExpansionCalculator.getBackScrimScaledExpansion(expansion);
+        expectedAlpha = BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(expansion);
         assertAlphaAfterExpansion(mNotificationsScrim, expectedAlpha, expansion);
     }
 
@@ -1284,7 +1284,7 @@
         // Verify normal behavior after
         mScrimController.setUnocclusionAnimationRunning(false);
         float expansion = 0.4f;
-        float alpha = 1 - BouncerPanelExpansionCalculator.getBackScrimScaledExpansion(expansion);
+        float alpha = 1 - BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(expansion);
         assertAlphaAfterExpansion(mNotificationsScrim, alpha, expansion);
     }
 
@@ -1316,15 +1316,15 @@
         mScrimController.transitionTo(ScrimState.KEYGUARD);
 
         float expansion = 0.8f;
-        float alpha = 1 - BouncerPanelExpansionCalculator.getBackScrimScaledExpansion(expansion);
+        float alpha = 1 - BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(expansion);
         assertAlphaAfterExpansion(mNotificationsScrim, alpha, expansion);
 
         expansion = 0.4f;
-        alpha = 1 - BouncerPanelExpansionCalculator.getBackScrimScaledExpansion(expansion);
+        alpha = 1 - BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(expansion);
         assertAlphaAfterExpansion(mNotificationsScrim, alpha, expansion);
 
         expansion = 0.2f;
-        alpha = 1 - BouncerPanelExpansionCalculator.getBackScrimScaledExpansion(expansion);
+        alpha = 1 - BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(expansion);
         assertAlphaAfterExpansion(mNotificationsScrim, alpha, expansion);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt
index 799dafc..e3d2a29 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt
@@ -28,6 +28,7 @@
 import android.os.Handler
 import android.os.UserHandle
 import android.os.UserManager
+import android.provider.Settings
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.view.ThreadedRenderer
@@ -51,6 +52,7 @@
 import com.android.systemui.statusbar.phone.NotificationShadeWindowView
 import com.android.systemui.telephony.TelephonyListenerManager
 import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.settings.GlobalSettings
 import com.android.systemui.util.settings.SecureSettings
 import com.android.systemui.util.time.FakeSystemClock
 import org.junit.Assert.assertEquals
@@ -67,6 +69,7 @@
 import org.mockito.Mockito.any
 import org.mockito.Mockito.doNothing
 import org.mockito.Mockito.doReturn
+import org.mockito.Mockito.eq
 import org.mockito.Mockito.mock
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
@@ -95,6 +98,7 @@
     @Mock private lateinit var notificationShadeWindowView: NotificationShadeWindowView
     @Mock private lateinit var threadedRenderer: ThreadedRenderer
     @Mock private lateinit var dialogLaunchAnimator: DialogLaunchAnimator
+    @Mock private lateinit var globalSettings: GlobalSettings
     private lateinit var testableLooper: TestableLooper
     private lateinit var bgExecutor: FakeExecutor
     private lateinit var longRunningExecutor: FakeExecutor
@@ -148,6 +152,22 @@
         `when`(userTracker.userId).thenReturn(ownerId)
         `when`(userTracker.userInfo).thenReturn(ownerInfo)
 
+        `when`(
+            globalSettings.getIntForUser(
+                eq(Settings.Global.ADD_USERS_WHEN_LOCKED),
+                anyInt(),
+                eq(UserHandle.USER_SYSTEM)
+            )
+        ).thenReturn(0)
+
+        `when`(
+            globalSettings.getIntForUser(
+                eq(Settings.Global.USER_SWITCHER_ENABLED),
+                anyInt(),
+                eq(UserHandle.USER_SYSTEM)
+            )
+        ).thenReturn(1)
+
         setupController()
     }
 
@@ -168,6 +188,7 @@
                 falsingManager,
                 telephonyListenerManager,
                 secureSettings,
+                globalSettings,
                 bgExecutor,
                 longRunningExecutor,
                 uiExecutor,
@@ -469,4 +490,43 @@
         // THEN a supervised user can NOT be constructed
         assertFalse(userSwitcherController.canCreateSupervisedUser())
     }
+
+    @Test
+    fun testCannotCreateUserWhenUserSwitcherDisabled() {
+        `when`(
+            globalSettings.getIntForUser(
+                eq(Settings.Global.USER_SWITCHER_ENABLED),
+                anyInt(),
+                eq(UserHandle.USER_SYSTEM)
+            )
+        ).thenReturn(0)
+        setupController()
+        assertFalse(userSwitcherController.canCreateUser())
+    }
+
+    @Test
+    fun testCannotCreateGuestUserWhenUserSwitcherDisabled() {
+        `when`(
+            globalSettings.getIntForUser(
+                eq(Settings.Global.USER_SWITCHER_ENABLED),
+                anyInt(),
+                eq(UserHandle.USER_SYSTEM)
+            )
+        ).thenReturn(0)
+        setupController()
+        assertFalse(userSwitcherController.canCreateGuest(false))
+    }
+
+    @Test
+    fun testCannotCreateSupervisedUserWhenUserSwitcherDisabled() {
+        `when`(
+            globalSettings.getIntForUser(
+                eq(Settings.Global.USER_SWITCHER_ENABLED),
+                anyInt(),
+                eq(UserHandle.USER_SYSTEM)
+            )
+        ).thenReturn(0)
+        setupController()
+        assertFalse(userSwitcherController.canCreateSupervisedUser())
+    }
 }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index efde2a5..e29f11a 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -49,6 +49,12 @@
 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_DATA_SAVER;
+import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_USER_RESTRICTED;
+import static android.net.ConnectivityManager.BLOCKED_REASON_APP_STANDBY;
+import static android.net.ConnectivityManager.BLOCKED_REASON_BATTERY_SAVER;
+import static android.net.ConnectivityManager.BLOCKED_REASON_DOZE;
+import static android.net.ConnectivityManager.BLOCKED_REASON_LOW_POWER_STANDBY;
 import static android.net.ConnectivityManager.BLOCKED_REASON_NONE;
 import static android.os.FactoryTest.FACTORY_TEST_OFF;
 import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
@@ -17306,8 +17312,22 @@
                 // TODO: We can reuse this data in
                 // ProcessList#incrementProcStateSeqAndNotifyAppsLOSP instead of calling into
                 // NetworkManagementService.
-                return mUidNetworkBlockedReasons.get(uid, BLOCKED_REASON_NONE)
-                        != BLOCKED_REASON_NONE;
+                final int uidBlockedReasons = mUidNetworkBlockedReasons.get(
+                        uid, BLOCKED_REASON_NONE);
+                if (uidBlockedReasons == BLOCKED_REASON_NONE) {
+                    return false;
+                }
+                final int topExemptedBlockedReasons = BLOCKED_REASON_BATTERY_SAVER
+                        | BLOCKED_REASON_DOZE
+                        | BLOCKED_REASON_APP_STANDBY
+                        | BLOCKED_REASON_LOW_POWER_STANDBY
+                        | BLOCKED_METERED_REASON_DATA_SAVER
+                        | BLOCKED_METERED_REASON_USER_RESTRICTED;
+                final int effectiveBlockedReasons =
+                        uidBlockedReasons & ~topExemptedBlockedReasons;
+                // Only consider it as blocked if it is not blocked by a reason
+                // that is not exempted by app being in the top state.
+                return effectiveBlockedReasons == BLOCKED_REASON_NONE;
             }
         }
 
diff --git a/services/core/java/com/android/server/health/HealthRegCallbackAidl.java b/services/core/java/com/android/server/health/HealthRegCallbackAidl.java
index 629011a..90a2f48 100644
--- a/services/core/java/com/android/server/health/HealthRegCallbackAidl.java
+++ b/services/core/java/com/android/server/health/HealthRegCallbackAidl.java
@@ -115,5 +115,13 @@
         public void healthInfoChanged(HealthInfo healthInfo) throws RemoteException {
             mServiceInfoCallback.update(healthInfo);
         }
+        @Override
+        public String getInterfaceHash() {
+            return IHealthInfoCallback.HASH;
+        }
+        @Override
+        public int getInterfaceVersion() {
+            return IHealthInfoCallback.VERSION;
+        }
     }
 }
diff --git a/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java b/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java
index a1ee46b..acc0746 100644
--- a/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java
+++ b/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java
@@ -389,6 +389,15 @@
                     mCallback.handleTransactionResult(transactionId, success);
                 });
             }
+            @Override
+            public String getInterfaceHash() {
+                return android.hardware.contexthub.IContextHubCallback.HASH;
+            }
+
+            @Override
+            public int getInterfaceVersion() {
+                return android.hardware.contexthub.IContextHubCallback.VERSION;
+            }
         }
 
         ContextHubWrapperAidl(android.hardware.contexthub.IContextHub hub) {
diff --git a/services/core/java/com/android/server/notification/PermissionHelper.java b/services/core/java/com/android/server/notification/PermissionHelper.java
index b4230c1..a09aa7c 100644
--- a/services/core/java/com/android/server/notification/PermissionHelper.java
+++ b/services/core/java/com/android/server/notification/PermissionHelper.java
@@ -55,8 +55,10 @@
     private final PermissionManagerServiceInternal mPmi;
     private final IPackageManager mPackageManager;
     private final IPermissionManager mPermManager;
-    // TODO (b/194833441): Remove when the migration is enabled
+    // TODO (b/194833441): Remove this boolean (but keep the isMigrationEnabled() method)
+    //  when the migration is enabled
     private final boolean mMigrationEnabled;
+    private final boolean mIsTv;
     private final boolean mForceUserSetOnUpgrade;
 
     public PermissionHelper(PermissionManagerServiceInternal pmi, IPackageManager packageManager,
@@ -67,10 +69,17 @@
         mPermManager = permManager;
         mMigrationEnabled = migrationEnabled;
         mForceUserSetOnUpgrade = forceUserSetOnUpgrade;
+        boolean isTv;
+        try {
+            isTv = mPackageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK, 0);
+        } catch (RemoteException e) {
+            isTv = false;
+        }
+        mIsTv = isTv;
     }
 
     public boolean isMigrationEnabled() {
-        return mMigrationEnabled;
+        return mMigrationEnabled && !mIsTv;
     }
 
     /**
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
index c524fb7..d11ea53 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
@@ -297,6 +297,8 @@
             .OnRuntimePermissionStateChangedListener>
             mRuntimePermissionStateChangedListeners = new ArrayList<>();
 
+    private final boolean mIsLeanback;
+
     @NonNull
     private final OnPermissionChangeListeners mOnPermissionChangeListeners;
 
@@ -380,6 +382,7 @@
         mContext = context;
         mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
         mUserManagerInt = LocalServices.getService(UserManagerInternal.class);
+        mIsLeanback = availableFeatures.containsKey(PackageManager.FEATURE_LEANBACK);
 
         mPrivilegedPermissionAllowlistSourcePackageNames.add(PLATFORM_PACKAGE_NAME);
         // PackageManager.hasSystemFeature() is not used here because PackageManagerService
@@ -2822,6 +2825,14 @@
                                     }
                                 }
                             }
+                            if (mIsLeanback && NOTIFICATION_PERMISSIONS.contains(permName)) {
+                                uidState.grantPermission(bp);
+                                if (origPermState == null || !origPermState.isGranted()) {
+                                    if (uidState.grantPermission(bp)) {
+                                        wasChanged = true;
+                                    }
+                                }
+                            }
                         } else {
                             if (origPermState == null) {
                                 // New permission
diff --git a/services/core/java/com/android/server/vibrator/VibrationSettings.java b/services/core/java/com/android/server/vibrator/VibrationSettings.java
index 18e9904..ac635a0 100644
--- a/services/core/java/com/android/server/vibrator/VibrationSettings.java
+++ b/services/core/java/com/android/server/vibrator/VibrationSettings.java
@@ -238,8 +238,6 @@
         // Listen to all settings that might affect the result of Vibrator.getVibrationIntensity.
         registerSettingsObserver(Settings.System.getUriFor(Settings.System.VIBRATE_INPUT_DEVICES));
         registerSettingsObserver(Settings.System.getUriFor(Settings.System.VIBRATE_ON));
-        registerSettingsObserver(Settings.System.getUriFor(Settings.System.VIBRATE_WHEN_RINGING));
-        registerSettingsObserver(Settings.System.getUriFor(Settings.System.APPLY_RAMPING_RINGER));
         registerSettingsObserver(Settings.System.getUriFor(
                 Settings.System.HAPTIC_FEEDBACK_ENABLED));
         registerSettingsObserver(
@@ -449,19 +447,12 @@
             mCurrentVibrationIntensities.put(USAGE_NOTIFICATION, notificationIntensity);
             mCurrentVibrationIntensities.put(USAGE_MEDIA, mediaIntensity);
             mCurrentVibrationIntensities.put(USAGE_UNKNOWN, mediaIntensity);
+            mCurrentVibrationIntensities.put(USAGE_RINGTONE, ringIntensity);
 
             // Communication request is not disabled by the notification setting.
             mCurrentVibrationIntensities.put(USAGE_COMMUNICATION_REQUEST,
                     positiveNotificationIntensity);
 
-            if (!loadBooleanSetting(Settings.System.VIBRATE_WHEN_RINGING)
-                    && !loadBooleanSetting(Settings.System.APPLY_RAMPING_RINGER)) {
-                // Make sure deprecated boolean setting still disables ringtone vibrations.
-                mCurrentVibrationIntensities.put(USAGE_RINGTONE, Vibrator.VIBRATION_INTENSITY_OFF);
-            } else {
-                mCurrentVibrationIntensities.put(USAGE_RINGTONE, ringIntensity);
-            }
-
             // This should adapt the behavior preceding the introduction of this new setting
             // key, which is to apply HAPTIC_FEEDBACK_INTENSITY, unless it's disabled.
             mCurrentVibrationIntensities.put(USAGE_HARDWARE_FEEDBACK, hardwareFeedbackIntensity);
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index c525129..dc4e117 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -6300,7 +6300,7 @@
         // starting window is drawn, the transition can start earlier. Exclude finishing and bubble
         // because it may be a trampoline.
         if (!wasTaskVisible && mStartingData != null && !finishing && !mLaunchedFromBubble
-                && !mDisplayContent.mAppTransition.isReady()
+                && mVisibleRequested && !mDisplayContent.mAppTransition.isReady()
                 && !mDisplayContent.mAppTransition.isRunning()
                 && mDisplayContent.isNextTransitionForward()) {
             // The pending transition state will be cleared after the transition is started, so
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 5969e85..5b87463 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -3860,7 +3860,8 @@
                 @AnimationType int type, @Nullable AnimationAdapter snapshotAnim);
     }
 
-    void addTrustedOverlay(SurfaceControlViewHost.SurfacePackage overlay) {
+    void addTrustedOverlay(SurfaceControlViewHost.SurfacePackage overlay,
+            @Nullable WindowState initialWindowState) {
         if (mOverlayHost == null) {
             mOverlayHost = new TrustedOverlayHost(mWmService);
         }
@@ -3876,6 +3877,20 @@
                     "Error sending initial configuration change to WindowContainer overlay");
             removeTrustedOverlay(overlay);
         }
+
+        // Emit an initial WindowState so that proper insets are available to overlay views
+        // shortly after the overlay is added.
+        if (initialWindowState != null) {
+            final InsetsState insetsState = initialWindowState.getInsetsState();
+            final Rect dispBounds = getBounds();
+            try {
+                overlay.getRemoteInterface().onInsetsChanged(insetsState, dispBounds);
+            } catch (Exception e) {
+                ProtoLog.e(WM_DEBUG_ANIM,
+                        "Error sending initial insets change to WindowContainer overlay");
+                removeTrustedOverlay(overlay);
+            }
+        }
     }
 
     void removeTrustedOverlay(SurfaceControlViewHost.SurfacePackage overlay) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 77d31df..4d262ef 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -8135,7 +8135,7 @@
                 if (task == null) {
                     throw new IllegalArgumentException("no task with taskId" + taskId);
                 }
-                task.addTrustedOverlay(overlay);
+                task.addTrustedOverlay(overlay, task.getTopVisibleAppMainWindow());
             }
         }
 
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java
index 0c28d8c..0a50e79 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java
@@ -193,7 +193,7 @@
     public void removeListener_noMoreCallbacksToListener() {
         mVibrationSettings.addListener(mListenerMock);
 
-        setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 0);
+        setUserSetting(Settings.System.RING_VIBRATION_INTENSITY, 0);
         verify(mListenerMock).onChange();
 
         mVibrationSettings.removeListener(mListenerMock);
@@ -291,8 +291,6 @@
     public void shouldIgnoreVibration_withRingerModeSilent_ignoresRingtoneAndNotification() {
         // Vibrating settings on are overruled by ringer mode.
         setUserSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED, 1);
-        setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 1);
-        setUserSetting(Settings.System.APPLY_RAMPING_RINGER, 1);
         setRingerMode(AudioManager.RINGER_MODE_SILENT);
 
         for (int usage : ALL_USAGES) {
@@ -360,44 +358,25 @@
             assertVibrationNotIgnoredForUsage(usage);
         }
     }
+
     @Test
-    public void shouldIgnoreVibration_withRingSettingsOff_disableRingtoneVibrations() {
+    public void shouldIgnoreVibration_withRingSettingsOff_allowsAllVibrations() {
+        // VIBRATE_WHEN_RINGING is deprecated and should have no effect on the ring vibration
+        // setting. The ramping ringer is also independent now, instead of a 3-state setting.
         setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 0);
         setUserSetting(Settings.System.APPLY_RAMPING_RINGER, 0);
 
         for (int usage : ALL_USAGES) {
-            if (usage == USAGE_RINGTONE) {
-                assertVibrationIgnoredForUsage(usage, Vibration.Status.IGNORED_FOR_SETTINGS);
-            } else {
-                assertVibrationNotIgnoredForUsage(usage);
-            }
+            assertVibrationNotIgnoredForUsage(usage);
             assertVibrationNotIgnoredForUsageAndFlags(usage,
                     VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF);
         }
     }
 
     @Test
-    public void shouldIgnoreVibration_withRingSettingsOn_allowsAllVibrations() {
-        setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 1);
-        setUserSetting(Settings.System.APPLY_RAMPING_RINGER, 0);
-
-        for (int usage : ALL_USAGES) {
-            assertVibrationNotIgnoredForUsage(usage);
-        }
-    }
-
-    @Test
-    public void shouldIgnoreVibration_withRampingRingerOn_allowsAllVibrations() {
-        setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 0);
-        setUserSetting(Settings.System.APPLY_RAMPING_RINGER, 1);
-
-        for (int usage : ALL_USAGES) {
-            assertVibrationNotIgnoredForUsage(usage);
-        }
-    }
-
-    @Test
     public void shouldIgnoreVibration_withHapticFeedbackDisabled_ignoresTouchVibration() {
+        // HAPTIC_FEEDBACK_ENABLED is deprecated but it was the only setting used to disable touch
+        // feedback vibrations. Continue to apply this on top of the intensity setting.
         setUserSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED, 0);
 
         for (int usage : ALL_USAGES) {
@@ -459,8 +438,6 @@
     @Test
     public void shouldIgnoreVibration_withRingSettingsOff_ignoresRingtoneVibrations() {
         // Vibrating settings on are overruled by ring intensity setting.
-        setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 1);
-        setUserSetting(Settings.System.APPLY_RAMPING_RINGER, 1);
         setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
         setUserSetting(Settings.System.RING_VIBRATION_INTENSITY, VIBRATION_INTENSITY_OFF);
 
@@ -479,7 +456,6 @@
     public void shouldIgnoreVibration_updateTriggeredAfterInternalRingerModeChanged() {
         // Vibrating settings on are overruled by ringer mode.
         setUserSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED, 1);
-        setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 1);
         setUserSetting(Settings.System.APPLY_RAMPING_RINGER, 1);
         setRingerMode(AudioManager.RINGER_MODE_NORMAL);
 
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
index 4fbf006..c735bb7 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
@@ -559,30 +559,26 @@
     }
 
     @Test
-    public void vibrate_withRingtone_usesRingtoneSettings() throws Exception {
+    public void vibrate_withRingtone_usesRingerModeSettings() throws Exception {
         mockVibrators(1);
         FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1);
         fakeVibrator.setSupportedEffects(VibrationEffect.EFFECT_CLICK,
                 VibrationEffect.EFFECT_HEAVY_CLICK, VibrationEffect.EFFECT_DOUBLE_CLICK);
 
-        setRingerMode(AudioManager.RINGER_MODE_NORMAL);
-        setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 0);
-        setUserSetting(Settings.System.APPLY_RAMPING_RINGER, 0);
+        setRingerMode(AudioManager.RINGER_MODE_SILENT);
         VibratorManagerService service = createSystemReadyService();
         vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), RINGTONE_ATTRS);
         // Wait before checking it never played.
         assertFalse(waitUntil(s -> !fakeVibrator.getAllEffectSegments().isEmpty(),
                 service, /* timeout= */ 50));
 
-        setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 0);
-        setUserSetting(Settings.System.APPLY_RAMPING_RINGER, 1);
+        setRingerMode(AudioManager.RINGER_MODE_NORMAL);
         service = createSystemReadyService();
         vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK), RINGTONE_ATTRS);
         assertTrue(waitUntil(s -> fakeVibrator.getAllEffectSegments().size() == 1,
                 service, TEST_TIMEOUT_MILLIS));
 
-        setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 1);
-        setUserSetting(Settings.System.APPLY_RAMPING_RINGER, 0);
+        setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
         service = createSystemReadyService();
         vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK), RINGTONE_ATTRS);
         assertTrue(waitUntil(s -> fakeVibrator.getAllEffectSegments().size() == 2,
@@ -1225,7 +1221,6 @@
         mockVibrators(1);
         mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL);
         setRingerMode(AudioManager.RINGER_MODE_NORMAL);
-        setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 1);
         createSystemReadyService();
 
         IBinder firstToken = mock(IBinder.class);
@@ -1296,21 +1291,17 @@
         ExternalVibration externalVibration = new ExternalVibration(UID, PACKAGE_NAME, audioAttrs,
                 mock(IExternalVibrationController.class));
 
-        setRingerMode(AudioManager.RINGER_MODE_NORMAL);
-        setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 0);
-        setUserSetting(Settings.System.APPLY_RAMPING_RINGER, 0);
+        setRingerMode(AudioManager.RINGER_MODE_SILENT);
         createSystemReadyService();
         int scale = mExternalVibratorService.onExternalVibrationStart(externalVibration);
         assertEquals(IExternalVibratorService.SCALE_MUTE, scale);
 
-        setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 0);
-        setUserSetting(Settings.System.APPLY_RAMPING_RINGER, 1);
+        setRingerMode(AudioManager.RINGER_MODE_NORMAL);
         createSystemReadyService();
         scale = mExternalVibratorService.onExternalVibrationStart(externalVibration);
         assertNotEquals(IExternalVibratorService.SCALE_MUTE, scale);
 
-        setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 1);
-        setUserSetting(Settings.System.APPLY_RAMPING_RINGER, 0);
+        setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
         createSystemReadyService();
         scale = mExternalVibratorService.onExternalVibrationStart(externalVibration);
         assertNotEquals(IExternalVibratorService.SCALE_MUTE, scale);
diff --git a/services/usb/java/com/android/server/usb/hal/port/UsbPortAidl.java b/services/usb/java/com/android/server/usb/hal/port/UsbPortAidl.java
index 600fc27..94273a3 100644
--- a/services/usb/java/com/android/server/usb/hal/port/UsbPortAidl.java
+++ b/services/usb/java/com/android/server/usb/hal/port/UsbPortAidl.java
@@ -725,5 +725,15 @@
                         e);
             }
         }
+
+        @Override
+        public String getInterfaceHash() {
+            return IUsbCallback.HASH;
+        }
+
+        @Override
+        public int getInterfaceVersion() {
+            return IUsbCallback.VERSION;
+        }
     }
 }