Merge "Add Wear settings to the SETTINGS_TO_BACKUP list."
diff --git a/Android.bp b/Android.bp
index 6892205..7db16f6 100644
--- a/Android.bp
+++ b/Android.bp
@@ -405,6 +405,7 @@
     ],
     lint: {
         extra_check_modules: ["AndroidFrameworkLintChecker"],
+        disabled_checks: ["ApiMightLeakAppVisibility"],
     },
     errorprone: {
         javacflags: [
diff --git a/apct-tests/perftests/core/src/android/view/HandwritingInitiatorPerfTest.java b/apct-tests/perftests/core/src/android/view/HandwritingInitiatorPerfTest.java
index 086e185..123b2ee 100644
--- a/apct-tests/perftests/core/src/android/view/HandwritingInitiatorPerfTest.java
+++ b/apct-tests/perftests/core/src/android/view/HandwritingInitiatorPerfTest.java
@@ -27,7 +27,6 @@
 import android.content.Context;
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.util.DisplayMetrics;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodManager;
 
@@ -64,9 +63,7 @@
         mTouchSlop = viewConfiguration.getScaledTouchSlop();
         final InputMethodManager inputMethodManager =
                 mContext.getSystemService(InputMethodManager.class);
-        final DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
-        mHandwritingInitiator = new HandwritingInitiator(viewConfiguration, inputMethodManager,
-                displayMetrics);
+        mHandwritingInitiator = new HandwritingInitiator(viewConfiguration, inputMethodManager);
     }
 
     @Test
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 8a7e598..3f6adef 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -1440,6 +1440,8 @@
 
     int fadedFramesCount = 0;
     int lastDisplayedProgress = 0;
+    int colorTransitionStart = animation.colorTransitionStart;
+    int colorTransitionEnd = animation.colorTransitionEnd;
     for (size_t i=0 ; i<pcount ; i++) {
         const Animation::Part& part(animation.parts[i]);
         const size_t fcount = part.frames.size();
@@ -1452,15 +1454,27 @@
             continue; //to next part
         }
 
-        if (animation.dynamicColoringEnabled && part.useDynamicColoring && !mDynamicColorsApplied) {
-            SLOGD("Trying to load dynamic color sysprops.");
-            initDynamicColors();
-        }
-
         // process the part not only while the count allows but also if already fading
         for (int r=0 ; !part.count || r<part.count || fadedFramesCount > 0 ; r++) {
             if (shouldStopPlayingPart(part, fadedFramesCount, lastDisplayedProgress)) break;
 
+            // It's possible that the sysprops were not loaded yet at this boot phase.
+            // If that's the case, then we should keep trying until they are available.
+            if (animation.dynamicColoringEnabled && !mDynamicColorsApplied
+                && (part.useDynamicColoring || part.postDynamicColoring)) {
+                SLOGD("Trying to load dynamic color sysprops.");
+                initDynamicColors();
+                if (mDynamicColorsApplied) {
+                    // Sysprops were loaded. Next step is to adjust the animation if we loaded
+                    // the colors after the animation should have started.
+                    const int transitionLength = colorTransitionEnd - colorTransitionStart;
+                    if (part.postDynamicColoring) {
+                        colorTransitionStart = 0;
+                        colorTransitionEnd = fmin(transitionLength, fcount - 1);
+                    }
+                }
+            }
+
             mCallbacks->playPart(i, part, r);
 
             glClearColor(
@@ -1490,9 +1504,8 @@
                 // - 1 for parts that come after.
                 float colorProgress = part.useDynamicColoring
                     ? fmin(fmax(
-                        ((float)j - animation.colorTransitionStart) /
-                            fmax(animation.colorTransitionEnd -
-                                animation.colorTransitionStart, 1.0f), 0.0f), 1.0f)
+                        ((float)j - colorTransitionStart) /
+                            fmax(colorTransitionEnd - colorTransitionStart, 1.0f), 0.0f), 1.0f)
                     : (part.postDynamicColoring ? 1 : 0);
 
                 processDisplayEvents();
diff --git a/core/api/current.txt b/core/api/current.txt
index 0c25397..b5b7146 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -786,6 +786,10 @@
     field public static final int hand_secondTintMode = 16844349; // 0x101063d
     field public static final int handle = 16843354; // 0x101025a
     field public static final int handleProfiling = 16842786; // 0x1010022
+    field public static final int handwritingBoundsOffsetBottom;
+    field public static final int handwritingBoundsOffsetLeft;
+    field public static final int handwritingBoundsOffsetRight;
+    field public static final int handwritingBoundsOffsetTop;
     field public static final int hapticFeedbackEnabled = 16843358; // 0x101025e
     field public static final int hardwareAccelerated = 16843475; // 0x10102d3
     field public static final int hasCode = 16842764; // 0x101000c
@@ -10882,7 +10886,7 @@
   }
 
   public static interface SharedPreferences.OnSharedPreferenceChangeListener {
-    method public void onSharedPreferenceChanged(android.content.SharedPreferences, String);
+    method public void onSharedPreferenceChanged(android.content.SharedPreferences, @Nullable String);
   }
 
   public class SyncAdapterType implements android.os.Parcelable {
@@ -49714,6 +49718,10 @@
     method public boolean getGlobalVisibleRect(android.graphics.Rect, android.graphics.Point);
     method public final boolean getGlobalVisibleRect(android.graphics.Rect);
     method public android.os.Handler getHandler();
+    method public float getHandwritingBoundsOffsetBottom();
+    method public float getHandwritingBoundsOffsetLeft();
+    method public float getHandwritingBoundsOffsetRight();
+    method public float getHandwritingBoundsOffsetTop();
     method public final boolean getHasOverlappingRendering();
     method public final int getHeight();
     method public void getHitRect(android.graphics.Rect);
@@ -50077,6 +50085,7 @@
     method public void setForegroundTintBlendMode(@Nullable android.graphics.BlendMode);
     method public void setForegroundTintList(@Nullable android.content.res.ColorStateList);
     method public void setForegroundTintMode(@Nullable android.graphics.PorterDuff.Mode);
+    method public void setHandwritingBoundsOffsets(float, float, float, float);
     method public void setHapticFeedbackEnabled(boolean);
     method public void setHasTransientState(boolean);
     method public void setHorizontalFadingEdgeEnabled(boolean);
diff --git a/core/api/module-lib-lint-baseline.txt b/core/api/module-lib-lint-baseline.txt
index 0c1ebb3..27436ce 100644
--- a/core/api/module-lib-lint-baseline.txt
+++ b/core/api/module-lib-lint-baseline.txt
@@ -1,4 +1,6 @@
 // Baseline format: 1.0
+SamShouldBeLast: android.app.Activity#convertToTranslucent(android.app.Activity.TranslucentConversionListener, android.app.ActivityOptions):
+    SAM-compatible parameters (such as parameter 1, "callback", in android.app.Activity.convertToTranslucent) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.app.ActivityManager#addOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener, int):
     SAM-compatible parameters (such as parameter 1, "listener", in android.app.ActivityManager.addOnUidImportanceListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.app.PendingIntent#send(android.content.Context, int, android.content.Intent, android.app.PendingIntent.OnFinished, android.os.Handler):
@@ -9,6 +11,24 @@
     SAM-compatible parameters (such as parameter 4, "onFinished", in android.app.PendingIntent.send) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.app.PendingIntent#send(int, android.app.PendingIntent.OnFinished, android.os.Handler):
     SAM-compatible parameters (such as parameter 2, "onFinished", in android.app.PendingIntent.send) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+SamShouldBeLast: android.content.pm.ApplicationInfo#dump(android.util.Printer, String):
+    SAM-compatible parameters (such as parameter 1, "pw", in android.content.pm.ApplicationInfo.dump) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+SamShouldBeLast: android.content.pm.PackageItemInfo#dumpBack(android.util.Printer, String):
+    SAM-compatible parameters (such as parameter 1, "pw", in android.content.pm.PackageItemInfo.dumpBack) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+SamShouldBeLast: android.content.pm.PackageItemInfo#dumpFront(android.util.Printer, String):
+    SAM-compatible parameters (such as parameter 1, "pw", in android.content.pm.PackageItemInfo.dumpFront) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+SamShouldBeLast: android.location.LocationManager#addNmeaListener(android.location.OnNmeaMessageListener, android.os.Handler):
+    SAM-compatible parameters (such as parameter 1, "listener", in android.location.LocationManager.addNmeaListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(String, long, float, android.location.LocationListener, android.os.Looper):
+    SAM-compatible parameters (such as parameter 4, "listener", in android.location.LocationManager.requestLocationUpdates) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(android.location.LocationRequest, android.location.LocationListener, android.os.Looper):
+    SAM-compatible parameters (such as parameter 2, "listener", in android.location.LocationManager.requestLocationUpdates) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(long, float, android.location.Criteria, android.location.LocationListener, android.os.Looper):
+    SAM-compatible parameters (such as parameter 4, "listener", in android.location.LocationManager.requestLocationUpdates) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+SamShouldBeLast: android.location.LocationManager#requestSingleUpdate(String, android.location.LocationListener, android.os.Looper):
+    SAM-compatible parameters (such as parameter 2, "listener", in android.location.LocationManager.requestSingleUpdate) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+SamShouldBeLast: android.location.LocationManager#requestSingleUpdate(android.location.Criteria, android.location.LocationListener, android.os.Looper):
+    SAM-compatible parameters (such as parameter 2, "listener", in android.location.LocationManager.requestSingleUpdate) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.AudioManager#abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes):
     SAM-compatible parameters (such as parameter 1, "l", in android.media.AudioManager.abandonAudioFocus) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.AudioManager#requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes, int, int):
diff --git a/core/api/system-lint-baseline.txt b/core/api/system-lint-baseline.txt
index db375d4..025e862 100644
--- a/core/api/system-lint-baseline.txt
+++ b/core/api/system-lint-baseline.txt
@@ -1,36 +1,20 @@
 // Baseline format: 1.0
 ArrayReturn: android.view.contentcapture.ViewNode#getAutofillOptions():
-
-ExecutorRegistration: android.media.MediaPlayer#setOnRtpRxNoticeListener(android.content.Context, android.media.MediaPlayer.OnRtpRxNoticeListener, android.os.Handler):
-    Registration methods should have overload that accepts delivery Executor: `setOnRtpRxNoticeListener`
+    Method should return Collection<CharSequence> (or subclass) instead of raw array; was `java.lang.CharSequence[]`
 
 
 GenericException: android.app.prediction.AppPredictor#finalize():
-    
+    Methods must not throw generic exceptions (`java.lang.Throwable`)
 GenericException: android.hardware.location.ContextHubClient#finalize():
-    
+    Methods must not throw generic exceptions (`java.lang.Throwable`)
 GenericException: android.service.autofill.augmented.FillWindow#finalize():
-    
-
-
-IntentBuilderName: android.app.search.SearchAction#getIntent():
-    
-IntentBuilderName: android.app.smartspace.SmartspaceAction#getIntent():
-    Methods creating an Intent should be named `create<Foo>Intent()`, was `getIntent`
+    Methods must not throw generic exceptions (`java.lang.Throwable`)
 
 
 KotlinKeyword: android.app.Notification#when:
-    
+    Avoid field names that are Kotlin hard keywords ("when"); see https://android.github.io/kotlin-guides/interop.html#no-hard-keywords
 
 
-MissingGetterMatchingBuilder: android.os.NewUserRequest.Builder#setAdmin():
-    android.os.NewUserRequest does not declare a `getAdmin()` method matching method android.os.NewUserRequest.Builder.setAdmin()
-MissingGetterMatchingBuilder: android.os.NewUserRequest.Builder#setEphemeral():
-    android.os.NewUserRequest does not declare a `getEphemeral()` method matching method android.os.NewUserRequest.Builder.setEphemeral()
-MissingGetterMatchingBuilder: android.security.keystore.KeyGenParameterSpec.Builder#setUid(int):
-    android.security.keystore.KeyGenParameterSpec does not declare a `getUid()` method matching method android.security.keystore.KeyGenParameterSpec.Builder.setUid(int)
-MissingGetterMatchingBuilder: android.service.autofill.Dataset.Builder#setFieldInlinePresentation(android.view.autofill.AutofillId, android.view.autofill.AutofillValue, java.util.regex.Pattern, android.service.autofill.InlinePresentation):
-    android.service.autofill.Dataset does not declare a `getFieldInlinePresentation()` method matching method android.service.autofill.Dataset.Builder.setFieldInlinePresentation(android.view.autofill.AutofillId,android.view.autofill.AutofillValue,java.util.regex.Pattern,android.service.autofill.InlinePresentation)
 MissingGetterMatchingBuilder: android.telecom.CallScreeningService.CallResponse.Builder#setShouldScreenCallViaAudioProcessing(boolean):
     android.telecom.CallScreeningService.CallResponse does not declare a `shouldScreenCallViaAudioProcessing()` method matching method android.telecom.CallScreeningService.CallResponse.Builder.setShouldScreenCallViaAudioProcessing(boolean)
 MissingGetterMatchingBuilder: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String):
@@ -38,166 +22,135 @@
 
 
 MissingNullability: android.media.soundtrigger.SoundTriggerDetectionService#onUnbind(android.content.Intent) parameter #0:
-    
+    Missing nullability on parameter `intent` in method `onUnbind`
 MissingNullability: android.media.tv.TvRecordingClient.RecordingCallback#onEvent(String, String, android.os.Bundle) parameter #0:
-    
+    Missing nullability on parameter `inputId` in method `onEvent`
 MissingNullability: android.media.tv.TvRecordingClient.RecordingCallback#onEvent(String, String, android.os.Bundle) parameter #1:
-    
+    Missing nullability on parameter `eventType` in method `onEvent`
 MissingNullability: android.media.tv.TvRecordingClient.RecordingCallback#onEvent(String, String, android.os.Bundle) parameter #2:
-    
+    Missing nullability on parameter `eventArgs` in method `onEvent`
 MissingNullability: android.printservice.recommendation.RecommendationService#attachBaseContext(android.content.Context) parameter #0:
-    
+    Missing nullability on parameter `base` in method `attachBaseContext`
 MissingNullability: android.provider.ContactsContract.MetadataSync#CONTENT_URI:
-    
+    Missing nullability on field `CONTENT_URI` in class `class android.provider.ContactsContract.MetadataSync`
 MissingNullability: android.provider.ContactsContract.MetadataSync#METADATA_AUTHORITY_URI:
-    
+    Missing nullability on field `METADATA_AUTHORITY_URI` in class `class android.provider.ContactsContract.MetadataSync`
 MissingNullability: android.provider.ContactsContract.MetadataSyncState#CONTENT_URI:
-    
+    Missing nullability on field `CONTENT_URI` in class `class android.provider.ContactsContract.MetadataSyncState`
 MissingNullability: android.provider.SearchIndexablesProvider#attachInfo(android.content.Context, android.content.pm.ProviderInfo) parameter #0:
-    
+    Missing nullability on parameter `context` in method `attachInfo`
 MissingNullability: android.provider.SearchIndexablesProvider#attachInfo(android.content.Context, android.content.pm.ProviderInfo) parameter #1:
-    
+    Missing nullability on parameter `info` in method `attachInfo`
 MissingNullability: android.service.autofill.augmented.AugmentedAutofillService#onUnbind(android.content.Intent) parameter #0:
-    
+    Missing nullability on parameter `intent` in method `onUnbind`
 MissingNullability: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0:
-    
+    Missing nullability on parameter `fd` in method `dump`
 MissingNullability: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #1:
-    
+    Missing nullability on parameter `pw` in method `dump`
 MissingNullability: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #2:
-    
+    Missing nullability on parameter `args` in method `dump`
 MissingNullability: android.service.notification.NotificationAssistantService#attachBaseContext(android.content.Context) parameter #0:
-    
+    Missing nullability on parameter `base` in method `attachBaseContext`
 MissingNullability: android.telephony.NetworkService#onUnbind(android.content.Intent) parameter #0:
-    
-MissingNullability: android.telephony.SubscriptionPlan.Builder#createRecurringDaily(java.time.ZonedDateTime) parameter #0:
-    
-MissingNullability: android.telephony.SubscriptionPlan.Builder#createRecurringMonthly(java.time.ZonedDateTime) parameter #0:
-    
-MissingNullability: android.telephony.SubscriptionPlan.Builder#createRecurringWeekly(java.time.ZonedDateTime) parameter #0:
-    
+    Missing nullability on parameter `intent` in method `onUnbind`
 MissingNullability: android.telephony.data.DataService#onUnbind(android.content.Intent) parameter #0:
-    
+    Missing nullability on parameter `intent` in method `onUnbind`
 MissingNullability: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String):
-    
+    Missing nullability on method `setServiceId` return
 MissingNullability: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String) parameter #0:
-    
-
-
-NoSettingsProvider: android.provider.Settings.Secure#FAST_PAIR_SCAN_ENABLED:
-    New setting keys are not allowed (Field: FAST_PAIR_SCAN_ENABLED); use getters/setters in relevant manager class
-
-
-OnNameExpected: android.service.smartspace.SmartspaceService#notifySmartspaceEvent(android.app.smartspace.SmartspaceSessionId, android.app.smartspace.SmartspaceTargetEvent):
-    Methods implemented by developers should follow the on<Something> style, was `notifySmartspaceEvent`
+    Missing nullability on parameter `serviceId` in method `setServiceId`
 
 
 ProtectedMember: android.printservice.recommendation.RecommendationService#attachBaseContext(android.content.Context):
-    
+    Protected methods not allowed; must be public: method android.printservice.recommendation.RecommendationService.attachBaseContext(android.content.Context)}
 ProtectedMember: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]):
-    
+    Protected methods not allowed; must be public: method android.service.contentcapture.ContentCaptureService.dump(java.io.FileDescriptor,java.io.PrintWriter,String[])}
 ProtectedMember: android.service.notification.NotificationAssistantService#attachBaseContext(android.content.Context):
-    
-
+    Protected methods not allowed; must be public: method android.service.notification.NotificationAssistantService.attachBaseContext(android.content.Context)}
 
 
 SamShouldBeLast: android.accounts.AccountManager#addAccount(String, String, String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 6, "callback", in android.accounts.AccountManager.addAccount) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean):
-    
+    SAM-compatible parameters (such as parameter 1, "listener", in android.accounts.AccountManager.addOnAccountsUpdatedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean, String[]):
-    
+    SAM-compatible parameters (such as parameter 1, "listener", in android.accounts.AccountManager.addOnAccountsUpdatedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#confirmCredentials(android.accounts.Account, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 4, "callback", in android.accounts.AccountManager.confirmCredentials) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#editProperties(String, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 3, "callback", in android.accounts.AccountManager.editProperties) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#finishSession(android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 3, "callback", in android.accounts.AccountManager.finishSession) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#getAccountsByTypeAndFeatures(String, String[], android.accounts.AccountManagerCallback<android.accounts.Account[]>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 3, "callback", in android.accounts.AccountManager.getAccountsByTypeAndFeatures) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#getAuthToken(android.accounts.Account, String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 5, "callback", in android.accounts.AccountManager.getAuthToken) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#getAuthToken(android.accounts.Account, String, android.os.Bundle, boolean, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 5, "callback", in android.accounts.AccountManager.getAuthToken) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#getAuthToken(android.accounts.Account, String, boolean, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 4, "callback", in android.accounts.AccountManager.getAuthToken) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#getAuthTokenByFeatures(String, String, String[], android.app.Activity, android.os.Bundle, android.os.Bundle, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 7, "callback", in android.accounts.AccountManager.getAuthTokenByFeatures) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#hasFeatures(android.accounts.Account, String[], android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 3, "callback", in android.accounts.AccountManager.hasFeatures) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#isCredentialsUpdateSuggested(android.accounts.Account, String, android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 3, "callback", in android.accounts.AccountManager.isCredentialsUpdateSuggested) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#removeAccount(android.accounts.Account, android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 2, "callback", in android.accounts.AccountManager.removeAccount) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#removeAccount(android.accounts.Account, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 3, "callback", in android.accounts.AccountManager.removeAccount) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#renameAccount(android.accounts.Account, String, android.accounts.AccountManagerCallback<android.accounts.Account>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 3, "callback", in android.accounts.AccountManager.renameAccount) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#startAddAccountSession(String, String, String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 6, "callback", in android.accounts.AccountManager.startAddAccountSession) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#startUpdateCredentialsSession(android.accounts.Account, String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 5, "callback", in android.accounts.AccountManager.startUpdateCredentialsSession) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#updateCredentials(android.accounts.Account, String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 5, "callback", in android.accounts.AccountManager.updateCredentials) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.app.AlarmManager#set(int, long, String, android.app.AlarmManager.OnAlarmListener, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 4, "listener", in android.app.AlarmManager.set) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.app.AlarmManager#setExact(int, long, String, android.app.AlarmManager.OnAlarmListener, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 4, "listener", in android.app.AlarmManager.setExact) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.app.AlarmManager#setWindow(int, long, long, String, android.app.AlarmManager.OnAlarmListener, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 5, "listener", in android.app.AlarmManager.setWindow) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.app.WallpaperInfo#dump(android.util.Printer, String):
-    
+    SAM-compatible parameters (such as parameter 1, "pw", in android.app.WallpaperInfo.dump) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.app.WallpaperManager#addOnColorsChangedListener(android.app.WallpaperManager.OnColorsChangedListener, android.os.Handler):
-    
-SamShouldBeLast: android.app.admin.DevicePolicyManager#installSystemUpdate(android.content.ComponentName, android.net.Uri, java.util.concurrent.Executor, android.app.admin.DevicePolicyManager.InstallSystemUpdateCallback):
-    
+    SAM-compatible parameters (such as parameter 1, "listener", in android.app.WallpaperManager.addOnColorsChangedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.content.IntentFilter#dump(android.util.Printer, String):
-    
+    SAM-compatible parameters (such as parameter 1, "du", in android.content.IntentFilter.dump) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.content.pm.ApplicationInfo#dump(android.util.Printer, String):
-    
+    SAM-compatible parameters (such as parameter 1, "pw", in android.content.pm.ApplicationInfo.dump) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.content.pm.PackageItemInfo#dumpBack(android.util.Printer, String):
-    
+    SAM-compatible parameters (such as parameter 1, "pw", in android.content.pm.PackageItemInfo.dumpBack) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.content.pm.PackageItemInfo#dumpFront(android.util.Printer, String):
-    
+    SAM-compatible parameters (such as parameter 1, "pw", in android.content.pm.PackageItemInfo.dumpFront) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.content.pm.ResolveInfo#dump(android.util.Printer, String):
-    
+    SAM-compatible parameters (such as parameter 1, "pw", in android.content.pm.ResolveInfo.dump) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.location.Location#dump(android.util.Printer, String):
-    
+    SAM-compatible parameters (such as parameter 1, "pw", in android.location.Location.dump) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.location.LocationManager#addNmeaListener(android.location.OnNmeaMessageListener, android.os.Handler):
-    
-SamShouldBeLast: android.location.LocationManager#registerGnssMeasurementsCallback(java.util.concurrent.Executor, android.location.GnssMeasurementsEvent.Callback):
-    
-SamShouldBeLast: android.location.LocationManager#registerGnssNavigationMessageCallback(java.util.concurrent.Executor, android.location.GnssNavigationMessage.Callback):
-    
-SamShouldBeLast: android.location.LocationManager#registerGnssStatusCallback(java.util.concurrent.Executor, android.location.GnssStatus.Callback):
-    
+    SAM-compatible parameters (such as parameter 1, "listener", in android.location.LocationManager.addNmeaListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(String, long, float, android.location.LocationListener, android.os.Looper):
-    
-SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(String, long, float, java.util.concurrent.Executor, android.location.LocationListener):
-    
-SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(android.location.LocationRequest, java.util.concurrent.Executor, android.location.LocationListener):
-    
+    SAM-compatible parameters (such as parameter 4, "listener", in android.location.LocationManager.requestLocationUpdates) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(long, float, android.location.Criteria, android.location.LocationListener, android.os.Looper):
-    
-SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(long, float, android.location.Criteria, java.util.concurrent.Executor, android.location.LocationListener):
-    
+    SAM-compatible parameters (such as parameter 4, "listener", in android.location.LocationManager.requestLocationUpdates) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.location.LocationManager#requestSingleUpdate(String, android.location.LocationListener, android.os.Looper):
-    
+    SAM-compatible parameters (such as parameter 2, "listener", in android.location.LocationManager.requestSingleUpdate) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.location.LocationManager#requestSingleUpdate(android.location.Criteria, android.location.LocationListener, android.os.Looper):
-    
+    SAM-compatible parameters (such as parameter 2, "listener", in android.location.LocationManager.requestSingleUpdate) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.AudioFocusRequest.Builder#setOnAudioFocusChangeListener(android.media.AudioManager.OnAudioFocusChangeListener, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 1, "listener", in android.media.AudioFocusRequest.Builder.setOnAudioFocusChangeListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.AudioManager#requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, int, int):
-    
+    SAM-compatible parameters (such as parameter 1, "l", in android.media.AudioManager.requestAudioFocus) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.AudioRecord#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler):
-    
-SamShouldBeLast: android.media.AudioRecord#registerAudioRecordingCallback(java.util.concurrent.Executor, android.media.AudioManager.AudioRecordingCallback):
-    
-SamShouldBeLast: android.media.AudioRecordingMonitor#registerAudioRecordingCallback(java.util.concurrent.Executor, android.media.AudioManager.AudioRecordingCallback):
-    
+    SAM-compatible parameters (such as parameter 1, "listener", in android.media.AudioRecord.addOnRoutingChangedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.AudioRouting#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 1, "listener", in android.media.AudioRouting.addOnRoutingChangedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.AudioTrack#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 1, "listener", in android.media.AudioTrack.addOnRoutingChangedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+SamShouldBeLast: android.media.MediaCodec#setOnFrameRenderedListener(android.media.MediaCodec.OnFrameRenderedListener, android.os.Handler):
+    SAM-compatible parameters (such as parameter 1, "listener", in android.media.MediaCodec.setOnFrameRenderedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.MediaPlayer#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler):
     SAM-compatible parameters (such as parameter 1, "listener", in android.media.MediaPlayer.addOnRoutingChangedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.MediaPlayer#setOnDrmInfoListener(android.media.MediaPlayer.OnDrmInfoListener, android.os.Handler):
@@ -206,82 +159,65 @@
     SAM-compatible parameters (such as parameter 1, "listener", in android.media.MediaPlayer.setOnDrmPreparedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.MediaPlayer#setOnMediaTimeDiscontinuityListener(android.media.MediaPlayer.OnMediaTimeDiscontinuityListener, android.os.Handler):
     SAM-compatible parameters (such as parameter 1, "listener", in android.media.MediaPlayer.setOnMediaTimeDiscontinuityListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
-SamShouldBeLast: android.media.MediaPlayer#setOnRtpRxNoticeListener(android.content.Context, android.media.MediaPlayer.OnRtpRxNoticeListener, android.os.Handler):
-    SAM-compatible parameters (such as parameter 2, "listener", in android.media.MediaPlayer.setOnRtpRxNoticeListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.MediaPlayer#setOnSubtitleDataListener(android.media.MediaPlayer.OnSubtitleDataListener, android.os.Handler):
     SAM-compatible parameters (such as parameter 1, "listener", in android.media.MediaPlayer.setOnSubtitleDataListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.MediaRecorder#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler):
-    
-SamShouldBeLast: android.media.MediaRecorder#registerAudioRecordingCallback(java.util.concurrent.Executor, android.media.AudioManager.AudioRecordingCallback):
-    
+    SAM-compatible parameters (such as parameter 1, "listener", in android.media.MediaRecorder.addOnRoutingChangedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.session.MediaSessionManager#addOnActiveSessionsChangedListener(android.media.session.MediaSessionManager.OnActiveSessionsChangedListener, android.content.ComponentName):
-    
+    SAM-compatible parameters (such as parameter 1, "sessionListener", in android.media.session.MediaSessionManager.addOnActiveSessionsChangedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.session.MediaSessionManager#addOnActiveSessionsChangedListener(android.media.session.MediaSessionManager.OnActiveSessionsChangedListener, android.content.ComponentName, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 1, "sessionListener", in android.media.session.MediaSessionManager.addOnActiveSessionsChangedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.session.MediaSessionManager#addOnSession2TokensChangedListener(android.media.session.MediaSessionManager.OnSession2TokensChangedListener, android.os.Handler):
-    
-SamShouldBeLast: android.media.session.MediaSessionManager#registerCallback(java.util.concurrent.Executor, android.media.session.MediaSessionManager.Callback):
-    
+    SAM-compatible parameters (such as parameter 1, "listener", in android.media.session.MediaSessionManager.addOnSession2TokensChangedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.nfc.NfcAdapter#enableReaderMode(android.app.Activity, android.nfc.NfcAdapter.ReaderCallback, int, android.os.Bundle):
-    
+    SAM-compatible parameters (such as parameter 2, "callback", in android.nfc.NfcAdapter.enableReaderMode) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.nfc.NfcAdapter#ignore(android.nfc.Tag, int, android.nfc.NfcAdapter.OnTagRemovedListener, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 3, "tagRemovedListener", in android.nfc.NfcAdapter.ignore) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.nfc.NfcAdapter#setBeamPushUrisCallback(android.nfc.NfcAdapter.CreateBeamUrisCallback, android.app.Activity):
-    
+    SAM-compatible parameters (such as parameter 1, "callback", in android.nfc.NfcAdapter.setBeamPushUrisCallback) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.nfc.NfcAdapter#setNdefPushMessageCallback(android.nfc.NfcAdapter.CreateNdefMessageCallback, android.app.Activity, android.app.Activity...):
-    
+    SAM-compatible parameters (such as parameter 1, "callback", in android.nfc.NfcAdapter.setNdefPushMessageCallback) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.nfc.NfcAdapter#setOnNdefPushCompleteCallback(android.nfc.NfcAdapter.OnNdefPushCompleteCallback, android.app.Activity, android.app.Activity...):
-    
+    SAM-compatible parameters (such as parameter 1, "callback", in android.nfc.NfcAdapter.setOnNdefPushCompleteCallback) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.os.Binder#attachInterface(android.os.IInterface, String):
-    
+    SAM-compatible parameters (such as parameter 1, "owner", in android.os.Binder.attachInterface) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.os.Binder#linkToDeath(android.os.IBinder.DeathRecipient, int):
-    
+    SAM-compatible parameters (such as parameter 1, "recipient", in android.os.Binder.linkToDeath) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.os.Binder#unlinkToDeath(android.os.IBinder.DeathRecipient, int):
-    
+    SAM-compatible parameters (such as parameter 1, "recipient", in android.os.Binder.unlinkToDeath) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.os.Handler#dump(android.util.Printer, String):
-    
+    SAM-compatible parameters (such as parameter 1, "pw", in android.os.Handler.dump) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.os.Handler#postAtTime(Runnable, Object, long):
-    
+    SAM-compatible parameters (such as parameter 1, "r", in android.os.Handler.postAtTime) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.os.Handler#postAtTime(Runnable, long):
-    
+    SAM-compatible parameters (such as parameter 1, "r", in android.os.Handler.postAtTime) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.os.Handler#postDelayed(Runnable, Object, long):
-    
+    SAM-compatible parameters (such as parameter 1, "r", in android.os.Handler.postDelayed) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.os.Handler#postDelayed(Runnable, long):
-    
+    SAM-compatible parameters (such as parameter 1, "r", in android.os.Handler.postDelayed) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.os.Handler#removeCallbacks(Runnable, Object):
-    
+    SAM-compatible parameters (such as parameter 1, "r", in android.os.Handler.removeCallbacks) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.os.IBinder#linkToDeath(android.os.IBinder.DeathRecipient, int):
-    
+    SAM-compatible parameters (such as parameter 1, "recipient", in android.os.IBinder.linkToDeath) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.os.IBinder#unlinkToDeath(android.os.IBinder.DeathRecipient, int):
-    
+    SAM-compatible parameters (such as parameter 1, "recipient", in android.os.IBinder.unlinkToDeath) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.os.RecoverySystem#verifyPackage(java.io.File, android.os.RecoverySystem.ProgressListener, java.io.File):
-    
+    SAM-compatible parameters (such as parameter 2, "listener", in android.os.RecoverySystem.verifyPackage) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.security.KeyChain#choosePrivateKeyAlias(android.app.Activity, android.security.KeyChainAliasCallback, String[], java.security.Principal[], String, int, String):
     SAM-compatible parameters (such as parameter 2, "response", in android.security.KeyChain.choosePrivateKeyAlias) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.security.KeyChain#choosePrivateKeyAlias(android.app.Activity, android.security.KeyChainAliasCallback, String[], java.security.Principal[], android.net.Uri, String):
     SAM-compatible parameters (such as parameter 2, "response", in android.security.KeyChain.choosePrivateKeyAlias) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.view.View#postDelayed(Runnable, long):
-    
+    SAM-compatible parameters (such as parameter 1, "action", in android.view.View.postDelayed) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.view.View#postOnAnimationDelayed(Runnable, long):
-    
+    SAM-compatible parameters (such as parameter 1, "action", in android.view.View.postOnAnimationDelayed) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.view.View#scheduleDrawable(android.graphics.drawable.Drawable, Runnable, long):
-    
+    SAM-compatible parameters (such as parameter 2, "what", in android.view.View.scheduleDrawable) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.view.Window#addOnFrameMetricsAvailableListener(android.view.Window.OnFrameMetricsAvailableListener, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 1, "listener", in android.view.Window.addOnFrameMetricsAvailableListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.view.accessibility.AccessibilityManager#addAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 1, "listener", in android.view.accessibility.AccessibilityManager.addAccessibilityStateChangeListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.view.accessibility.AccessibilityManager#addTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 1, "listener", in android.view.accessibility.AccessibilityManager.addTouchExplorationStateChangeListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.webkit.WebChromeClient#onShowFileChooser(android.webkit.WebView, android.webkit.ValueCallback<android.net.Uri[]>, android.webkit.WebChromeClient.FileChooserParams):
-    
-
-
-ServiceName: android.content.Context#CLOUDSEARCH_SERVICE:
-
-
-UserHandleName: android.app.search.SearchAction.Builder#setUserHandle(android.os.UserHandle):
-    Method taking UserHandle should be named `doFooAsUser` or `queryFooForUser`, was `setUserHandle`
-UserHandleName: android.app.search.SearchTarget.Builder#setUserHandle(android.os.UserHandle):
-    
-UserHandleName: android.app.smartspace.SmartspaceAction.Builder#setUserHandle(android.os.UserHandle):
-    Method taking UserHandle should be named `doFooAsUser` or `queryFooForUser`, was `setUserHandle`
+    SAM-compatible parameters (such as parameter 2, "filePathCallback", in android.webkit.WebChromeClient.onShowFileChooser) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 0cc98218..7bf51d1 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -464,6 +464,7 @@
     method @NonNull public android.graphics.Rect getMaxBounds();
     method public int getRotation();
     method public int getWindowingMode();
+    method public static boolean isFloating(int);
     method public void setActivityType(int);
     method public void setAppBounds(android.graphics.Rect);
     method public void setBounds(android.graphics.Rect);
@@ -1251,12 +1252,10 @@
 
   public final class InputManager {
     method public void addUniqueIdAssociation(@NonNull String, @NonNull String);
-    method public int getBlockUntrustedTouchesMode(@NonNull android.content.Context);
     method @Nullable public String getCurrentKeyboardLayoutForInputDevice(@NonNull android.hardware.input.InputDeviceIdentifier);
     method @NonNull public java.util.List<java.lang.String> getKeyboardLayoutDescriptorsForInputDevice(@NonNull android.view.InputDevice);
     method @RequiresPermission(android.Manifest.permission.SET_KEYBOARD_LAYOUT) public void removeKeyboardLayoutForInputDevice(@NonNull android.hardware.input.InputDeviceIdentifier, @NonNull String);
     method public void removeUniqueIdAssociation(@NonNull String);
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setBlockUntrustedTouchesMode(@NonNull android.content.Context, int);
     method @RequiresPermission(android.Manifest.permission.SET_KEYBOARD_LAYOUT) public void setCurrentKeyboardLayoutForInputDevice(@NonNull android.hardware.input.InputDeviceIdentifier, @NonNull String);
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setMaximumObscuringOpacityForTouch(@FloatRange(from=0, to=1) float);
     field public static final long BLOCK_UNTRUSTED_TOUCHES = 158002302L; // 0x96aec7eL
diff --git a/core/api/test-lint-baseline.txt b/core/api/test-lint-baseline.txt
index 01604e6..0a906be 100644
--- a/core/api/test-lint-baseline.txt
+++ b/core/api/test-lint-baseline.txt
@@ -1,920 +1,270 @@
 // Baseline format: 1.0
 AcronymName: android.app.NotificationChannel#isImportanceLockedByOEM():
-    
+    Acronyms should not be capitalized in method names: was `isImportanceLockedByOEM`, should this be `isImportanceLockedByOem`?
 AcronymName: android.app.NotificationChannel#setImportanceLockedByOEM(boolean):
-    
+    Acronyms should not be capitalized in method names: was `setImportanceLockedByOEM`, should this be `setImportanceLockedByOem`?
 
 
-ActionValue: android.location.Location#EXTRA_NO_GPS_LOCATION:
-    
-ActionValue: android.net.TetheringManager#ACTION_TETHER_STATE_CHANGED:
-    
-ActionValue: android.net.TetheringManager#EXTRA_ACTIVE_TETHER:
-    
-ActionValue: android.net.TetheringManager#EXTRA_AVAILABLE_TETHER:
-    
-ActionValue: android.net.TetheringManager#EXTRA_ERRORED_TETHER:
-    
-ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_ADDITIONAL_CALL_INFO:
-    
-ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_CALL_RAT_TYPE:
-    
-ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_CHILD_NUMBER:
-    
-ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_CNA:
-    
-ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_CNAP:
-    
-ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_CODEC:
-    
-ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_DIALSTRING:
-    
-ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_DISPLAY_TEXT:
-    
-ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_EMERGENCY_CALL:
-    
-ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_IS_CALL_PULL:
-    
-ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_OI:
-    
-ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_OIR:
-    
-ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_REMOTE_URI:
-    
-ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_USSD:
-    
-ActionValue: android.telephony.ims.ImsReasonInfo#EXTRA_MSG_SERVICE_NOT_AUTHORIZED:
-    
-ActionValue: android.telephony.mbms.vendor.VendorUtils#ACTION_CLEANUP:
-    
-ActionValue: android.telephony.mbms.vendor.VendorUtils#ACTION_DOWNLOAD_RESULT_INTERNAL:
-    
-ActionValue: android.telephony.mbms.vendor.VendorUtils#ACTION_FILE_DESCRIPTOR_REQUEST:
-    
-ActionValue: android.telephony.mbms.vendor.VendorUtils#EXTRA_FD_COUNT:
-    
-ActionValue: android.telephony.mbms.vendor.VendorUtils#EXTRA_FINAL_URI:
-    
-ActionValue: android.telephony.mbms.vendor.VendorUtils#EXTRA_FREE_URI_LIST:
-    
-ActionValue: android.telephony.mbms.vendor.VendorUtils#EXTRA_PAUSED_LIST:
-    
-ActionValue: android.telephony.mbms.vendor.VendorUtils#EXTRA_PAUSED_URI_LIST:
-    
-ActionValue: android.telephony.mbms.vendor.VendorUtils#EXTRA_SERVICE_ID:
-    
-ActionValue: android.telephony.mbms.vendor.VendorUtils#EXTRA_TEMP_FILES_IN_USE:
-    
-ActionValue: android.telephony.mbms.vendor.VendorUtils#EXTRA_TEMP_FILE_ROOT:
-    
-ActionValue: android.telephony.mbms.vendor.VendorUtils#EXTRA_TEMP_LIST:
-    
-
-
-AllUpper: android.media.audiopolicy.AudioProductStrategy#sDefaultAttributes:
-    Constant field names must be named with only upper case characters: `android.media.audiopolicy.AudioProductStrategy#sDefaultAttributes`, should be `S_DEFAULT_ATTRIBUTES`?
-
-
-ArrayReturn: android.app.UiAutomation#executeShellCommandRw(String):
-    
-ArrayReturn: android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel#KeyphraseSoundModel(java.util.UUID, java.util.UUID, byte[], android.hardware.soundtrigger.SoundTrigger.Keyphrase[]) parameter #3:
-    
-ArrayReturn: android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel#KeyphraseSoundModel(java.util.UUID, java.util.UUID, byte[], android.hardware.soundtrigger.SoundTrigger.Keyphrase[], int) parameter #3:
-    
-ArrayReturn: android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel#getKeyphrases():
-    
-ArrayReturn: android.location.GnssMeasurementsEvent#GnssMeasurementsEvent(android.location.GnssClock, android.location.GnssMeasurement[]) parameter #1:
-    
 ArrayReturn: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String, int, boolean, int, android.media.audiofx.AudioEffect.Descriptor[], android.media.audiofx.AudioEffect.Descriptor[]) parameter #10:
-    
+    Method parameter should be Collection<Descriptor> (or subclass) instead of raw array; was `android.media.audiofx.AudioEffect.Descriptor[]`
 ArrayReturn: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String, int, boolean, int, android.media.audiofx.AudioEffect.Descriptor[], android.media.audiofx.AudioEffect.Descriptor[]) parameter #11:
-    
-ArrayReturn: android.metrics.LogMaker#LogMaker(Object[]) parameter #0:
-    
-ArrayReturn: android.metrics.LogMaker#deserialize(Object[]) parameter #0:
-    
-ArrayReturn: android.metrics.LogMaker#serialize():
-    
-ArrayReturn: android.net.TestNetworkManager#createTunInterface(android.net.LinkAddress[]) parameter #0:
-    
-ArrayReturn: android.os.HwBlob#wrapArray(boolean[]):
-    
-ArrayReturn: android.os.HwBlob#wrapArray(byte[]):
-    
-ArrayReturn: android.os.HwBlob#wrapArray(double[]):
-    
-ArrayReturn: android.os.HwBlob#wrapArray(float[]):
-    
-ArrayReturn: android.os.HwBlob#wrapArray(int[]):
-    
-ArrayReturn: android.os.HwBlob#wrapArray(long[]):
-    
-ArrayReturn: android.os.HwBlob#wrapArray(short[]):
-    
-ArrayReturn: android.os.NativeHandle#NativeHandle(java.io.FileDescriptor[], int[], boolean) parameter #0:
-    
-ArrayReturn: android.os.NativeHandle#getFileDescriptors():
-    
-ArrayReturn: android.security.keystore.AttestationUtils#attestDeviceIds(android.content.Context, int[], byte[]):
-    
-ArrayReturn: android.telephony.ims.ImsUtListener#onUtConfigurationCallBarringQueried(int, android.telephony.ims.ImsSsInfo[]) parameter #1:
-    
-ArrayReturn: android.telephony.ims.ImsUtListener#onUtConfigurationCallForwardQueried(int, android.telephony.ims.ImsCallForwardInfo[]) parameter #1:
-    
-ArrayReturn: android.telephony.ims.ImsUtListener#onUtConfigurationCallWaitingQueried(int, android.telephony.ims.ImsSsInfo[]) parameter #1:
-    
-ArrayReturn: android.telephony.ims.stub.ImsRegistrationImplBase#onSubscriberAssociatedUriChanged(android.net.Uri[]) parameter #0:
-    
+    Method parameter should be Collection<Descriptor> (or subclass) instead of raw array; was `android.media.audiofx.AudioEffect.Descriptor[]`
 ArrayReturn: android.view.Display#getSupportedWideColorGamut():
-    
+    Method should return Collection<ColorSpace> (or subclass) instead of raw array; was `android.graphics.ColorSpace[]`
 ArrayReturn: android.view.FocusFinder#sort(android.view.View[], int, int, android.view.ViewGroup, boolean) parameter #0:
-    
-ArrayReturn: android.view.contentcapture.ViewNode#getAutofillOptions():
-    
+    Method parameter should be Collection<View> (or subclass) instead of raw array; was `android.view.View[]`
 ArrayReturn: android.view.contentcapture.ViewNode.ViewStructureImpl#setAutofillOptions(CharSequence[]) parameter #0:
-    
-ArrayReturn: android.view.inspector.InspectableProperty#enumMapping():
-    
-ArrayReturn: android.view.inspector.InspectableProperty#flagMapping():
-    
+    Method parameter should be Collection<CharSequence> (or subclass) instead of raw array; was `java.lang.CharSequence[]`
 
 
-AutoBoxing: android.os.HwBlob#wrapArray(byte[]):
-    
-AutoBoxing: android.os.HwBlob#wrapArray(double[]):
-    
-AutoBoxing: android.os.HwBlob#wrapArray(float[]):
-    
-AutoBoxing: android.os.HwBlob#wrapArray(int[]):
-    
-AutoBoxing: android.os.HwBlob#wrapArray(long[]):
-    
-AutoBoxing: android.os.HwBlob#wrapArray(short[]):
-    
 AutoBoxing: android.os.VintfObject#getTargetFrameworkCompatibilityMatrixVersion():
-    
+    Must avoid boxed primitives (`java.lang.Long`)
 
 
-BannedThrow: android.app.ActivityTaskManager#removeStacksInWindowingModes(int[]):
-    
-BannedThrow: android.app.ActivityTaskManager#removeStacksWithActivityTypes(int[]):
-    
-BannedThrow: android.app.ActivityTaskManager#setTaskWindowingMode(int, int, boolean):
-    
-BannedThrow: android.app.ActivityTaskManager#setTaskWindowingModeSplitScreenPrimary(int, int, boolean, boolean, android.graphics.Rect, boolean):
-    
-BannedThrow: android.media.audiofx.AudioEffect#getParameter(byte[], byte[]):
-    
-BannedThrow: android.media.audiofx.AudioEffect#getParameter(int, byte[]):
-    
-BannedThrow: android.media.audiofx.AudioEffect#getParameter(int, int[]):
-    
-BannedThrow: android.media.audiofx.AudioEffect#getParameter(int, short[]):
-    
-BannedThrow: android.media.audiofx.AudioEffect#getParameter(int[], short[]):
-    
-BannedThrow: android.media.audiofx.AudioEffect#setParameter(byte[], byte[]):
-    
-BannedThrow: android.media.audiofx.AudioEffect#setParameter(int, byte[]):
-    
-BannedThrow: android.media.audiofx.AudioEffect#setParameter(int, int):
-    
-BannedThrow: android.media.audiofx.AudioEffect#setParameter(int, short):
-    
-BannedThrow: android.media.audiofx.AudioEffect#setParameter(int[], byte[]):
-    
-BannedThrow: android.media.audiofx.AudioEffect#setParameter(int[], int[]):
-    
-BannedThrow: android.media.audiopolicy.AudioMix.Builder#Builder(android.media.audiopolicy.AudioMixingRule):
-    
-BannedThrow: android.media.audiopolicy.AudioMix.Builder#build():
-    
-BannedThrow: android.media.audiopolicy.AudioMix.Builder#setDevice(android.media.AudioDeviceInfo):
-    
-BannedThrow: android.media.audiopolicy.AudioMix.Builder#setFormat(android.media.AudioFormat):
-    
-BannedThrow: android.media.audiopolicy.AudioMix.Builder#setRouteFlags(int):
-    
-BannedThrow: android.media.audiopolicy.AudioMixingRule.Builder#addMixRule(int, Object):
-    
-BannedThrow: android.media.audiopolicy.AudioMixingRule.Builder#addRule(android.media.AudioAttributes, int):
-    
-BannedThrow: android.media.audiopolicy.AudioMixingRule.Builder#excludeMixRule(int, Object):
-    
-BannedThrow: android.media.audiopolicy.AudioMixingRule.Builder#excludeRule(android.media.AudioAttributes, int):
-    
-BannedThrow: android.media.audiopolicy.AudioPolicy#createAudioRecordSink(android.media.audiopolicy.AudioMix):
-    
-BannedThrow: android.media.audiopolicy.AudioPolicy#createAudioTrackSource(android.media.audiopolicy.AudioMix):
-    
-BannedThrow: android.media.audiopolicy.AudioPolicy#setFocusDuckingBehavior(int):
-    
-BannedThrow: android.media.audiopolicy.AudioPolicy.Builder#addMix(android.media.audiopolicy.AudioMix):
-    
-BannedThrow: android.media.audiopolicy.AudioPolicy.Builder#setLooper(android.os.Looper):
-    
-BannedThrow: android.os.HwBinder#getService(String, String):
-    
-BannedThrow: android.os.HwBinder#getService(String, String, boolean):
-    
-BannedThrow: android.os.Process#getThreadScheduler(int):
-    
-
-
-BuilderSetStyle: android.media.audiopolicy.AudioMixingRule.Builder#allowPrivilegedPlaybackCapture(boolean):
-    
-BuilderSetStyle: android.media.audiopolicy.AudioMixingRule.Builder#excludeMixRule(int, Object):
-    
-BuilderSetStyle: android.media.audiopolicy.AudioMixingRule.Builder#excludeRule(android.media.AudioAttributes, int):
-    
-BuilderSetStyle: android.net.NetworkCapabilities.Builder#removeCapability(int):
-    
-BuilderSetStyle: android.net.NetworkCapabilities.Builder#removeTransportType(int):
-    
-BuilderSetStyle: android.net.metrics.RaEvent.Builder#updateDnsslLifetime(long):
-    
-BuilderSetStyle: android.net.metrics.RaEvent.Builder#updatePrefixPreferredLifetime(long):
-    
-BuilderSetStyle: android.net.metrics.RaEvent.Builder#updatePrefixValidLifetime(long):
-    
-BuilderSetStyle: android.net.metrics.RaEvent.Builder#updateRdnssLifetime(long):
-    
-BuilderSetStyle: android.net.metrics.RaEvent.Builder#updateRouteInfoLifetime(long):
-    
-BuilderSetStyle: android.net.metrics.RaEvent.Builder#updateRouterLifetime(long):
-    
 BuilderSetStyle: android.os.StrictMode.ThreadPolicy.Builder#detectExplicitGc():
-    
-BuilderSetStyle: android.os.StrictMode.VmPolicy.Builder#detectIncorrectContextUse():
-    
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.os.StrictMode.ThreadPolicy.Builder.detectExplicitGc()
 BuilderSetStyle: android.os.StrictMode.VmPolicy.Builder#permitIncorrectContextUse():
-    
-
-
-CallbackInterface: android.app.prediction.AppPredictor.Callback:
-    
-CallbackInterface: android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback:
-    
-CallbackInterface: android.widget.Magnifier.Callback:
-    
-
-
-CallbackMethodName: android.os.RemoteCallback:
-    
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.os.StrictMode.VmPolicy.Builder.permitIncorrectContextUse()
 
 
 ConcreteCollection: android.content.AutofillOptions#disabledActivities:
-    
+    Field type is concrete collection (`android.util.ArrayMap`); must be higher-level interface
 ConcreteCollection: android.content.AutofillOptions#whitelistedActivitiesForAugmentedAutofill:
-    
+    Field type is concrete collection (`android.util.ArraySet`); must be higher-level interface
 ConcreteCollection: android.content.ContentCaptureOptions#ContentCaptureOptions(int, int, int, int, int, android.util.ArraySet<android.content.ComponentName>) parameter #5:
-    
+    Parameter type is concrete collection (`android.util.ArraySet`); must be higher-level interface
 ConcreteCollection: android.content.ContentCaptureOptions#whitelistedComponents:
-    
+    Field type is concrete collection (`android.util.ArraySet`); must be higher-level interface
 ConcreteCollection: android.database.sqlite.SQLiteDebug.PagerStats#dbStats:
-    
-ConcreteCollection: android.os.HwParcel#readBoolVector():
-    
-ConcreteCollection: android.os.HwParcel#readDoubleVector():
-    
-ConcreteCollection: android.os.HwParcel#readFloatVector():
-    
-ConcreteCollection: android.os.HwParcel#readInt16Vector():
-    
-ConcreteCollection: android.os.HwParcel#readInt32Vector():
-    
-ConcreteCollection: android.os.HwParcel#readInt64Vector():
-    
-ConcreteCollection: android.os.HwParcel#readInt8Vector():
-    
-ConcreteCollection: android.os.HwParcel#readNativeHandleVector():
-    
-ConcreteCollection: android.os.HwParcel#readStringVector():
-    
-ConcreteCollection: android.os.HwParcel#writeBoolVector(java.util.ArrayList<java.lang.Boolean>) parameter #0:
-    
-ConcreteCollection: android.os.HwParcel#writeDoubleVector(java.util.ArrayList<java.lang.Double>) parameter #0:
-    
-ConcreteCollection: android.os.HwParcel#writeFloatVector(java.util.ArrayList<java.lang.Float>) parameter #0:
-    
-ConcreteCollection: android.os.HwParcel#writeInt16Vector(java.util.ArrayList<java.lang.Short>) parameter #0:
-    
-ConcreteCollection: android.os.HwParcel#writeInt32Vector(java.util.ArrayList<java.lang.Integer>) parameter #0:
-    
-ConcreteCollection: android.os.HwParcel#writeInt64Vector(java.util.ArrayList<java.lang.Long>) parameter #0:
-    
-ConcreteCollection: android.os.HwParcel#writeInt8Vector(java.util.ArrayList<java.lang.Byte>) parameter #0:
-    
-ConcreteCollection: android.os.HwParcel#writeNativeHandleVector(java.util.ArrayList<android.os.NativeHandle>) parameter #0:
-    
-ConcreteCollection: android.os.HwParcel#writeStringVector(java.util.ArrayList<java.lang.String>) parameter #0:
-    
+    Field type is concrete collection (`java.util.ArrayList`); must be higher-level interface
 ConcreteCollection: android.service.autofill.CompositeUserData#getFieldClassificationAlgorithms():
-    
+    Return type is concrete collection (`android.util.ArrayMap`); must be higher-level interface
 ConcreteCollection: android.service.autofill.CompositeUserData#getFieldClassificationArgs():
-    
+    Return type is concrete collection (`android.util.ArrayMap`); must be higher-level interface
 ConcreteCollection: android.service.autofill.InternalTransformation#batchApply(android.service.autofill.ValueFinder, android.widget.RemoteViews, java.util.ArrayList<android.util.Pair<java.lang.Integer,android.service.autofill.InternalTransformation>>) parameter #2:
-    
+    Parameter type is concrete collection (`java.util.ArrayList`); must be higher-level interface
 ConcreteCollection: android.service.autofill.UserData#getFieldClassificationAlgorithms():
-    
-ConcreteCollection: android.telephony.ims.ImsConferenceState#mParticipants:
-    
+    Return type is concrete collection (`android.util.ArrayMap`); must be higher-level interface
 
 
 ContextFirst: android.os.VibrationEffect#get(android.net.Uri, android.content.Context) parameter #1:
-    
-
-
-ContextNameSuffix: android.telephony.mbms.vendor.MbmsGroupCallServiceBase:
-    
+    Context is distinct, so it must be the first argument (method `get`)
 
 
 EndsWithImpl: android.view.contentcapture.ViewNode.ViewStructureImpl:
-    
+    Don't expose your implementation details: `ViewStructureImpl` ends with `Impl`
 
 
 Enum: android.view.inspector.InspectableProperty.ValueType:
-    
+    Enums are discouraged in Android APIs
 
 
-EqualsAndHashCode: android.app.prediction.AppPredictionContext#equals(Object):
-    
-EqualsAndHashCode: android.app.prediction.AppTarget#equals(Object):
-    
-EqualsAndHashCode: android.app.prediction.AppTargetEvent#equals(Object):
-    
-EqualsAndHashCode: android.net.apf.ApfCapabilities#equals(Object):
-    
-EqualsAndHashCode: android.net.metrics.ApfProgramEvent#equals(Object):
-    
-EqualsAndHashCode: android.net.metrics.ApfStats#equals(Object):
-    
-EqualsAndHashCode: android.net.metrics.DhcpClientEvent#equals(Object):
-    
-EqualsAndHashCode: android.net.metrics.IpManagerEvent#equals(Object):
-    
-EqualsAndHashCode: android.net.metrics.IpReachabilityEvent#equals(Object):
-    
-EqualsAndHashCode: android.net.metrics.NetworkEvent#equals(Object):
-    
-EqualsAndHashCode: android.net.metrics.RaEvent#equals(Object):
-    
-EqualsAndHashCode: android.net.metrics.ValidationProbeEvent#equals(Object):
-    
-EqualsAndHashCode: android.os.IncidentManager.PendingReport#equals(Object):
-    
 EqualsAndHashCode: android.os.StrictMode.ViolationInfo#hashCode():
-    
+    Must override both equals and hashCode; missing one in android.os.StrictMode.ViolationInfo
 
 
-ExecutorRegistration: android.content.pm.PackageManager#addOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener):
-    
-ExecutorRegistration: android.hardware.camera2.CameraDevice#createCustomCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.hardware.camera2.params.OutputConfiguration>, int, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler):
-    
 ExecutorRegistration: android.media.audiofx.AudioEffect#setParameterListener(android.media.audiofx.AudioEffect.OnParameterChangeListener):
-    
-ExecutorRegistration: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyFocusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener):
-    
-ExecutorRegistration: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyStatusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyStatusListener):
-    
-ExecutorRegistration: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyVolumeCallback(android.media.audiopolicy.AudioPolicy.AudioPolicyVolumeCallback):
-    
-ExecutorRegistration: android.os.IncidentManager#cancelAuthorization(android.os.IncidentManager.AuthListener):
-    
-ExecutorRegistration: android.os.IncidentManager#requestAuthorization(int, String, int, android.os.IncidentManager.AuthListener):
-    
-ExecutorRegistration: android.os.RemoteCallback#RemoteCallback(android.os.RemoteCallback.OnResultListener, android.os.Handler):
-    
+    Registration methods should have overload that accepts delivery Executor: `setParameterListener`
 ExecutorRegistration: android.permission.PermissionControllerManager#countPermissionApps(java.util.List<java.lang.String>, int, android.permission.PermissionControllerManager.OnCountPermissionAppsResultCallback, android.os.Handler):
-    
+    Registration methods should have overload that accepts delivery Executor: `countPermissionApps`
 ExecutorRegistration: android.permission.PermissionControllerManager#getAppPermissions(String, android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback, android.os.Handler):
-    
+    Registration methods should have overload that accepts delivery Executor: `getAppPermissions`
 ExecutorRegistration: android.service.watchdog.ExplicitHealthCheckService#setCallback(android.os.RemoteCallback):
-    
-ExecutorRegistration: android.telephony.ims.stub.ImsCallSessionImplBase#setListener(android.telephony.ims.ImsCallSessionListener):
-    
-ExecutorRegistration: android.telephony.ims.stub.ImsUtImplBase#setListener(android.telephony.ims.ImsUtListener):
-    
-ExecutorRegistration: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener):
-    
-ExecutorRegistration: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener):
-    
-ExecutorRegistration: android.telephony.mbms.vendor.MbmsDownloadServiceBase#initialize(int, android.telephony.mbms.MbmsDownloadSessionCallback):
-    
-ExecutorRegistration: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#initialize(android.telephony.mbms.MbmsGroupCallSessionCallback, int):
-    
-ExecutorRegistration: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#startGroupCall(int, long, java.util.List<java.lang.Integer>, java.util.List<java.lang.Integer>, android.telephony.mbms.GroupCallCallback):
-    
-ExecutorRegistration: android.telephony.mbms.vendor.MbmsStreamingServiceBase#initialize(android.telephony.mbms.MbmsStreamingSessionCallback, int):
-    
-ExecutorRegistration: android.telephony.mbms.vendor.MbmsStreamingServiceBase#startStreaming(int, String, android.telephony.mbms.StreamingServiceCallback):
-    
+    Registration methods should have overload that accepts delivery Executor: `setCallback`
 ExecutorRegistration: android.window.WindowOrganizer#applySyncTransaction(android.window.WindowContainerTransaction, android.window.WindowContainerTransactionCallback):
-    
+    Registration methods should have overload that accepts delivery Executor: `applySyncTransaction`
 
 
 ForbiddenSuperClass: android.app.AppDetailsActivity:
-    
+    AppDetailsActivity should not extend `Activity`. Activity subclasses are impossible to compose. Expose a composable API instead.
 
 
-GenericException: android.app.prediction.AppPredictor#finalize():
-    
 GenericException: android.service.autofill.CharSequenceTransformation#apply(android.service.autofill.ValueFinder, android.widget.RemoteViews, int):
-    
+    Methods must not throw generic exceptions (`java.lang.Exception`)
 GenericException: android.service.autofill.DateTransformation#apply(android.service.autofill.ValueFinder, android.widget.RemoteViews, int):
-    
+    Methods must not throw generic exceptions (`java.lang.Exception`)
 GenericException: android.service.autofill.ImageTransformation#apply(android.service.autofill.ValueFinder, android.widget.RemoteViews, int):
-    
-GenericException: android.service.autofill.augmented.FillWindow#finalize():
-    
+    Methods must not throw generic exceptions (`java.lang.Exception`)
 
 
-GetterOnBuilder: android.hardware.display.BrightnessConfiguration.Builder#getMaxCorrectionsByCategory():
-    
-GetterOnBuilder: android.hardware.display.BrightnessConfiguration.Builder#getMaxCorrectionsByPackageName():
-    
-
-
-GetterSetterNames: android.app.NotificationChannel#isBlockableSystem():
-    
-GetterSetterNames: android.app.NotificationChannel#isImportanceLockedByCriticalDeviceFunction():
-    
-GetterSetterNames: android.app.NotificationChannel#isImportanceLockedByOEM():
-    
 GetterSetterNames: android.location.GnssClock#setBiasNanos(double):
-    
+    Symmetric method for `hasBiasNanos` must be named `setHasBiasNanos`; was `setBiasNanos`
 GetterSetterNames: android.location.GnssClock#setBiasUncertaintyNanos(double):
-    
+    Symmetric method for `hasBiasUncertaintyNanos` must be named `setHasBiasUncertaintyNanos`; was `setBiasUncertaintyNanos`
 GetterSetterNames: android.location.GnssClock#setDriftNanosPerSecond(double):
-    
+    Symmetric method for `hasDriftNanosPerSecond` must be named `setHasDriftNanosPerSecond`; was `setDriftNanosPerSecond`
 GetterSetterNames: android.location.GnssClock#setDriftUncertaintyNanosPerSecond(double):
-    
+    Symmetric method for `hasDriftUncertaintyNanosPerSecond` must be named `setHasDriftUncertaintyNanosPerSecond`; was `setDriftUncertaintyNanosPerSecond`
 GetterSetterNames: android.location.GnssClock#setElapsedRealtimeNanos(long):
-    
+    Symmetric method for `hasElapsedRealtimeNanos` must be named `setHasElapsedRealtimeNanos`; was `setElapsedRealtimeNanos`
 GetterSetterNames: android.location.GnssClock#setElapsedRealtimeUncertaintyNanos(double):
-    
+    Symmetric method for `hasElapsedRealtimeUncertaintyNanos` must be named `setHasElapsedRealtimeUncertaintyNanos`; was `setElapsedRealtimeUncertaintyNanos`
 GetterSetterNames: android.location.GnssClock#setFullBiasNanos(long):
-    
+    Symmetric method for `hasFullBiasNanos` must be named `setHasFullBiasNanos`; was `setFullBiasNanos`
 GetterSetterNames: android.location.GnssClock#setLeapSecond(int):
-    
+    Symmetric method for `hasLeapSecond` must be named `setHasLeapSecond`; was `setLeapSecond`
 GetterSetterNames: android.location.GnssClock#setReferenceCarrierFrequencyHzForIsb(double):
-    
+    Symmetric method for `hasReferenceCarrierFrequencyHzForIsb` must be named `setHasReferenceCarrierFrequencyHzForIsb`; was `setReferenceCarrierFrequencyHzForIsb`
 GetterSetterNames: android.location.GnssClock#setReferenceCodeTypeForIsb(String):
-    
+    Symmetric method for `hasReferenceCodeTypeForIsb` must be named `setHasReferenceCodeTypeForIsb`; was `setReferenceCodeTypeForIsb`
 GetterSetterNames: android.location.GnssClock#setReferenceConstellationTypeForIsb(int):
-    
+    Symmetric method for `hasReferenceConstellationTypeForIsb` must be named `setHasReferenceConstellationTypeForIsb`; was `setReferenceConstellationTypeForIsb`
 GetterSetterNames: android.location.GnssClock#setTimeUncertaintyNanos(double):
-    
+    Symmetric method for `hasTimeUncertaintyNanos` must be named `setHasTimeUncertaintyNanos`; was `setTimeUncertaintyNanos`
 GetterSetterNames: android.location.GnssMeasurement#setBasebandCn0DbHz(double):
-    
+    Symmetric method for `hasBasebandCn0DbHz` must be named `setHasBasebandCn0DbHz`; was `setBasebandCn0DbHz`
 GetterSetterNames: android.location.GnssMeasurement#setCarrierFrequencyHz(float):
-    
+    Symmetric method for `hasCarrierFrequencyHz` must be named `setHasCarrierFrequencyHz`; was `setCarrierFrequencyHz`
 GetterSetterNames: android.location.GnssMeasurement#setCodeType(String):
-    
+    Symmetric method for `hasCodeType` must be named `setHasCodeType`; was `setCodeType`
 GetterSetterNames: android.location.GnssMeasurement#setCorrelationVectors(java.util.Collection<android.location.CorrelationVector>):
-    
+    Symmetric method for `hasCorrelationVectors` must be named `setHasCorrelationVectors`; was `setCorrelationVectors`
 GetterSetterNames: android.location.GnssMeasurement#setFullInterSignalBiasNanos(double):
-    
+    Symmetric method for `hasFullInterSignalBiasNanos` must be named `setHasFullInterSignalBiasNanos`; was `setFullInterSignalBiasNanos`
 GetterSetterNames: android.location.GnssMeasurement#setFullInterSignalBiasUncertaintyNanos(double):
-    
+    Symmetric method for `hasFullInterSignalBiasUncertaintyNanos` must be named `setHasFullInterSignalBiasUncertaintyNanos`; was `setFullInterSignalBiasUncertaintyNanos`
 GetterSetterNames: android.location.GnssMeasurement#setSatelliteInterSignalBiasNanos(double):
-    
+    Symmetric method for `hasSatelliteInterSignalBiasNanos` must be named `setHasSatelliteInterSignalBiasNanos`; was `setSatelliteInterSignalBiasNanos`
 GetterSetterNames: android.location.GnssMeasurement#setSatelliteInterSignalBiasUncertaintyNanos(double):
-    
+    Symmetric method for `hasSatelliteInterSignalBiasUncertaintyNanos` must be named `setHasSatelliteInterSignalBiasUncertaintyNanos`; was `setSatelliteInterSignalBiasUncertaintyNanos`
 GetterSetterNames: android.location.GnssMeasurement#setSatellitePvt(android.location.SatellitePvt):
-    
+    Symmetric method for `hasSatellitePvt` must be named `setHasSatellitePvt`; was `setSatellitePvt`
 GetterSetterNames: android.location.GnssMeasurement#setSnrInDb(double):
-    
-GetterSetterNames: android.location.LocationRequest#isLocationSettingsIgnored():
-    
-GetterSetterNames: android.location.LocationRequest#isLowPowerMode():
-    
+    Symmetric method for `hasSnrInDb` must be named `setHasSnrInDb`; was `setSnrInDb`
 GetterSetterNames: android.net.NetworkPolicyManager#getRestrictBackground():
     Symmetric method for `setRestrictBackground` must be named `isRestrictBackground`; was `getRestrictBackground`
-GetterSetterNames: android.os.IncidentReportArgs#isAll():
-    
-GetterSetterNames: android.service.notification.NotificationStats#setDirectReplied():
-    
-GetterSetterNames: android.service.notification.NotificationStats#setExpanded():
-    
-GetterSetterNames: android.service.notification.NotificationStats#setSeen():
-    
-GetterSetterNames: android.service.notification.NotificationStats#setSnoozed():
-    
-GetterSetterNames: android.service.notification.NotificationStats#setViewedSettings():
-    
-GetterSetterNames: android.view.View#isAutofilled():
-    
-GetterSetterNames: android.view.View#isDefaultFocusHighlightEnabled():
-    
 
 
-IllegalStateException: android.media.audiopolicy.AudioMix.Builder#build():
-    
-
-
-IntentBuilderName: android.app.backup.BackupManager#getConfigurationIntent(String):
-    
-IntentBuilderName: android.app.backup.BackupManager#getDataManagementIntent(String):
-    
 IntentBuilderName: android.hardware.soundtrigger.KeyphraseEnrollmentInfo#getManageKeyphraseIntent(int, String, java.util.Locale):
-    
+    Methods creating an Intent should be named `create<Foo>Intent()`, was `getManageKeyphraseIntent`
 
 
 IntentName: android.provider.Settings.Secure#VOICE_INTERACTION_SERVICE:
-    
+    Intent action constant name must be ACTION_FOO: VOICE_INTERACTION_SERVICE
 IntentName: android.provider.Telephony.Sms.Intents#SMS_CARRIER_PROVISION_ACTION:
-    
-IntentName: android.service.notification.Adjustment#KEY_CONTEXTUAL_ACTIONS:
-    
+    Intent action constant name must be ACTION_FOO: SMS_CARRIER_PROVISION_ACTION
 
 
-InterfaceConstant: android.service.autofill.AutofillFieldClassificationService#SERVICE_INTERFACE:
-    
-InterfaceConstant: android.service.autofill.augmented.AugmentedAutofillService#SERVICE_INTERFACE:
-    
-InterfaceConstant: android.service.contentcapture.ContentCaptureService#SERVICE_INTERFACE:
-    
-InterfaceConstant: android.service.notification.NotificationAssistantService#SERVICE_INTERFACE:
-    
-InterfaceConstant: android.telecom.PhoneAccountSuggestionService#SERVICE_INTERFACE:
-    
-
-
-InternalField: android.media.audiopolicy.AudioProductStrategy#sDefaultAttributes:
-    Internal field sDefaultAttributes must not be exposed
-InternalField: android.telephony.ims.ImsConferenceState#mParticipants:
-    
-
-
-KotlinOperator: android.os.WorkSource#get(int):
-    
+KotlinOperator: android.os.PackageTagsList#contains(android.os.PackageTagsList):
+    Method can be invoked as a "in" operator from Kotlin: `contains` (this is usually desirable; just make sure it makes sense for this type of object)
 KotlinOperator: android.util.SparseArrayMap#get(int, K):
-    
-KotlinOperator: android.util.SparseArrayMap#get(int, String):
-    
+    Method can be invoked with an indexing operator from Kotlin: `get` (this is usually desirable; just make sure it makes sense for this type of object)
 
 
-ListenerInterface: android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener:
-    
-ListenerInterface: android.media.audiopolicy.AudioPolicy.AudioPolicyStatusListener:
-    
-ListenerInterface: android.os.IncidentManager.AuthListener:
-    
-ListenerInterface: android.telephony.ims.ImsCallSessionListener:
-    
-ListenerInterface: android.telephony.ims.ImsUtListener:
-    
-
-
-ListenerLast: android.hardware.camera2.CameraDevice#createCustomCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.hardware.camera2.params.OutputConfiguration>, int, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) parameter #4:
-    
-ListenerLast: android.location.LocationManager#requestLocationUpdates(android.location.LocationRequest, android.location.LocationListener, android.os.Looper) parameter #2:
-    
 ListenerLast: android.permission.PermissionControllerManager#countPermissionApps(java.util.List<java.lang.String>, int, android.permission.PermissionControllerManager.OnCountPermissionAppsResultCallback, android.os.Handler) parameter #3:
-    
+    Listeners should always be at end of argument list (method `countPermissionApps`)
 ListenerLast: android.permission.PermissionControllerManager#getAppPermissions(String, android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback, android.os.Handler) parameter #2:
-    
-ListenerLast: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#initialize(android.telephony.mbms.MbmsGroupCallSessionCallback, int) parameter #1:
-    
-ListenerLast: android.telephony.mbms.vendor.MbmsStreamingServiceBase#initialize(android.telephony.mbms.MbmsStreamingSessionCallback, int) parameter #1:
-    
+    Listeners should always be at end of argument list (method `getAppPermissions`)
 
 
 ManagerConstructor: android.content.pm.ShortcutManager#ShortcutManager(android.content.Context):
-    
-
-
-ManagerLookup: android.telephony.ims.ImsMmTelManager#createForSubscriptionId(int):
-    
-ManagerLookup: android.telephony.ims.ProvisioningManager#createForSubscriptionId(int):
-    
-
-
-MethodNameTense: android.telephony.ims.feature.CapabilityChangeRequest#getCapabilitiesToEnable():
-    
-
-
-MethodNameUnits: android.telephony.ims.ImsCallForwardInfo#getTimeSeconds():
-    
+    Managers must always be obtained from Context; no direct constructors
 
 
 MinMaxConstant: android.os.UserHandle#MIN_SECONDARY_USER_ID:
-    
+    If min/max could change in future, make them dynamic methods: android.os.UserHandle#MIN_SECONDARY_USER_ID
 MinMaxConstant: android.view.autofill.AutofillManager#MAX_TEMP_AUGMENTED_SERVICE_DURATION_MS:
-    
+    If min/max could change in future, make them dynamic methods: android.view.autofill.AutofillManager#MAX_TEMP_AUGMENTED_SERVICE_DURATION_MS
 
 
-MissingGetterMatchingBuilder: android.app.AppOpsManager.HistoricalOpsRequest.Builder#setFlags(int):
-    
-MissingGetterMatchingBuilder: android.app.AppOpsManager.HistoricalOpsRequest.Builder#setOpNames(java.util.List<java.lang.String>):
-    
-MissingGetterMatchingBuilder: android.app.AppOpsManager.HistoricalOpsRequest.Builder#setPackageName(String):
-    
-MissingGetterMatchingBuilder: android.app.AppOpsManager.HistoricalOpsRequest.Builder#setUid(int):
-    
-MissingGetterMatchingBuilder: android.content.integrity.RuleSet.Builder#addRules(java.util.List<android.content.integrity.Rule>):
-    
-MissingGetterMatchingBuilder: android.hardware.display.BrightnessConfiguration.Builder#addCorrectionByCategory(int, android.hardware.display.BrightnessCorrection):
-    
-MissingGetterMatchingBuilder: android.hardware.display.BrightnessConfiguration.Builder#addCorrectionByPackageName(String, android.hardware.display.BrightnessCorrection):
-    
-MissingGetterMatchingBuilder: android.hardware.display.BrightnessConfiguration.Builder#setDescription(String):
-    
-MissingGetterMatchingBuilder: android.hardware.lights.LightsRequest.Builder#setLight(android.hardware.lights.Light, android.hardware.lights.LightState):
-    
 MissingGetterMatchingBuilder: android.media.VolumeShaper.Configuration.Builder#setOptionFlags(int):
-    
-MissingGetterMatchingBuilder: android.media.audiopolicy.AudioMix.Builder#setDevice(android.media.AudioDeviceInfo):
-    
-MissingGetterMatchingBuilder: android.media.audiopolicy.AudioMix.Builder#setFormat(android.media.AudioFormat):
-    
-MissingGetterMatchingBuilder: android.media.audiopolicy.AudioMix.Builder#setRouteFlags(int):
-    
-MissingGetterMatchingBuilder: android.media.audiopolicy.AudioMixingRule.Builder#addMixRule(int, Object):
-    
-MissingGetterMatchingBuilder: android.media.audiopolicy.AudioMixingRule.Builder#addRule(android.media.AudioAttributes, int):
-    
-MissingGetterMatchingBuilder: android.media.audiopolicy.AudioPolicy.Builder#addMix(android.media.audiopolicy.AudioMix):
-    
-MissingGetterMatchingBuilder: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyFocusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener):
-    
-MissingGetterMatchingBuilder: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyStatusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyStatusListener):
-    
-MissingGetterMatchingBuilder: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyVolumeCallback(android.media.audiopolicy.AudioPolicy.AudioPolicyVolumeCallback):
-    
-MissingGetterMatchingBuilder: android.media.audiopolicy.AudioPolicy.Builder#setIsAudioFocusPolicy(boolean):
-    
+    android.media.VolumeShaper.Configuration does not declare a `getOptionFlags()` method matching method android.media.VolumeShaper.Configuration.Builder.setOptionFlags(int)
 MissingGetterMatchingBuilder: android.media.audiopolicy.AudioPolicy.Builder#setIsTestFocusPolicy(boolean):
-    
-MissingGetterMatchingBuilder: android.media.audiopolicy.AudioPolicy.Builder#setLooper(android.os.Looper):
-    
-MissingGetterMatchingBuilder: android.net.CaptivePortalData.Builder#setBytesRemaining(long):
-    
-MissingGetterMatchingBuilder: android.net.CaptivePortalData.Builder#setExpiryTime(long):
-    
-MissingGetterMatchingBuilder: android.net.CaptivePortalData.Builder#setRefreshTime(long):
-    
-MissingGetterMatchingBuilder: android.net.NetworkCapabilities.Builder#addCapability(int):
-    
-MissingGetterMatchingBuilder: android.net.NetworkCapabilities.Builder#setRequestorPackageName(String):
-    
-MissingGetterMatchingBuilder: android.net.NetworkCapabilities.Builder#setRequestorUid(int):
-    
-MissingGetterMatchingBuilder: android.net.TetheringManager.TetheringRequest.Builder#setShouldShowEntitlementUi(boolean):
-    
-MissingGetterMatchingBuilder: android.net.TetheringManager.TetheringRequest.Builder#setStaticIpv4Addresses(android.net.LinkAddress, android.net.LinkAddress):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfProgramEvent.Builder#setActualLifetime(long):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfProgramEvent.Builder#setCurrentRas(int):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfProgramEvent.Builder#setFilteredRas(int):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfProgramEvent.Builder#setFlags(boolean, boolean):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfProgramEvent.Builder#setLifetime(long):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfProgramEvent.Builder#setProgramLength(int):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setDroppedRas(int):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setDurationMs(long):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setMatchingRas(int):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setMaxProgramSize(int):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setParseErrors(int):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setProgramUpdates(int):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setProgramUpdatesAll(int):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setProgramUpdatesAllowingMulticast(int):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setReceivedRas(int):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setZeroLifetimeRas(int):
-    
-MissingGetterMatchingBuilder: android.net.metrics.DhcpClientEvent.Builder#setDurationMs(int):
-    
-MissingGetterMatchingBuilder: android.net.metrics.DhcpClientEvent.Builder#setMsg(String):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ValidationProbeEvent.Builder#setDurationMs(long):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ValidationProbeEvent.Builder#setProbeType(int, boolean):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ValidationProbeEvent.Builder#setReturnCode(int):
-    
+    android.media.audiopolicy.AudioPolicy does not declare a `isIsTestFocusPolicy()` method matching method android.media.audiopolicy.AudioPolicy.Builder.setIsTestFocusPolicy(boolean)
 MissingGetterMatchingBuilder: android.security.keystore.KeyGenParameterSpec.Builder#setUniqueIdIncluded(boolean):
-    
-MissingGetterMatchingBuilder: android.service.autofill.Dataset.Builder#setFieldInlinePresentation(android.view.autofill.AutofillId, android.view.autofill.AutofillValue, java.util.regex.Pattern, android.service.autofill.InlinePresentation):
-    
-MissingGetterMatchingBuilder: android.service.autofill.augmented.FillResponse.Builder#setClientState(android.os.Bundle):
-    
-MissingGetterMatchingBuilder: android.service.autofill.augmented.FillResponse.Builder#setFillWindow(android.service.autofill.augmented.FillWindow):
-    
-MissingGetterMatchingBuilder: android.service.autofill.augmented.FillResponse.Builder#setInlineSuggestions(java.util.List<android.service.autofill.Dataset>):
-    
-MissingGetterMatchingBuilder: android.telecom.CallScreeningService.CallResponse.Builder#setShouldScreenCallViaAudioProcessing(boolean):
-    
+    android.security.keystore.KeyGenParameterSpec does not declare a `isUniqueIdIncluded()` method matching method android.security.keystore.KeyGenParameterSpec.Builder.setUniqueIdIncluded(boolean)
 MissingGetterMatchingBuilder: android.telecom.ConnectionRequest.Builder#setIsAdhocConferenceCall(boolean):
-    
+    android.telecom.ConnectionRequest does not declare a `isIsAdhocConferenceCall()` method matching method android.telecom.ConnectionRequest.Builder.setIsAdhocConferenceCall(boolean)
 MissingGetterMatchingBuilder: android.telecom.ConnectionRequest.Builder#setRttPipeFromInCall(android.os.ParcelFileDescriptor):
-    
+    android.telecom.ConnectionRequest does not declare a `getRttPipeFromInCall()` method matching method android.telecom.ConnectionRequest.Builder.setRttPipeFromInCall(android.os.ParcelFileDescriptor)
 MissingGetterMatchingBuilder: android.telecom.ConnectionRequest.Builder#setRttPipeToInCall(android.os.ParcelFileDescriptor):
-    
+    android.telecom.ConnectionRequest does not declare a `getRttPipeToInCall()` method matching method android.telecom.ConnectionRequest.Builder.setRttPipeToInCall(android.os.ParcelFileDescriptor)
 MissingGetterMatchingBuilder: android.telecom.ConnectionRequest.Builder#setShouldShowIncomingCallUi(boolean):
-    
-MissingGetterMatchingBuilder: android.telecom.PhoneAccount.Builder#setGroupId(String):
-    
-MissingGetterMatchingBuilder: android.telephony.NetworkRegistrationInfo.Builder#setEmergencyOnly(boolean):
-    
-MissingGetterMatchingBuilder: android.telephony.ims.ImsSsData.Builder#setCallForwardingInfo(java.util.List<android.telephony.ims.ImsCallForwardInfo>):
-    
-MissingGetterMatchingBuilder: android.telephony.ims.stub.ImsFeatureConfiguration.Builder#addFeature(int, int):
-    
-MissingGetterMatchingBuilder: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String):
-    
+    android.telecom.ConnectionRequest does not declare a `shouldShowIncomingCallUi()` method matching method android.telecom.ConnectionRequest.Builder.setShouldShowIncomingCallUi(boolean)
 MissingGetterMatchingBuilder: android.view.Display.Mode.Builder#setResolution(int, int):
     android.view.Display.Mode does not declare a `getResolution()` method matching method android.view.Display.Mode.Builder.setResolution(int,int)
 
 
 MissingNullability: android.app.Activity#onMovedToDisplay(int, android.content.res.Configuration) parameter #1:
-    
-MissingNullability: android.app.ActivityManager#addOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener, int) parameter #0:
-    
+    Missing nullability on parameter `config` in method `onMovedToDisplay`
 MissingNullability: android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning(android.content.ComponentName) parameter #0:
-    
-MissingNullability: android.app.ActivityManager#forceStopPackage(String) parameter #0:
-    
-MissingNullability: android.app.ActivityManager#getPackageImportance(String) parameter #0:
-    
+    Missing nullability on parameter `activity` in method `alwaysShowUnsupportedCompileSdkWarning`
 MissingNullability: android.app.ActivityManager#holdLock(android.os.IBinder, int) parameter #0:
-    
-MissingNullability: android.app.ActivityManager#removeOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener) parameter #0:
-    
+    Missing nullability on parameter `token` in method `holdLock`
 MissingNullability: android.app.ActivityManager#scheduleApplicationInfoChanged(java.util.List<java.lang.String>, int) parameter #0:
-    
+    Missing nullability on parameter `packages` in method `scheduleApplicationInfoChanged`
 MissingNullability: android.app.ActivityManager.TaskDescription#getIconFilename():
-    
+    Missing nullability on method `getIconFilename` return
 MissingNullability: android.app.ActivityTaskManager#clearLaunchParamsForPackages(java.util.List<java.lang.String>) parameter #0:
-    
-MissingNullability: android.app.ActivityTaskManager#listAllStacks():
-    
-MissingNullability: android.app.ActivityTaskManager#moveTopActivityToPinnedStack(int, android.graphics.Rect) parameter #1:
-    
-MissingNullability: android.app.ActivityTaskManager#removeStacksInWindowingModes(int[]) parameter #0:
-    
-MissingNullability: android.app.ActivityTaskManager#removeStacksWithActivityTypes(int[]) parameter #0:
-    
-MissingNullability: android.app.ActivityTaskManager#resizeDockedStack(android.graphics.Rect, android.graphics.Rect) parameter #0:
-    
-MissingNullability: android.app.ActivityTaskManager#resizeDockedStack(android.graphics.Rect, android.graphics.Rect) parameter #1:
-    
-MissingNullability: android.app.ActivityTaskManager#resizePinnedStack(int, android.graphics.Rect, boolean) parameter #1:
-    
+    Missing nullability on parameter `packageNames` in method `clearLaunchParamsForPackages`
 MissingNullability: android.app.ActivityTaskManager#resizeTask(int, android.graphics.Rect) parameter #1:
-    
-MissingNullability: android.app.ActivityTaskManager#setTaskWindowingModeSplitScreenPrimary(int, int, boolean, boolean, android.graphics.Rect, boolean) parameter #4:
-    
+    Missing nullability on parameter `bounds` in method `resizeTask`
 MissingNullability: android.app.ActivityTaskManager#supportsMultiWindow(android.content.Context) parameter #0:
-    
+    Missing nullability on parameter `context` in method `supportsMultiWindow`
 MissingNullability: android.app.ActivityTaskManager#supportsSplitScreenMultiWindow(android.content.Context) parameter #0:
-    
+    Missing nullability on parameter `context` in method `supportsSplitScreenMultiWindow`
 MissingNullability: android.app.AppDetailsActivity#onCreate(android.os.Bundle) parameter #0:
-    
-MissingNullability: android.app.AppOpsManager#getOpStrs():
-    
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
 MissingNullability: android.app.AppOpsManager#isOperationActive(int, int, String) parameter #2:
-    
+    Missing nullability on parameter `packageName` in method `isOperationActive`
 MissingNullability: android.app.AppOpsManager#opToPermission(int):
-    
+    Missing nullability on method `opToPermission` return
 MissingNullability: android.app.AppOpsManager#permissionToOpCode(String) parameter #0:
-    
-MissingNullability: android.app.AppOpsManager#setMode(String, int, String, int) parameter #0:
-    
-MissingNullability: android.app.AppOpsManager#setMode(String, int, String, int) parameter #2:
-    
+    Missing nullability on parameter `permission` in method `permissionToOpCode`
 MissingNullability: android.app.AppOpsManager#setMode(int, int, String, int) parameter #2:
-    
-MissingNullability: android.app.AppOpsManager#setUidMode(String, int, int) parameter #0:
-    
-MissingNullability: android.app.AppOpsManager.HistoricalOp#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.app.AppOpsManager.HistoricalOps#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.app.AppOpsManager.HistoricalUidOps#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.app.AppOpsManager.OpEntry#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on parameter `packageName` in method `setMode`
 MissingNullability: android.app.NotificationManager#allowAssistantAdjustment(String) parameter #0:
-    
+    Missing nullability on parameter `capability` in method `allowAssistantAdjustment`
 MissingNullability: android.app.NotificationManager#disallowAssistantAdjustment(String) parameter #0:
-    
+    Missing nullability on parameter `capability` in method `disallowAssistantAdjustment`
 MissingNullability: android.app.NotificationManager#getEffectsSuppressor():
-    
-MissingNullability: android.app.NotificationManager#matchesCallFilter(android.os.Bundle) parameter #0:
-    
-MissingNullability: android.app.PictureInPictureParams#getActions():
-    
-MissingNullability: android.app.PictureInPictureParams#getSourceRectHint():
-    
+    Missing nullability on method `getEffectsSuppressor` return
 MissingNullability: android.app.TimePickerDialog#getTimePicker():
-    
-MissingNullability: android.app.UiAutomation#executeShellCommandRw(String):
-    
-MissingNullability: android.app.UiAutomation#executeShellCommandRw(String) parameter #0:
-    
-MissingNullability: android.app.UiAutomation#grantRuntimePermission(String, String, android.os.UserHandle) parameter #0:
-    
-MissingNullability: android.app.UiAutomation#grantRuntimePermission(String, String, android.os.UserHandle) parameter #1:
-    
-MissingNullability: android.app.UiAutomation#grantRuntimePermission(String, String, android.os.UserHandle) parameter #2:
-    
-MissingNullability: android.app.UiAutomation#revokeRuntimePermission(String, String, android.os.UserHandle) parameter #0:
-    
-MissingNullability: android.app.UiAutomation#revokeRuntimePermission(String, String, android.os.UserHandle) parameter #1:
-    
-MissingNullability: android.app.UiAutomation#revokeRuntimePermission(String, String, android.os.UserHandle) parameter #2:
-    
-MissingNullability: android.app.WallpaperManager#setWallpaperComponent(android.content.ComponentName) parameter #0:
-    
+    Missing nullability on method `getTimePicker` return
 MissingNullability: android.app.WindowConfiguration#compareTo(android.app.WindowConfiguration) parameter #0:
-    
+    Missing nullability on parameter `that` in method `compareTo`
 MissingNullability: android.app.WindowConfiguration#getAppBounds():
-    
+    Missing nullability on method `getAppBounds` return
 MissingNullability: android.app.WindowConfiguration#getBounds():
-    
+    Missing nullability on method `getBounds` return
 MissingNullability: android.app.WindowConfiguration#setAppBounds(android.graphics.Rect) parameter #0:
-    
+    Missing nullability on parameter `rect` in method `setAppBounds`
 MissingNullability: android.app.WindowConfiguration#setBounds(android.graphics.Rect) parameter #0:
-    
+    Missing nullability on parameter `rect` in method `setBounds`
 MissingNullability: android.app.WindowConfiguration#setTo(android.app.WindowConfiguration) parameter #0:
-    
+    Missing nullability on parameter `other` in method `setTo`
 MissingNullability: android.app.WindowConfiguration#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on parameter `dest` in method `writeToParcel`
 MissingNullability: android.app.admin.DevicePolicyManager#getOwnerInstalledCaCerts(android.os.UserHandle):
-    
+    Missing nullability on method `getOwnerInstalledCaCerts` return
 MissingNullability: android.app.admin.SecurityLog.SecurityEvent#SecurityEvent(long, byte[]) parameter #1:
-    
-MissingNullability: android.app.backup.BackupManager#getConfigurationIntent(String):
-    
-MissingNullability: android.app.backup.BackupManager#getConfigurationIntent(String) parameter #0:
-    
-MissingNullability: android.app.backup.BackupManager#getDataManagementIntent(String):
-    
-MissingNullability: android.app.backup.BackupManager#getDataManagementIntent(String) parameter #0:
-    
-MissingNullability: android.app.backup.BackupManager#getDestinationString(String):
-    
-MissingNullability: android.app.backup.BackupManager#getDestinationString(String) parameter #0:
-    
-MissingNullability: android.app.prediction.AppPredictionSessionId#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on parameter `data` in method `SecurityEvent`
 MissingNullability: android.app.prediction.AppPredictor#getSessionId():
-    
-MissingNullability: android.app.prediction.AppTarget#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.app.prediction.AppTargetEvent#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.app.prediction.AppTargetId#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on method `getSessionId` return
 MissingNullability: android.content.AutofillOptions#forWhitelistingItself():
-    
+    Missing nullability on method `forWhitelistingItself` return
 MissingNullability: android.content.AutofillOptions#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on parameter `parcel` in method `writeToParcel`
 MissingNullability: android.content.ContentCaptureOptions#forWhitelistingItself():
-    
+    Missing nullability on method `forWhitelistingItself` return
 MissingNullability: android.content.ContentCaptureOptions#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on parameter `parcel` in method `writeToParcel`
 MissingNullability: android.content.ContentResolver#getSyncAdapterPackagesForAuthorityAsUser(String, int):
-    
+    Missing nullability on method `getSyncAdapterPackagesForAuthorityAsUser` return
 MissingNullability: android.content.ContentResolver#getSyncAdapterPackagesForAuthorityAsUser(String, int) parameter #0:
-    
-MissingNullability: android.content.Context#getDisplay():
-    
-MissingNullability: android.content.Context#getUser():
-    
-MissingNullability: android.content.ContextWrapper#getDisplay():
-    
-MissingNullability: android.content.ContextWrapper#setContentCaptureOptions(android.content.ContentCaptureOptions) parameter #0:
-    
+    Missing nullability on parameter `authority` in method `getSyncAdapterPackagesForAuthorityAsUser`
 MissingNullability: android.content.pm.ActivityInfo#isTranslucentOrFloating(android.content.res.TypedArray) parameter #0:
-    
+    Missing nullability on parameter `attributes` in method `isTranslucentOrFloating`
 MissingNullability: android.content.pm.LauncherApps#LauncherApps(android.content.Context) parameter #0:
-    
-MissingNullability: android.content.pm.PackageInstaller.SessionParams#setGrantedRuntimePermissions(String[]) parameter #0:
-    
+    Missing nullability on parameter `context` in method `LauncherApps`
 MissingNullability: android.content.pm.PackageManager#getHoldLockToken():
-    Missing nullability on method `BINDER` return
+    Missing nullability on method `getHoldLockToken` return
 MissingNullability: android.content.pm.PackageManager#getNamesForUids(int[]) parameter #0:
-    
+    Missing nullability on parameter `uids` in method `getNamesForUids`
 MissingNullability: android.content.pm.PackageManager#holdLock(android.os.IBinder, int) parameter #0:
-    
+    Missing nullability on parameter `token` in method `holdLock`
 MissingNullability: android.content.pm.ShortcutManager#ShortcutManager(android.content.Context) parameter #0:
-    
+    Missing nullability on parameter `context` in method `ShortcutManager`
 MissingNullability: android.content.pm.UserInfo#UserInfo(android.content.pm.UserInfo) parameter #0:
     Missing nullability on parameter `orig` in method `UserInfo`
 MissingNullability: android.content.pm.UserInfo#UserInfo(int, String, String, int) parameter #1:
@@ -942,1469 +292,477 @@
 MissingNullability: android.content.pm.UserInfo#writeToParcel(android.os.Parcel, int) parameter #0:
     Missing nullability on parameter `dest` in method `writeToParcel`
 MissingNullability: android.content.res.AssetManager#getOverlayablesToString(String) parameter #0:
-    
+    Missing nullability on parameter `packageName` in method `getOverlayablesToString`
 MissingNullability: android.content.res.Configuration#windowConfiguration:
-    
-MissingNullability: android.content.rollback.PackageRollbackInfo#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.content.rollback.RollbackInfo#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on field `windowConfiguration` in class `class android.content.res.Configuration`
 MissingNullability: android.database.sqlite.SQLiteDebug#dump(android.util.Printer, String[]) parameter #0:
-    
+    Missing nullability on parameter `printer` in method `dump`
 MissingNullability: android.database.sqlite.SQLiteDebug#dump(android.util.Printer, String[]) parameter #1:
-    
+    Missing nullability on parameter `args` in method `dump`
 MissingNullability: android.database.sqlite.SQLiteDebug#getDatabaseInfo():
-    
+    Missing nullability on method `getDatabaseInfo` return
 MissingNullability: android.database.sqlite.SQLiteDebug.DbStats#DbStats(String, long, long, int, int, int, int) parameter #0:
-    
+    Missing nullability on parameter `dbName` in method `DbStats`
 MissingNullability: android.database.sqlite.SQLiteDebug.DbStats#cache:
-    
+    Missing nullability on field `cache` in class `class android.database.sqlite.SQLiteDebug.DbStats`
 MissingNullability: android.database.sqlite.SQLiteDebug.DbStats#dbName:
-    
+    Missing nullability on field `dbName` in class `class android.database.sqlite.SQLiteDebug.DbStats`
 MissingNullability: android.database.sqlite.SQLiteDebug.PagerStats#dbStats:
-    
+    Missing nullability on field `dbStats` in class `class android.database.sqlite.SQLiteDebug.PagerStats`
 MissingNullability: android.database.sqlite.SQLiteDirectCursorDriver#SQLiteDirectCursorDriver(android.database.sqlite.SQLiteDatabase, String, String, android.os.CancellationSignal) parameter #0:
-    
+    Missing nullability on parameter `db` in method `SQLiteDirectCursorDriver`
 MissingNullability: android.database.sqlite.SQLiteDirectCursorDriver#SQLiteDirectCursorDriver(android.database.sqlite.SQLiteDatabase, String, String, android.os.CancellationSignal) parameter #1:
-    
+    Missing nullability on parameter `sql` in method `SQLiteDirectCursorDriver`
 MissingNullability: android.database.sqlite.SQLiteDirectCursorDriver#SQLiteDirectCursorDriver(android.database.sqlite.SQLiteDatabase, String, String, android.os.CancellationSignal) parameter #2:
-    
+    Missing nullability on parameter `editTable` in method `SQLiteDirectCursorDriver`
 MissingNullability: android.database.sqlite.SQLiteDirectCursorDriver#SQLiteDirectCursorDriver(android.database.sqlite.SQLiteDatabase, String, String, android.os.CancellationSignal) parameter #3:
-    
+    Missing nullability on parameter `cancellationSignal` in method `SQLiteDirectCursorDriver`
 MissingNullability: android.database.sqlite.SQLiteDirectCursorDriver#cursorRequeried(android.database.Cursor) parameter #0:
-    
+    Missing nullability on parameter `cursor` in method `cursorRequeried`
 MissingNullability: android.database.sqlite.SQLiteDirectCursorDriver#query(android.database.sqlite.SQLiteDatabase.CursorFactory, String[]):
-    
+    Missing nullability on method `query` return
 MissingNullability: android.database.sqlite.SQLiteDirectCursorDriver#query(android.database.sqlite.SQLiteDatabase.CursorFactory, String[]) parameter #0:
-    
+    Missing nullability on parameter `factory` in method `query`
 MissingNullability: android.database.sqlite.SQLiteDirectCursorDriver#query(android.database.sqlite.SQLiteDatabase.CursorFactory, String[]) parameter #1:
-    
+    Missing nullability on parameter `selectionArgs` in method `query`
 MissingNullability: android.database.sqlite.SQLiteDirectCursorDriver#setBindArguments(String[]) parameter #0:
-    
+    Missing nullability on parameter `bindArgs` in method `setBindArguments`
 MissingNullability: android.database.sqlite.SQLiteGlobal#getDefaultJournalMode():
-    
+    Missing nullability on method `getDefaultJournalMode` return
 MissingNullability: android.database.sqlite.SQLiteGlobal#getDefaultSyncMode():
-    
+    Missing nullability on method `getDefaultSyncMode` return
 MissingNullability: android.database.sqlite.SQLiteGlobal#getWALSyncMode():
-    
+    Missing nullability on method `getWALSyncMode` return
 MissingNullability: android.graphics.ImageDecoder#createSource(android.content.res.Resources, java.io.InputStream, int) parameter #0:
-    
-MissingNullability: android.graphics.ImageDecoder#createSource(android.content.res.Resources, java.io.InputStream, int) parameter #1:
-    
+    Missing nullability on parameter `res` in method `createSource`
 MissingNullability: android.graphics.drawable.AdaptiveIconDrawable#getSafeZone():
-    
+    Missing nullability on method `getSafeZone` return
 MissingNullability: android.graphics.drawable.ColorDrawable#getXfermode():
-    
-MissingNullability: android.hardware.camera2.CameraDevice#createCustomCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.hardware.camera2.params.OutputConfiguration>, int, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) parameter #0:
-    
+    Missing nullability on method `getXfermode` return
 MissingNullability: android.hardware.camera2.CameraManager#getCameraIdListNoLazy():
-    
-MissingNullability: android.hardware.display.AmbientBrightnessDayStats#getBucketBoundaries():
-    
-MissingNullability: android.hardware.display.AmbientBrightnessDayStats#getLocalDate():
-    
-MissingNullability: android.hardware.display.AmbientBrightnessDayStats#getStats():
-    
-MissingNullability: android.hardware.display.AmbientBrightnessDayStats#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on method `getCameraIdListNoLazy` return
 MissingNullability: android.hardware.display.AmbientDisplayConfiguration#AmbientDisplayConfiguration(android.content.Context) parameter #0:
-    
-MissingNullability: android.hardware.display.BrightnessChangeEvent#luxTimestamps:
-    
-MissingNullability: android.hardware.display.BrightnessChangeEvent#luxValues:
-    
-MissingNullability: android.hardware.display.BrightnessChangeEvent#packageName:
-    
-MissingNullability: android.hardware.display.BrightnessChangeEvent#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.hardware.display.BrightnessConfiguration#getCurve():
-    
-MissingNullability: android.hardware.display.BrightnessConfiguration#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.hardware.display.BrightnessConfiguration.Builder#Builder(float[], float[]) parameter #0:
-    
-MissingNullability: android.hardware.display.BrightnessConfiguration.Builder#Builder(float[], float[]) parameter #1:
-    
-MissingNullability: android.hardware.display.BrightnessCorrection#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.hardware.display.DisplayManager#getAmbientBrightnessStats():
-    
-MissingNullability: android.hardware.display.DisplayManager#getBrightnessConfiguration():
-    
-MissingNullability: android.hardware.display.DisplayManager#getBrightnessEvents():
-    
-MissingNullability: android.hardware.display.DisplayManager#getStableDisplaySize():
-    
-MissingNullability: android.hardware.display.DisplayManager#setBrightnessConfiguration(android.hardware.display.BrightnessConfiguration) parameter #0:
-    
+    Missing nullability on parameter `context` in method `AmbientDisplayConfiguration`
 MissingNullability: android.location.GnssClock#set(android.location.GnssClock) parameter #0:
-    
+    Missing nullability on parameter `clock` in method `set`
 MissingNullability: android.location.GnssMeasurement#set(android.location.GnssMeasurement) parameter #0:
-    
-MissingNullability: android.location.GnssMeasurementsEvent#GnssMeasurementsEvent(android.location.GnssClock, android.location.GnssMeasurement[]) parameter #0:
-    
-MissingNullability: android.location.GnssMeasurementsEvent#GnssMeasurementsEvent(android.location.GnssClock, android.location.GnssMeasurement[]) parameter #1:
-    
+    Missing nullability on parameter `measurement` in method `set`
 MissingNullability: android.location.GnssNavigationMessage#set(android.location.GnssNavigationMessage) parameter #0:
-    
+    Missing nullability on parameter `navigationMessage` in method `set`
 MissingNullability: android.location.GnssNavigationMessage#setData(byte[]) parameter #0:
-    
-MissingNullability: android.location.LocationManager#getTestProviderCurrentRequests(String) parameter #0:
-    
-MissingNullability: android.location.LocationRequest#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.media.AudioAttributes#SDK_USAGES:
-    Missing nullability on field `SDK_USAGES` in class `class android.media.AudioAttributes`
+    Missing nullability on parameter `value` in method `setData`
 MissingNullability: android.media.AudioAttributes#getSdkUsages():
     Missing nullability on method `getSdkUsages` return
-MissingNullability: android.media.AudioFocusInfo#writeToParcel(android.os.Parcel, int) parameter #0:
-    
 MissingNullability: android.media.AudioManager#getPublicStreamTypes():
     Missing nullability on method `getPublicStreamTypes` return
 MissingNullability: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String) parameter #3:
-    
+    Missing nullability on parameter `clientFormat` in method `AudioRecordingConfiguration`
 MissingNullability: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String) parameter #4:
-    
+    Missing nullability on parameter `devFormat` in method `AudioRecordingConfiguration`
 MissingNullability: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String) parameter #6:
-    
+    Missing nullability on parameter `packageName` in method `AudioRecordingConfiguration`
 MissingNullability: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String, int, boolean, int, android.media.audiofx.AudioEffect.Descriptor[], android.media.audiofx.AudioEffect.Descriptor[]) parameter #10:
-    
+    Missing nullability on parameter `clientEffects` in method `AudioRecordingConfiguration`
 MissingNullability: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String, int, boolean, int, android.media.audiofx.AudioEffect.Descriptor[], android.media.audiofx.AudioEffect.Descriptor[]) parameter #11:
-    
+    Missing nullability on parameter `deviceEffects` in method `AudioRecordingConfiguration`
 MissingNullability: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String, int, boolean, int, android.media.audiofx.AudioEffect.Descriptor[], android.media.audiofx.AudioEffect.Descriptor[]) parameter #3:
-    
+    Missing nullability on parameter `clientFormat` in method `AudioRecordingConfiguration`
 MissingNullability: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String, int, boolean, int, android.media.audiofx.AudioEffect.Descriptor[], android.media.audiofx.AudioEffect.Descriptor[]) parameter #4:
-    
+    Missing nullability on parameter `devFormat` in method `AudioRecordingConfiguration`
 MissingNullability: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String, int, boolean, int, android.media.audiofx.AudioEffect.Descriptor[], android.media.audiofx.AudioEffect.Descriptor[]) parameter #6:
-    
-MissingNullability: android.media.AudioSystem#streamToString(int):
-    Missing nullability on method `streamToString` return
+    Missing nullability on parameter `packageName` in method `AudioRecordingConfiguration`
 MissingNullability: android.media.PlaybackParams#setAudioStretchMode(int):
-    
+    Missing nullability on method `setAudioStretchMode` return
 MissingNullability: android.media.audiofx.AudioEffect#EFFECT_TYPE_NULL:
-    
+    Missing nullability on field `EFFECT_TYPE_NULL` in class `class android.media.audiofx.AudioEffect`
 MissingNullability: android.media.audiofx.AudioEffect#byteArrayToInt(byte[]) parameter #0:
-    
+    Missing nullability on parameter `valueBuf` in method `byteArrayToInt`
 MissingNullability: android.media.audiofx.AudioEffect#byteArrayToShort(byte[]) parameter #0:
-    
+    Missing nullability on parameter `valueBuf` in method `byteArrayToShort`
 MissingNullability: android.media.audiofx.AudioEffect#getParameter(byte[], byte[]) parameter #0:
-    
+    Missing nullability on parameter `param` in method `getParameter`
 MissingNullability: android.media.audiofx.AudioEffect#getParameter(byte[], byte[]) parameter #1:
-    
+    Missing nullability on parameter `value` in method `getParameter`
 MissingNullability: android.media.audiofx.AudioEffect#getParameter(int, byte[]) parameter #1:
-    
+    Missing nullability on parameter `value` in method `getParameter`
 MissingNullability: android.media.audiofx.AudioEffect#getParameter(int, int[]) parameter #1:
-    
+    Missing nullability on parameter `value` in method `getParameter`
 MissingNullability: android.media.audiofx.AudioEffect#getParameter(int, short[]) parameter #1:
-    
+    Missing nullability on parameter `value` in method `getParameter`
 MissingNullability: android.media.audiofx.AudioEffect#getParameter(int[], short[]) parameter #0:
-    
+    Missing nullability on parameter `param` in method `getParameter`
 MissingNullability: android.media.audiofx.AudioEffect#getParameter(int[], short[]) parameter #1:
-    
+    Missing nullability on parameter `value` in method `getParameter`
 MissingNullability: android.media.audiofx.AudioEffect#intToByteArray(int):
-    
+    Missing nullability on method `intToByteArray` return
 MissingNullability: android.media.audiofx.AudioEffect#isEffectTypeAvailable(java.util.UUID) parameter #0:
-    
+    Missing nullability on parameter `type` in method `isEffectTypeAvailable`
 MissingNullability: android.media.audiofx.AudioEffect#setParameter(byte[], byte[]) parameter #0:
-    
+    Missing nullability on parameter `param` in method `setParameter`
 MissingNullability: android.media.audiofx.AudioEffect#setParameter(byte[], byte[]) parameter #1:
-    
+    Missing nullability on parameter `value` in method `setParameter`
 MissingNullability: android.media.audiofx.AudioEffect#setParameter(int, byte[]) parameter #1:
-    
+    Missing nullability on parameter `value` in method `setParameter`
 MissingNullability: android.media.audiofx.AudioEffect#setParameter(int[], byte[]) parameter #0:
-    
+    Missing nullability on parameter `param` in method `setParameter`
 MissingNullability: android.media.audiofx.AudioEffect#setParameter(int[], byte[]) parameter #1:
-    
+    Missing nullability on parameter `value` in method `setParameter`
 MissingNullability: android.media.audiofx.AudioEffect#setParameter(int[], int[]) parameter #0:
-    
+    Missing nullability on parameter `param` in method `setParameter`
 MissingNullability: android.media.audiofx.AudioEffect#setParameter(int[], int[]) parameter #1:
-    
+    Missing nullability on parameter `value` in method `setParameter`
 MissingNullability: android.media.audiofx.AudioEffect#setParameterListener(android.media.audiofx.AudioEffect.OnParameterChangeListener) parameter #0:
-    
+    Missing nullability on parameter `listener` in method `setParameterListener`
 MissingNullability: android.media.audiofx.AudioEffect#shortToByteArray(short):
-    
+    Missing nullability on method `shortToByteArray` return
 MissingNullability: android.media.audiofx.AudioEffect.Descriptor#Descriptor(android.os.Parcel) parameter #0:
-    
+    Missing nullability on parameter `in` in method `Descriptor`
 MissingNullability: android.media.audiofx.AudioEffect.Descriptor#writeToParcel(android.os.Parcel) parameter #0:
-    
+    Missing nullability on parameter `dest` in method `writeToParcel`
 MissingNullability: android.media.audiofx.AudioEffect.OnParameterChangeListener#onParameterChange(android.media.audiofx.AudioEffect, int, byte[], byte[]) parameter #0:
-    
+    Missing nullability on parameter `effect` in method `onParameterChange`
 MissingNullability: android.media.audiofx.AudioEffect.OnParameterChangeListener#onParameterChange(android.media.audiofx.AudioEffect, int, byte[], byte[]) parameter #2:
-    
+    Missing nullability on parameter `param` in method `onParameterChange`
 MissingNullability: android.media.audiofx.AudioEffect.OnParameterChangeListener#onParameterChange(android.media.audiofx.AudioEffect, int, byte[], byte[]) parameter #3:
-    
-MissingNullability: android.media.audiopolicy.AudioMix.Builder#Builder(android.media.audiopolicy.AudioMixingRule) parameter #0:
-    
-MissingNullability: android.media.audiopolicy.AudioMix.Builder#build():
-    
-MissingNullability: android.media.audiopolicy.AudioMix.Builder#setDevice(android.media.AudioDeviceInfo):
-    
-MissingNullability: android.media.audiopolicy.AudioMix.Builder#setFormat(android.media.AudioFormat):
-    
-MissingNullability: android.media.audiopolicy.AudioMix.Builder#setFormat(android.media.AudioFormat) parameter #0:
-    
-MissingNullability: android.media.audiopolicy.AudioMix.Builder#setRouteFlags(int):
-    
-MissingNullability: android.media.audiopolicy.AudioMixingRule.Builder#addMixRule(int, Object):
-    
-MissingNullability: android.media.audiopolicy.AudioMixingRule.Builder#addMixRule(int, Object) parameter #1:
-    
-MissingNullability: android.media.audiopolicy.AudioMixingRule.Builder#addRule(android.media.AudioAttributes, int):
-    
-MissingNullability: android.media.audiopolicy.AudioMixingRule.Builder#addRule(android.media.AudioAttributes, int) parameter #0:
-    
-MissingNullability: android.media.audiopolicy.AudioMixingRule.Builder#build():
-    
-MissingNullability: android.media.audiopolicy.AudioMixingRule.Builder#excludeMixRule(int, Object):
-    
-MissingNullability: android.media.audiopolicy.AudioMixingRule.Builder#excludeMixRule(int, Object) parameter #1:
-    
-MissingNullability: android.media.audiopolicy.AudioMixingRule.Builder#excludeRule(android.media.AudioAttributes, int):
-    
-MissingNullability: android.media.audiopolicy.AudioMixingRule.Builder#excludeRule(android.media.AudioAttributes, int) parameter #0:
-    
-MissingNullability: android.media.audiopolicy.AudioPolicy#createAudioRecordSink(android.media.audiopolicy.AudioMix):
-    
-MissingNullability: android.media.audiopolicy.AudioPolicy#createAudioRecordSink(android.media.audiopolicy.AudioMix) parameter #0:
-    
-MissingNullability: android.media.audiopolicy.AudioPolicy#createAudioTrackSource(android.media.audiopolicy.AudioMix):
-    
-MissingNullability: android.media.audiopolicy.AudioPolicy#createAudioTrackSource(android.media.audiopolicy.AudioMix) parameter #0:
-    
-MissingNullability: android.media.audiopolicy.AudioPolicy#setRegistration(String) parameter #0:
-    
-MissingNullability: android.media.audiopolicy.AudioPolicy#toLogFriendlyString():
-    
-MissingNullability: android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener#onAudioFocusAbandon(android.media.AudioFocusInfo) parameter #0:
-    
-MissingNullability: android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener#onAudioFocusGrant(android.media.AudioFocusInfo, int) parameter #0:
-    
-MissingNullability: android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener#onAudioFocusLoss(android.media.AudioFocusInfo, boolean) parameter #0:
-    
-MissingNullability: android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener#onAudioFocusRequest(android.media.AudioFocusInfo, int) parameter #0:
-    
-MissingNullability: android.media.audiopolicy.AudioPolicy.AudioPolicyStatusListener#onMixStateUpdate(android.media.audiopolicy.AudioMix) parameter #0:
-    
-MissingNullability: android.media.audiopolicy.AudioPolicy.Builder#Builder(android.content.Context) parameter #0:
-    
-MissingNullability: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyFocusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener) parameter #0:
-    
-MissingNullability: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyStatusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyStatusListener) parameter #0:
-    
-MissingNullability: android.metrics.LogMaker#LogMaker(Object[]) parameter #0:
-    
-MissingNullability: android.metrics.LogMaker#addTaggedData(int, Object):
-    
-MissingNullability: android.metrics.LogMaker#addTaggedData(int, Object) parameter #1:
-    
-MissingNullability: android.metrics.LogMaker#clearCategory():
-    
-MissingNullability: android.metrics.LogMaker#clearPackageName():
-    
-MissingNullability: android.metrics.LogMaker#clearSubtype():
-    
-MissingNullability: android.metrics.LogMaker#clearTaggedData(int):
-    
-MissingNullability: android.metrics.LogMaker#clearType():
-    
-MissingNullability: android.metrics.LogMaker#deserialize(Object[]) parameter #0:
-    
-MissingNullability: android.metrics.LogMaker#getCounterName():
-    
-MissingNullability: android.metrics.LogMaker#getPackageName():
-    
-MissingNullability: android.metrics.LogMaker#getTaggedData(int):
-    
-MissingNullability: android.metrics.LogMaker#isSubsetOf(android.metrics.LogMaker) parameter #0:
-    
-MissingNullability: android.metrics.LogMaker#isValidValue(Object) parameter #0:
-    
-MissingNullability: android.metrics.LogMaker#serialize():
-    
-MissingNullability: android.metrics.LogMaker#setCategory(int):
-    
-MissingNullability: android.metrics.LogMaker#setPackageName(String):
-    
-MissingNullability: android.metrics.LogMaker#setPackageName(String) parameter #0:
-    
-MissingNullability: android.metrics.LogMaker#setSubtype(int):
-    
-MissingNullability: android.metrics.LogMaker#setType(int):
-    
-MissingNullability: android.metrics.MetricsReader#next():
-    
-MissingNullability: android.net.NetworkCapabilities#getCapabilities():
-    
-MissingNullability: android.net.StaticIpConfiguration#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.net.TestNetworkInterface#CREATOR:
-    
-MissingNullability: android.net.TestNetworkInterface#TestNetworkInterface(android.os.ParcelFileDescriptor, String) parameter #0:
-    
-MissingNullability: android.net.TestNetworkInterface#TestNetworkInterface(android.os.ParcelFileDescriptor, String) parameter #1:
-    
-MissingNullability: android.net.TestNetworkInterface#getFileDescriptor():
-    
-MissingNullability: android.net.TestNetworkInterface#getInterfaceName():
-    
-MissingNullability: android.net.TestNetworkInterface#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.net.TestNetworkManager#createTapInterface():
-    
-MissingNullability: android.net.TestNetworkManager#createTunInterface(android.net.LinkAddress[]):
-    
-MissingNullability: android.net.apf.ApfCapabilities#CREATOR:
-    
-MissingNullability: android.net.apf.ApfCapabilities#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.net.metrics.DhcpClientEvent.Builder#setMsg(String) parameter #0:
-    
+    Missing nullability on parameter `value` in method `onParameterChange`
 MissingNullability: android.os.Build#is64BitAbi(String) parameter #0:
-    
+    Missing nullability on parameter `abi` in method `is64BitAbi`
 MissingNullability: android.os.Build.VERSION#ACTIVE_CODENAMES:
-    
+    Missing nullability on field `ACTIVE_CODENAMES` in class `class android.os.Build.VERSION`
 MissingNullability: android.os.Environment#buildPath(java.io.File, java.lang.String...):
-    
+    Missing nullability on method `buildPath` return
 MissingNullability: android.os.Environment#buildPath(java.io.File, java.lang.String...) parameter #0:
-    
+    Missing nullability on parameter `base` in method `buildPath`
 MissingNullability: android.os.Environment#buildPath(java.io.File, java.lang.String...) parameter #1:
-    
+    Missing nullability on parameter `segments` in method `buildPath`
 MissingNullability: android.os.FileUtils#contains(java.io.File, java.io.File) parameter #0:
-    
+    Missing nullability on parameter `dir` in method `contains`
 MissingNullability: android.os.FileUtils#contains(java.io.File, java.io.File) parameter #1:
-    
-MissingNullability: android.os.HwBinder#getService(String, String):
-    
-MissingNullability: android.os.HwBinder#getService(String, String) parameter #0:
-    
-MissingNullability: android.os.HwBinder#getService(String, String) parameter #1:
-    
-MissingNullability: android.os.HwBinder#getService(String, String, boolean):
-    
-MissingNullability: android.os.HwBinder#getService(String, String, boolean) parameter #0:
-    
-MissingNullability: android.os.HwBinder#getService(String, String, boolean) parameter #1:
-    
-MissingNullability: android.os.HwBinder#onTransact(int, android.os.HwParcel, android.os.HwParcel, int) parameter #1:
-    
-MissingNullability: android.os.HwBinder#onTransact(int, android.os.HwParcel, android.os.HwParcel, int) parameter #2:
-    
-MissingNullability: android.os.HwBinder#registerService(String) parameter #0:
-    
-MissingNullability: android.os.HwBinder#transact(int, android.os.HwParcel, android.os.HwParcel, int) parameter #1:
-    
-MissingNullability: android.os.HwBinder#transact(int, android.os.HwParcel, android.os.HwParcel, int) parameter #2:
-    
-MissingNullability: android.os.HwBlob#copyToBoolArray(long, boolean[], int) parameter #1:
-    
-MissingNullability: android.os.HwBlob#copyToDoubleArray(long, double[], int) parameter #1:
-    
-MissingNullability: android.os.HwBlob#copyToFloatArray(long, float[], int) parameter #1:
-    
-MissingNullability: android.os.HwBlob#copyToInt16Array(long, short[], int) parameter #1:
-    
-MissingNullability: android.os.HwBlob#copyToInt32Array(long, int[], int) parameter #1:
-    
-MissingNullability: android.os.HwBlob#copyToInt64Array(long, long[], int) parameter #1:
-    
-MissingNullability: android.os.HwBlob#copyToInt8Array(long, byte[], int) parameter #1:
-    
-MissingNullability: android.os.HwBlob#getString(long):
-    
-MissingNullability: android.os.HwBlob#putBlob(long, android.os.HwBlob) parameter #1:
-    
-MissingNullability: android.os.HwBlob#putBoolArray(long, boolean[]) parameter #1:
-    
-MissingNullability: android.os.HwBlob#putDoubleArray(long, double[]) parameter #1:
-    
-MissingNullability: android.os.HwBlob#putFloatArray(long, float[]) parameter #1:
-    
-MissingNullability: android.os.HwBlob#putInt16Array(long, short[]) parameter #1:
-    
-MissingNullability: android.os.HwBlob#putInt32Array(long, int[]) parameter #1:
-    
-MissingNullability: android.os.HwBlob#putInt64Array(long, long[]) parameter #1:
-    
-MissingNullability: android.os.HwBlob#putInt8Array(long, byte[]) parameter #1:
-    
-MissingNullability: android.os.HwBlob#putString(long, String) parameter #1:
-    
-MissingNullability: android.os.HwBlob#wrapArray(boolean[]):
-    
-MissingNullability: android.os.HwBlob#wrapArray(byte[]):
-    
-MissingNullability: android.os.HwBlob#wrapArray(double[]):
-    
-MissingNullability: android.os.HwBlob#wrapArray(float[]):
-    
-MissingNullability: android.os.HwBlob#wrapArray(int[]):
-    
-MissingNullability: android.os.HwBlob#wrapArray(long[]):
-    
-MissingNullability: android.os.HwBlob#wrapArray(short[]):
-    
-MissingNullability: android.os.HwParcel#enforceInterface(String) parameter #0:
-    
-MissingNullability: android.os.HwParcel#readBoolVector():
-    
-MissingNullability: android.os.HwParcel#readBuffer(long):
-    
-MissingNullability: android.os.HwParcel#readDoubleVector():
-    
-MissingNullability: android.os.HwParcel#readEmbeddedBuffer(long, long, long, boolean):
-    
-MissingNullability: android.os.HwParcel#readFloatVector():
-    
-MissingNullability: android.os.HwParcel#readInt16Vector():
-    
-MissingNullability: android.os.HwParcel#readInt32Vector():
-    
-MissingNullability: android.os.HwParcel#readInt64Vector():
-    
-MissingNullability: android.os.HwParcel#readInt8Vector():
-    
-MissingNullability: android.os.HwParcel#readString():
-    
-MissingNullability: android.os.HwParcel#readStringVector():
-    
-MissingNullability: android.os.HwParcel#readStrongBinder():
-    
-MissingNullability: android.os.HwParcel#writeBoolVector(java.util.ArrayList<java.lang.Boolean>) parameter #0:
-    
-MissingNullability: android.os.HwParcel#writeBuffer(android.os.HwBlob) parameter #0:
-    
-MissingNullability: android.os.HwParcel#writeDoubleVector(java.util.ArrayList<java.lang.Double>) parameter #0:
-    
-MissingNullability: android.os.HwParcel#writeFloatVector(java.util.ArrayList<java.lang.Float>) parameter #0:
-    
-MissingNullability: android.os.HwParcel#writeInt16Vector(java.util.ArrayList<java.lang.Short>) parameter #0:
-    
-MissingNullability: android.os.HwParcel#writeInt32Vector(java.util.ArrayList<java.lang.Integer>) parameter #0:
-    
-MissingNullability: android.os.HwParcel#writeInt64Vector(java.util.ArrayList<java.lang.Long>) parameter #0:
-    
-MissingNullability: android.os.HwParcel#writeInt8Vector(java.util.ArrayList<java.lang.Byte>) parameter #0:
-    
-MissingNullability: android.os.HwParcel#writeInterfaceToken(String) parameter #0:
-    
-MissingNullability: android.os.HwParcel#writeString(String) parameter #0:
-    
-MissingNullability: android.os.HwParcel#writeStringVector(java.util.ArrayList<java.lang.String>) parameter #0:
-    
-MissingNullability: android.os.HwParcel#writeStrongBinder(android.os.IHwBinder) parameter #0:
-    
-MissingNullability: android.os.IHwBinder#linkToDeath(android.os.IHwBinder.DeathRecipient, long) parameter #0:
-    
-MissingNullability: android.os.IHwBinder#queryLocalInterface(String):
-    
-MissingNullability: android.os.IHwBinder#queryLocalInterface(String) parameter #0:
-    
-MissingNullability: android.os.IHwBinder#transact(int, android.os.HwParcel, android.os.HwParcel, int) parameter #1:
-    
-MissingNullability: android.os.IHwBinder#transact(int, android.os.HwParcel, android.os.HwParcel, int) parameter #2:
-    
-MissingNullability: android.os.IHwBinder#unlinkToDeath(android.os.IHwBinder.DeathRecipient) parameter #0:
-    
-MissingNullability: android.os.IHwInterface#asBinder():
-    
-MissingNullability: android.os.IncidentManager#approveReport(android.net.Uri) parameter #0:
-    
-MissingNullability: android.os.IncidentManager#cancelAuthorization(android.os.IncidentManager.AuthListener) parameter #0:
-    
-MissingNullability: android.os.IncidentManager#deleteIncidentReports(android.net.Uri) parameter #0:
-    
-MissingNullability: android.os.IncidentManager#denyReport(android.net.Uri) parameter #0:
-    
-MissingNullability: android.os.IncidentManager#getIncidentReport(android.net.Uri) parameter #0:
-    
-MissingNullability: android.os.IncidentManager#getIncidentReportList(String) parameter #0:
-    
-MissingNullability: android.os.IncidentManager#getPendingReports():
-    
-MissingNullability: android.os.IncidentManager#reportIncident(android.os.IncidentReportArgs) parameter #0:
-    
-MissingNullability: android.os.IncidentManager#requestAuthorization(int, String, int, android.os.IncidentManager.AuthListener) parameter #1:
-    
-MissingNullability: android.os.IncidentManager#requestAuthorization(int, String, int, android.os.IncidentManager.AuthListener) parameter #3:
-    
-MissingNullability: android.os.IncidentManager.IncidentReport#IncidentReport(android.os.Parcel) parameter #0:
-    
-MissingNullability: android.os.IncidentManager.IncidentReport#getInputStream():
-    
-MissingNullability: android.os.IncidentManager.IncidentReport#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.os.IncidentReportArgs#IncidentReportArgs(android.os.Parcel) parameter #0:
-    
-MissingNullability: android.os.IncidentReportArgs#addHeader(byte[]) parameter #0:
-    
-MissingNullability: android.os.IncidentReportArgs#readFromParcel(android.os.Parcel) parameter #0:
-    
-MissingNullability: android.os.IncidentReportArgs#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on parameter `file` in method `contains`
 MissingNullability: android.os.ParcelFileDescriptor#getFile(java.io.FileDescriptor):
-    
+    Missing nullability on method `getFile` return
 MissingNullability: android.os.ParcelFileDescriptor#getFile(java.io.FileDescriptor) parameter #0:
-    
-MissingNullability: android.os.RemoteCallback#RemoteCallback(android.os.RemoteCallback.OnResultListener) parameter #0:
-    
-MissingNullability: android.os.RemoteCallback#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on parameter `fd` in method `getFile`
 MissingNullability: android.os.StrictMode#setViolationLogger(android.os.StrictMode.ViolationLogger) parameter #0:
-    
+    Missing nullability on parameter `listener` in method `setViolationLogger`
 MissingNullability: android.os.StrictMode.ViolationInfo#ViolationInfo(android.os.Parcel) parameter #0:
-    
+    Missing nullability on parameter `in` in method `ViolationInfo`
 MissingNullability: android.os.StrictMode.ViolationInfo#ViolationInfo(android.os.Parcel, boolean) parameter #0:
-    
+    Missing nullability on parameter `in` in method `ViolationInfo`
 MissingNullability: android.os.StrictMode.ViolationInfo#broadcastIntentAction:
-    
+    Missing nullability on field `broadcastIntentAction` in class `class android.os.StrictMode.ViolationInfo`
 MissingNullability: android.os.StrictMode.ViolationInfo#dump(android.util.Printer, String) parameter #0:
-    
+    Missing nullability on parameter `pw` in method `dump`
 MissingNullability: android.os.StrictMode.ViolationInfo#dump(android.util.Printer, String) parameter #1:
-    
+    Missing nullability on parameter `prefix` in method `dump`
 MissingNullability: android.os.StrictMode.ViolationInfo#getStackTrace():
-    
+    Missing nullability on method `getStackTrace` return
 MissingNullability: android.os.StrictMode.ViolationInfo#getViolationClass():
-    
+    Missing nullability on method `getViolationClass` return
 MissingNullability: android.os.StrictMode.ViolationInfo#getViolationDetails():
-    
+    Missing nullability on method `getViolationDetails` return
 MissingNullability: android.os.StrictMode.ViolationInfo#tags:
-    
+    Missing nullability on field `tags` in class `class android.os.StrictMode.ViolationInfo`
 MissingNullability: android.os.StrictMode.ViolationInfo#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on parameter `dest` in method `writeToParcel`
 MissingNullability: android.os.StrictMode.ViolationLogger#log(android.os.StrictMode.ViolationInfo) parameter #0:
-    
-MissingNullability: android.os.UserHandle#of(int):
-    
+    Missing nullability on parameter `info` in method `log`
 MissingNullability: android.os.VibrationEffect#RINGTONES:
-    
+    Missing nullability on field `RINGTONES` in class `class android.os.VibrationEffect`
 MissingNullability: android.os.VibrationEffect#get(android.net.Uri, android.content.Context) parameter #0:
-    
+    Missing nullability on parameter `uri` in method `get`
 MissingNullability: android.os.VibrationEffect#get(android.net.Uri, android.content.Context) parameter #1:
-    
+    Missing nullability on parameter `context` in method `get`
 MissingNullability: android.os.VibrationEffect#get(int):
-    
+    Missing nullability on method `get` return
 MissingNullability: android.os.VibrationEffect#get(int, boolean):
-    
+    Missing nullability on method `get` return
 MissingNullability: android.os.VintfObject#getHalNamesAndVersions():
-    
+    Missing nullability on method `getHalNamesAndVersions` return
 MissingNullability: android.os.VintfObject#getSepolicyVersion():
-    
+    Missing nullability on method `getSepolicyVersion` return
 MissingNullability: android.os.VintfObject#getTargetFrameworkCompatibilityMatrixVersion():
-    
+    Missing nullability on method `getTargetFrameworkCompatibilityMatrixVersion` return
 MissingNullability: android.os.VintfObject#getVndkSnapshots():
-    
+    Missing nullability on method `getVndkSnapshots` return
 MissingNullability: android.os.VintfObject#report():
-    
+    Missing nullability on method `report` return
 MissingNullability: android.os.VintfRuntimeInfo#getCpuInfo():
-    
+    Missing nullability on method `getCpuInfo` return
 MissingNullability: android.os.VintfRuntimeInfo#getHardwareId():
-    
+    Missing nullability on method `getHardwareId` return
 MissingNullability: android.os.VintfRuntimeInfo#getKernelVersion():
-    
+    Missing nullability on method `getKernelVersion` return
 MissingNullability: android.os.VintfRuntimeInfo#getNodeName():
-    
+    Missing nullability on method `getNodeName` return
 MissingNullability: android.os.VintfRuntimeInfo#getOsName():
-    
+    Missing nullability on method `getOsName` return
 MissingNullability: android.os.VintfRuntimeInfo#getOsRelease():
-    
+    Missing nullability on method `getOsRelease` return
 MissingNullability: android.os.VintfRuntimeInfo#getOsVersion():
-    
+    Missing nullability on method `getOsVersion` return
 MissingNullability: android.os.WorkSource#add(int, String) parameter #1:
-    
-MissingNullability: android.os.WorkSource#addReturningNewbs(android.os.WorkSource) parameter #0:
-    
-MissingNullability: android.os.WorkSource#getName(int):
-    
-MissingNullability: android.os.WorkSource#setReturningDiffs(android.os.WorkSource) parameter #0:
-    
+    Missing nullability on parameter `name` in method `add`
 MissingNullability: android.os.health.HealthKeys.Constants#Constants(Class) parameter #0:
-    
+    Missing nullability on parameter `clazz` in method `Constants`
 MissingNullability: android.os.health.HealthKeys.Constants#getDataType():
-    
+    Missing nullability on method `getDataType` return
 MissingNullability: android.os.health.HealthKeys.Constants#getKeys(int):
-    
+    Missing nullability on method `getKeys` return
 MissingNullability: android.os.health.HealthStats#HealthStats(android.os.Parcel) parameter #0:
-    
+    Missing nullability on parameter `in` in method `HealthStats`
 MissingNullability: android.os.health.HealthStatsParceler#HealthStatsParceler(android.os.Parcel) parameter #0:
-    
+    Missing nullability on parameter `in` in method `HealthStatsParceler`
 MissingNullability: android.os.health.HealthStatsParceler#HealthStatsParceler(android.os.health.HealthStatsWriter) parameter #0:
-    
+    Missing nullability on parameter `writer` in method `HealthStatsParceler`
 MissingNullability: android.os.health.HealthStatsParceler#getHealthStats():
-    
+    Missing nullability on method `getHealthStats` return
 MissingNullability: android.os.health.HealthStatsParceler#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on parameter `out` in method `writeToParcel`
 MissingNullability: android.os.health.HealthStatsWriter#HealthStatsWriter(android.os.health.HealthKeys.Constants) parameter #0:
-    
+    Missing nullability on parameter `constants` in method `HealthStatsWriter`
 MissingNullability: android.os.health.HealthStatsWriter#addMeasurements(int, String, long) parameter #1:
-    
+    Missing nullability on parameter `name` in method `addMeasurements`
 MissingNullability: android.os.health.HealthStatsWriter#addStats(int, String, android.os.health.HealthStatsWriter) parameter #1:
-    
+    Missing nullability on parameter `name` in method `addStats`
 MissingNullability: android.os.health.HealthStatsWriter#addStats(int, String, android.os.health.HealthStatsWriter) parameter #2:
-    
+    Missing nullability on parameter `value` in method `addStats`
 MissingNullability: android.os.health.HealthStatsWriter#addTimers(int, String, android.os.health.TimerStat) parameter #1:
-    
+    Missing nullability on parameter `name` in method `addTimers`
 MissingNullability: android.os.health.HealthStatsWriter#addTimers(int, String, android.os.health.TimerStat) parameter #2:
-    
+    Missing nullability on parameter `value` in method `addTimers`
 MissingNullability: android.os.health.HealthStatsWriter#flattenToParcel(android.os.Parcel) parameter #0:
-    
+    Missing nullability on parameter `out` in method `flattenToParcel`
 MissingNullability: android.os.storage.StorageVolume#getPath():
-    
-MissingNullability: android.permission.RuntimePermissionPresentationInfo#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on method `getPath` return
 MissingNullability: android.provider.CalendarContract.Calendars#SYNC_WRITABLE_COLUMNS:
-    
+    Missing nullability on field `SYNC_WRITABLE_COLUMNS` in class `class android.provider.CalendarContract.Calendars`
 MissingNullability: android.provider.CalendarContract.Events#SYNC_WRITABLE_COLUMNS:
-    
-MissingNullability: android.provider.ContactsContract.CommonDataKinds.Phone#ENTERPRISE_CONTENT_URI:
-    
+    Missing nullability on field `SYNC_WRITABLE_COLUMNS` in class `class android.provider.CalendarContract.Events`
 MissingNullability: android.provider.ContactsContract.RawContactsEntity#CORP_CONTENT_URI:
-    
-MissingNullability: android.provider.DeviceConfig#getProperty(String, String):
-    
-MissingNullability: android.provider.DeviceConfig#getString(String, String, String):
-    
-MissingNullability: android.provider.MediaStore#deleteContributedMedia(android.content.Context, String, android.os.UserHandle) parameter #0:
-    
-MissingNullability: android.provider.MediaStore#deleteContributedMedia(android.content.Context, String, android.os.UserHandle) parameter #1:
-    
-MissingNullability: android.provider.MediaStore#deleteContributedMedia(android.content.Context, String, android.os.UserHandle) parameter #2:
-    
-MissingNullability: android.provider.MediaStore#getContributedMediaSize(android.content.Context, String, android.os.UserHandle) parameter #0:
-    
-MissingNullability: android.provider.MediaStore#getContributedMediaSize(android.content.Context, String, android.os.UserHandle) parameter #1:
-    
-MissingNullability: android.provider.MediaStore#getContributedMediaSize(android.content.Context, String, android.os.UserHandle) parameter #2:
-    
-MissingNullability: android.provider.MediaStore#scanFile(android.content.Context, java.io.File):
-    
-MissingNullability: android.provider.MediaStore#scanFile(android.content.Context, java.io.File) parameter #0:
-    
-MissingNullability: android.provider.MediaStore#scanFile(android.content.Context, java.io.File) parameter #1:
-    
-MissingNullability: android.provider.MediaStore#scanFileFromShell(android.content.Context, java.io.File):
-    
-MissingNullability: android.provider.MediaStore#scanFileFromShell(android.content.Context, java.io.File) parameter #0:
-    
-MissingNullability: android.provider.MediaStore#scanFileFromShell(android.content.Context, java.io.File) parameter #1:
-    
-MissingNullability: android.provider.MediaStore#scanVolume(android.content.Context, java.io.File) parameter #0:
-    
-MissingNullability: android.provider.MediaStore#scanVolume(android.content.Context, java.io.File) parameter #1:
-    
-MissingNullability: android.provider.MediaStore#waitForIdle(android.content.Context) parameter #0:
-    
-MissingNullability: android.security.KeyStoreException#KeyStoreException(int, String) parameter #1:
-    
-MissingNullability: android.security.keystore.AttestationUtils#attestDeviceIds(android.content.Context, int[], byte[]) parameter #0:
-    
+    Missing nullability on field `CORP_CONTENT_URI` in class `class android.provider.ContactsContract.RawContactsEntity`
 MissingNullability: android.security.keystore.KeyProtection.Builder#setBoundToSpecificSecureUserId(long):
-    
-MissingNullability: android.service.autofill.AutofillFieldClassificationService#onBind(android.content.Intent):
-    
-MissingNullability: android.service.autofill.AutofillFieldClassificationService#onBind(android.content.Intent) parameter #0:
-    
+    Missing nullability on method `setBoundToSpecificSecureUserId` return
 MissingNullability: android.service.autofill.CompositeUserData#getCategoryIds():
-    
+    Missing nullability on method `getCategoryIds` return
 MissingNullability: android.service.autofill.CompositeUserData#getDefaultFieldClassificationArgs():
-    
+    Missing nullability on method `getDefaultFieldClassificationArgs` return
 MissingNullability: android.service.autofill.CompositeUserData#getFieldClassificationAlgorithms():
-    
+    Missing nullability on method `getFieldClassificationAlgorithms` return
 MissingNullability: android.service.autofill.CompositeUserData#getFieldClassificationArgs():
-    
+    Missing nullability on method `getFieldClassificationArgs` return
 MissingNullability: android.service.autofill.CompositeUserData#getValues():
-    
+    Missing nullability on method `getValues` return
 MissingNullability: android.service.autofill.CompositeUserData#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on parameter `parcel` in method `writeToParcel`
 MissingNullability: android.service.autofill.UserData#getFieldClassificationAlgorithms():
-    
-MissingNullability: android.service.autofill.augmented.AugmentedAutofillService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0:
-    
-MissingNullability: android.service.autofill.augmented.AugmentedAutofillService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #1:
-    
-MissingNullability: android.service.autofill.augmented.AugmentedAutofillService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #2:
-    
-MissingNullability: android.service.autofill.augmented.AugmentedAutofillService#onUnbind(android.content.Intent) parameter #0:
-    
-MissingNullability: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0:
-    
-MissingNullability: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #1:
-    
-MissingNullability: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #2:
-    
-MissingNullability: android.service.notification.Adjustment#Adjustment(String, String, android.os.Bundle, CharSequence, int) parameter #0:
-    
-MissingNullability: android.service.notification.Adjustment#Adjustment(String, String, android.os.Bundle, CharSequence, int) parameter #1:
-    
-MissingNullability: android.service.notification.Adjustment#Adjustment(String, String, android.os.Bundle, CharSequence, int) parameter #2:
-    
-MissingNullability: android.service.notification.Adjustment#Adjustment(String, String, android.os.Bundle, CharSequence, int) parameter #3:
-    
-MissingNullability: android.service.notification.Adjustment#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.service.notification.NotificationAssistantService#attachBaseContext(android.content.Context) parameter #0:
-    
-MissingNullability: android.service.notification.NotificationStats#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.service.notification.SnoozeCriterion#SnoozeCriterion(String, CharSequence, CharSequence) parameter #0:
-    
-MissingNullability: android.service.notification.SnoozeCriterion#SnoozeCriterion(String, CharSequence, CharSequence) parameter #1:
-    
-MissingNullability: android.service.notification.SnoozeCriterion#SnoozeCriterion(String, CharSequence, CharSequence) parameter #2:
-    
-MissingNullability: android.service.notification.SnoozeCriterion#SnoozeCriterion(android.os.Parcel) parameter #0:
-    
-MissingNullability: android.service.notification.SnoozeCriterion#getConfirmation():
-    
-MissingNullability: android.service.notification.SnoozeCriterion#getExplanation():
-    
-MissingNullability: android.service.notification.SnoozeCriterion#getId():
-    
-MissingNullability: android.service.notification.SnoozeCriterion#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on method `getFieldClassificationAlgorithms` return
 MissingNullability: android.telecom.Call.Details#getTelecomCallId():
-    
-MissingNullability: android.telecom.CallScreeningService.CallResponse.Builder#setShouldScreenCallFurther(boolean):
-    
-MissingNullability: android.telecom.Conference#getPrimaryConnection():
-    
-MissingNullability: android.telecom.PhoneAccountSuggestionService#onBind(android.content.Intent):
-    
-MissingNullability: android.telecom.PhoneAccountSuggestionService#onBind(android.content.Intent) parameter #0:
-    
-MissingNullability: android.telephony.CallQuality#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.DataSpecificRegistrationInfo#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.LteVopsSupportInfo#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.NetworkRegistrationInfo#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on method `getTelecomCallId` return
 MissingNullability: android.telephony.ServiceState#addNetworkRegistrationInfo(android.telephony.NetworkRegistrationInfo) parameter #0:
-    
+    Missing nullability on parameter `nri` in method `addNetworkRegistrationInfo`
 MissingNullability: android.telephony.ServiceState#setCellBandwidths(int[]) parameter #0:
-    
+    Missing nullability on parameter `bandwidths` in method `setCellBandwidths`
 MissingNullability: android.telephony.SmsManager#checkSmsShortCodeDestination(String, String) parameter #0:
-    
+    Missing nullability on parameter `destAddress` in method `checkSmsShortCodeDestination`
 MissingNullability: android.telephony.SmsManager#checkSmsShortCodeDestination(String, String) parameter #1:
-    
-MissingNullability: android.telephony.TelephonyManager#checkCarrierPrivilegesForPackage(String) parameter #0:
-    
-MissingNullability: android.telephony.TelephonyManager#getCarrierPackageNamesForIntent(android.content.Intent):
-    
-MissingNullability: android.telephony.TelephonyManager#getCarrierPackageNamesForIntent(android.content.Intent) parameter #0:
-    
+    Missing nullability on parameter `countryIso` in method `checkSmsShortCodeDestination`
 MissingNullability: android.telephony.TelephonyManager#getLine1AlphaTag():
-    
+    Missing nullability on method `getLine1AlphaTag` return
 MissingNullability: android.telephony.TelephonyManager#getRadioHalVersion():
-    
-MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String) parameter #0:
-    
-MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String) parameter #1:
-    
-MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String) parameter #2:
-    
-MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String) parameter #3:
-    
-MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String) parameter #4:
-    
-MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String) parameter #5:
-    
-MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String) parameter #6:
-    
+    Missing nullability on method `getRadioHalVersion` return
 MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #0:
-    
+    Missing nullability on parameter `mccmnc` in method `setCarrierTestOverride`
 MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #1:
-    
+    Missing nullability on parameter `imsi` in method `setCarrierTestOverride`
 MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #2:
-    
+    Missing nullability on parameter `iccid` in method `setCarrierTestOverride`
 MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #3:
-    
+    Missing nullability on parameter `gid1` in method `setCarrierTestOverride`
 MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #4:
-    
+    Missing nullability on parameter `gid2` in method `setCarrierTestOverride`
 MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #5:
-    
+    Missing nullability on parameter `plmn` in method `setCarrierTestOverride`
 MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #6:
-    
+    Missing nullability on parameter `spn` in method `setCarrierTestOverride`
 MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #7:
-    
+    Missing nullability on parameter `carrierPriviledgeRules` in method `setCarrierTestOverride`
 MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #8:
-    
-MissingNullability: android.telephony.ims.ImsCallForwardInfo#getNumber():
-    
-MissingNullability: android.telephony.ims.ImsCallForwardInfo#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#ImsCallProfile(int, int, android.os.Bundle, android.telephony.ims.ImsStreamMediaProfile) parameter #2:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#ImsCallProfile(int, int, android.os.Bundle, android.telephony.ims.ImsStreamMediaProfile) parameter #3:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtra(String):
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtra(String) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtra(String, String):
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtra(String, String) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtra(String, String) parameter #1:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtraBoolean(String) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtraBoolean(String, boolean) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtraInt(String) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtraInt(String, int) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtras():
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#getMediaProfile():
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#getVideoStateFromImsCallProfile(android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#setCallExtra(String, String) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#setCallExtra(String, String) parameter #1:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#setCallExtraBoolean(String, boolean) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#setCallExtraInt(String, int) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#updateCallExtras(android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#updateCallType(android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#updateMediaProfile(android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionConferenceExtendFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionConferenceExtendReceived(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionConferenceExtendReceived(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile) parameter #1:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionConferenceExtended(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionConferenceExtended(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile) parameter #1:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionConferenceStateUpdated(android.telephony.ims.ImsConferenceState) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionHandover(int, int, android.telephony.ims.ImsReasonInfo) parameter #2:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionHandoverFailed(int, int, android.telephony.ims.ImsReasonInfo) parameter #2:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionHeld(android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionHoldFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionHoldReceived(android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionInitiated(android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionInitiatedFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionInviteParticipantsRequestFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionMergeComplete(android.telephony.ims.stub.ImsCallSessionImplBase) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionMergeFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionMergeStarted(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionMergeStarted(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile) parameter #1:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionProgressing(android.telephony.ims.ImsStreamMediaProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionRemoveParticipantsRequestFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionResumeFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionResumeReceived(android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionResumed(android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionRttMessageReceived(String) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionRttModifyRequestReceived(android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionSuppServiceReceived(android.telephony.ims.ImsSuppServiceNotification) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionTerminated(android.telephony.ims.ImsReasonInfo) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionUpdateFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionUpdateReceived(android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionUpdated(android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionUssdMessageReceived(int, String) parameter #1:
-    
-MissingNullability: android.telephony.ims.ImsConferenceState#getConnectionStateForStatus(String) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsConferenceState#mParticipants:
-    
-MissingNullability: android.telephony.ims.ImsConferenceState#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsExternalCallState#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsReasonInfo#ImsReasonInfo(int, int, String) parameter #2:
-    
-MissingNullability: android.telephony.ims.ImsReasonInfo#getExtraMessage():
-    
-MissingNullability: android.telephony.ims.ImsReasonInfo#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsService#createMmTelFeature(int):
-    
-MissingNullability: android.telephony.ims.ImsService#createRcsFeature(int):
-    
-MissingNullability: android.telephony.ims.ImsService#getConfig(int):
-    
-MissingNullability: android.telephony.ims.ImsService#getRegistration(int):
-    
-MissingNullability: android.telephony.ims.ImsService#onUpdateSupportedImsFeatures(android.telephony.ims.stub.ImsFeatureConfiguration) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsService#querySupportedImsFeatures():
-    
-MissingNullability: android.telephony.ims.ImsSsData#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsSsInfo#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsStreamMediaProfile#copyFrom(android.telephony.ims.ImsStreamMediaProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsStreamMediaProfile#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsSuppServiceNotification#ImsSuppServiceNotification(int, int, int, int, String, String[]) parameter #4:
-    
-MissingNullability: android.telephony.ims.ImsSuppServiceNotification#ImsSuppServiceNotification(int, int, int, int, String, String[]) parameter #5:
-    
-MissingNullability: android.telephony.ims.ImsSuppServiceNotification#history:
-    
-MissingNullability: android.telephony.ims.ImsSuppServiceNotification#number:
-    
-MissingNullability: android.telephony.ims.ImsSuppServiceNotification#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsUtListener#onSupplementaryServiceIndication(android.telephony.ims.ImsSsData) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsUtListener#onUtConfigurationCallBarringQueried(int, android.telephony.ims.ImsSsInfo[]) parameter #1:
-    
-MissingNullability: android.telephony.ims.ImsUtListener#onUtConfigurationCallForwardQueried(int, android.telephony.ims.ImsCallForwardInfo[]) parameter #1:
-    
-MissingNullability: android.telephony.ims.ImsUtListener#onUtConfigurationCallWaitingQueried(int, android.telephony.ims.ImsSsInfo[]) parameter #1:
-    
-MissingNullability: android.telephony.ims.ImsUtListener#onUtConfigurationQueried(int, android.os.Bundle) parameter #1:
-    
-MissingNullability: android.telephony.ims.ImsUtListener#onUtConfigurationQueryFailed(int, android.telephony.ims.ImsReasonInfo) parameter #1:
-    
-MissingNullability: android.telephony.ims.ImsUtListener#onUtConfigurationUpdateFailed(int, android.telephony.ims.ImsReasonInfo) parameter #1:
-    
-MissingNullability: android.telephony.ims.ImsVideoCallProvider#changeCameraCapabilities(android.telecom.VideoProfile.CameraCapabilities) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSendSessionModifyRequest(android.telecom.VideoProfile, android.telecom.VideoProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSendSessionModifyRequest(android.telecom.VideoProfile, android.telecom.VideoProfile) parameter #1:
-    
-MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSendSessionModifyResponse(android.telecom.VideoProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSetCamera(String) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSetCamera(String, int) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSetDisplaySurface(android.view.Surface) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSetPauseImage(android.net.Uri) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSetPreviewSurface(android.view.Surface) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsVideoCallProvider#receiveSessionModifyRequest(android.telecom.VideoProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsVideoCallProvider#receiveSessionModifyResponse(int, android.telecom.VideoProfile, android.telecom.VideoProfile) parameter #1:
-    
-MissingNullability: android.telephony.ims.ImsVideoCallProvider#receiveSessionModifyResponse(int, android.telecom.VideoProfile, android.telecom.VideoProfile) parameter #2:
-    
-MissingNullability: android.telephony.ims.feature.CapabilityChangeRequest#getCapabilitiesToDisable():
-    
-MissingNullability: android.telephony.ims.feature.CapabilityChangeRequest#getCapabilitiesToEnable():
-    
-MissingNullability: android.telephony.ims.feature.CapabilityChangeRequest#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.ims.feature.ImsFeature#changeEnabledCapabilities(android.telephony.ims.feature.CapabilityChangeRequest, android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy) parameter #0:
-    
-MissingNullability: android.telephony.ims.feature.ImsFeature#changeEnabledCapabilities(android.telephony.ims.feature.CapabilityChangeRequest, android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy) parameter #1:
-    
-MissingNullability: android.telephony.ims.feature.MmTelFeature#queryCapabilityStatus():
-    
-MissingNullability: android.telephony.ims.feature.MmTelFeature.MmTelCapabilities#MmTelCapabilities(android.telephony.ims.feature.ImsFeature.Capabilities) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#accept(int, android.telephony.ims.ImsStreamMediaProfile) parameter #1:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#deflect(String) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#extendToConference(String[]) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#getCallId():
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#getCallProfile():
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#getImsVideoCallProvider():
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#getLocalCallProfile():
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#getProperty(String):
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#getProperty(String) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#getRemoteCallProfile():
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#hold(android.telephony.ims.ImsStreamMediaProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#inviteParticipants(String[]) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#removeParticipants(String[]) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#resume(android.telephony.ims.ImsStreamMediaProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#sendDtmf(char, android.os.Message) parameter #1:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#sendRttMessage(String) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#sendRttModifyRequest(android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#sendUssd(String) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#setListener(android.telephony.ims.ImsCallSessionListener) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#start(String, android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#start(String, android.telephony.ims.ImsCallProfile) parameter #1:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#startConference(String[], android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#startConference(String[], android.telephony.ims.ImsCallProfile) parameter #1:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#update(int, android.telephony.ims.ImsStreamMediaProfile) parameter #1:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase.State#toString(int):
-    
-MissingNullability: android.telephony.ims.stub.ImsConfigImplBase#getConfigString(int):
-    
-MissingNullability: android.telephony.ims.stub.ImsConfigImplBase#notifyProvisionedValueChanged(int, String) parameter #1:
-    
-MissingNullability: android.telephony.ims.stub.ImsConfigImplBase#setConfig(int, String) parameter #1:
-    
-MissingNullability: android.telephony.ims.stub.ImsFeatureConfiguration#getServiceFeatures():
-    
-MissingNullability: android.telephony.ims.stub.ImsFeatureConfiguration#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsFeatureConfiguration.Builder#addFeature(int, int):
-    
-MissingNullability: android.telephony.ims.stub.ImsFeatureConfiguration.Builder#build():
-    
-MissingNullability: android.telephony.ims.stub.ImsMultiEndpointImplBase#onImsExternalCallStateUpdate(java.util.List<android.telephony.ims.ImsExternalCallState>) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsRegistrationImplBase#onDeregistered(android.telephony.ims.ImsReasonInfo) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsRegistrationImplBase#onSubscriberAssociatedUriChanged(android.net.Uri[]) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsRegistrationImplBase#onTechnologyChangeFailed(int, android.telephony.ims.ImsReasonInfo) parameter #1:
-    
-MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#getSmsFormat():
-    
-MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#onSmsReceived(int, String, byte[]) parameter #1:
-    
-MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#onSmsReceived(int, String, byte[]) parameter #2:
-    
-MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#onSmsStatusReportReceived(int, String, byte[]) parameter #1:
-    
-MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#onSmsStatusReportReceived(int, String, byte[]) parameter #2:
-    
-MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#onSmsStatusReportReceived(int, int, String, byte[]) parameter #2:
-    
-MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#onSmsStatusReportReceived(int, int, String, byte[]) parameter #3:
-    
-MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#sendSms(int, int, String, String, boolean, byte[]) parameter #2:
-    
-MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#sendSms(int, int, String, String, boolean, byte[]) parameter #3:
-    
-MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#sendSms(int, int, String, String, boolean, byte[]) parameter #5:
-    
-MissingNullability: android.telephony.ims.stub.ImsUtImplBase#queryCallForward(int, String) parameter #1:
-    
-MissingNullability: android.telephony.ims.stub.ImsUtImplBase#setListener(android.telephony.ims.ImsUtListener) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsUtImplBase#transact(android.os.Bundle) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsUtImplBase#updateCallBarring(int, int, String[]) parameter #2:
-    
-MissingNullability: android.telephony.ims.stub.ImsUtImplBase#updateCallBarringForServiceClass(int, int, String[], int) parameter #2:
-    
-MissingNullability: android.telephony.ims.stub.ImsUtImplBase#updateCallForward(int, int, String, int, int) parameter #2:
-    
-MissingNullability: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String):
-    
-MissingNullability: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String) parameter #0:
-    
-MissingNullability: android.telephony.mbms.FileInfo#FileInfo(android.net.Uri, String) parameter #0:
-    
-MissingNullability: android.telephony.mbms.FileInfo#FileInfo(android.net.Uri, String) parameter #1:
-    
-MissingNullability: android.telephony.mbms.FileServiceInfo#FileServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>) parameter #0:
-    
-MissingNullability: android.telephony.mbms.FileServiceInfo#FileServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>) parameter #1:
-    
-MissingNullability: android.telephony.mbms.FileServiceInfo#FileServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>) parameter #2:
-    
-MissingNullability: android.telephony.mbms.FileServiceInfo#FileServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>) parameter #3:
-    
-MissingNullability: android.telephony.mbms.FileServiceInfo#FileServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>) parameter #4:
-    
-MissingNullability: android.telephony.mbms.FileServiceInfo#FileServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>) parameter #5:
-    
-MissingNullability: android.telephony.mbms.FileServiceInfo#FileServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>) parameter #6:
-    
-MissingNullability: android.telephony.mbms.StreamingServiceInfo#StreamingServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date) parameter #0:
-    
-MissingNullability: android.telephony.mbms.StreamingServiceInfo#StreamingServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date) parameter #1:
-    
-MissingNullability: android.telephony.mbms.StreamingServiceInfo#StreamingServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date) parameter #2:
-    
-MissingNullability: android.telephony.mbms.StreamingServiceInfo#StreamingServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date) parameter #3:
-    
-MissingNullability: android.telephony.mbms.StreamingServiceInfo#StreamingServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date) parameter #4:
-    
-MissingNullability: android.telephony.mbms.StreamingServiceInfo#StreamingServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date) parameter #5:
-    
-MissingNullability: android.telephony.mbms.UriPathPair#getContentUri():
-    
-MissingNullability: android.telephony.mbms.UriPathPair#getFilePathUri():
-    
-MissingNullability: android.telephony.mbms.UriPathPair#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener) parameter #0:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener) parameter #1:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener) parameter #0:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener) parameter #1:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#asBinder():
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#cancelDownload(android.telephony.mbms.DownloadRequest) parameter #0:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#download(android.telephony.mbms.DownloadRequest) parameter #0:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#initialize(int, android.telephony.mbms.MbmsDownloadSessionCallback) parameter #1:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#onTransact(int, android.os.Parcel, android.os.Parcel, int) parameter #1:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#onTransact(int, android.os.Parcel, android.os.Parcel, int) parameter #2:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#removeProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener) parameter #0:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#removeProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener) parameter #1:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#removeStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener) parameter #0:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#removeStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener) parameter #1:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#requestDownloadState(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo) parameter #0:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#requestDownloadState(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo) parameter #1:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#requestUpdateFileServices(int, java.util.List<java.lang.String>) parameter #1:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#resetDownloadKnowledge(android.telephony.mbms.DownloadRequest) parameter #0:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#setTempFileRootDirectory(int, String) parameter #1:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#onBind(android.content.Intent):
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#onBind(android.content.Intent) parameter #0:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsStreamingServiceBase#asBinder():
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsStreamingServiceBase#getPlaybackUri(int, String) parameter #1:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsStreamingServiceBase#initialize(android.telephony.mbms.MbmsStreamingSessionCallback, int) parameter #0:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsStreamingServiceBase#onTransact(int, android.os.Parcel, android.os.Parcel, int) parameter #1:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsStreamingServiceBase#onTransact(int, android.os.Parcel, android.os.Parcel, int) parameter #2:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsStreamingServiceBase#requestUpdateStreamingServices(int, java.util.List<java.lang.String>) parameter #1:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsStreamingServiceBase#startStreaming(int, String, android.telephony.mbms.StreamingServiceCallback) parameter #1:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsStreamingServiceBase#startStreaming(int, String, android.telephony.mbms.StreamingServiceCallback) parameter #2:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsStreamingServiceBase#stopStreaming(int, String) parameter #1:
-    
-MissingNullability: android.telephony.mbms.vendor.VendorUtils#getAppReceiverFromPackageName(android.content.Context, String):
-    
-MissingNullability: android.telephony.mbms.vendor.VendorUtils#getAppReceiverFromPackageName(android.content.Context, String) parameter #0:
-    
-MissingNullability: android.telephony.mbms.vendor.VendorUtils#getAppReceiverFromPackageName(android.content.Context, String) parameter #1:
-    
+    Missing nullability on parameter `apn` in method `setCarrierTestOverride`
 MissingNullability: android.text.Selection.MemoryTextWatcher#afterTextChanged(android.text.Editable) parameter #0:
-    
+    Missing nullability on parameter `s` in method `afterTextChanged`
 MissingNullability: android.text.Selection.MemoryTextWatcher#beforeTextChanged(CharSequence, int, int, int) parameter #0:
-    
+    Missing nullability on parameter `s` in method `beforeTextChanged`
 MissingNullability: android.text.Selection.MemoryTextWatcher#onTextChanged(CharSequence, int, int, int) parameter #0:
-    
+    Missing nullability on parameter `s` in method `onTextChanged`
 MissingNullability: android.transition.TransitionManager#getTransition(android.transition.Scene):
-    
+    Missing nullability on method `getTransition` return
 MissingNullability: android.transition.TransitionManager#getTransition(android.transition.Scene) parameter #0:
-    
+    Missing nullability on parameter `scene` in method `getTransition`
 MissingNullability: android.util.FeatureFlagUtils#getAllFeatureFlags():
-    
+    Missing nullability on method `getAllFeatureFlags` return
 MissingNullability: android.util.FeatureFlagUtils#isEnabled(android.content.Context, String) parameter #0:
-    
+    Missing nullability on parameter `context` in method `isEnabled`
 MissingNullability: android.util.FeatureFlagUtils#isEnabled(android.content.Context, String) parameter #1:
-    
+    Missing nullability on parameter `feature` in method `isEnabled`
 MissingNullability: android.util.FeatureFlagUtils#setEnabled(android.content.Context, String, boolean) parameter #0:
-    
+    Missing nullability on parameter `context` in method `setEnabled`
 MissingNullability: android.util.FeatureFlagUtils#setEnabled(android.content.Context, String, boolean) parameter #1:
-    
+    Missing nullability on parameter `feature` in method `setEnabled`
 MissingNullability: android.util.TimeUtils#formatDuration(long):
-    
+    Missing nullability on method `formatDuration` return
 MissingNullability: android.util.proto.EncodedBuffer#dumpBuffers(String) parameter #0:
-    
+    Missing nullability on parameter `tag` in method `dumpBuffers`
 MissingNullability: android.util.proto.EncodedBuffer#dumpByteString(String, String, byte[]) parameter #0:
-    
+    Missing nullability on parameter `tag` in method `dumpByteString`
 MissingNullability: android.util.proto.EncodedBuffer#dumpByteString(String, String, byte[]) parameter #1:
-    
+    Missing nullability on parameter `prefix` in method `dumpByteString`
 MissingNullability: android.util.proto.EncodedBuffer#dumpByteString(String, String, byte[]) parameter #2:
-    
+    Missing nullability on parameter `buf` in method `dumpByteString`
 MissingNullability: android.util.proto.EncodedBuffer#getBytes(int):
-    
+    Missing nullability on method `getBytes` return
 MissingNullability: android.util.proto.EncodedBuffer#getDebugString():
-    
+    Missing nullability on method `getDebugString` return
 MissingNullability: android.util.proto.EncodedBuffer#writeRawBuffer(byte[]) parameter #0:
-    
+    Missing nullability on parameter `val` in method `writeRawBuffer`
 MissingNullability: android.util.proto.EncodedBuffer#writeRawBuffer(byte[], int, int) parameter #0:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#ProtoOutputStream(java.io.FileDescriptor) parameter #0:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#ProtoOutputStream(java.io.OutputStream) parameter #0:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#dump(String) parameter #0:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#getBytes():
-    
-MissingNullability: android.util.proto.ProtoOutputStream#write(long, String) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#write(long, byte[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writeBytes(long, byte[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writeObject(long, byte[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writePackedBool(long, boolean[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writePackedDouble(long, double[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writePackedEnum(long, int[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writePackedFixed32(long, int[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writePackedFixed64(long, long[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writePackedFloat(long, float[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writePackedInt32(long, int[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writePackedInt64(long, long[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writePackedSFixed32(long, int[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writePackedSFixed64(long, long[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writePackedSInt32(long, int[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writePackedSInt64(long, long[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writePackedUInt32(long, int[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writePackedUInt64(long, long[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writeRepeatedBytes(long, byte[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writeRepeatedObject(long, byte[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writeRepeatedString(long, String) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writeString(long, String) parameter #1:
-    
+    Missing nullability on parameter `val` in method `writeRawBuffer`
 MissingNullability: android.util.proto.ProtoParseException#ProtoParseException(String) parameter #0:
-    
-MissingNullability: android.util.proto.ProtoStream#FIELD_TYPE_NAMES:
-    
-MissingNullability: android.util.proto.ProtoStream#getFieldCountString(long):
-    
-MissingNullability: android.util.proto.ProtoStream#getFieldIdString(long):
-    
-MissingNullability: android.util.proto.ProtoStream#getFieldTypeString(long):
-    
-MissingNullability: android.util.proto.ProtoStream#getWireTypeString(int):
-    
-MissingNullability: android.util.proto.ProtoStream#token2String(long):
-    
+    Missing nullability on parameter `msg` in method `ProtoParseException`
 MissingNullability: android.util.proto.WireTypeMismatchException#WireTypeMismatchException(String) parameter #0:
-    
+    Missing nullability on parameter `msg` in method `WireTypeMismatchException`
 MissingNullability: android.view.Choreographer#postCallback(int, Runnable, Object) parameter #1:
-    
+    Missing nullability on parameter `action` in method `postCallback`
 MissingNullability: android.view.Choreographer#postCallback(int, Runnable, Object) parameter #2:
-    
+    Missing nullability on parameter `token` in method `postCallback`
 MissingNullability: android.view.Choreographer#postCallbackDelayed(int, Runnable, Object, long) parameter #1:
-    
+    Missing nullability on parameter `action` in method `postCallbackDelayed`
 MissingNullability: android.view.Choreographer#postCallbackDelayed(int, Runnable, Object, long) parameter #2:
-    
+    Missing nullability on parameter `token` in method `postCallbackDelayed`
 MissingNullability: android.view.Choreographer#removeCallbacks(int, Runnable, Object) parameter #1:
-    
+    Missing nullability on parameter `action` in method `removeCallbacks`
 MissingNullability: android.view.Choreographer#removeCallbacks(int, Runnable, Object) parameter #2:
-    
+    Missing nullability on parameter `token` in method `removeCallbacks`
 MissingNullability: android.view.FocusFinder#sort(android.view.View[], int, int, android.view.ViewGroup, boolean) parameter #0:
-    
+    Missing nullability on parameter `views` in method `sort`
 MissingNullability: android.view.FocusFinder#sort(android.view.View[], int, int, android.view.ViewGroup, boolean) parameter #3:
-    
+    Missing nullability on parameter `root` in method `sort`
 MissingNullability: android.view.KeyEvent#actionToString(int):
-    
-MissingNullability: android.view.SurfaceControlViewHost#SurfaceControlViewHost(android.content.Context, android.view.Display, android.view.SurfaceControl) parameter #0:
-    
-MissingNullability: android.view.SurfaceControlViewHost#SurfaceControlViewHost(android.content.Context, android.view.Display, android.view.SurfaceControl) parameter #1:
-    
-MissingNullability: android.view.SurfaceControlViewHost#SurfaceControlViewHost(android.content.Context, android.view.Display, android.view.SurfaceControl) parameter #2:
-    
-MissingNullability: android.view.SurfaceControlViewHost#addView(android.view.View, android.view.WindowManager.LayoutParams) parameter #0:
-    
-MissingNullability: android.view.SurfaceControlViewHost#addView(android.view.View, android.view.WindowManager.LayoutParams) parameter #1:
-    
+    Missing nullability on method `actionToString` return
 MissingNullability: android.view.SurfaceControlViewHost#relayout(android.view.WindowManager.LayoutParams) parameter #0:
-    
+    Missing nullability on parameter `attrs` in method `relayout`
 MissingNullability: android.view.View#getTooltipView():
-    
+    Missing nullability on method `getTooltipView` return
 MissingNullability: android.view.View#isDefaultFocusHighlightNeeded(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable) parameter #0:
-    
+    Missing nullability on parameter `background` in method `isDefaultFocusHighlightNeeded`
 MissingNullability: android.view.View#isDefaultFocusHighlightNeeded(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable) parameter #1:
-    
+    Missing nullability on parameter `foreground` in method `isDefaultFocusHighlightNeeded`
 MissingNullability: android.view.ViewDebug#startRenderingCommandsCapture(android.view.View, java.util.concurrent.Executor, java.util.concurrent.Callable<java.io.OutputStream>) parameter #0:
-    
+    Missing nullability on parameter `tree` in method `startRenderingCommandsCapture`
 MissingNullability: android.view.ViewDebug#startRenderingCommandsCapture(android.view.View, java.util.concurrent.Executor, java.util.concurrent.Callable<java.io.OutputStream>) parameter #1:
-    
+    Missing nullability on parameter `executor` in method `startRenderingCommandsCapture`
 MissingNullability: android.view.ViewDebug#startRenderingCommandsCapture(android.view.View, java.util.concurrent.Executor, java.util.concurrent.Callable<java.io.OutputStream>) parameter #2:
-    
-MissingNullability: android.view.ViewDebug#startRenderingCommandsCapture(android.view.View, java.util.concurrent.Executor, java.util.function.Function<android.graphics.Picture,java.lang.Boolean>) parameter #0:
-    
-MissingNullability: android.view.ViewDebug#startRenderingCommandsCapture(android.view.View, java.util.concurrent.Executor, java.util.function.Function<android.graphics.Picture,java.lang.Boolean>) parameter #1:
-    
-MissingNullability: android.view.ViewDebug#startRenderingCommandsCapture(android.view.View, java.util.concurrent.Executor, java.util.function.Function<android.graphics.Picture,java.lang.Boolean>) parameter #2:
-    
+    Missing nullability on parameter `callback` in method `startRenderingCommandsCapture`
 MissingNullability: android.view.WindowManager#holdLock(android.os.IBinder, int) parameter #0:
-    
+    Missing nullability on parameter `token` in method `holdLock`
 MissingNullability: android.view.WindowManager.LayoutParams#accessibilityTitle:
-    
-MissingNullability: android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener#onAccessibilityServicesStateChanged(android.view.accessibility.AccessibilityManager) parameter #0:
-    
-MissingNullability: android.view.accessibility.AccessibilityNodeInfo#setNumInstancesInUseCounter(java.util.concurrent.atomic.AtomicInteger) parameter #0:
-    
+    Missing nullability on field `accessibilityTitle` in class `class android.view.WindowManager.LayoutParams`
 MissingNullability: android.view.accessibility.AccessibilityNodeInfo#writeToParcelNoRecycle(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on parameter `parcel` in method `writeToParcelNoRecycle`
 MissingNullability: android.view.accessibility.AccessibilityWindowInfo#setNumInstancesInUseCounter(java.util.concurrent.atomic.AtomicInteger) parameter #0:
-    
-MissingNullability: android.view.contentcapture.ContentCaptureEvent#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on parameter `counter` in method `setNumInstancesInUseCounter`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#asyncNewChild(int):
-    
+    Missing nullability on method `asyncNewChild` return
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#getAutofillId():
-    
+    Missing nullability on method `getAutofillId` return
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#getExtras():
-    
+    Missing nullability on method `getExtras` return
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#getHint():
-    
+    Missing nullability on method `getHint` return
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#getNode():
-    
+    Missing nullability on method `getNode` return
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#getTempRect():
-    
+    Missing nullability on method `getTempRect` return
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#getText():
-    
+    Missing nullability on method `getText` return
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#newChild(int):
-    
+    Missing nullability on method `newChild` return
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#newHtmlInfoBuilder(String):
-    
+    Missing nullability on method `newHtmlInfoBuilder` return
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#newHtmlInfoBuilder(String) parameter #0:
-    
+    Missing nullability on parameter `tagName` in method `newHtmlInfoBuilder`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setAutofillHints(String[]) parameter #0:
-    
+    Missing nullability on parameter `hints` in method `setAutofillHints`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setAutofillId(android.view.autofill.AutofillId) parameter #0:
-    
+    Missing nullability on parameter `id` in method `setAutofillId`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setAutofillId(android.view.autofill.AutofillId, int) parameter #0:
-    
+    Missing nullability on parameter `parentId` in method `setAutofillId`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setAutofillOptions(CharSequence[]) parameter #0:
-    
+    Missing nullability on parameter `options` in method `setAutofillOptions`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setAutofillValue(android.view.autofill.AutofillValue) parameter #0:
-    
+    Missing nullability on parameter `value` in method `setAutofillValue`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setClassName(String) parameter #0:
-    
+    Missing nullability on parameter `className` in method `setClassName`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setContentDescription(CharSequence) parameter #0:
-    
+    Missing nullability on parameter `contentDescription` in method `setContentDescription`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setHint(CharSequence) parameter #0:
-    
+    Missing nullability on parameter `hint` in method `setHint`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setHintIdEntry(String) parameter #0:
-    
+    Missing nullability on parameter `entryName` in method `setHintIdEntry`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setHtmlInfo(android.view.ViewStructure.HtmlInfo) parameter #0:
-    
+    Missing nullability on parameter `htmlInfo` in method `setHtmlInfo`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setId(int, String, String, String) parameter #1:
-    
+    Missing nullability on parameter `packageName` in method `setId`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setId(int, String, String, String) parameter #2:
-    
+    Missing nullability on parameter `typeName` in method `setId`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setId(int, String, String, String) parameter #3:
-    
+    Missing nullability on parameter `entryName` in method `setId`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setLocaleList(android.os.LocaleList) parameter #0:
-    
+    Missing nullability on parameter `localeList` in method `setLocaleList`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setText(CharSequence) parameter #0:
-    
+    Missing nullability on parameter `text` in method `setText`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setText(CharSequence, int, int) parameter #0:
-    
+    Missing nullability on parameter `text` in method `setText`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setTextLines(int[], int[]) parameter #0:
-    
+    Missing nullability on parameter `charOffsets` in method `setTextLines`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setTextLines(int[], int[]) parameter #1:
-    
+    Missing nullability on parameter `baselines` in method `setTextLines`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setTransformation(android.graphics.Matrix) parameter #0:
-    
+    Missing nullability on parameter `matrix` in method `setTransformation`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setWebDomain(String) parameter #0:
-    
+    Missing nullability on parameter `domain` in method `setWebDomain`
 MissingNullability: android.widget.CalendarView#getBoundsForDate(long, android.graphics.Rect) parameter #1:
-    
+    Missing nullability on parameter `outBounds` in method `getBoundsForDate`
 MissingNullability: android.widget.ImageView#isDefaultFocusHighlightNeeded(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable) parameter #0:
-    
+    Missing nullability on parameter `background` in method `isDefaultFocusHighlightNeeded`
 MissingNullability: android.widget.ImageView#isDefaultFocusHighlightNeeded(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable) parameter #1:
-    
+    Missing nullability on parameter `foreground` in method `isDefaultFocusHighlightNeeded`
 MissingNullability: android.widget.Magnifier#getMagnifierDefaultSize():
-    
+    Missing nullability on method `getMagnifierDefaultSize` return
 MissingNullability: android.widget.Magnifier#setOnOperationCompleteCallback(android.widget.Magnifier.Callback) parameter #0:
-    
+    Missing nullability on parameter `callback` in method `setOnOperationCompleteCallback`
 MissingNullability: android.widget.NumberPicker#getDisplayedValueForCurrentSelection():
-    
+    Missing nullability on method `getDisplayedValueForCurrentSelection` return
 MissingNullability: android.widget.PopupMenu#getMenuListView():
-    
+    Missing nullability on method `getMenuListView` return
 MissingNullability: android.widget.TimePicker#getAmView():
-    
+    Missing nullability on method `getAmView` return
 MissingNullability: android.widget.TimePicker#getHourView():
-    
+    Missing nullability on method `getHourView` return
 MissingNullability: android.widget.TimePicker#getMinuteView():
-    
+    Missing nullability on method `getMinuteView` return
 MissingNullability: android.widget.TimePicker#getPmView():
-    
+    Missing nullability on method `getPmView` return
 
 
 MutableBareField: android.content.AutofillOptions#appDisabledExpiration:
-    
+    Bare field appDisabledExpiration must be marked final, or moved behind accessors if mutable
 MutableBareField: android.content.AutofillOptions#augmentedAutofillEnabled:
-    
+    Bare field augmentedAutofillEnabled must be marked final, or moved behind accessors if mutable
 MutableBareField: android.content.AutofillOptions#disabledActivities:
-    
+    Bare field disabledActivities must be marked final, or moved behind accessors if mutable
 MutableBareField: android.content.AutofillOptions#whitelistedActivitiesForAugmentedAutofill:
-    
+    Bare field whitelistedActivitiesForAugmentedAutofill must be marked final, or moved behind accessors if mutable
 MutableBareField: android.content.pm.UserInfo#convertedFromPreCreated:
     Bare field convertedFromPreCreated must be marked final, or moved behind accessors if mutable
 MutableBareField: android.content.pm.UserInfo#creationTime:
@@ -2438,588 +796,230 @@
 MutableBareField: android.content.pm.UserInfo#userType:
     Bare field userType must be marked final, or moved behind accessors if mutable
 MutableBareField: android.database.sqlite.SQLiteDebug.DbStats#cache:
-    
+    Bare field cache must be marked final, or moved behind accessors if mutable
 MutableBareField: android.database.sqlite.SQLiteDebug.DbStats#dbName:
-    
+    Bare field dbName must be marked final, or moved behind accessors if mutable
 MutableBareField: android.database.sqlite.SQLiteDebug.DbStats#dbSize:
-    
+    Bare field dbSize must be marked final, or moved behind accessors if mutable
 MutableBareField: android.database.sqlite.SQLiteDebug.DbStats#lookaside:
-    
+    Bare field lookaside must be marked final, or moved behind accessors if mutable
 MutableBareField: android.database.sqlite.SQLiteDebug.DbStats#pageSize:
-    
+    Bare field pageSize must be marked final, or moved behind accessors if mutable
 MutableBareField: android.database.sqlite.SQLiteDebug.PagerStats#dbStats:
-    
+    Bare field dbStats must be marked final, or moved behind accessors if mutable
 MutableBareField: android.database.sqlite.SQLiteDebug.PagerStats#largestMemAlloc:
-    
+    Bare field largestMemAlloc must be marked final, or moved behind accessors if mutable
 MutableBareField: android.database.sqlite.SQLiteDebug.PagerStats#memoryUsed:
-    
+    Bare field memoryUsed must be marked final, or moved behind accessors if mutable
 MutableBareField: android.database.sqlite.SQLiteDebug.PagerStats#pageCacheOverflow:
-    
+    Bare field pageCacheOverflow must be marked final, or moved behind accessors if mutable
 MutableBareField: android.os.StrictMode.ViolationInfo#broadcastIntentAction:
-    
+    Bare field broadcastIntentAction must be marked final, or moved behind accessors if mutable
 MutableBareField: android.os.StrictMode.ViolationInfo#durationMillis:
-    
+    Bare field durationMillis must be marked final, or moved behind accessors if mutable
 MutableBareField: android.os.StrictMode.ViolationInfo#numAnimationsRunning:
-    
+    Bare field numAnimationsRunning must be marked final, or moved behind accessors if mutable
 MutableBareField: android.os.StrictMode.ViolationInfo#numInstances:
-    
+    Bare field numInstances must be marked final, or moved behind accessors if mutable
 MutableBareField: android.os.StrictMode.ViolationInfo#tags:
-    
+    Bare field tags must be marked final, or moved behind accessors if mutable
 MutableBareField: android.os.StrictMode.ViolationInfo#violationNumThisLoop:
-    
+    Bare field violationNumThisLoop must be marked final, or moved behind accessors if mutable
 MutableBareField: android.os.StrictMode.ViolationInfo#violationUptimeMillis:
-    
+    Bare field violationUptimeMillis must be marked final, or moved behind accessors if mutable
 
 
 NoByteOrShort: android.media.audiofx.AudioEffect#byteArrayToShort(byte[]):
-    
+    Should avoid odd sized primitives; use `int` instead of `short` in method android.media.audiofx.AudioEffect.byteArrayToShort(byte[])
 NoByteOrShort: android.media.audiofx.AudioEffect#setParameter(int, short) parameter #1:
-    
+    Should avoid odd sized primitives; use `int` instead of `short` in parameter value in android.media.audiofx.AudioEffect.setParameter(int param, short value)
 NoByteOrShort: android.media.audiofx.AudioEffect#shortToByteArray(short) parameter #0:
-    
-NoByteOrShort: android.os.HwBlob#getInt16(long):
-    
-NoByteOrShort: android.os.HwBlob#getInt8(long):
-    
-NoByteOrShort: android.os.HwBlob#putInt16(long, short) parameter #1:
-    
-NoByteOrShort: android.os.HwBlob#putInt8(long, byte) parameter #1:
-    
-NoByteOrShort: android.os.HwParcel#readInt16():
-    
-NoByteOrShort: android.os.HwParcel#readInt8():
-    
-NoByteOrShort: android.os.HwParcel#writeInt16(short) parameter #0:
-    
-NoByteOrShort: android.os.HwParcel#writeInt8(byte) parameter #0:
-    
+    Should avoid odd sized primitives; use `int` instead of `short` in parameter value in android.media.audiofx.AudioEffect.shortToByteArray(short value)
 NoByteOrShort: android.util.proto.EncodedBuffer#readRawByte():
-    
+    Should avoid odd sized primitives; use `int` instead of `byte` in method android.util.proto.EncodedBuffer.readRawByte()
 NoByteOrShort: android.util.proto.EncodedBuffer#writeRawByte(byte) parameter #0:
-    
-
-
-NoClone: android.net.util.SocketUtils#bindSocketToInterface(java.io.FileDescriptor, String) parameter #0:
-    
-NoClone: android.net.util.SocketUtils#closeSocket(java.io.FileDescriptor) parameter #0:
-    
-NoClone: android.os.NativeHandle#NativeHandle(java.io.FileDescriptor, boolean) parameter #0:
-    
-NoClone: android.os.NativeHandle#getFileDescriptor():
-    
-NoClone: android.os.ParcelFileDescriptor#getFile(java.io.FileDescriptor) parameter #0:
-    
-NoClone: android.service.autofill.augmented.AugmentedAutofillService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0:
-    
-NoClone: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0:
-    
-NoClone: android.util.proto.ProtoOutputStream#ProtoOutputStream(java.io.FileDescriptor) parameter #0:
-    
+    Should avoid odd sized primitives; use `int` instead of `byte` in parameter val in android.util.proto.EncodedBuffer.writeRawByte(byte val)
 
 
 NoSettingsProvider: android.provider.Settings.Global#APP_OPS_CONSTANTS:
-    
-NoSettingsProvider: android.provider.Settings.Global#AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES:
-    
+    New setting keys are not allowed (Field: APP_OPS_CONSTANTS); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Global#AUTOMATIC_POWER_SAVE_MODE:
-    
+    New setting keys are not allowed (Field: AUTOMATIC_POWER_SAVE_MODE); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Global#BATTERY_SAVER_CONSTANTS:
-    
+    New setting keys are not allowed (Field: BATTERY_SAVER_CONSTANTS); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Global#DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD:
-    
+    New setting keys are not allowed (Field: DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Global#DYNAMIC_POWER_SAVINGS_ENABLED:
-    
+    New setting keys are not allowed (Field: DYNAMIC_POWER_SAVINGS_ENABLED); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Global#HIDDEN_API_BLACKLIST_EXEMPTIONS:
-    
+    New setting keys are not allowed (Field: HIDDEN_API_BLACKLIST_EXEMPTIONS); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Global#HIDDEN_API_POLICY:
-    
+    New setting keys are not allowed (Field: HIDDEN_API_POLICY); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Global#HIDE_ERROR_DIALOGS:
-    
-NoSettingsProvider: android.provider.Settings.Global#LOCATION_GLOBAL_KILL_SWITCH:
-    
-NoSettingsProvider: android.provider.Settings.Global#LOCATION_IGNORE_SETTINGS_PACKAGE_WHITELIST:
-    
+    New setting keys are not allowed (Field: HIDE_ERROR_DIALOGS); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Global#LOW_POWER_MODE:
-    
+    New setting keys are not allowed (Field: LOW_POWER_MODE); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Global#LOW_POWER_MODE_STICKY:
-    
-NoSettingsProvider: android.provider.Settings.Global#NOTIFICATION_BUBBLES:
-    
+    New setting keys are not allowed (Field: LOW_POWER_MODE_STICKY); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Global#OVERLAY_DISPLAY_DEVICES:
-    
-NoSettingsProvider: android.provider.Settings.Global#TETHER_OFFLOAD_DISABLED:
-    
-NoSettingsProvider: android.provider.Settings.Global#USE_OPEN_WIFI_PACKAGE:
-    
+    New setting keys are not allowed (Field: OVERLAY_DISPLAY_DEVICES); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED:
-    
+    New setting keys are not allowed (Field: ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#ACCESSIBILITY_MAGNIFICATION_CAPABILITY:
-    
+    New setting keys are not allowed (Field: ACCESSIBILITY_MAGNIFICATION_CAPABILITY); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#ACCESSIBILITY_MAGNIFICATION_MODE:
-    
-NoSettingsProvider: android.provider.Settings.Secure#ACCESSIBILITY_MAGNIFICATION_MODE_ALL:
-    
-NoSettingsProvider: android.provider.Settings.Secure#ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN:
-    
-NoSettingsProvider: android.provider.Settings.Secure#ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW:
-    
+    New setting keys are not allowed (Field: ACCESSIBILITY_MAGNIFICATION_MODE); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#ACCESSIBILITY_SHORTCUT_TARGET_SERVICE:
-    
-NoSettingsProvider: android.provider.Settings.Secure#AUTOFILL_FEATURE_FIELD_CLASSIFICATION:
-    
+    New setting keys are not allowed (Field: ACCESSIBILITY_SHORTCUT_TARGET_SERVICE); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#AUTOFILL_SERVICE:
-    
-NoSettingsProvider: android.provider.Settings.Secure#AUTOFILL_USER_DATA_MAX_CATEGORY_COUNT:
-    
-NoSettingsProvider: android.provider.Settings.Secure#AUTOFILL_USER_DATA_MAX_FIELD_CLASSIFICATION_IDS_SIZE:
-    
-NoSettingsProvider: android.provider.Settings.Secure#AUTOFILL_USER_DATA_MAX_USER_DATA_SIZE:
-    
-NoSettingsProvider: android.provider.Settings.Secure#AUTOFILL_USER_DATA_MAX_VALUE_LENGTH:
-    
-NoSettingsProvider: android.provider.Settings.Secure#AUTOFILL_USER_DATA_MIN_VALUE_LENGTH:
-    
+    New setting keys are not allowed (Field: AUTOFILL_SERVICE); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#CONTENT_CAPTURE_ENABLED:
-    
+    New setting keys are not allowed (Field: CONTENT_CAPTURE_ENABLED); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#DISABLED_PRINT_SERVICES:
-    
-NoSettingsProvider: android.provider.Settings.Secure#DOZE_ALWAYS_ON:
-    
+    New setting keys are not allowed (Field: DISABLED_PRINT_SERVICES); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#ENABLED_VR_LISTENERS:
-    
+    New setting keys are not allowed (Field: ENABLED_VR_LISTENERS); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#IMMERSIVE_MODE_CONFIRMATIONS:
-    
-NoSettingsProvider: android.provider.Settings.Secure#LOCATION_ACCESS_CHECK_DELAY_MILLIS:
-    
-NoSettingsProvider: android.provider.Settings.Secure#LOCATION_ACCESS_CHECK_INTERVAL_MILLIS:
-    
-NoSettingsProvider: android.provider.Settings.Secure#LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS:
-    
-NoSettingsProvider: android.provider.Settings.Secure#LOCK_SCREEN_SHOW_NOTIFICATIONS:
-    
-NoSettingsProvider: android.provider.Settings.Secure#NFC_PAYMENT_DEFAULT_COMPONENT:
-    
+    New setting keys are not allowed (Field: IMMERSIVE_MODE_CONFIRMATIONS); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#NOTIFICATION_BADGING:
-    
+    New setting keys are not allowed (Field: NOTIFICATION_BADGING); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#POWER_MENU_LOCKED_SHOW_CONTENT:
-    
+    New setting keys are not allowed (Field: POWER_MENU_LOCKED_SHOW_CONTENT); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#SYNC_PARENT_SOUNDS:
-    
-NoSettingsProvider: android.provider.Settings.Secure#USER_SETUP_COMPLETE:
-    
+    New setting keys are not allowed (Field: SYNC_PARENT_SOUNDS); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#VOICE_INTERACTION_SERVICE:
-    
+    New setting keys are not allowed (Field: VOICE_INTERACTION_SERVICE); use getters/setters in relevant manager class
 
 
-NotCloseable: android.app.prediction.AppPredictor:
-    
-NotCloseable: android.net.EthernetManager.TetheredInterfaceRequest:
-    
-NotCloseable: android.os.HwParcel:
-    
-NotCloseable: android.telephony.ims.stub.ImsUtImplBase:
-    
-
-
-NullableCollection: android.os.UserManager#createProfileForUser(String, String, int, int, String[]) parameter #4:
-    Type of parameter disallowedPackages in android.os.UserManager.createProfileForUser(String name, String userType, int flags, int userId, String[] disallowedPackages) is a nullable collection (`java.lang.String[]`); must be non-null
-
-
-OnNameExpected: android.service.autofill.augmented.AugmentedAutofillService#dump(java.io.PrintWriter, String[]):
-    
-OnNameExpected: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]):
-    
 OnNameExpected: android.service.notification.ConditionProviderService#isBound():
-    
-OnNameExpected: android.service.notification.NotificationAssistantService#attachBaseContext(android.content.Context):
-    
-OnNameExpected: android.service.quicksettings.TileService#isQuickSettingsSupported():
-    
+    If implemented by developer, should follow the on<Something> style; otherwise consider marking final
 OnNameExpected: android.service.watchdog.ExplicitHealthCheckService#setCallback(android.os.RemoteCallback):
-    
-OnNameExpected: android.telephony.ims.ImsService#createMmTelFeature(int):
-    
-OnNameExpected: android.telephony.ims.ImsService#createRcsFeature(int):
-    
-OnNameExpected: android.telephony.ims.ImsService#disableIms(int):
-    
-OnNameExpected: android.telephony.ims.ImsService#enableIms(int):
-    
-OnNameExpected: android.telephony.ims.ImsService#getConfig(int):
-    
-OnNameExpected: android.telephony.ims.ImsService#getRegistration(int):
-    
-OnNameExpected: android.telephony.ims.ImsService#querySupportedImsFeatures():
-    
-OnNameExpected: android.telephony.ims.ImsService#readyForFeatureCreation():
-    
-OnNameExpected: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#dispose(int):
-    
-OnNameExpected: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#initialize(android.telephony.mbms.MbmsGroupCallSessionCallback, int):
-    
-OnNameExpected: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#startGroupCall(int, long, java.util.List<java.lang.Integer>, java.util.List<java.lang.Integer>, android.telephony.mbms.GroupCallCallback):
-    
-OnNameExpected: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#stopGroupCall(int, long):
-    
-OnNameExpected: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#updateGroupCall(int, long, java.util.List<java.lang.Integer>, java.util.List<java.lang.Integer>):
-    
-
-
-OptionalBuilderConstructorArgument: android.app.prediction.AppTargetEvent.Builder#Builder(android.app.prediction.AppTarget, int) parameter #0:
-    
-OptionalBuilderConstructorArgument: android.net.CaptivePortalData.Builder#Builder(android.net.CaptivePortalData) parameter #0:
-    
-OptionalBuilderConstructorArgument: android.os.VibrationAttributes.Builder#Builder(android.media.AudioAttributes, android.os.VibrationEffect) parameter #1:
-    
+    If implemented by developer, should follow the on<Something> style; otherwise consider marking final
 
 
 PackageLayering: android.util.FeatureFlagUtils:
-    
+    Method parameter type `android.content.Context` violates package layering: nothing in `package android.util` should depend on `package android.content`
 
 
-ParcelConstructor: android.os.IncidentManager.IncidentReport#IncidentReport(android.os.Parcel):
-    
-ParcelConstructor: android.os.IncidentReportArgs#IncidentReportArgs(android.os.Parcel):
-    
 ParcelConstructor: android.os.StrictMode.ViolationInfo#ViolationInfo(android.os.Parcel):
-    
+    Parcelable inflation is exposed through CREATOR, not raw constructors, in android.os.StrictMode.ViolationInfo
 ParcelConstructor: android.os.health.HealthStatsParceler#HealthStatsParceler(android.os.Parcel):
-    
-ParcelConstructor: android.service.notification.SnoozeCriterion#SnoozeCriterion(android.os.Parcel):
-    
+    Parcelable inflation is exposed through CREATOR, not raw constructors, in android.os.health.HealthStatsParceler
 
 
 ParcelCreator: android.app.WindowConfiguration:
-    
-ParcelCreator: android.net.metrics.ApfProgramEvent:
-    
-ParcelCreator: android.net.metrics.ApfStats:
-    
-ParcelCreator: android.net.metrics.DhcpClientEvent:
-    
-ParcelCreator: android.net.metrics.DhcpErrorEvent:
-    
-ParcelCreator: android.net.metrics.IpConnectivityLog.Event:
-    
-ParcelCreator: android.net.metrics.IpManagerEvent:
-    
-ParcelCreator: android.net.metrics.IpReachabilityEvent:
-    
-ParcelCreator: android.net.metrics.NetworkEvent:
-    
-ParcelCreator: android.net.metrics.RaEvent:
-    
-ParcelCreator: android.net.metrics.ValidationProbeEvent:
-    
+    Parcelable requires a `CREATOR` field; missing in android.app.WindowConfiguration
 ParcelCreator: android.service.autofill.InternalOnClickAction:
-    
+    Parcelable requires a `CREATOR` field; missing in android.service.autofill.InternalOnClickAction
 ParcelCreator: android.service.autofill.InternalSanitizer:
-    
+    Parcelable requires a `CREATOR` field; missing in android.service.autofill.InternalSanitizer
 ParcelCreator: android.service.autofill.InternalTransformation:
-    
+    Parcelable requires a `CREATOR` field; missing in android.service.autofill.InternalTransformation
 ParcelCreator: android.service.autofill.InternalValidator:
-    
+    Parcelable requires a `CREATOR` field; missing in android.service.autofill.InternalValidator
 
 
 ParcelNotFinal: android.app.WindowConfiguration:
-    
+    Parcelable classes must be final: android.app.WindowConfiguration is not final
 ParcelNotFinal: android.content.pm.UserInfo:
     Parcelable classes must be final: android.content.pm.UserInfo is not final
-ParcelNotFinal: android.net.metrics.IpConnectivityLog.Event:
-    
-ParcelNotFinal: android.os.IncidentManager.IncidentReport:
-    
 ParcelNotFinal: android.os.health.HealthStatsParceler:
-    
+    Parcelable classes must be final: android.os.health.HealthStatsParceler is not final
 ParcelNotFinal: android.service.autofill.InternalOnClickAction:
-    
+    Parcelable classes must be final: android.service.autofill.InternalOnClickAction is not final
 ParcelNotFinal: android.service.autofill.InternalSanitizer:
-    
+    Parcelable classes must be final: android.service.autofill.InternalSanitizer is not final
 ParcelNotFinal: android.service.autofill.InternalTransformation:
-    
+    Parcelable classes must be final: android.service.autofill.InternalTransformation is not final
 ParcelNotFinal: android.service.autofill.InternalValidator:
-    
+    Parcelable classes must be final: android.service.autofill.InternalValidator is not final
 
 
 ProtectedMember: android.app.AppDetailsActivity#onCreate(android.os.Bundle):
-    
-ProtectedMember: android.os.VibrationEffect#scale(int, float, int):
-    
-ProtectedMember: android.service.autofill.augmented.AugmentedAutofillService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]):
-    
-ProtectedMember: android.service.autofill.augmented.AugmentedAutofillService#dump(java.io.PrintWriter, String[]):
-    
-ProtectedMember: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]):
-    
-ProtectedMember: android.service.notification.NotificationAssistantService#attachBaseContext(android.content.Context):
-    
-ProtectedMember: android.util.proto.ProtoStream#FIELD_TYPE_NAMES:
-    
+    Protected methods not allowed; must be public: method android.app.AppDetailsActivity.onCreate(android.os.Bundle)}
 ProtectedMember: android.view.View#resetResolvedDrawables():
-    
+    Protected methods not allowed; must be public: method android.view.View.resetResolvedDrawables()}
 ProtectedMember: android.view.ViewGroup#resetResolvedDrawables():
-    
-
-
-RawAidl: android.telephony.mbms.vendor.MbmsDownloadServiceBase:
-    
-RawAidl: android.telephony.mbms.vendor.MbmsStreamingServiceBase:
-    
+    Protected methods not allowed; must be public: method android.view.ViewGroup.resetResolvedDrawables()}
 
 
 RethrowRemoteException: android.app.ActivityManager#resumeAppSwitches():
-    
-RethrowRemoteException: android.os.HwBinder#getService(String, String):
-    
-RethrowRemoteException: android.os.HwBinder#getService(String, String, boolean):
-    
-RethrowRemoteException: android.os.HwBinder#onTransact(int, android.os.HwParcel, android.os.HwParcel, int):
-    
-RethrowRemoteException: android.os.HwBinder#registerService(String):
-    
-RethrowRemoteException: android.os.HwBinder#transact(int, android.os.HwParcel, android.os.HwParcel, int):
-    
-RethrowRemoteException: android.os.IHwBinder#transact(int, android.os.HwParcel, android.os.HwParcel, int):
-    
-RethrowRemoteException: android.telephony.ims.ImsService#onUpdateSupportedImsFeatures(android.telephony.ims.stub.ImsFeatureConfiguration):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#cancelDownload(android.telephony.mbms.DownloadRequest):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#dispose(int):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#download(android.telephony.mbms.DownloadRequest):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#initialize(int, android.telephony.mbms.MbmsDownloadSessionCallback):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#listPendingDownloads(int):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#onTransact(int, android.os.Parcel, android.os.Parcel, int):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#removeProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#removeStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#requestDownloadState(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#requestUpdateFileServices(int, java.util.List<java.lang.String>):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#resetDownloadKnowledge(android.telephony.mbms.DownloadRequest):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#setTempFileRootDirectory(int, String):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#dispose(int):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#initialize(android.telephony.mbms.MbmsGroupCallSessionCallback, int):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsStreamingServiceBase#dispose(int):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsStreamingServiceBase#getPlaybackUri(int, String):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsStreamingServiceBase#initialize(android.telephony.mbms.MbmsStreamingSessionCallback, int):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsStreamingServiceBase#onTransact(int, android.os.Parcel, android.os.Parcel, int):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsStreamingServiceBase#requestUpdateStreamingServices(int, java.util.List<java.lang.String>):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsStreamingServiceBase#startStreaming(int, String, android.telephony.mbms.StreamingServiceCallback):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsStreamingServiceBase#stopStreaming(int, String):
-    
+    Methods calling system APIs should rethrow `RemoteException` as `RuntimeException` (but do not list it in the throws clause)
 
 
-SamShouldBeLast: android.app.ActivityManager#addOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener, int):
-    
 SamShouldBeLast: android.database.sqlite.SQLiteDebug#dump(android.util.Printer, String[]):
-    
+    SAM-compatible parameters (such as parameter 1, "printer", in android.database.sqlite.SQLiteDebug.dump) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.database.sqlite.SQLiteDirectCursorDriver#query(android.database.sqlite.SQLiteDatabase.CursorFactory, String[]):
-    
-SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(android.location.LocationRequest, android.location.LocationListener, android.os.Looper):
-    
-SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(android.location.LocationRequest, java.util.concurrent.Executor, android.location.LocationListener):
-    
-SamShouldBeLast: android.os.BugreportManager#startBugreport(android.os.ParcelFileDescriptor, android.os.ParcelFileDescriptor, android.os.BugreportParams, java.util.concurrent.Executor, android.os.BugreportManager.BugreportCallback):
-    
-SamShouldBeLast: android.os.IHwBinder#linkToDeath(android.os.IHwBinder.DeathRecipient, long):
-    
+    SAM-compatible parameters (such as parameter 1, "factory", in android.database.sqlite.SQLiteDirectCursorDriver.query) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.os.StrictMode.ViolationInfo#dump(android.util.Printer, String):
-    
+    SAM-compatible parameters (such as parameter 1, "pw", in android.os.StrictMode.ViolationInfo.dump) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.permission.PermissionControllerManager#countPermissionApps(java.util.List<java.lang.String>, int, android.permission.PermissionControllerManager.OnCountPermissionAppsResultCallback, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 3, "callback", in android.permission.PermissionControllerManager.countPermissionApps) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.permission.PermissionControllerManager#getAppPermissions(String, android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback, android.os.Handler):
-    
-SamShouldBeLast: android.permission.PermissionControllerManager#revokeRuntimePermissions(java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, java.util.concurrent.Executor, android.permission.PermissionControllerManager.OnRevokeRuntimePermissionsCallback):
-    
+    SAM-compatible parameters (such as parameter 2, "callback", in android.permission.PermissionControllerManager.getAppPermissions) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.service.autofill.CharSequenceTransformation#apply(android.service.autofill.ValueFinder, android.widget.RemoteViews, int):
-    
+    SAM-compatible parameters (such as parameter 1, "finder", in android.service.autofill.CharSequenceTransformation.apply) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.service.autofill.DateTransformation#apply(android.service.autofill.ValueFinder, android.widget.RemoteViews, int):
-    
+    SAM-compatible parameters (such as parameter 1, "finder", in android.service.autofill.DateTransformation.apply) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.service.autofill.ImageTransformation#apply(android.service.autofill.ValueFinder, android.widget.RemoteViews, int):
-    
+    SAM-compatible parameters (such as parameter 1, "finder", in android.service.autofill.ImageTransformation.apply) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.service.autofill.InternalTransformation#batchApply(android.service.autofill.ValueFinder, android.widget.RemoteViews, java.util.ArrayList<android.util.Pair<java.lang.Integer,android.service.autofill.InternalTransformation>>):
-    
-SamShouldBeLast: android.telephony.ims.ImsMmTelManager#getFeatureState(java.util.function.Consumer<java.lang.Integer>, java.util.concurrent.Executor):
-    
+    SAM-compatible parameters (such as parameter 1, "finder", in android.service.autofill.InternalTransformation.batchApply) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.view.Choreographer#postCallback(int, Runnable, Object):
-    
+    SAM-compatible parameters (such as parameter 2, "action", in android.view.Choreographer.postCallback) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.view.Choreographer#postCallbackDelayed(int, Runnable, Object, long):
-    
+    SAM-compatible parameters (such as parameter 2, "action", in android.view.Choreographer.postCallbackDelayed) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.view.Choreographer#removeCallbacks(int, Runnable, Object):
-    
-SamShouldBeLast: android.view.ViewDebug#startRenderingCommandsCapture(android.view.View, java.util.concurrent.Executor, java.util.function.Function<android.graphics.Picture,java.lang.Boolean>):
-    
-SamShouldBeLast: android.view.accessibility.AccessibilityManager#addAccessibilityServicesStateChangeListener(android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener, android.os.Handler):
-    
-
-
-ServiceName: android.Manifest.permission#BIND_CELL_BROADCAST_SERVICE:
-    
-ServiceName: android.app.AppOpsManager#OPSTR_BIND_ACCESSIBILITY_SERVICE:
-    
-ServiceName: android.provider.Settings.Secure#ACCESSIBILITY_SHORTCUT_TARGET_SERVICE:
-    
-ServiceName: android.provider.Settings.Secure#AUTOFILL_SERVICE:
-    
-ServiceName: android.provider.Settings.Secure#VOICE_INTERACTION_SERVICE:
-    
-
-
-SetterReturnsThis: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyFocusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener):
-    
-SetterReturnsThis: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyStatusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyStatusListener):
-    
-
-
-StartWithLower: android.content.pm.PackageManager#BINDER():
-    Method name must start with lowercase char: BINDER
-
-
-StaticFinalBuilder: android.content.integrity.RuleSet.Builder:
-    
-StaticFinalBuilder: android.hardware.display.BrightnessConfiguration.Builder:
-    
-StaticFinalBuilder: android.media.audiopolicy.AudioMix.Builder:
-    
-StaticFinalBuilder: android.media.audiopolicy.AudioMixingRule.Builder:
-    
-StaticFinalBuilder: android.media.audiopolicy.AudioPolicy.Builder:
-    
-StaticFinalBuilder: android.net.CaptivePortalData.Builder:
-    
-StaticFinalBuilder: android.net.TetheringManager.TetheringRequest.Builder:
-    
-StaticFinalBuilder: android.telephony.ims.stub.ImsFeatureConfiguration.Builder:
-    
+    SAM-compatible parameters (such as parameter 2, "action", in android.view.Choreographer.removeCallbacks) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 
 
 StaticUtils: android.os.health.HealthKeys:
-    
+    Fully-static utility classes must not have constructor
 StaticUtils: android.service.autofill.InternalTransformation:
-    
-StaticUtils: android.telephony.mbms.vendor.VendorUtils:
-    
+    Fully-static utility classes must not have constructor
 StaticUtils: android.util.FeatureFlagUtils:
-    
-StaticUtils: android.util.proto.ProtoStream:
-    
+    Fully-static utility classes must not have constructor
 
 
 StreamFiles: android.os.Environment#buildPath(java.io.File, java.lang.String...):
-    
+    Methods accepting `File` should also accept `FileDescriptor` or streams: method android.os.Environment.buildPath(java.io.File,java.lang.String...)
 StreamFiles: android.os.FileUtils#contains(java.io.File, java.io.File):
-    
-StreamFiles: android.provider.MediaStore#scanFile(android.content.Context, java.io.File):
-    
-StreamFiles: android.provider.MediaStore#scanFileFromShell(android.content.Context, java.io.File):
-    
-StreamFiles: android.provider.MediaStore#scanVolume(android.content.Context, java.io.File):
-    
+    Methods accepting `File` should also accept `FileDescriptor` or streams: method android.os.FileUtils.contains(java.io.File,java.io.File)
 
 
 UseIcu: android.hardware.soundtrigger.KeyphraseEnrollmentInfo#getKeyphraseMetadata(String, java.util.Locale) parameter #1:
-    
+    Type `java.util.Locale` should be replaced with richer ICU type `android.icu.util.ULocale`
 UseIcu: android.hardware.soundtrigger.KeyphraseEnrollmentInfo#getManageKeyphraseIntent(int, String, java.util.Locale) parameter #2:
-    
+    Type `java.util.Locale` should be replaced with richer ICU type `android.icu.util.ULocale`
 UseIcu: android.hardware.soundtrigger.KeyphraseMetadata#supportsLocale(java.util.Locale) parameter #0:
-    
-UseIcu: android.hardware.soundtrigger.SoundTrigger.Keyphrase#Keyphrase(int, int, java.util.Locale, String, int[]) parameter #2:
-    
-UseIcu: android.hardware.soundtrigger.SoundTrigger.Keyphrase#getLocale():
-    
+    Type `java.util.Locale` should be replaced with richer ICU type `android.icu.util.ULocale`
 
 
-UseParcelFileDescriptor: android.util.proto.ProtoOutputStream#ProtoOutputStream(java.io.FileDescriptor) parameter #0:
-    
-
-
-UserHandle: android.app.ActivityManager#switchUser(android.os.UserHandle):
-    
 UserHandle: android.app.admin.DevicePolicyManager#getOwnerInstalledCaCerts(android.os.UserHandle):
-    
+    When a method overload is needed to target a specific UserHandle, callers should be directed to use Context.createPackageContextAsUser() and re-obtain the relevant Manager, and no new API should be added
 UserHandle: android.app.usage.StorageStatsManager#queryCratesForPackage(java.util.UUID, String, android.os.UserHandle):
-    
+    When a method overload is needed to target a specific UserHandle, callers should be directed to use Context.createPackageContextAsUser() and re-obtain the relevant Manager, and no new API should be added
 UserHandle: android.app.usage.StorageStatsManager#queryCratesForUser(java.util.UUID, android.os.UserHandle):
-    
-UserHandle: android.companion.CompanionDeviceManager#isDeviceAssociated(String, android.net.MacAddress, android.os.UserHandle):
-    
-UserHandle: android.companion.CompanionDeviceManager#isDeviceAssociatedForWifiConnection(String, android.net.MacAddress, android.os.UserHandle):
-    
+    When a method overload is needed to target a specific UserHandle, callers should be directed to use Context.createPackageContextAsUser() and re-obtain the relevant Manager, and no new API should be added
 UserHandle: android.content.pm.PackageManager#getInstallReason(String, android.os.UserHandle):
-    
-UserHandle: android.content.pm.PackageManager#getPermissionFlags(String, String, android.os.UserHandle):
-    
-UserHandle: android.content.pm.PackageManager#grantRuntimePermission(String, String, android.os.UserHandle):
-    
-UserHandle: android.content.pm.PackageManager#revokeRuntimePermission(String, String, android.os.UserHandle):
-    
-UserHandle: android.content.pm.PackageManager#revokeRuntimePermission(String, String, android.os.UserHandle, String):
-    
-UserHandle: android.content.pm.PackageManager#updatePermissionFlags(String, String, int, int, android.os.UserHandle):
-    
-UserHandle: android.location.LocationManager#setLocationEnabledForUser(boolean, android.os.UserHandle):
-    
-UserHandle: android.permission.PermissionControllerManager#applyStagedRuntimePermissionBackup(String, android.os.UserHandle, java.util.concurrent.Executor, java.util.function.Consumer<java.lang.Boolean>):
-    
-UserHandle: android.permission.PermissionControllerManager#getRuntimePermissionBackup(android.os.UserHandle, java.util.concurrent.Executor, java.util.function.Consumer<byte[]>):
-    
-UserHandle: android.permission.PermissionControllerManager#stageAndApplyRuntimePermissionsBackup(byte[], android.os.UserHandle):
-    
-UserHandle: android.telecom.TelecomManager#getDefaultDialerPackage(android.os.UserHandle):
-    
+    When a method overload is needed to target a specific UserHandle, callers should be directed to use Context.createPackageContextAsUser() and re-obtain the relevant Manager, and no new API should be added
 
 
 UserHandleName: android.content.AutofillOptions:
-    
+    Classes holding a set of parameters should be called `FooParams`, was `AutofillOptions`
 UserHandleName: android.content.ContentCaptureOptions:
-    
-UserHandleName: android.os.IncidentReportArgs:
-    
-UserHandleName: android.provider.MediaStore#deleteContributedMedia(android.content.Context, String, android.os.UserHandle):
-    
-UserHandleName: android.provider.MediaStore#getContributedMediaSize(android.content.Context, String, android.os.UserHandle):
-    
+    Classes holding a set of parameters should be called `FooParams`, was `ContentCaptureOptions`
 
 
-VisiblySynchronized: PsiClassObjectAccessExpression:
-    
-VisiblySynchronized: PsiThisExpression:
-    
-VisiblySynchronized: android.app.ActivityManager#addOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener, int):
-    
-VisiblySynchronized: android.app.ActivityManager#removeOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener):
-    
-VisiblySynchronized: android.content.ContentProviderClient#setDetectNotResponding(long):
-    
+VisiblySynchronized: PsiThisExpression:this:
+    Internal locks must not be exposed (synchronizing on this or class is still externally observable): method android.content.res.AssetManager.getApkPaths()
 VisiblySynchronized: android.content.res.AssetManager#getApkPaths():
-    
+    Internal locks must not be exposed (synchronizing on this or class is still externally observable): method android.content.res.AssetManager.getApkPaths()
 VisiblySynchronized: android.content.res.AssetManager#getLastResourceResolution():
-    
+    Internal locks must not be exposed (synchronizing on this or class is still externally observable): method android.content.res.AssetManager.getLastResourceResolution()
 VisiblySynchronized: android.content.res.AssetManager#getOverlayablesToString(String):
-    
+    Internal locks must not be exposed (synchronizing on this or class is still externally observable): method android.content.res.AssetManager.getOverlayablesToString(String)
 VisiblySynchronized: android.content.res.AssetManager#setResourceResolutionLoggingEnabled(boolean):
-    
+    Internal locks must not be exposed (synchronizing on this or class is still externally observable): method android.content.res.AssetManager.setResourceResolutionLoggingEnabled(boolean)
 VisiblySynchronized: android.os.MessageQueue#removeSyncBarrier(int):
-    
+    Internal locks must not be exposed (synchronizing on this or class is still externally observable): method android.os.MessageQueue.removeSyncBarrier(int)
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index d641a3b..d16f331 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -960,7 +960,7 @@
     @Override
     public int checkSignatures(String pkg1, String pkg2) {
         try {
-            return mPM.checkSignatures(pkg1, pkg2);
+            return mPM.checkSignatures(pkg1, pkg2, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index e9c29b8..77d7839 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -51,6 +51,7 @@
 import android.view.WindowManager.LayoutParams;
 import android.view.WindowManagerGlobal;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.policy.IKeyguardDismissCallback;
 import com.android.internal.policy.IKeyguardLockedStateListener;
 import com.android.internal.util.Preconditions;
@@ -756,7 +757,9 @@
         }
     }
 
-    private boolean checkInitialLockMethodUsage() {
+    /** @hide */
+    @VisibleForTesting
+    public boolean checkInitialLockMethodUsage() {
         if (!hasPermission(Manifest.permission.SET_INITIAL_LOCK)) {
             throw new SecurityException("Requires SET_INITIAL_LOCK permission.");
         }
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 53e7559..974d20a 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1901,6 +1901,11 @@
 
             /**
              * Construct a new builder for {@link Action} object.
+             * <p>As of Android {@link android.os.Build.VERSION_CODES#N},
+             * action button icons will not be displayed on action buttons, but are still required
+             * and are available to
+             * {@link android.service.notification.NotificationListenerService notification listeners},
+             * which may display them in other contexts, for example on a wearable device.
              * @param icon icon to show for this action
              * @param title the title of the action
              * @param intent the {@link PendingIntent} to fire when users trigger this action
@@ -1923,6 +1928,12 @@
              * both are displayed or required, depends on where and how the action is used, and the
              * {@link Style} applied to the Notification.
              *
+             * <p>As of Android {@link android.os.Build.VERSION_CODES#N}, action button icons
+             * will not be displayed on action buttons, but are still required and are available
+             * to {@link android.service.notification.NotificationListenerService notification
+             * listeners}, which may display them in other contexts, for example on a wearable
+             * device.
+             *
              * <p>When the {@code title} is a {@link android.text.Spanned}, any colors set by a
              * {@link ForegroundColorSpan} or {@link TextAppearanceSpan} may be removed or displayed
              * with an altered in luminance to ensure proper contrast within the Notification.
@@ -4918,6 +4929,12 @@
          * while processing broadcast receivers or services in response to notification action
          * clicks. To launch an activity in those cases, provide a {@link PendingIntent} to the
          * activity itself.
+         * <p>
+         * As of Android {@link android.os.Build.VERSION_CODES#N},
+         * action button icons will not be displayed on action buttons, but are still required
+         * and are available to
+         * {@link android.service.notification.NotificationListenerService notification listeners},
+         * which may display them in other contexts, for example on a wearable device.
          *
          * @param icon Resource ID of a drawable that represents the action.
          * @param title Text describing the action.
diff --git a/core/java/android/app/TEST_MAPPING b/core/java/android/app/TEST_MAPPING
index a8ae191..d94209a 100644
--- a/core/java/android/app/TEST_MAPPING
+++ b/core/java/android/app/TEST_MAPPING
@@ -168,6 +168,23 @@
                     "exclude-annotation": "androidx.test.filters.FlakyTest"
                 }
             ]
+        },
+        {
+            "name": "FrameworksCoreTests",
+            "options": [
+                {
+                    "exclude-annotation": "androidx.test.filters.FlakyTest"
+                },
+                {
+                    "exclude-annotation": "org.junit.Ignore"
+                },
+                {
+                    "include-filter": "android.app.KeyguardManagerTest"
+                }
+            ],
+            "file_patterns": [
+                "(/|^)KeyguardManager.java"
+            ]
         }
     ],
     "presubmit-large": [
diff --git a/core/java/android/app/WindowConfiguration.java b/core/java/android/app/WindowConfiguration.java
index e502ba0..5ef3fc0 100644
--- a/core/java/android/app/WindowConfiguration.java
+++ b/core/java/android/app/WindowConfiguration.java
@@ -819,11 +819,8 @@
         return isFloating(mWindowingMode);
     }
 
-    /**
-     * Returns true if the windowingMode represents a floating window.
-     * @hide
-     */
-    public static boolean isFloating(int windowingMode) {
+    /** Returns true if the windowingMode represents a floating window. */
+    public static boolean isFloating(@WindowingMode int windowingMode) {
         return windowingMode == WINDOWING_MODE_FREEFORM || windowingMode == WINDOWING_MODE_PINNED;
     }
 
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 26b9bc8..41a0e61 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -3322,8 +3322,8 @@
      * Activity action: Starts the device policy management role holder updater.
      *
      * <p>The activity must handle the device policy management role holder update and set the
-     * intent result to either {@link Activity#RESULT_OK} if the update was successful or not
-     * necessary, {@link #RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_RECOVERABLE_ERROR} if
+     * intent result. This can include {@link Activity#RESULT_OK} if the update was successful,
+     * {@link #RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_RECOVERABLE_ERROR} if
      * it encounters a problem that may be solved by relaunching it again, {@link
      * #RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_PROVISIONING_DISABLED} if role holder
      * provisioning is disabled, or {@link
@@ -3376,7 +3376,8 @@
 
     /**
      * An {@code int} extra which contains the result code of the last attempt to update
-     * the device policy management role holder.
+     * the device policy management role holder via {@link
+     * #ACTION_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER}.
      *
      * <p>This extra is provided to the device policy management role holder via either {@link
      * #ACTION_ROLE_HOLDER_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE} or {@link
@@ -3394,6 +3395,8 @@
      *    encounters a problem that may be solved by relaunching it again.
      *    <li>{@link #RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_UNRECOVERABLE_ERROR} if
      *    it encounters a problem that will not be solved by relaunching it again.
+     *    <li>Any other value returned by {@link
+     *    #ACTION_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER}
      * </ul>
      *
      * @hide
diff --git a/core/java/android/app/admin/PreferentialNetworkServiceConfig.java b/core/java/android/app/admin/PreferentialNetworkServiceConfig.java
index 54170a2..24b4f4b 100644
--- a/core/java/android/app/admin/PreferentialNetworkServiceConfig.java
+++ b/core/java/android/app/admin/PreferentialNetworkServiceConfig.java
@@ -16,15 +16,31 @@
 
 package android.app.admin;
 
+import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
+import static org.xmlpull.v1.XmlPullParser.END_TAG;
+import static org.xmlpull.v1.XmlPullParser.TEXT;
+
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.SuppressLint;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.IndentingPrintWriter;
+import android.util.Log;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
 
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
 import java.util.Objects;
+import java.util.stream.Collectors;
 
 /**
  * Network configuration to be set for the user profile
@@ -37,6 +53,20 @@
     final int[] mIncludedUids;
     final int[] mExcludedUids;
 
+    private static final String LOG_TAG = "PreferentialNetworkServiceConfig";
+    private static final String TAG_PREFERENTIAL_NETWORK_SERVICE_CONFIG =
+            "preferential_network_service_config";
+    private static final String TAG_CONFIG_ENABLED =
+            "preferential_network_service_config_enabled";
+    private static final String TAG_UID = "uid";
+    private static final String TAG_NETWORK_ID =
+            "preferential_network_service_network_id";
+    private static final String TAG_ALLOW_FALLBACK_TO_DEFAULT_CONNECTION =
+            "allow_fallback_to_default_connection";
+    private static final String TAG_INCLUDED_UIDS = "included_uids";
+    private static final String TAG_EXCLUDED_UIDS = "excluded_uids";
+    private static final String ATTR_VALUE = "value";
+
     /** @hide */
     public static final PreferentialNetworkServiceConfig DEFAULT =
             (new PreferentialNetworkServiceConfig.Builder()).build();
@@ -159,8 +189,8 @@
         return "PreferentialNetworkServiceConfig{"
                 + "mIsEnabled=" + isEnabled()
                 + "mAllowFallbackToDefaultConnection=" + isFallbackToDefaultConnectionAllowed()
-                + "mIncludedUids=" + mIncludedUids.toString()
-                + "mExcludedUids=" + mExcludedUids.toString()
+                + "mIncludedUids=" + Arrays.toString(mIncludedUids)
+                + "mExcludedUids=" + Arrays.toString(mExcludedUids)
                 + "mNetworkId=" + mNetworkId
                 + '}';
     }
@@ -309,6 +339,135 @@
         dest.writeIntArray(mExcludedUids);
     }
 
+    private void writeAttributeValueToXml(TypedXmlSerializer out, String tag, int value)
+            throws IOException {
+        out.startTag(null, tag);
+        out.attributeInt(null, ATTR_VALUE, value);
+        out.endTag(null, tag);
+    }
+
+    private void writeAttributeValueToXml(TypedXmlSerializer out, String tag, boolean value)
+            throws IOException {
+        out.startTag(null, tag);
+        out.attributeBoolean(null, ATTR_VALUE, value);
+        out.endTag(null, tag);
+    }
+
+    private void writeAttributeValuesToXml(TypedXmlSerializer out, String outerTag, String innerTag,
+            @NonNull Collection<String> values) throws IOException {
+        out.startTag(null, outerTag);
+        for (String value : values) {
+            out.startTag(null, innerTag);
+            out.attribute(null, ATTR_VALUE, value);
+            out.endTag(null, innerTag);
+        }
+        out.endTag(null, outerTag);
+    }
+
+    private static  void readAttributeValues(
+            TypedXmlPullParser parser, String tag, Collection<String> result)
+            throws XmlPullParserException, IOException {
+        result.clear();
+        int outerDepthDAM = parser.getDepth();
+        int typeDAM;
+        while ((typeDAM = parser.next()) != END_DOCUMENT
+                && (typeDAM != END_TAG || parser.getDepth() > outerDepthDAM)) {
+            if (typeDAM == END_TAG || typeDAM == TEXT) {
+                continue;
+            }
+            String tagDAM = parser.getName();
+            if (tag.equals(tagDAM)) {
+                result.add(parser.getAttributeValue(null, ATTR_VALUE));
+            } else {
+                Log.e(LOG_TAG, "Expected tag " + tag + " but found " + tagDAM);
+            }
+        }
+    }
+
+    private List<String> intArrayToStringList(int[] array) {
+        return Arrays.stream(array).mapToObj(String::valueOf).collect(Collectors.toList());
+    }
+
+    private static int[] readStringListToIntArray(TypedXmlPullParser parser, String tag)
+            throws XmlPullParserException, IOException {
+        List<String> stringList = new ArrayList<>();
+        readAttributeValues(parser, tag, stringList);
+        int[] intArray = stringList.stream()
+                .map(s -> Integer.parseInt(s))
+                .mapToInt(Integer::intValue)
+                .toArray();
+        return intArray;
+    }
+
+    /**
+     * @hide
+     */
+    public static PreferentialNetworkServiceConfig getPreferentialNetworkServiceConfig(
+            TypedXmlPullParser parser, String tag) throws XmlPullParserException, IOException  {
+        int outerDepthDAM = parser.getDepth();
+        int typeDAM;
+        PreferentialNetworkServiceConfig.Builder resultBuilder =
+                new PreferentialNetworkServiceConfig.Builder();
+        while ((typeDAM = parser.next()) != END_DOCUMENT
+                && (typeDAM != END_TAG || parser.getDepth() > outerDepthDAM)) {
+            if (typeDAM == END_TAG || typeDAM == TEXT) {
+                continue;
+            }
+            String tagDAM = parser.getName();
+            if (TAG_CONFIG_ENABLED.equals(tagDAM)) {
+                resultBuilder.setEnabled(parser.getAttributeBoolean(null, ATTR_VALUE,
+                        DevicePolicyManager.PREFERENTIAL_NETWORK_SERVICE_ENABLED_DEFAULT));
+            } else if (TAG_NETWORK_ID.equals(tagDAM)) {
+                int val = parser.getAttributeInt(null, ATTR_VALUE, 0);
+                if (val != 0) {
+                    resultBuilder.setNetworkId(val);
+                }
+            } else if (TAG_ALLOW_FALLBACK_TO_DEFAULT_CONNECTION.equals(tagDAM)) {
+                resultBuilder.setFallbackToDefaultConnectionAllowed(parser.getAttributeBoolean(
+                        null, ATTR_VALUE, true));
+            } else if (TAG_INCLUDED_UIDS.equals(tagDAM)) {
+                resultBuilder.setIncludedUids(readStringListToIntArray(parser, TAG_UID));
+            } else if (TAG_EXCLUDED_UIDS.equals(tagDAM)) {
+                resultBuilder.setExcludedUids(readStringListToIntArray(parser, TAG_UID));
+            } else {
+                Log.w(LOG_TAG, "Unknown tag under " + tag + ": " + tagDAM);
+            }
+        }
+        return resultBuilder.build();
+    }
+
+    /**
+     * @hide
+     */
+    public void writeToXml(@NonNull TypedXmlSerializer out) throws IOException {
+        out.startTag(null, TAG_PREFERENTIAL_NETWORK_SERVICE_CONFIG);
+        writeAttributeValueToXml(out, TAG_CONFIG_ENABLED, isEnabled());
+        writeAttributeValueToXml(out, TAG_NETWORK_ID, getNetworkId());
+        writeAttributeValueToXml(out, TAG_ALLOW_FALLBACK_TO_DEFAULT_CONNECTION,
+                isFallbackToDefaultConnectionAllowed());
+        writeAttributeValuesToXml(out, TAG_INCLUDED_UIDS, TAG_UID,
+                intArrayToStringList(getIncludedUids()));
+        writeAttributeValuesToXml(out, TAG_EXCLUDED_UIDS, TAG_UID,
+                intArrayToStringList(getExcludedUids()));
+        out.endTag(null, TAG_PREFERENTIAL_NETWORK_SERVICE_CONFIG);
+    }
+
+    /**
+     * @hide
+     */
+    public void dump(IndentingPrintWriter pw) {
+        pw.print("networkId=");
+        pw.println(mNetworkId);
+        pw.print("isEnabled=");
+        pw.println(mIsEnabled);
+        pw.print("allowFallbackToDefaultConnection=");
+        pw.println(mAllowFallbackToDefaultConnection);
+        pw.print("includedUids=");
+        pw.println(mIncludedUids);
+        pw.print("excludedUids=");
+        pw.println(mExcludedUids);
+    }
+
     @Override
     public int describeContents() {
         return 0;
diff --git a/core/java/android/app/ambientcontext/AmbientContextManager.java b/core/java/android/app/ambientcontext/AmbientContextManager.java
index 7f913e7..dd1dd0c 100644
--- a/core/java/android/app/ambientcontext/AmbientContextManager.java
+++ b/core/java/android/app/ambientcontext/AmbientContextManager.java
@@ -153,7 +153,7 @@
      *   eventTypes.add(AmbientContextEvent.EVENT_SNORE);
      *
      *   // Create Consumer
-     *   Consumer<Integer> statusConsumer = response -> {
+     *   Consumer<Integer> statusConsumer = status -> {
      *     int status = status.getStatusCode();
      *     if (status == AmbientContextManager.STATUS_SUCCESS) {
      *       // Show user it's enabled
diff --git a/core/java/android/app/smartspace/ISmartspaceManager.aidl b/core/java/android/app/smartspace/ISmartspaceManager.aidl
index e7ec889..8dc07a1 100644
--- a/core/java/android/app/smartspace/ISmartspaceManager.aidl
+++ b/core/java/android/app/smartspace/ISmartspaceManager.aidl
@@ -26,7 +26,7 @@
 /**
  * @hide
  */
-interface ISmartspaceManager {
+oneway interface ISmartspaceManager {
 
     void createSmartspaceSession(in SmartspaceConfig config, in SmartspaceSessionId sessionId,
             in IBinder token);
diff --git a/core/java/android/content/SharedPreferences.java b/core/java/android/content/SharedPreferences.java
index c193868..de6dc22 100644
--- a/core/java/android/content/SharedPreferences.java
+++ b/core/java/android/content/SharedPreferences.java
@@ -68,7 +68,7 @@
          *            {@link android.os.Build.VERSION_CODES#R Android R} or later, will receive
          *            a {@code null} value when preferences are cleared.
          */
-        void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key);
+        void onSharedPreferenceChanged(SharedPreferences sharedPreferences, @Nullable String key);
     }
 
     /**
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 9738ff6..f49ab57 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -100,8 +100,7 @@
 
     boolean isProtectedBroadcast(String actionName);
 
-    @UnsupportedAppUsage
-    int checkSignatures(String pkg1, String pkg2);
+    int checkSignatures(String pkg1, String pkg2, int userId);
 
     @UnsupportedAppUsage
     int checkUidSignatures(int uid1, int uid2);
diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index 31f3b6a..06edf66 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -1363,19 +1363,27 @@
 
             // Consolidate positional feedback to reduce noise during authentication.
             case FACE_ACQUIRED_NOT_DETECTED:
+                return context.getString(R.string.face_acquired_not_detected);
             case FACE_ACQUIRED_TOO_CLOSE:
+                return context.getString(R.string.face_acquired_too_close);
             case FACE_ACQUIRED_TOO_FAR:
+                return context.getString(R.string.face_acquired_too_far);
             case FACE_ACQUIRED_TOO_HIGH:
+                return context.getString(R.string.face_acquired_too_high);
             case FACE_ACQUIRED_TOO_LOW:
+                return context.getString(R.string.face_acquired_too_low);
             case FACE_ACQUIRED_TOO_RIGHT:
+                return context.getString(R.string.face_acquired_too_right);
             case FACE_ACQUIRED_TOO_LEFT:
+                return context.getString(R.string.face_acquired_too_left);
             case FACE_ACQUIRED_POOR_GAZE:
-            case FACE_ACQUIRED_PAN_TOO_EXTREME:
-            case FACE_ACQUIRED_TILT_TOO_EXTREME:
-            case FACE_ACQUIRED_ROLL_TOO_EXTREME:
                 return context.getString(R.string.face_acquired_poor_gaze);
-
-            // Provide more detailed feedback for other soft errors.
+            case FACE_ACQUIRED_PAN_TOO_EXTREME:
+                return context.getString(R.string.face_acquired_pan_too_extreme);
+            case FACE_ACQUIRED_TILT_TOO_EXTREME:
+                return context.getString(R.string.face_acquired_tilt_too_extreme);
+            case FACE_ACQUIRED_ROLL_TOO_EXTREME:
+                return context.getString(R.string.face_acquired_roll_too_extreme);
             case FACE_ACQUIRED_INSUFFICIENT:
                 return context.getString(R.string.face_acquired_insufficient);
             case FACE_ACQUIRED_TOO_BRIGHT:
@@ -1394,6 +1402,10 @@
                 return context.getString(R.string.face_acquired_obscured);
             case FACE_ACQUIRED_SENSOR_DIRTY:
                 return context.getString(R.string.face_acquired_sensor_dirty);
+            case FACE_ACQUIRED_DARK_GLASSES_DETECTED:
+                return context.getString(R.string.face_acquired_dark_glasses_detected);
+            case FACE_ACQUIRED_MOUTH_COVERING_DETECTED:
+                return context.getString(R.string.face_acquired_mouth_covering_detected);
 
             // Find and return the appropriate vendor-specific message.
             case FACE_ACQUIRED_VENDOR: {
@@ -1459,11 +1471,13 @@
             case FACE_ACQUIRED_ROLL_TOO_EXTREME:
                 return context.getString(R.string.face_acquired_roll_too_extreme);
             case FACE_ACQUIRED_FACE_OBSCURED:
-            case FACE_ACQUIRED_DARK_GLASSES_DETECTED:
-            case FACE_ACQUIRED_MOUTH_COVERING_DETECTED:
                 return context.getString(R.string.face_acquired_obscured);
             case FACE_ACQUIRED_SENSOR_DIRTY:
                 return context.getString(R.string.face_acquired_sensor_dirty);
+            case FACE_ACQUIRED_DARK_GLASSES_DETECTED:
+                return context.getString(R.string.face_acquired_dark_glasses_detected);
+            case FACE_ACQUIRED_MOUTH_COVERING_DETECTED:
+                return context.getString(R.string.face_acquired_mouth_covering_detected);
             case FACE_ACQUIRED_VENDOR: {
                 String[] msgArray = context.getResources().getStringArray(
                         R.array.face_acquired_vendor);
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 90db461..54f6fef 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -36,7 +36,6 @@
 import android.hardware.lights.LightsManager;
 import android.hardware.lights.LightsRequest;
 import android.os.Binder;
-import android.os.BlockUntrustedTouchesMode;
 import android.os.Build;
 import android.os.CombinedVibration;
 import android.os.Handler;
@@ -67,7 +66,6 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.SomeArgs;
-import com.android.internal.util.ArrayUtils;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -87,13 +85,6 @@
     private static final int MSG_DEVICE_REMOVED = 2;
     private static final int MSG_DEVICE_CHANGED = 3;
 
-    /** @hide */
-    public static final int[] BLOCK_UNTRUSTED_TOUCHES_MODES = {
-            BlockUntrustedTouchesMode.DISABLED,
-            BlockUntrustedTouchesMode.PERMISSIVE,
-            BlockUntrustedTouchesMode.BLOCK
-    };
-
     private static InputManager sInstance;
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
@@ -200,14 +191,6 @@
     public static final float DEFAULT_MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH = .8f;
 
     /**
-     * Default mode of the block untrusted touches mode feature.
-     * @hide
-     */
-    @BlockUntrustedTouchesMode
-    public static final int DEFAULT_BLOCK_UNTRUSTED_TOUCHES_MODE =
-            BlockUntrustedTouchesMode.BLOCK;
-
-    /**
      * Prevent touches from being consumed by apps if these touches passed through a non-trusted
      * window from a different UID and are considered unsafe.
      *
@@ -1015,50 +998,6 @@
     }
 
     /**
-     * Returns the current mode of the block untrusted touches feature, one of:
-     * <ul>
-     *     <li>{@link BlockUntrustedTouchesMode#DISABLED}
-     *     <li>{@link BlockUntrustedTouchesMode#PERMISSIVE}
-     *     <li>{@link BlockUntrustedTouchesMode#BLOCK}
-     * </ul>
-     *
-     * @hide
-     */
-    @TestApi
-    @BlockUntrustedTouchesMode
-    public int getBlockUntrustedTouchesMode(@NonNull Context context) {
-        int mode = Settings.Global.getInt(context.getContentResolver(),
-                Settings.Global.BLOCK_UNTRUSTED_TOUCHES_MODE, DEFAULT_BLOCK_UNTRUSTED_TOUCHES_MODE);
-        if (!ArrayUtils.contains(BLOCK_UNTRUSTED_TOUCHES_MODES, mode)) {
-            Log.w(TAG, "Unknown block untrusted touches feature mode " + mode + ", using "
-                    + "default " + DEFAULT_BLOCK_UNTRUSTED_TOUCHES_MODE);
-            return DEFAULT_BLOCK_UNTRUSTED_TOUCHES_MODE;
-        }
-        return mode;
-    }
-
-    /**
-     * Sets the mode of the block untrusted touches feature to one of:
-     * <ul>
-     *     <li>{@link BlockUntrustedTouchesMode#DISABLED}
-     *     <li>{@link BlockUntrustedTouchesMode#PERMISSIVE}
-     *     <li>{@link BlockUntrustedTouchesMode#BLOCK}
-     * </ul>
-     *
-     * @hide
-     */
-    @TestApi
-    @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
-    public void setBlockUntrustedTouchesMode(@NonNull Context context,
-            @BlockUntrustedTouchesMode int mode) {
-        if (!ArrayUtils.contains(BLOCK_UNTRUSTED_TOUCHES_MODES, mode)) {
-            throw new IllegalArgumentException("Invalid feature mode " + mode);
-        }
-        Settings.Global.putInt(context.getContentResolver(),
-                Settings.Global.BLOCK_UNTRUSTED_TOUCHES_MODE, mode);
-    }
-
-    /**
      * Queries the framework about whether any physical keys exist on any currently attached input
      * devices that are capable of producing the given array of key codes.
      *
diff --git a/core/java/android/net/VpnProfileState.java b/core/java/android/net/VpnProfileState.java
index 0f21a9d..552a2c1 100644
--- a/core/java/android/net/VpnProfileState.java
+++ b/core/java/android/net/VpnProfileState.java
@@ -24,6 +24,7 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
 import java.util.StringJoiner;
 
 /**
@@ -176,4 +177,19 @@
         resultJoiner.add("Lockdown: " + isLockdownEnabled());
         return resultJoiner.toString();
     }
+
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (!(obj instanceof VpnProfileState)) return false;
+        final VpnProfileState that = (VpnProfileState) obj;
+        return (getState() == that.getState()
+                && Objects.equals(getSessionId(), that.getSessionId())
+                && isAlwaysOn() == that.isAlwaysOn()
+                && isLockdownEnabled() == that.isLockdownEnabled());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getState(), getSessionId(), isAlwaysOn(), isLockdownEnabled());
+    }
 }
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index 1f888ba..cb7e6f7 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -107,21 +107,13 @@
     private static final int UPDATABLE_DRIVER_GLOBAL_OPT_IN_PRERELEASE_DRIVER = 2;
     private static final int UPDATABLE_DRIVER_GLOBAL_OPT_IN_OFF = 3;
 
-    // System properties related to ANGLE and legacy GLES graphics drivers.
-    private static final String PROPERTY_EGL_SYSTEM_DRIVER = "ro.hardware.egl";
-    // TODO (b/224558229): Properly add this to the list of system properties for a device:
-    private static final String PROPERTY_EGL_LEGACY_DRIVER = "ro.hardware.egl.legacy";
-
     // Values for ANGLE_GL_DRIVER_ALL_ANGLE
     private static final int ANGLE_GL_DRIVER_ALL_ANGLE_ON = 1;
     private static final int ANGLE_GL_DRIVER_ALL_ANGLE_OFF = 0;
-    private static final int ANGLE_GL_DRIVER_ALL_LEGACY = -1;
 
     // Values for ANGLE_GL_DRIVER_SELECTION_VALUES
     private static final String ANGLE_GL_DRIVER_CHOICE_DEFAULT = "default";
     private static final String ANGLE_GL_DRIVER_CHOICE_ANGLE = "angle";
-    private static final String ANGLE_GL_DRIVER_CHOICE_LEGACY = "legacy";
-    // The following value is a deprecated choice for "legacy"
     private static final String ANGLE_GL_DRIVER_CHOICE_NATIVE = "native";
 
     private ClassLoader mClassLoader;
@@ -129,13 +121,6 @@
     private String mLibraryPermittedPaths;
     private GameManager mGameManager;
 
-    private boolean mAngleIsSystemDriver = false;
-    // When ANGLE is the system driver, this is the name of the legacy driver.
-    //
-    // TODO (b/224558229): This is temporarily set to a value that works for Pixel 6, until
-    // PROPERTY_EGL_LEGACY_DRIVER has been properly plumbed and this becomes broadly available.
-    private String mEglLegacyDriver = "mali";
-
     private int mAngleOptInIndex = -1;
 
     /**
@@ -153,24 +138,6 @@
         setupGpuLayers(context, coreSettings, pm, packageName, appInfoWithMetaData);
         Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);
 
-        // Determine if ANGLE is the system driver, as this will determine other logic
-        final String eglSystemDriver = SystemProperties.get(PROPERTY_EGL_SYSTEM_DRIVER);
-        Log.v(TAG, "GLES system driver is '" + eglSystemDriver + "'");
-        mAngleIsSystemDriver = eglSystemDriver.equals(ANGLE_DRIVER_NAME);
-        if (mAngleIsSystemDriver) {
-            // Lookup the legacy driver, to send down to the EGL loader
-            /* TODO (b/224558229): This is temporarily set to a value that works for Pixel 6, until
-             * PROPERTY_EGL_LEGACY_DRIVER has been properly plumbed and this becomes broadly
-             * available:
-            final String eglLegacyDriver = SystemProperties.get(PROPERTY_EGL_LEGACY_DRIVER);
-            if (eglLegacyDriver.isEmpty()) {
-            */
-            mEglLegacyDriver = "mali";
-            /*}*/
-            Log.v(TAG, "Legacy GLES driver is '" + mEglLegacyDriver + "'");
-        }
-
-        // Setup ANGLE and pass down ANGLE details to the C++ code
         Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "setupAngle");
         boolean useAngle = false;
         if (setupAngle(context, coreSettings, pm, packageName)) {
@@ -221,13 +188,13 @@
     /**
      * Query to determine if ANGLE should be used
      */
-    private boolean shouldUseAngle(Context context, Bundle coreSettings, String packageName) {
+    private boolean shouldUseAngle(Context context, Bundle coreSettings,
+            String packageName) {
         if (TextUtils.isEmpty(packageName)) {
-            Log.v(TAG, "No package name specified; use the system driver");
-            return mAngleIsSystemDriver ? true : false;
+            Log.v(TAG, "No package name specified, ANGLE should not be used");
+            return false;
         }
 
-        // getDriverForPackage() will change "default" into either "angle" or "legacy"
         final String devOptIn = getDriverForPackage(context, coreSettings, packageName);
         Log.v(TAG, "ANGLE Developer option for '" + packageName + "' "
                 + "set to: '" + devOptIn + "'");
@@ -235,14 +202,14 @@
         // We only want to use ANGLE if the developer has explicitly chosen something other than
         // default driver.
         final boolean forceAngle = devOptIn.equals(ANGLE_GL_DRIVER_CHOICE_ANGLE);
-        final boolean forceLegacy = devOptIn.equals(ANGLE_GL_DRIVER_CHOICE_LEGACY);
-        if (forceAngle || forceLegacy) {
+        final boolean forceNative = devOptIn.equals(ANGLE_GL_DRIVER_CHOICE_NATIVE);
+        if (forceAngle || forceNative) {
             Log.v(TAG, "ANGLE developer option for " + packageName + ": " + devOptIn);
         }
 
         final boolean gameModeEnabledAngle = isAngleEnabledByGameMode(context, packageName);
 
-        return !forceLegacy && (forceAngle || gameModeEnabledAngle);
+        return !forceNative && (forceAngle || gameModeEnabledAngle);
     }
 
     private int getVulkanVersion(PackageManager pm) {
@@ -450,51 +417,34 @@
         return ai;
     }
 
-    /**
-     * Return the appropriate "default" driver choice.
-     */
-    private String getDefaultDriverChoice() {
-        if (mAngleIsSystemDriver) {
-            return ANGLE_GL_DRIVER_CHOICE_ANGLE;
-        } else {
-            return ANGLE_GL_DRIVER_CHOICE_LEGACY;
-        }
-    }
-
     private String getDriverForPackage(Context context, Bundle bundle, String packageName) {
-        // Check the semi-global switch (i.e. once system has booted enough) for whether ANGLE
-        // should be forced on or off for "all appplications"
         final int allUseAngle;
         if (bundle != null) {
-            allUseAngle = bundle.getInt(Settings.Global.ANGLE_GL_DRIVER_ALL_ANGLE);
+            allUseAngle =
+                    bundle.getInt(Settings.Global.ANGLE_GL_DRIVER_ALL_ANGLE);
         } else {
             ContentResolver contentResolver = context.getContentResolver();
             allUseAngle = Settings.Global.getInt(contentResolver,
-                    Settings.Global.ANGLE_GL_DRIVER_ALL_ANGLE, ANGLE_GL_DRIVER_ALL_ANGLE_OFF);
+                    Settings.Global.ANGLE_GL_DRIVER_ALL_ANGLE,
+                    ANGLE_GL_DRIVER_ALL_ANGLE_OFF);
         }
         if (allUseAngle == ANGLE_GL_DRIVER_ALL_ANGLE_ON) {
             Log.v(TAG, "Turn on ANGLE for all applications.");
             return ANGLE_GL_DRIVER_CHOICE_ANGLE;
         }
-        if (allUseAngle == ANGLE_GL_DRIVER_ALL_LEGACY) {
-            Log.v(TAG, "Disable ANGLE for all applications.");
-            return ANGLE_GL_DRIVER_CHOICE_LEGACY;
-        }
 
         // Make sure we have a good package name
         if (TextUtils.isEmpty(packageName)) {
-            return getDefaultDriverChoice();
+            return ANGLE_GL_DRIVER_CHOICE_DEFAULT;
         }
 
-        // Get the per-application settings lists
         final ContentResolver contentResolver = context.getContentResolver();
-        final List<String> optInPackages = getGlobalSettingsString(
-                contentResolver, bundle, Settings.Global.ANGLE_GL_DRIVER_SELECTION_PKGS);
-        final List<String> optInValues = getGlobalSettingsString(
-                contentResolver, bundle, Settings.Global.ANGLE_GL_DRIVER_SELECTION_VALUES);
-        Log.v(TAG, "getDriverForPackage(): Currently set values for:");
-        Log.v(TAG, "getDriverForPackage():   angle_gl_driver_selection_pkgs =" + optInPackages);
-        Log.v(TAG, "getDriverForPackage():   angle_gl_driver_selection_values =" + optInValues);
+        final List<String> optInPackages =
+                getGlobalSettingsString(contentResolver, bundle,
+                        Settings.Global.ANGLE_GL_DRIVER_SELECTION_PKGS);
+        final List<String> optInValues =
+                getGlobalSettingsString(contentResolver, bundle,
+                        Settings.Global.ANGLE_GL_DRIVER_SELECTION_VALUES);
 
         // Make sure we have good settings to use
         if (optInPackages.size() != optInValues.size()) {
@@ -504,34 +454,17 @@
                             + optInPackages.size() + ", "
                         + "number of values: "
                             + optInValues.size());
-            return getDefaultDriverChoice();
+            return ANGLE_GL_DRIVER_CHOICE_DEFAULT;
         }
 
-        // See if this application is listed in the per-application settings lists
         final int pkgIndex = getPackageIndex(packageName, optInPackages);
 
         if (pkgIndex < 0) {
-            // The application is NOT listed in the per-application settings lists; and so use the
-            // system driver (i.e. either ANGLE or the Legacy driver)
-            Log.v(TAG, "getDriverForPackage(): No per-application setting");
-            return getDefaultDriverChoice();
+            return ANGLE_GL_DRIVER_CHOICE_DEFAULT;
         }
         mAngleOptInIndex = pkgIndex;
 
-        Log.v(TAG,
-                "getDriverForPackage(): using per-application switch: "
-                        + optInValues.get(pkgIndex));
-        // The application IS listed in the per-application settings lists; and so use the
-        // setting--choosing the current system driver if the setting is "default" (i.e. either
-        // ANGLE or the Legacy driver)
-        String rtnValue = optInValues.get(pkgIndex);
-        if (rtnValue.equals(ANGLE_GL_DRIVER_CHOICE_DEFAULT)) {
-            return getDefaultDriverChoice();
-        }
-        if (rtnValue.equals(ANGLE_GL_DRIVER_CHOICE_NATIVE)) {
-            return ANGLE_GL_DRIVER_CHOICE_LEGACY;
-        }
-        return rtnValue;
+        return optInValues.get(pkgIndex);
     }
 
     /**
@@ -581,13 +514,7 @@
     }
 
     /**
-     * Determine whether ANGLE should be used, set it up if so, and pass ANGLE details down to
-     * the C++ GraphicsEnv class.
-     *
-     * If ANGLE will be used, GraphicsEnv::setAngleInfo() will be called to enable ANGLE to be
-     * properly used.  Otherwise, GraphicsEnv::setLegacyDriverInfo() will be called to
-     * enable the legacy GLES driver (e.g. when ANGLE is the system driver) to be identified and
-     * used.
+     * Pass ANGLE details down to trigger enable logic
      *
      * @param context
      * @param bundle
@@ -600,7 +527,6 @@
             String packageName) {
 
         if (!shouldUseAngle(context, bundle, packageName)) {
-            setLegacyDriverInfo(packageName, mAngleIsSystemDriver, mEglLegacyDriver);
             return false;
         }
 
@@ -615,7 +541,6 @@
                 angleInfo = pm.getApplicationInfo(anglePkgName, 0);
             } catch (PackageManager.NameNotFoundException e) {
                 Log.w(TAG, "ANGLE debug package '" + anglePkgName + "' not installed");
-                setLegacyDriverInfo(packageName, mAngleIsSystemDriver, mEglLegacyDriver);
                 return false;
             }
         }
@@ -625,18 +550,16 @@
             anglePkgName = getAnglePackageName(pm);
             if (TextUtils.isEmpty(anglePkgName)) {
                 Log.w(TAG, "Failed to find ANGLE package.");
-                setLegacyDriverInfo(packageName, mAngleIsSystemDriver, mEglLegacyDriver);
                 return false;
             }
 
-            Log.v(TAG, "ANGLE package enabled: " + anglePkgName);
+            Log.i(TAG, "ANGLE package enabled: " + anglePkgName);
             try {
                 // Production ANGLE libraries must be pre-installed as a system app
                 angleInfo = pm.getApplicationInfo(anglePkgName,
                         PackageManager.MATCH_SYSTEM_ONLY);
             } catch (PackageManager.NameNotFoundException e) {
                 Log.w(TAG, "ANGLE package '" + anglePkgName + "' not installed");
-                setLegacyDriverInfo(packageName, mAngleIsSystemDriver, mEglLegacyDriver);
                 return false;
             }
         }
@@ -650,14 +573,12 @@
                 + "!/lib/"
                 + abi;
 
-        if (DEBUG) {
-            Log.v(TAG, "ANGLE package libs: " + paths);
-        }
+        if (DEBUG) Log.v(TAG, "ANGLE package libs: " + paths);
 
         // We need to call setAngleInfo() with the package name and the developer option value
-        // (legacy/angle/other).  Later, when we are actually trying to load a driver,
-        // GraphicsEnv::getShouldUseAngle() has seen the package name before and can confidently
-        // answer yes/no based on the previously set developer option value.
+        //(native/angle/other). Then later when we are actually trying to load a driver,
+        //GraphicsEnv::getShouldUseAngle() has seen the package name before and can confidently
+        //answer yes/no based on the previously set developer option value.
         final String devOptIn;
         final String[] features = getAngleEglFeatures(context, bundle);
         final boolean gameModeEnabledAngle = isAngleEnabledByGameMode(context, packageName);
@@ -666,7 +587,7 @@
         } else {
             devOptIn = getDriverForPackage(context, bundle, packageName);
         }
-        setAngleInfo(paths, packageName, mAngleIsSystemDriver, devOptIn, features);
+        setAngleInfo(paths, packageName, devOptIn, features);
 
         return true;
     }
@@ -955,10 +876,8 @@
     private static native void setDriverPathAndSphalLibraries(String path, String sphalLibraries);
     private static native void setGpuStats(String driverPackageName, String driverVersionName,
             long driverVersionCode, long driverBuildTime, String appPackageName, int vulkanVersion);
-    private static native void setAngleInfo(String path, String appPackage,
-            boolean angleIsSystemDriver, String devOptIn, String[] features);
-    private static native void setLegacyDriverInfo(
-            String appPackage, boolean angleIsSystemDriver, String legacyDriverName);
+    private static native void setAngleInfo(String path, String appPackage, String devOptIn,
+            String[] features);
     private static native boolean getShouldUseAngle(String packageName);
     private static native boolean setInjectLayersPrSetDumpable();
 
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 1528f6a..60b1429 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -16885,22 +16885,6 @@
         public static final String SHOW_NEW_NOTIF_DISMISS = "show_new_notif_dismiss";
 
         /**
-         * Block untrusted touches mode.
-         *
-         * Can be one of:
-         * <ul>
-         *      <li>0 = {@link BlockUntrustedTouchesMode#DISABLED}: Feature is off.
-         *      <li>1 = {@link BlockUntrustedTouchesMode#PERMISSIVE}: Untrusted touches are flagged
-         *          but not blocked
-         *      <li>2 = {@link BlockUntrustedTouchesMode#BLOCK}: Untrusted touches are blocked
-         * </ul>
-         *
-         * @hide
-         */
-        @Readable
-        public static final String BLOCK_UNTRUSTED_TOUCHES_MODE = "block_untrusted_touches";
-
-        /**
          * The maximum allowed obscuring opacity by UID to propagate touches.
          *
          * For certain window types (eg. SAWs), the decision of honoring {@link LayoutParams
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index 6a9afdb..eca83e5 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -251,6 +251,8 @@
         // A Queue of pending requests to execute on the overlay.
         private final ArrayDeque<Consumer<IDreamOverlay>> mRequests;
 
+        private Handler mHandler = new Handler(Looper.getMainLooper());
+
         private boolean mBound;
 
         OverlayConnection() {
@@ -259,34 +261,40 @@
 
         public void bind(Context context, @Nullable ComponentName overlayService,
                 ComponentName dreamService) {
-            if (overlayService == null) {
-                return;
-            }
+            mHandler.post(() -> {
+                if (overlayService == null) {
+                    return;
+                }
 
-            final ServiceInfo serviceInfo = fetchServiceInfo(context, dreamService);
+                final ServiceInfo serviceInfo = fetchServiceInfo(context, dreamService);
 
-            final Intent overlayIntent = new Intent();
-            overlayIntent.setComponent(overlayService);
-            overlayIntent.putExtra(EXTRA_SHOW_COMPLICATIONS,
-                    fetchShouldShowComplications(context, serviceInfo));
+                final Intent overlayIntent = new Intent();
+                overlayIntent.setComponent(overlayService);
+                overlayIntent.putExtra(EXTRA_SHOW_COMPLICATIONS,
+                        fetchShouldShowComplications(context, serviceInfo));
 
-            context.bindService(overlayIntent,
-                    this, Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE);
-            mBound = true;
+                context.bindService(overlayIntent,
+                        this, Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE);
+                mBound = true;
+            });
         }
 
         public void unbind(Context context) {
-            if (!mBound) {
-                return;
-            }
+            mHandler.post(() -> {
+                if (!mBound) {
+                    return;
+                }
 
-            context.unbindService(this);
-            mBound = false;
+                context.unbindService(this);
+                mBound = false;
+            });
         }
 
         public void request(Consumer<IDreamOverlay> request) {
-            mRequests.push(request);
-            evaluate();
+            mHandler.post(() -> {
+                mRequests.push(request);
+                evaluate();
+            });
         }
 
         private void evaluate() {
@@ -304,15 +312,19 @@
 
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
-            // Store Overlay and execute pending requests.
-            mOverlay = IDreamOverlay.Stub.asInterface(service);
-            evaluate();
+            mHandler.post(() -> {
+                // Store Overlay and execute pending requests.
+                mOverlay = IDreamOverlay.Stub.asInterface(service);
+                evaluate();
+            });
         }
 
         @Override
         public void onServiceDisconnected(ComponentName name) {
-            // Clear Overlay binder to prevent further request processing.
-            mOverlay = null;
+            mHandler.post(() -> {
+                // Clear Overlay binder to prevent further request processing.
+                mOverlay = null;
+            });
         }
     }
 
diff --git a/core/java/android/service/games/GameSessionService.java b/core/java/android/service/games/GameSessionService.java
index df5bad5..52c8ec3 100644
--- a/core/java/android/service/games/GameSessionService.java
+++ b/core/java/android/service/games/GameSessionService.java
@@ -21,6 +21,7 @@
 import android.annotation.SdkConstant;
 import android.annotation.SystemApi;
 import android.app.Service;
+import android.content.Context;
 import android.content.Intent;
 import android.hardware.display.DisplayManager;
 import android.os.Binder;
@@ -28,6 +29,7 @@
 import android.os.IBinder;
 import android.view.Display;
 import android.view.SurfaceControlViewHost;
+import android.view.WindowManager;
 
 import com.android.internal.infra.AndroidFuture;
 import com.android.internal.util.function.pooled.PooledLambda;
@@ -117,13 +119,18 @@
         }
 
         IBinder hostToken = new Binder();
+
+        // Use a WindowContext so that views attached to the SurfaceControlViewHost will receive
+        // configuration changes (rather than always perceiving the global configuration).
+        final Context windowContext = createWindowContext(display,
+                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, /*options=*/ null);
         SurfaceControlViewHost surfaceControlViewHost =
-                new SurfaceControlViewHost(this, display, hostToken);
+                new SurfaceControlViewHost(windowContext, display, hostToken);
 
         gameSession.attach(
                 gameSessionController,
                 createGameSessionRequest.getTaskId(),
-                this,
+                windowContext,
                 surfaceControlViewHost,
                 gameSessionViewHostConfiguration.mWidthPx,
                 gameSessionViewHostConfiguration.mHeightPx);
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index 4bbfbc2..b783f6b8 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -1095,7 +1095,7 @@
             if (!mWindowVisible) {
                 mWindowVisible = true;
                 if (mUiEnabled) {
-                    mWindow.show();
+                    showWindow();
                 }
             }
             if (showCallback != null) {
@@ -1284,9 +1284,25 @@
         }
     }
 
+    void showWindow() {
+        if (mWindow != null) {
+            mWindow.show();
+            try {
+                mSystemService.setSessionWindowVisible(mToken, true);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed to notify session window shown", e);
+            }
+        }
+    }
+
     void ensureWindowHidden() {
         if (mWindow != null) {
             mWindow.hide();
+            try {
+                mSystemService.setSessionWindowVisible(mToken, false);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed to notify session window hidden", e);
+            }
         }
     }
 
@@ -1377,7 +1393,7 @@
             if (mWindowVisible) {
                 if (enabled) {
                     ensureWindowAdded();
-                    mWindow.show();
+                    showWindow();
                 } else {
                     ensureWindowHidden();
                 }
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index 60593ca..77591a7 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -765,18 +765,24 @@
                 startNanos = System.nanoTime();
                 final long jitterNanos = startNanos - frameTimeNanos;
                 if (jitterNanos >= frameIntervalNanos) {
-                    final long skippedFrames = jitterNanos / frameIntervalNanos;
-                    if (skippedFrames >= SKIPPED_FRAME_WARNING_LIMIT) {
-                        Log.i(TAG, "Skipped " + skippedFrames + " frames!  "
-                                + "The application may be doing too much work on its main thread.");
-                    }
                     final long lastFrameOffset = jitterNanos % frameIntervalNanos;
-                    if (DEBUG_JANK) {
-                        Log.d(TAG, "Missed vsync by " + (jitterNanos * 0.000001f) + " ms "
-                                + "which is more than the frame interval of "
-                                + (frameIntervalNanos * 0.000001f) + " ms!  "
-                                + "Skipping " + skippedFrames + " frames and setting frame "
-                                + "time to " + (lastFrameOffset * 0.000001f) + " ms in the past.");
+                    if (frameIntervalNanos == 0) {
+                        Log.i(TAG, "Vsync data empty due to timeout");
+                    } else {
+                        final long skippedFrames = jitterNanos / frameIntervalNanos;
+                        if (skippedFrames >= SKIPPED_FRAME_WARNING_LIMIT) {
+                            Log.i(TAG, "Skipped " + skippedFrames + " frames!  "
+                                    + "The application may be doing too much work on its main "
+                                    + "thread.");
+                        }
+                        if (DEBUG_JANK) {
+                            Log.d(TAG, "Missed vsync by " + (jitterNanos * 0.000001f) + " ms "
+                                    + "which is more than the frame interval of "
+                                    + (frameIntervalNanos * 0.000001f) + " ms!  "
+                                    + "Skipping " + skippedFrames + " frames and setting frame "
+                                    + "time to " + (lastFrameOffset * 0.000001f)
+                                    + " ms in the past.");
+                        }
                     }
                     frameTimeNanos = startNanos - lastFrameOffset;
                     DisplayEventReceiver.VsyncEventData latestVsyncEventData =
diff --git a/core/java/android/view/HandwritingInitiator.java b/core/java/android/view/HandwritingInitiator.java
index 3247bb7..5ef1cd2 100644
--- a/core/java/android/view/HandwritingInitiator.java
+++ b/core/java/android/view/HandwritingInitiator.java
@@ -19,8 +19,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.graphics.Rect;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
 import android.view.inputmethod.InputMethodManager;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -51,12 +49,6 @@
  * @hide
  */
 public class HandwritingInitiator {
-    /** The amount of extra space added to handwriting in dip. */
-    private static final int HANDWRITING_AREA_PADDING_DIP = 20;
-
-    /** The amount of extra space added to handwriting in px. */
-    private final float mHandwritingAreaPaddingPx;
-
     /**
      * The touchSlop from {@link ViewConfiguration} used to decide whether a pointer is considered
      * moving or stationary.
@@ -96,13 +88,9 @@
 
     @VisibleForTesting
     public HandwritingInitiator(@NonNull ViewConfiguration viewConfiguration,
-            @NonNull InputMethodManager inputMethodManager, DisplayMetrics displayMetrics) {
+            @NonNull InputMethodManager inputMethodManager) {
         mTouchSlop = viewConfiguration.getScaledTouchSlop();
         mHandwritingTimeoutInMillis = ViewConfiguration.getLongPressTimeout();
-        mHandwritingAreaPaddingPx = TypedValue.applyDimension(
-                TypedValue.COMPLEX_UNIT_DIP,
-                HANDWRITING_AREA_PADDING_DIP,
-                displayMetrics);
         mImm = inputMethodManager;
     }
 
@@ -262,8 +250,8 @@
         }
 
         final Rect handwritingArea = getViewHandwritingArea(connectedView);
-        if (containsInExtendedHandwritingArea(handwritingArea,
-                mState.mStylusDownX, mState.mStylusDownY)) {
+        if (isInHandwritingArea(handwritingArea, mState.mStylusDownX,
+                mState.mStylusDownY, connectedView)) {
             startHandwriting(connectedView);
         } else {
             reset();
@@ -303,7 +291,7 @@
         final View connectedView = getConnectedView();
         if (connectedView != null && connectedView.isAutoHandwritingEnabled()) {
             Rect handwritingArea = getViewHandwritingArea(connectedView);
-            if (containsInExtendedHandwritingArea(handwritingArea, x, y)) {
+            if (isInHandwritingArea(handwritingArea, x, y, connectedView)) {
                 final float distance = distance(handwritingArea, x, y);
                 if (distance == 0f) return connectedView;
 
@@ -318,7 +306,7 @@
         for (HandwritableViewInfo viewInfo : handwritableViewInfos) {
             final View view = viewInfo.getView();
             final Rect handwritingArea = viewInfo.getHandwritingArea();
-            if (!containsInExtendedHandwritingArea(handwritingArea, x, y)) continue;
+            if (!isInHandwritingArea(handwritingArea, x, y, view)) continue;
 
             final float distance = distance(handwritingArea, x, y);
 
@@ -409,24 +397,28 @@
     }
 
     /**
-     * Return true if the (x, y) is inside by the given {@link Rect} extended by the View's
-     * handwriting extends settings.
+     * Return true if the (x, y) is inside by the given {@link Rect} with the View's
+     * handwriting bounds with offsets applied.
      */
-    private boolean containsInExtendedHandwritingArea(@Nullable Rect handwritingArea,
-            float x, float y) {
+    private boolean isInHandwritingArea(@Nullable Rect handwritingArea,
+            float x, float y, View view) {
         if (handwritingArea == null) return false;
-        return contains(handwritingArea, x, y, mHandwritingAreaPaddingPx, mHandwritingAreaPaddingPx,
-                mHandwritingAreaPaddingPx, mHandwritingAreaPaddingPx);
+
+        return contains(handwritingArea, x, y,
+                view.getHandwritingBoundsOffsetLeft(),
+                view.getHandwritingBoundsOffsetTop(),
+                view.getHandwritingBoundsOffsetRight(),
+                view.getHandwritingBoundsOffsetBottom());
     }
 
     /**
-     * Return true if the (x, y) is inside by the given {@link Rect} extended by the given
-     * extendLeft, extendTop, extendRight and extendBottom.
+     * Return true if the (x, y) is inside by the given {@link Rect} offset by the given
+     * offsetLeft, offsetTop, offsetRight and offsetBottom.
      */
     private static boolean contains(@NonNull Rect rect, float x, float y,
-            float extendLeft, float extendTop, float extendRight, float extendBottom) {
-        return x >= rect.left - extendLeft && x < rect.right  + extendRight
-                && y >= rect.top - extendTop && y < rect.bottom + extendBottom;
+            float offsetLeft, float offsetTop, float offsetRight, float offsetBottom) {
+        return x >= rect.left - offsetLeft && x < rect.right  + offsetRight
+                && y >= rect.top - offsetTop && y < rect.bottom + offsetBottom;
     }
 
     private boolean largerThanTouchSlop(float x1, float y1, float x2, float y2) {
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index 6aab635..4d9033d 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -25,6 +25,7 @@
 import static android.view.InsetsSourceConsumerProto.PENDING_FRAME;
 import static android.view.InsetsSourceConsumerProto.PENDING_VISIBLE_FRAME;
 import static android.view.InsetsSourceConsumerProto.SOURCE_CONTROL;
+import static android.view.InsetsSourceControl.INVALID_HINTS;
 import static android.view.InsetsState.ITYPE_IME;
 import static android.view.InsetsState.getDefaultVisibility;
 import static android.view.InsetsState.toPublicType;
@@ -163,8 +164,10 @@
             // We are gaining control, and need to run an animation since previous state
             // didn't match
             final boolean requestedVisible = isRequestedVisibleAwaitingControl();
-            final boolean needAnimation = requestedVisible != mState.getSource(mType).isVisible();
-            if (control.getLeash() != null && (needAnimation || mIsAnimationPending)) {
+            final boolean fakeControl = INVALID_HINTS.equals(control.getInsetsHint());
+            final boolean needsAnimation = requestedVisible != mState.getSource(mType).isVisible()
+                    && !fakeControl;
+            if (control.getLeash() != null && (needsAnimation || mIsAnimationPending)) {
                 if (DEBUG) Log.d(TAG, String.format("Gaining control in %s, requestedVisible: %b",
                         mController.getHost().getRootViewTitle(), requestedVisible));
                 if (requestedVisible) {
@@ -174,7 +177,7 @@
                 }
                 mIsAnimationPending = false;
             } else {
-                if (needAnimation) {
+                if (needsAnimation) {
                     // We need animation but we haven't had a leash yet. Set this flag that when we
                     // get the leash we can play the deferred animation.
                     mIsAnimationPending = true;
diff --git a/core/java/android/view/InsetsSourceControl.java b/core/java/android/view/InsetsSourceControl.java
index 9d98a3e..2cf827d 100644
--- a/core/java/android/view/InsetsSourceControl.java
+++ b/core/java/android/view/InsetsSourceControl.java
@@ -39,6 +39,8 @@
  */
 public class InsetsSourceControl implements Parcelable {
 
+    public static final Insets INVALID_HINTS = Insets.of(-1, -1, -1, -1);
+
     private final @InternalInsetsType int mType;
     private final @Nullable SurfaceControl mLeash;
     private final Point mSurfacePosition;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 39012ca..459fcf0 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4475,6 +4475,26 @@
     protected int mPaddingBottom;
 
     /**
+     * The amount of pixel offset applied to the left edge of this view's handwriting bounds.
+     */
+    private float mHandwritingBoundsOffsetLeft;
+
+    /**
+     * The amount of pixel offset applied to the top edge of this view's handwriting bounds.
+     */
+    private float mHandwritingBoundsOffsetTop;
+
+    /**
+     * The amount of pixel offset applied to the right edge of this view's handwriting bounds.
+     */
+    private float mHandwritingBoundsOffsetRight;
+
+    /**
+     * The amount of pixel offset applied to the bottom edge of this view's handwriting bounds.
+     */
+    private float mHandwritingBoundsOffsetBottom;
+
+    /**
      * The layout insets in pixels, that is the distance in pixels between the
      * visible edges of this view its bounds.
      */
@@ -6081,6 +6101,18 @@
                 case R.styleable.View_autoHandwritingEnabled:
                     setAutoHandwritingEnabled(a.getBoolean(attr, true));
                     break;
+                case R.styleable.View_handwritingBoundsOffsetLeft:
+                    mHandwritingBoundsOffsetLeft = a.getDimension(attr, 0);
+                    break;
+                case R.styleable.View_handwritingBoundsOffsetTop:
+                    mHandwritingBoundsOffsetTop = a.getDimension(attr, 0);
+                    break;
+                case R.styleable.View_handwritingBoundsOffsetRight:
+                    mHandwritingBoundsOffsetRight = a.getDimension(attr, 0);
+                    break;
+                case R.styleable.View_handwritingBoundsOffsetBottom:
+                    mHandwritingBoundsOffsetBottom = a.getDimension(attr, 0);
+                    break;
             }
         }
 
@@ -12016,12 +12048,91 @@
     }
 
     /**
-     * Set a list of handwriting areas in this view. If there is any stylus {@link MotionEvent}
-     * occurs within those areas, it will trigger stylus handwriting mode. This can be disabled by
+     * Set the amount of offset applied to this view's stylus handwriting bounds. A positive offset
+     * will offset the edge outwards.The base handwriting bounds of a view is its visible bounds.
+     * The handwriting bounds offsets are applied to the base handwriting bounds to determine the
+     * final handwriting bounds.
+     * <p> This method is mainly used to enlarge the view's handwriting bounds for a better user
+     * experience.
+     * <p> Note that when the view is clipped (e.g. the view is in a
+     * {@link android.widget.ScrollView}), the offsets are applied after the view's handwriting
+     * bounds is clipped.
+     *
+     * @param offsetLeft the amount of pixel offset applied to the left edge outwards of the view's
+     *                   handwriting bounds.
+     * @param offsetTop the amount of pixel offset applied to the top edge outwards of the view's
+     *                  handwriting bounds.
+     * @param offsetRight the amount of pixel offset applied to the right edge outwards of the
+     *                    view's handwriting bounds.
+     * @param offsetBottom the amount of pixel offset applied to the bottom edge outwards of the
+     *                     view's handwriting bounds.
+     *
+     * @see #setAutoHandwritingEnabled(boolean)
+     * @see #getHandwritingBoundsOffsetLeft()
+     * @see #getHandwritingBoundsOffsetTop()
+     * @see #getHandwritingBoundsOffsetRight()
+     * @see #getHandwritingBoundsOffsetBottom()
+     */
+    public void setHandwritingBoundsOffsets(float offsetLeft, float offsetTop,
+            float offsetRight, float offsetBottom) {
+        mHandwritingBoundsOffsetLeft = offsetLeft;
+        mHandwritingBoundsOffsetTop = offsetTop;
+        mHandwritingBoundsOffsetRight = offsetRight;
+        mHandwritingBoundsOffsetBottom = offsetBottom;
+    }
+
+    /**
+     * Return the amount of offset applied to the left edge of this view's handwriting bounds,
+     * in the unit of pixel.
+     *
+     * @see #setAutoHandwritingEnabled(boolean)
+     * @see #setHandwritingBoundsOffsets(float, float, float, float)
+     */
+    public float getHandwritingBoundsOffsetLeft() {
+        return mHandwritingBoundsOffsetLeft;
+    }
+
+    /**
+     * Return the amount of offset applied to the top edge of this view's handwriting bounds,
+     * in the unit of pixel.
+     *
+     * @see #setAutoHandwritingEnabled(boolean)
+     * @see #setHandwritingBoundsOffsets(float, float, float, float)
+     */
+    public float getHandwritingBoundsOffsetTop() {
+        return mHandwritingBoundsOffsetTop;
+    }
+
+    /**
+     * Return the amount of offset applied to the right edge of this view's handwriting bounds, in
+     * the unit of pixel.
+     *
+     * @see #setAutoHandwritingEnabled(boolean)
+     * @see #setHandwritingBoundsOffsets(float, float, float, float)
+     */
+    public float getHandwritingBoundsOffsetRight() {
+        return mHandwritingBoundsOffsetRight;
+    }
+
+    /**
+     * Return the amount of offset applied to the bottom edge of this view's handwriting bounds, in
+     * the unit of pixel.
+     *
+     * @see #setAutoHandwritingEnabled(boolean)
+     * @see #setHandwritingBoundsOffsets(float, float, float, float)
+     */
+    public float getHandwritingBoundsOffsetBottom() {
+        return mHandwritingBoundsOffsetBottom;
+    }
+
+
+    /**
+     * Set a handwriting area in this view. If there is any stylus {@link MotionEvent}
+     * occurs within this area, it will trigger stylus handwriting mode. This can be disabled by
      * disabling the auto handwriting initiation by calling
      * {@link #setAutoHandwritingEnabled(boolean)} with false.
      *
-     * @attr rects a list of handwriting area in the view's local coordiniates.
+     * @attr rect the handwriting area in the view's local coordiniates.
      *
      * @see android.view.inputmethod.InputMethodManager#startStylusHandwriting(View)
      * @see #setAutoHandwritingEnabled(boolean)
@@ -12066,8 +12177,8 @@
      * <p>In multiple-screen scenarios, if the surface spans multiple screens,
      * the coordinate space of the surface also spans multiple screens.
      *
-     * <p>After the method returns, the argument array contains the x- and
-     * y-coordinates of the view relative to the view's left and top edges,
+     * <p>After the method returns, the argument array contains the x and y
+     * coordinates of the view relative to the view's left and top edges,
      * respectively.
      *
      * @param location A two-element integer array in which the view coordinates
@@ -18743,18 +18854,37 @@
     }
 
     /**
-     * If some part of this view is not clipped by any of its parents, then
-     * return that area in r in global (root) coordinates. To convert r to local
-     * coordinates (without taking possible View rotations into account), offset
-     * it by -globalOffset (e.g. r.offset(-globalOffset.x, -globalOffset.y)).
-     * If the view is completely clipped or translated out, return false.
+     * Sets {@code r} to the coordinates of the non-clipped area of this view in
+     * the coordinate space of the view's root view. Sets {@code globalOffset}
+     * to the offset of the view's x and y coordinates from the coordinate space
+     * origin, which is the top left corner of the root view irrespective of
+     * screen decorations and system UI elements.
      *
-     * @param r If true is returned, r holds the global coordinates of the
-     *        visible portion of this view.
-     * @param globalOffset If true is returned, globalOffset holds the dx,dy
-     *        between this view and its root. globalOffet may be null.
-     * @return true if r is non-empty (i.e. part of the view is visible at the
-     *         root level.
+     * <p>To convert {@code r} to coordinates relative to the top left corner of
+     * this view (without taking view rotations into account), offset {@code r}
+     * by the inverse values of
+     * {@code globalOffset}&mdash;{@code r.offset(-globalOffset.x,
+     * -globalOffset.y)}&mdash;which is equivalent to calling
+     * {@link #getLocalVisibleRect(Rect) getLocalVisibleRect(Rect)}.
+     *
+     * <p><b>Note:</b> Do not use this method to determine the size of a window
+     * in multi-window mode; use
+     * {@link WindowManager#getCurrentWindowMetrics()}.
+     *
+     * @param r If the method returns true, contains the coordinates of the
+     *      visible portion of this view in the coordinate space of the view's
+     *      root view. If the method returns false, the contents of {@code r}
+     *      are undefined.
+     * @param globalOffset If the method returns true, contains the offset of
+     *      the x and y coordinates of this view from the top left corner of the
+     *      view's root view. If the method returns false, the contents of
+     *      {@code globalOffset} are undefined. The argument can be null (see
+     *      {@link #getGlobalVisibleRect(Rect) getGlobalVisibleRect(Rect)}.
+     * @return true if at least part of the view is visible within the root
+     *      view; false if the view is completely clipped or translated out of
+     *      the visible area of the root view.
+     *
+     * @see #getLocalVisibleRect(Rect)
      */
     public boolean getGlobalVisibleRect(Rect r, Point globalOffset) {
         int width = mRight - mLeft;
@@ -18769,10 +18899,48 @@
         return false;
     }
 
+    /**
+     * Sets {@code r} to the coordinates of the non-clipped area of this view in
+     * the coordinate space of the view's root view.
+     *
+     * <p>See {@link #getGlobalVisibleRect(Rect, Point)
+     * getGlobalVisibleRect(Rect, Point)} for more information.
+     *
+     * @param r If the method returns true, contains the coordinates of the
+     *      visible portion of this view in the coordinate space of the view's
+     *      root view. If the method returns false, the contents of {@code r}
+     *      are undefined.
+     * @return true if at least part of the view is visible within the root
+     *      view; otherwise false.
+     */
     public final boolean getGlobalVisibleRect(Rect r) {
         return getGlobalVisibleRect(r, null);
     }
 
+    /**
+     * Sets {@code r} to the coordinates of the non-clipped area of this view
+     * relative to the top left corner of the view.
+     *
+     * <p>If the view is clipped on the left or top, the left and top
+     * coordinates are offset from 0 by the clipped amount. For example, if the
+     * view is off screen 50px on the left and 30px at the top, the left and top
+     * coordinates are 50 and 30 respectively.
+     *
+     * <p>If the view is clipped on the right or bottom, the right and bottom
+     * coordinates are reduced by the clipped amount. For example, if the view
+     * is off screen 40px on the right and 20px at the bottom, the right
+     * coordinate is the view width - 40, and the bottom coordinate is the view
+     * height - 20.
+     *
+     * @param r If the method returns true, contains the coordinates of the
+     *      visible portion of this view relative to the top left corner of the
+     *      view. If the method returns false, the contents of {@code r} are
+     *      undefined.
+     * @return true if at least part of the view is visible; false if the view
+     *      is completely clipped or translated out of the visible area.
+     *
+     * @see #getGlobalVisibleRect(Rect, Point)
+     */
     public final boolean getLocalVisibleRect(Rect r) {
         final Point offset = mAttachInfo != null ? mAttachInfo.mPoint : new Point();
         if (getGlobalVisibleRect(r, offset)) {
@@ -25606,8 +25774,8 @@
      * multiple-screen environment, the coordinate space includes only the
      * screen on which the app is running.
      *
-     * <p>After the method returns, the argument array contains the x- and
-     * y-coordinates of the view relative to the view's left and top edges,
+     * <p>After the method returns, the argument array contains the x and y
+     * coordinates of the view relative to the view's left and top edges,
      * respectively.
      *
      * @param outLocation A two-element integer array in which the view
@@ -25637,8 +25805,8 @@
      * restricted to a single screen, the coordinate space includes only the
      * screen on which the app is running.
      *
-     * <p>After the method returns, the argument array contains the x- and
-     * y-coordinates of the view relative to the view's left and top edges,
+     * <p>After the method returns, the argument array contains the x and y
+     * coordinates of the view relative to the view's left and top edges,
      * respectively.
      *
      * @param outLocation A two-element integer array in which the view
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index af5440a..379a1c5 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -901,8 +901,7 @@
         mInsetsController = new InsetsController(new ViewRootInsetsControllerHost(this));
         mHandwritingInitiator = new HandwritingInitiator(
                 mViewConfiguration,
-                mContext.getSystemService(InputMethodManager.class),
-                context.getResources().getDisplayMetrics());
+                mContext.getSystemService(InputMethodManager.class));
 
         String processorOverrideName = context.getResources().getString(
                                     R.string.config_inputEventCompatProcessorOverrideClassName);
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 285a407..8127db5 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -4633,12 +4633,18 @@
             builder.setMatrix(mViewToScreenMatrix);
 
             if (includeEditorBounds) {
-                final RectF bounds = new RectF();
-                bounds.set(0 /* left */, 0 /* top */, mTextView.getWidth(), mTextView.getHeight());
+                final RectF editorBounds = new RectF();
+                editorBounds.set(0 /* left */, 0 /* top */,
+                        mTextView.getWidth(), mTextView.getHeight());
+                final RectF handwritingBounds = new RectF(
+                        -mTextView.getHandwritingBoundsOffsetLeft(),
+                        -mTextView.getHandwritingBoundsOffsetTop(),
+                        mTextView.getWidth() + mTextView.getHandwritingBoundsOffsetRight(),
+                        mTextView.getHeight() + mTextView.getHandwritingBoundsOffsetBottom());
                 EditorBoundsInfo.Builder boundsBuilder = new EditorBoundsInfo.Builder();
-                //TODO(b/210039666): add Handwriting bounds once they're available.
-                builder.setEditorBoundsInfo(
-                        boundsBuilder.setEditorBounds(bounds).build());
+                EditorBoundsInfo editorBoundsInfo = boundsBuilder.setEditorBounds(editorBounds)
+                        .setHandwritingBounds(handwritingBounds).build();
+                builder.setEditorBoundsInfo(editorBoundsInfo);
             }
 
             if (includeCharacterBounds || includeInsertionMarker) {
diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java
index 79dac19..7dc039d 100644
--- a/core/java/android/window/WindowContainerTransaction.java
+++ b/core/java/android/window/WindowContainerTransaction.java
@@ -650,6 +650,26 @@
     }
 
     /**
+     * Requests focus on the top running Activity in the given TaskFragment. This will only take
+     * effect if there is no focus, or if the current focus is in the same Task as the requested
+     * TaskFragment.
+     * @param fragmentToken client assigned unique token to create TaskFragment with specified in
+     *                      {@link TaskFragmentCreationParams#getFragmentToken()}.
+     * @hide
+     */
+    @NonNull
+    public WindowContainerTransaction requestFocusOnTaskFragment(@NonNull IBinder fragmentToken) {
+        final HierarchyOp hierarchyOp =
+                new HierarchyOp.Builder(
+                        HierarchyOp.HIERARCHY_OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT)
+                        .setContainer(fragmentToken)
+                        .build();
+        mHierarchyOps.add(hierarchyOp);
+        return this;
+
+    }
+
+    /**
      * When this {@link WindowContainerTransaction} failed to finish on the server side, it will
      * trigger callback with this {@param errorCallbackToken}.
      * @param errorCallbackToken    client provided token that will be passed back as parameter in
@@ -1057,6 +1077,7 @@
         public static final int HIERARCHY_OP_TYPE_RESTORE_TRANSIENT_ORDER = 15;
         public static final int HIERARCHY_OP_TYPE_ADD_RECT_INSETS_PROVIDER = 16;
         public static final int HIERARCHY_OP_TYPE_REMOVE_INSETS_PROVIDER = 17;
+        public static final int HIERARCHY_OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT = 18;
 
         // The following key(s) are for use with mLaunchOptions:
         // When launching a task (eg. from recents), this is the taskId to be launched.
@@ -1368,6 +1389,8 @@
                 case HIERARCHY_OP_TYPE_REMOVE_INSETS_PROVIDER:
                     return "{removeLocalInsetsProvider: container=" + mContainer
                             + " insetsType=" + Arrays.toString(mInsetsTypes) + "}";
+                case HIERARCHY_OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT:
+                    return "{requestFocusOnTaskFragment: container=" + mContainer + "}";
                 default:
                     return "{mType=" + mType + " container=" + mContainer + " reparent=" + mReparent
                             + " mToTop=" + mToTop
diff --git a/core/java/android/window/WindowProviderService.java b/core/java/android/window/WindowProviderService.java
index f8484d1..2d2c8de 100644
--- a/core/java/android/window/WindowProviderService.java
+++ b/core/java/android/window/WindowProviderService.java
@@ -165,10 +165,11 @@
         }
     }
 
+    // Suppress the lint because ths is overridden from Context.
     @SuppressLint("OnNameExpected")
     @Override
-    // Suppress the lint because ths is overridden from Context.
-    public @Nullable Object getSystemService(@NonNull String name) {
+    @Nullable
+    public Object getSystemService(@NonNull String name) {
         if (WINDOW_SERVICE.equals(name)) {
             return mWindowManager;
         }
diff --git a/core/java/android/window/WindowTokenClient.java b/core/java/android/window/WindowTokenClient.java
index 547535d..7db4243 100644
--- a/core/java/android/window/WindowTokenClient.java
+++ b/core/java/android/window/WindowTokenClient.java
@@ -19,8 +19,8 @@
 import static android.window.ConfigurationHelper.isDifferentDisplay;
 import static android.window.ConfigurationHelper.shouldUpdateResources;
 
+import android.annotation.AnyThread;
 import android.annotation.BinderThread;
-import android.annotation.MainThread;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.IWindowToken;
@@ -40,6 +40,7 @@
 import android.view.WindowManager.LayoutParams.WindowType;
 import android.view.WindowManagerGlobal;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.lang.ref.WeakReference;
@@ -68,6 +69,7 @@
 
     private IWindowManager mWms;
 
+    @GuardedBy("itself")
     private final Configuration mConfiguration = new Configuration();
 
     private boolean mShouldDumpConfigForIme;
@@ -91,7 +93,6 @@
             throw new IllegalStateException("Context is already attached.");
         }
         mContextRef = new WeakReference<>(context);
-        mConfiguration.setTo(context.getResources().getConfiguration());
         mShouldDumpConfigForIme = Build.IS_DEBUGGABLE
                 && context instanceof AbstractInputMethodService;
     }
@@ -137,8 +138,7 @@
             if (configuration == null) {
                 return false;
             }
-            mHandler.post(() -> onConfigurationChanged(configuration, displayId,
-                    false /* shouldReportConfigChange */));
+            onConfigurationChanged(configuration, displayId, false /* shouldReportConfigChange */);
             mAttachToWindowContainer = true;
             return true;
         } catch (RemoteException e) {
@@ -199,8 +199,19 @@
      *
      * Similar to {@link #onConfigurationChanged(Configuration, int)}, but adds a flag to control
      * whether to dispatch configuration update or not.
+     * <p>
+     * Note that this method must be executed on the main thread if
+     * {@code shouldReportConfigChange} is {@code true}, which is usually from
+     * {@link IWindowToken#onConfigurationChanged(Configuration, int)}
+     * directly, while this method could be run on any thread if it is used to initialize
+     * Context's {@code Configuration} via {@link #attachToDisplayArea(int, int, Bundle)}
+     * or {@link #attachToDisplayContent(int)}.
+     *
+     * @param shouldReportConfigChange {@code true} to indicate that the {@code Configuration}
+     *                                 should be dispatched to listeners.
+     *
      */
-    @MainThread
+    @AnyThread
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
     public void onConfigurationChanged(Configuration newConfig, int newDisplayId,
             boolean shouldReportConfigChange) {
@@ -208,18 +219,29 @@
         if (context == null) {
             return;
         }
-        final boolean displayChanged = isDifferentDisplay(context.getDisplayId(), newDisplayId);
-        final boolean shouldUpdateResources = shouldUpdateResources(this, mConfiguration,
-                newConfig, newConfig /* overrideConfig */, displayChanged,
-                null /* configChanged */);
+        final boolean displayChanged;
+        final boolean shouldUpdateResources;
+        final int diff;
+        final Configuration currentConfig;
+
+        synchronized (mConfiguration) {
+            displayChanged = isDifferentDisplay(context.getDisplayId(), newDisplayId);
+            shouldUpdateResources = shouldUpdateResources(this, mConfiguration,
+                    newConfig, newConfig /* overrideConfig */, displayChanged,
+                    null /* configChanged */);
+            diff = mConfiguration.diffPublicOnly(newConfig);
+            currentConfig = mShouldDumpConfigForIme ? new Configuration(mConfiguration) : null;
+            if (shouldUpdateResources) {
+                mConfiguration.setTo(newConfig);
+            }
+        }
 
         if (!shouldUpdateResources && mShouldDumpConfigForIme) {
             Log.d(TAG, "Configuration not dispatch to IME because configuration is up"
                     + " to date. Current config=" + context.getResources().getConfiguration()
-                    + ", reported config=" + mConfiguration
+                    + ", reported config=" + currentConfig
                     + ", updated config=" + newConfig);
         }
-
         if (shouldUpdateResources) {
             // TODO(ag/9789103): update resource manager logic to track non-activity tokens
             mResourcesManager.updateResourcesForActivity(this, newConfig, newDisplayId);
@@ -229,7 +251,7 @@
                 windowContext.dispatchConfigurationChanged(newConfig);
             }
 
-            final int diff = mConfiguration.diffPublicOnly(newConfig);
+
             if (shouldReportConfigChange && diff != 0
                     && context instanceof WindowProviderService) {
                 final WindowProviderService windowProviderService = (WindowProviderService) context;
@@ -244,11 +266,10 @@
                     Log.d(TAG, "Configuration not dispatch to IME because configuration has no "
                             + " public difference with updated config. "
                             + " Current config=" + context.getResources().getConfiguration()
-                            + ", reported config=" + mConfiguration
+                            + ", reported config=" + currentConfig
                             + ", updated config=" + newConfig);
                 }
             }
-            mConfiguration.setTo(newConfig);
         }
         if (displayChanged) {
             context.updateDisplay(newDisplayId);
diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
index 52d54cd..681693b 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
@@ -284,4 +284,9 @@
      * Stops to listen the status of visible activity.
      */
     void stopListeningVisibleActivityChanged(in IBinder token);
+
+    /**
+     * Notifies when the session window is shown or hidden.
+     */
+    void setSessionWindowVisible(in IBinder token, boolean visible);
 }
diff --git a/core/java/com/android/internal/app/IVoiceInteractionSessionListener.aidl b/core/java/com/android/internal/app/IVoiceInteractionSessionListener.aidl
index bc757e2..6e40988 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionSessionListener.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionSessionListener.aidl
@@ -30,6 +30,11 @@
     void onVoiceSessionHidden();
 
     /**
+     * Called when a voice session window is shown/hidden.
+     */
+    void onVoiceSessionWindowVisibilityChanged(boolean visible);
+
+    /**
      * Called when UI hints were received.
      */
     void onSetUiHints(in Bundle args);
diff --git a/core/java/com/android/internal/app/ResolverListAdapter.java b/core/java/com/android/internal/app/ResolverListAdapter.java
index 351ac45..0a07e0a 100644
--- a/core/java/com/android/internal/app/ResolverListAdapter.java
+++ b/core/java/com/android/internal/app/ResolverListAdapter.java
@@ -233,8 +233,14 @@
         // copied the original unfiltered items to a separate List instance and can now filter
         // the remainder in-place without any further bookkeeping.
         boolean needsCopyOfUnfiltered = (mUnfilteredResolveList == currentResolveList);
-        mUnfilteredResolveList = performSecondaryResolveListFiltering(
+        List<ResolvedComponentInfo> originalList = performSecondaryResolveListFiltering(
                 currentResolveList, needsCopyOfUnfiltered);
+        if (originalList != null) {
+            // Only need the originalList value if there was a modification (otherwise it's null
+            // and shouldn't overwrite mUnfilteredResolveList).
+            mUnfilteredResolveList = originalList;
+        }
+
 
         return finishRebuildingListWithFilteredResults(currentResolveList, doPostProcessing);
     }
@@ -293,7 +299,7 @@
      * appearing in the rebuilt-list results, while still considering those items for the "other
      * profile" special-treatment described in {@code rebuildList()}.
      *
-     * @return the same (possibly null) List reference as {@code currentResolveList}, if the list is
+     * @return the same (possibly null) List reference as {@code currentResolveList} if the list is
      * unmodified as a result of filtering; or, if some item(s) were removed, then either a copy of
      * the original {@code currentResolveList} (if {@code returnCopyOfOriginalListIfModified} is
      * true), or null (otherwise).
diff --git a/core/java/com/android/internal/policy/KidsModeSettingsObserver.java b/core/java/com/android/internal/policy/ForceShowNavBarSettingsObserver.java
similarity index 68%
copy from core/java/com/android/internal/policy/KidsModeSettingsObserver.java
copy to core/java/com/android/internal/policy/ForceShowNavBarSettingsObserver.java
index 8a1d407..fc064ea 100644
--- a/core/java/com/android/internal/policy/KidsModeSettingsObserver.java
+++ b/core/java/com/android/internal/policy/ForceShowNavBarSettingsObserver.java
@@ -24,17 +24,15 @@
 import android.provider.Settings;
 
 /**
- * A ContentObserver for listening kids mode relative setting keys:
- *  - {@link Settings.Secure#NAVIGATION_MODE}
- *  - {@link Settings.Secure#NAV_BAR_KIDS_MODE}
+ * A ContentObserver for listening {@link Settings.Secure#NAV_BAR_FORCE_VISIBLE} setting key.
  *
  * @hide
  */
-public class KidsModeSettingsObserver extends ContentObserver {
+public class ForceShowNavBarSettingsObserver extends ContentObserver {
     private Context mContext;
     private Runnable mOnChangeRunnable;
 
-    public KidsModeSettingsObserver(Handler handler, Context context) {
+    public ForceShowNavBarSettingsObserver(Handler handler, Context context) {
         super(handler);
         mContext = context;
     }
@@ -49,10 +47,7 @@
     public void register() {
         final ContentResolver r = mContext.getContentResolver();
         r.registerContentObserver(
-                Settings.Secure.getUriFor(Settings.Secure.NAVIGATION_MODE),
-                false, this, UserHandle.USER_ALL);
-        r.registerContentObserver(
-                Settings.Secure.getUriFor(Settings.Secure.NAV_BAR_KIDS_MODE),
+                Settings.Secure.getUriFor(Settings.Secure.NAV_BAR_FORCE_VISIBLE),
                 false, this, UserHandle.USER_ALL);
     }
 
@@ -71,13 +66,10 @@
     }
 
     /**
-     * Returns true only when it's in three button nav mode and the kid nav bar mode is enabled.
-     * Otherwise, return false.
+     * Returns true only when it's in orce show navigation bar mode. Otherwise, return false.
      */
     public boolean isEnabled() {
         return Settings.Secure.getIntForUser(mContext.getContentResolver(),
-                Settings.Secure.NAVIGATION_MODE, 0, UserHandle.USER_CURRENT) == 0
-                && Settings.Secure.getIntForUser(mContext.getContentResolver(),
-                Settings.Secure.NAV_BAR_KIDS_MODE, 0, UserHandle.USER_CURRENT) == 1;
+                Settings.Secure.NAV_BAR_FORCE_VISIBLE, 0, UserHandle.USER_CURRENT) == 1;
     }
 }
diff --git a/core/jni/android_os_GraphicsEnvironment.cpp b/core/jni/android_os_GraphicsEnvironment.cpp
index 78e2d31..f44e829 100644
--- a/core/jni/android_os_GraphicsEnvironment.cpp
+++ b/core/jni/android_os_GraphicsEnvironment.cpp
@@ -50,7 +50,7 @@
 }
 
 void setAngleInfo_native(JNIEnv* env, jobject clazz, jstring path, jstring appName,
-                         jboolean angleIsSystemDriver, jstring devOptIn, jobjectArray featuresObj) {
+                         jstring devOptIn, jobjectArray featuresObj) {
     ScopedUtfChars pathChars(env, path);
     ScopedUtfChars appNameChars(env, appName);
     ScopedUtfChars devOptInChars(env, devOptIn);
@@ -74,18 +74,7 @@
     }
 
     android::GraphicsEnv::getInstance().setAngleInfo(pathChars.c_str(), appNameChars.c_str(),
-                                                     angleIsSystemDriver, devOptInChars.c_str(),
-                                                     features);
-}
-
-void setLegacyDriverInfo_native(JNIEnv* env, jobject clazz, jstring appName,
-                                jboolean angleIsSystemDriver, jstring legacyDriverName) {
-    ScopedUtfChars appNameChars(env, appName);
-    ScopedUtfChars legacyDriverNameChars(env, legacyDriverName);
-
-    android::GraphicsEnv::getInstance().setLegacyDriverInfo(appNameChars.c_str(),
-                                                            angleIsSystemDriver,
-                                                            legacyDriverNameChars.c_str());
+                                                     devOptInChars.c_str(), features);
 }
 
 bool shouldUseAngle_native(JNIEnv* env, jobject clazz, jstring appName) {
@@ -131,10 +120,8 @@
         {"setInjectLayersPrSetDumpable", "()Z",
          reinterpret_cast<void*>(setInjectLayersPrSetDumpable_native)},
         {"setAngleInfo",
-         "(Ljava/lang/String;Ljava/lang/String;ZLjava/lang/String;[Ljava/lang/String;)V",
+         "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V",
          reinterpret_cast<void*>(setAngleInfo_native)},
-        {"setLegacyDriverInfo", "(Ljava/lang/String;ZLjava/lang/String;)V",
-         reinterpret_cast<void*>(setLegacyDriverInfo_native)},
         {"getShouldUseAngle", "(Ljava/lang/String;)Z",
          reinterpret_cast<void*>(shouldUseAngle_native)},
         {"setLayerPaths", "(Ljava/lang/ClassLoader;Ljava/lang/String;)V",
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 21bbac0..9d23b85 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -1599,10 +1599,11 @@
     // since the directory is owned by root.
     if (!is_system_server && getuid() == 0) {
         const int rc = createProcessGroup(uid, getpid());
-        if (rc == -EROFS) {
-            ALOGW("createProcessGroup failed, kernel missing CONFIG_CGROUP_CPUACCT?");
-        } else if (rc != 0) {
-            ALOGE("createProcessGroup(%d, %d) failed: %s", uid, /* pid= */ 0, strerror(-rc));
+        if (rc != 0) {
+            fail_fn(rc == -EROFS ? CREATE_ERROR("createProcessGroup failed, kernel missing "
+                                                "CONFIG_CGROUP_CPUACCT?")
+                                 : CREATE_ERROR("createProcessGroup(%d, %d) failed: %s", uid,
+                                                /* pid= */ 0, strerror(-rc)));
         }
     }
 
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index cae6165..b61609f 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"by jou kalender in te gaan"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS-boodskappe te stuur en te bekyk"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Lêers en dokumente"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"kry toegang tot lêers en dokumente op jou toestel"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musiek en ander oudio"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"kry toegang tot oudiolêers op jou toestel"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Foto\'s en video\'s"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"kry toegang tot prente en videolêers op jou toestel"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofoon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"oudio op te neem"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fisieke aktiwiteit"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 8bac983..542d38c 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"የእርስዎን ቀን መቁጠሪያ ይድረሱበት"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"ኤስኤምኤስ"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"የኤስኤምኤስ መልዕክቶችን ይላኩና ይመልከቱ"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"ፋይሎች እና ሰነዶች"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"ፋይሎች እና ሰነዶች ዘንድ በመሳሪያዎ ላይ ይድረሱ"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"ሙዚቃ እና ሌላ ኦዲዮ"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"በመሳሪያዎ ላይ የድምጽ ፋይሎችን ይድረሱ"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ፎቶዎች እና ቪዲዮዎች"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"በመሣሪያዎ ላይ ምስሎችን እና የቪዲዮ ፋይሎችን ይድረሱ"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"ማይክሮፎን"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ኦዲዮ ይቅዱ"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"አካላዊ እንቅስቃሴ"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 6134918..e0c3edf 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -309,12 +309,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"الوصول إلى تقويمك"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"‏إرسال رسائل قصيرة SMS وعرضها"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"الملفات والمستندات"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"الوصول إلى الملفات والمستندات على جهازك"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"الموسيقى والملفات الصوتية الأخرى"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"الوصول إلى الملفات الصوتية على جهازك"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"الصور والفيديوهات"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"الوصول إلى الصور وملفات الفيديو على جهازك"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"الميكروفون"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"تسجيل الصوت"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"النشاط البدني"</string>
@@ -354,7 +359,7 @@
     <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"عرض الإشعارات كأنشطة بملء الشاشة على الأجهزة المُقفَلة"</string>
     <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"السماح للتطبيق بعرض الإشعارات كأنشطة بملء الشاشة على الأجهزة المُقفَلة"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"تثبيت اختصارات"</string>
-    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"للسماح لتطبيق بإضافة اختصارات على الشاشة الرئيسية بدون تدخل المستخدم."</string>
+    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"السماح لتطبيق بإضافة اختصارات على الشاشة الرئيسية بدون تدخل المستخدم."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"إزالة الاختصارات"</string>
     <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"للسماح للتطبيق بإزالة اختصارات من الشاشة الرئيسية بدون تدخل المستخدم."</string>
     <string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"إعادة توجيه المكالمات الصادرة"</string>
@@ -1632,7 +1637,7 @@
     <string name="display_manager_overlay_display_title" msgid="1480158037150469170">"‏<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>، <xliff:g id="DPI">%4$d</xliff:g> نقطة لكل بوصة"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="2810034719482834679">"آمن"</string>
     <string name="kg_forgot_pattern_button_text" msgid="406145459223122537">"نسيت النقش"</string>
-    <string name="kg_wrong_pattern" msgid="1342812634464179931">"النقش غير صحيح"</string>
+    <string name="kg_wrong_pattern" msgid="1342812634464179931">"النقش غير صحيح."</string>
     <string name="kg_wrong_password" msgid="2384677900494439426">"كلمة مرور خاطئة"</string>
     <string name="kg_wrong_pin" msgid="3680925703673166482">"رقم تعريف شخصي خاطئ"</string>
     <string name="kg_pattern_instructions" msgid="8366024510502517748">"ارسم نقشك"</string>
@@ -1848,7 +1853,7 @@
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"العمل الثالث <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"طلب إدخال رقم التعريف الشخصي قبل إزالة التثبيت"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"طلب إدخال النقش الخاص بإلغاء القفل قبل إزالة التثبيت"</string>
-    <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"المطالبة بكلمة المرور قبل إزالة التثبيت"</string>
+    <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"طلب إدخال كلمة المرور قبل إزالة التثبيت"</string>
     <string name="package_installed_device_owner" msgid="7035926868974878525">"تم التثبيت بواسطة المشرف"</string>
     <string name="package_updated_device_owner" msgid="7560272363805506941">"تم التحديث بواسطة المشرف"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"تم الحذف بواسطة المشرف"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 6a32b9c..4c10ad9 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"আপোনাৰ কেলেণ্ডাৰ ব্যৱহাৰ কৰিব পাৰে"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"এছএমএছ"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"এছএমএছ বার্তা পঠিয়াব আৰু চাব পাৰে"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"ফাইল আৰু নথি"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"আপোনাৰ ডিভাইচত থকা ফাইল আৰু নথি এক্সেছ কৰে"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"সংগীত আৰু অন্যান্য অডিঅ’"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"আপোনাৰ ডিভাইচত অডিঅ’ ফাইলসমূহ এক্সেছ কৰক"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ফট’ আৰু ভিডিঅ’"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"আপোনাৰ ডিভাইচত থকা প্ৰতিচ্ছবি আৰু ভিডিঅ’ ফাইলসমূহ এক্সেছ কৰক"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"মাইক্ৰ\'ফ\'ন"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"অডিঅ\' ৰেকর্ড কৰিব পাৰে"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"শাৰীৰিক কাৰ্যকলাপ"</string>
@@ -2053,8 +2058,7 @@
     <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"অসুবিধা নিদিব সলনি হৈছে"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"কি কি অৱৰোধ কৰা হৈছে জানিবলৈ টিপক।"</string>
     <string name="review_notification_settings_title" msgid="5102557424459810820">"জাননীৰ ছেটিং পৰ্যালোচনা কৰক"</string>
-    <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
-    <skip />
+    <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13ৰ পৰা, আপুনি ইনষ্টল কৰা এপক জাননী পঠিয়াবলৈ আপোনাৰ অনুমতিৰ প্ৰয়োজন। আগৰে পৰা থকা এপৰ বাবে এই অনুমতিটো সলনি কৰিবলৈ টিপক।"</string>
     <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"পাছত মনত পেলাই দিব"</string>
     <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"অগ্ৰাহ্য কৰক"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"ছিষ্টেম"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index fa3a998..d6cb1f9 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"təqvimə daxil olun"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"göndərin və SMS mesajlarına baxın"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Fayllar &amp; sənədlər"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"cihazınızda fayllara və sənədlərə giriş"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musiqi və digər audio"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"cihazınızdakı audio fayllarına giriş"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Foto və videolar"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"cihazınızdakı şəkil və video fayllarına giriş"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"səsi qeydə alın"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fiziki fəaliyyət"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index e854f43..f982b3f 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -306,12 +306,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"pristupi kalendaru"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"šalje i pregleda SMS poruke"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Fajlovi i dokumenti"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"pristupanje fajlovima i dokumentima na uređaju"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Muzika i drugi audio sadržaj"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"pristup audio fajlovima na uređaju"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Slike i video snimci"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"pristup slikama i video fajlovima na uređaju"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"snima zvuk"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fizičke aktivnosti"</string>
@@ -351,7 +356,7 @@
     <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"prikazuje obaveštenja kao aktivnosti preko celog ekrana na zaključanom uređaju"</string>
     <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Omogućava aplikaciji da na zaključanom uređaju prikazuje obaveštenja kao aktivnosti preko celog ekrana."</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"Instaliranje prečica"</string>
-    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Omogućava aplikaciji da dodaje prečice na početni ekran bez intervencije korisnika."</string>
+    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"da dodaju prečice na početni ekran bez intervencije korisnika."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"deinstaliranje prečica"</string>
     <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Omogućava aplikaciji da uklanja prečice sa početnog ekrana bez intervencije korisnika."</string>
     <string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"preusmeravanje odlaznih poziva"</string>
@@ -2054,8 +2059,7 @@
     <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Režim Ne uznemiravaj je promenjen"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Dodirnite da biste proverili šta je blokirano."</string>
     <string name="review_notification_settings_title" msgid="5102557424459810820">"Pregledajte podešavanja obaveštenja"</string>
-    <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
-    <skip />
+    <string name="review_notification_settings_text" msgid="5916244866751849279">"Od Android-a 13 aplikacije koje instalirate moraju da imaju dozvolu za slanje obaveštenja. Dodirnite da biste promenili ovu dozvolu za postojeće aplikacije."</string>
     <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Podseti me kasnije"</string>
     <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Odbaci"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Sistem"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 3197b73..72a54c6 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -307,12 +307,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"атрымліваць доступ да вашага календара"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"адпраўляць і праглядаць SMS-паведамленні"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Файлы і дакументы"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"доступ да файлаў і дакументаў на вашай прыладзе"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Музыка і іншае аўдыя"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"доступ да аўдыяфайлаў на вашай прыладзе"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Фота і відэа"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"доступ да відарысаў і відэафайлаў на вашай прыладзе"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Мікрафон"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"запісваць аўдыя"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Фізічная актыўнасць"</string>
@@ -1226,7 +1231,7 @@
     <string name="unsupported_display_size_show" msgid="980129850974919375">"Заўсёды паказваць"</string>
     <string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"Праграма <xliff:g id="APP_NAME">%1$s</xliff:g> была створана для несумяшчальнай версии АС Android і можа паводзіць сябе неспадзявана. Можа быць даступна абноўленая версія праграмы."</string>
     <string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"Заўсёды паказваць"</string>
-    <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Праверыць на наяўнасць абнаўленняў"</string>
+    <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Праверыць наяўнасць абнаўленняў"</string>
     <string name="smv_application" msgid="3775183542777792638">"Прыкладанне <xliff:g id="APPLICATION">%1$s</xliff:g> (працэс <xliff:g id="PROCESS">%2$s</xliff:g>) парушыла ўласную палітыку StrictMode."</string>
     <string name="smv_process" msgid="1398801497130695446">"Працэс <xliff:g id="PROCESS">%1$s</xliff:g> парушыў уласную палітыку StrictMode."</string>
     <string name="android_upgrading_title" product="default" msgid="7279077384220829683">"Абнаўленне тэлефона…"</string>
@@ -1951,7 +1956,7 @@
     <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Гэтай праграме патрабуецца дадатковая бяспека. Паспрабуйце скарыстаць планшэт."</string>
     <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Гэтай праграме патрабуецца дадатковая бяспека. Паспрабуйце скарыстаць тэлефон."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Гэта праграма была створана для больш старой версіі Android і можа не працаваць належным чынам. Праверце наяўнасць абнаўленняў або звярніцеся да распрацоўшчыка."</string>
-    <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Праверыць на наяўнасць абнаўленняў"</string>
+    <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Праверыць наяўнасць абнаўленняў"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"У вас ёсць новыя паведамленні"</string>
     <string name="new_sms_notification_content" msgid="3197949934153460639">"Праглядзець праз праграму для SMS"</string>
     <string name="profile_encrypted_title" msgid="9001208667521266472">"Функцыі могуць быць абмежаваныя"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index ee7af66..480d4b7 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"има достъп до календара ви"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"да изпраща и преглежда SMS съобщения"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Файлове и документи"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"достъп до файловете и документите на устройството ви"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Музика и друго аудиосъдържание"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"да има достъп до аудиофайловете на устройството ви"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Снимки и видеоклипове"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"да има достъп до графичните и видеофайловете на устройството ви"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Микрофон"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"записва звук"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Физическа активност"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index b0a832e..091e50a 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"আপনার ক্যালেন্ডারে অ্যাক্সেস"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"এসএমএসগুলি পাঠাতে এবং দেখতে"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"ফাইল ও ডকুমেন্ট"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"আপনার ডিভাইসে ফাইল ও ডকুমেন্ট অ্যাক্সেস করুন"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"মিউজিক ও অন্যান্য অডিও"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"আপনার ডিভাইসে অডিও ফাইল অ্যাক্সেস করুন"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ফটো ও ভিডিও"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"আপনার ডিভাইসে ছবি ও ভিডিও ফাইল অ্যাক্সেস করুন"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"মাইক্রোফোন"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"অডিও রেকর্ড"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"শারীরিক অ্যাক্টিভিটি"</string>
@@ -349,7 +354,7 @@
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"অ্যাপ্লিকেশনটিকে স্ট্যাটাস বার প্রসারিত বা সঙ্কুচিত করতে দেয়৷"</string>
     <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"লক করা ডিভাইসে ফুল স্ক্রিন অ্যাক্টিভিটি হিসাবে বিজ্ঞপ্তি দেখায়"</string>
     <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"এই অ্যাপকে লক করা ডিভাইসে ফুল স্ক্রিন অ্যাক্টিভিটি হিসাবে বিজ্ঞপ্তি দেখানোর অনুমতি দেয়"</string>
-    <string name="permlab_install_shortcut" msgid="7451554307502256221">"শর্টকাটগুলি ইনস্টল করে"</string>
+    <string name="permlab_install_shortcut" msgid="7451554307502256221">"শর্টকাট ইনস্টল করা"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"একটি অ্যাপ্লিকেশানকে ব্যবহারকারীর হস্তক্ষেপ ছাড়াই হোমস্ক্রীণে শর্টকাটগুলি যোগ করার অনুমতি দেয়৷"</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"শর্টকাটগুলি আনইনস্টল করে"</string>
     <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"অ্যাপ্লিকেশানটিকে ব্যবহারকারীর হস্তক্ষেপ ছাড়াই হোমস্ক্রীণের শর্টকাটগুলি সরানোর অনুমতি দেয়৷"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index b73b6a9..370b13a 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -306,12 +306,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"pristupa vašem kalendaru"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"šalje i pregleda SMS poruke"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Fajlovi i dokumenti"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"pristup datotekama i dokumentima na vašem uređaju"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Muzika i drugi zvučni zapisi"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"pristup audio fajlovima na vašem uređaju"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotografije i videozapisi"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"pristup fajlovima slika i videozapisa na vašem uređaju"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"snima zvuk"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fizička aktivnost"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index ded50c7..a224663 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"accedir al calendari"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"enviar i llegir missatges SMS"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Fitxers i documents"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"accedir als fitxers i documents del dispositiu"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Música i altres fitxers d\'àudio"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"accedir a fitxers d\'àudio del dispositiu"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotos i vídeos"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"accedir a fitxers d\'imatge i de vídeo del dispositiu"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Micròfon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"gravar àudio"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Activitat física"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index aad6bc4..83d5843 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -307,12 +307,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"přístup ke kalendáři"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"odesílání a zobrazování zpráv SMS"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Soubory a dokumenty"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"přístup k souborům a dokumentům v zařízení"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Hudba a ostatní zvuk"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"přístup ke zvukovým souborům v zařízení"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotky a videa"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"přístup k obrázkům a videosouborům v zařízení"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"nahrávání zvuku"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fyzická aktivita"</string>
@@ -1846,7 +1851,7 @@
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. <xliff:g id="LABEL">%1$s</xliff:g> do práce"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Před uvolněním požádat o PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Před uvolněním požádat o bezpečnostní gesto"</string>
-    <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Před uvolněním požádat o heslo"</string>
+    <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Před odepnutím požádat o heslo"</string>
     <string name="package_installed_device_owner" msgid="7035926868974878525">"Nainstalováno administrátorem"</string>
     <string name="package_updated_device_owner" msgid="7560272363805506941">"Aktualizováno administrátorem"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Smazáno administrátorem"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 6c12cc2..be5f46c 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"have adgang til din kalender"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"Sms"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"sende og se sms-beskeder"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Filer og dokumenter"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"få adgang til filer og dokumenter på din enhed"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musik og anden lyd"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"Få adgang til lydfiler på din enhed"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Billeder og videoer"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"Få adgang til videofiler på din enhed"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"optage lyd"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fysisk aktivitet"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index f8c7596..8b63cf7 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"auf deinen Kalender zugreifen"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS senden und abrufen"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Dateien und Dokumente"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"Auf Dateien und Dokumente auf deinem Gerät zugreifen"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musik &amp; andere Audiodateien"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"Zugriff auf Audiodateien auf deinem Gerät"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotos &amp; Videos"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"Zugriff auf Bild- und Videodateien auf deinem Gerät"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"Audio aufnehmen"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Körperliche Aktivität"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index e949ce1..3ef9e50 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"έχει πρόσβαση στο ημερολόγιό σας"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"στέλνει και να διαβάζει μηνύματα SMS"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Αρχεία και έγγραφα"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"πρόσβαση σε αρχεία και έγγραφα στη συσκευή σας"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Μουσική και άλλο ηχητικό περιεχόμενο"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"πρόσβαση σε αρχεία ήχου στη συσκευή σας"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Φωτογραφίες και βίντεο"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"πρόσβαση σε αρχεία εικόνας και βίντεο στη συσκευή σας"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Μικρόφωνο"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ηχογραφεί"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Σωματική δραστ/τητα"</string>
@@ -2053,8 +2058,7 @@
     <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Η λειτουργία \"Μην ενοχλείτε\" άλλαξε"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Πατήστε για να ελέγξετε το περιεχόμενο που έχει αποκλειστεί."</string>
     <string name="review_notification_settings_title" msgid="5102557424459810820">"Έλεγχος ρυθμίσεων ειδοποιήσεων"</string>
-    <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
-    <skip />
+    <string name="review_notification_settings_text" msgid="5916244866751849279">"Από το Android 13 και έπειτα, οι εφαρμογές που εγκαθιστάτε θα χρειάζονται την άδειά σας για την αποστολή ειδοποιήσεων. Πατήστε για να αλλάξετε αυτήν την άδεια για υπάρχουσες εφαρμογές."</string>
     <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Υπενθύμιση αργότερα"</string>
     <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Παράβλεψη"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Σύστημα"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index aedac3e..6761570 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"access your calendar"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"send and view SMS messages"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Files &amp; documents"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"access files and documents on your device"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Music &amp; other audio"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"access audio files on your device"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Photos &amp; videos"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"access images and video files on your device"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Microphone"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"record audio"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Physical activity"</string>
@@ -2053,8 +2058,7 @@
     <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Do Not Disturb has changed"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Tap to check what\'s blocked."</string>
     <string name="review_notification_settings_title" msgid="5102557424459810820">"Review notification settings"</string>
-    <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
-    <skip />
+    <string name="review_notification_settings_text" msgid="5916244866751849279">"Starting in Android 13, apps that you install need your permission to send notifications. Tap to change this permission for existing apps."</string>
     <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Remind me later"</string>
     <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Dismiss"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"System"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 88fedc9..b680f84 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"access your calendar"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"send and view SMS messages"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Files &amp; documents"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"access files and documents on your device"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Music &amp; other audio"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"access audio files on your device"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Photos &amp; videos"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"access images and video files on your device"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Microphone"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"record audio"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Physical activity"</string>
@@ -2053,8 +2058,7 @@
     <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Do Not Disturb has changed"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Tap to check what\'s blocked."</string>
     <string name="review_notification_settings_title" msgid="5102557424459810820">"Review notification settings"</string>
-    <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
-    <skip />
+    <string name="review_notification_settings_text" msgid="5916244866751849279">"Starting in Android 13, apps that you install need your permission to send notifications. Tap to change this permission for existing apps."</string>
     <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Remind me later"</string>
     <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Dismiss"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"System"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index dd9de67..1263109 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"access your calendar"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"send and view SMS messages"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Files &amp; documents"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"access files and documents on your device"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Music &amp; other audio"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"access audio files on your device"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Photos &amp; videos"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"access images and video files on your device"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Microphone"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"record audio"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Physical activity"</string>
@@ -2053,8 +2058,7 @@
     <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Do Not Disturb has changed"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Tap to check what\'s blocked."</string>
     <string name="review_notification_settings_title" msgid="5102557424459810820">"Review notification settings"</string>
-    <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
-    <skip />
+    <string name="review_notification_settings_text" msgid="5916244866751849279">"Starting in Android 13, apps that you install need your permission to send notifications. Tap to change this permission for existing apps."</string>
     <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Remind me later"</string>
     <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Dismiss"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"System"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index a953730..df09b01 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"access your calendar"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"send and view SMS messages"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Files &amp; documents"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"access files and documents on your device"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Music &amp; other audio"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"access audio files on your device"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Photos &amp; videos"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"access images and video files on your device"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Microphone"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"record audio"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Physical activity"</string>
@@ -2053,8 +2058,7 @@
     <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Do Not Disturb has changed"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Tap to check what\'s blocked."</string>
     <string name="review_notification_settings_title" msgid="5102557424459810820">"Review notification settings"</string>
-    <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
-    <skip />
+    <string name="review_notification_settings_text" msgid="5916244866751849279">"Starting in Android 13, apps that you install need your permission to send notifications. Tap to change this permission for existing apps."</string>
     <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Remind me later"</string>
     <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Dismiss"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"System"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index aff6c07..7439725 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -305,12 +305,12 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‏‎‎‎‎‏‏‏‏‎‎‏‎‎‎‎‏‎‏‏‏‏‎‏‎‎‎‎‎‎‏‏‏‎‏‎‎‎‏‎‎‏‏‏‏‎‎‎‏‏‎access your calendar‎‏‎‎‏‎"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‎‎‎‏‎‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‎‎‏‎‎‎‎‏‏‎‎‏‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‎‎‎‎‏‎‏‎‎SMS‎‏‎‎‏‎"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‏‏‎‎‎‎‏‏‏‏‎‏‏‎‎‏‏‎‏‏‎‎‎‎‎‎‎‎‎‏‎‎‏‏‎‎‏‎‎‎‎‎‏‎‏‏‎‎‏‏‏‏‎‎send and view SMS messages‎‏‎‎‏‎"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‎‏‏‏‎‏‎‏‏‎‎‎‏‎‏‎‎‏‎‏‎‏‏‎‏‏‏‎‎‏‎‎‎‏‏‏‏‎‎‎‏‎‏‎‏‎‎‎Files &amp; documents‎‏‎‎‏‎"</string>
+    <string name="permgrouplab_storage" msgid="5570124978732352858">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‎‏‏‎‏‎‎‎‎‏‏‏‏‎‎‏‎‏‎‎‎‎‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‎‏‏‎‏‎‎Files and documents‎‏‎‎‏‎"</string>
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‎‎‏‏‏‏‏‎‏‎‏‎‏‎‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‏‏‏‎‏‏‏‏‎‎‏‏‎‏‎access files and documents on your device‎‏‎‎‏‎"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‏‏‎‎‎‏‏‏‎‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‏‏‎‎‎‎‏‎‏‎‎‎‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‎‎Music &amp; other audio‎‏‎‎‏‎"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‎‎‏‏‏‏‎‏‎‎‏‎‏‏‏‏‎‎‏‎‎‏‎‏‎‏‎‏‏‏‎‏‎‏‏‏‏‎‎‎‎‏‏‎‎‎‎‏‏‎‏‎‎‏‏‎‎access audio files on your device‎‏‎‎‏‎"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‏‎‎‏‏‏‎‏‏‏‏‎‏‎‏‏‎‎‎‏‎‎‏‏‎‏‏‎‏‎‏‎‎‎‏‎‎‎‏‏‎‎‏‏‏‏‎‏‎Photos &amp; videos‎‏‎‎‏‎"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‎‏‏‎‏‎‎‏‎‏‏‎‏‎‏‎‏‎‎‎‏‏‎‎‎‏‏‎‏‏‏‎‏‎‎‏‏‎‏‏‎‏‏‎‎‎‏‎‎‏‏‎‎‏‎‏‎access images and video files on your device‎‏‎‎‏‎"</string>
+    <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‎‏‎‏‎‎‎‎‏‏‏‏‎‎‏‏‏‏‎‏‏‏‎‏‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‏‏‎‎‏‎‏‎Music and audio‎‏‎‎‏‎"</string>
+    <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‏‏‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‏‎‎‎‎‏‎‏‎‎‎‎‏‎‏‏‏‎‏‏‎access music and audio on your device‎‏‎‎‏‎"</string>
+    <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‎‎‏‎‎‏‎‎‎‏‎‎‎‎‎‏‎‎‎‎‏‎‏‏‎‏‏‏‎‏‏‎‏‏‎‎‏‏‏‎‎‏‎‎‎‎‎‎‎‏‏‎‏‎‎‎Photos and videos‎‏‎‎‏‎"</string>
+    <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‏‎‎‎‎‎‏‎‏‏‎‏‏‏‏‎‏‏‎‎‏‏‎‎‎‎‎‏‎‎‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎‎‏‏‎‏‎‎‎‎‎access photos and videos on your device‎‏‎‎‏‎"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‏‏‎‏‏‎‎‏‏‎‏‏‎‏‎‎‎‏‏‎‏‏‏‏‎‏‏‏‎‏‎‏‏‎‏‏‏‎‏‎‏‎‎‎‎‏‏‏‎‏‎‏‏‎‎‎Microphone‎‏‎‎‏‎"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‎‎‏‎‏‎‎‏‏‏‏‏‎‎‎‏‏‏‏‎‏‏‎‏‏‎‏‎‎‎‎‏‏‏‎‏‏‎‏‎‎‏‏‏‏‏‎‎‏‎‏‎‏‎‎record audio‎‏‎‎‏‎"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‏‎‎‎‏‎‏‏‏‎‎‎‎‎‏‏‎‏‎‎‏‎‎‎‎‏‏‎‎‏‎‎‎‏‏‎‏‎‏‎‎‏‏‏‎‎‏‎‎‏‎‏‏‎‎Physical activity‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 62b2d76..bd460a1 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"acceder al calendario"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"enviar y ver mensajes SMS"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Archivos y documentos"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"Accede a archivos y documentos en tu dispositivo"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Música y otro contenido de audio"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"acceder a los archivos de audio en tu dispositivo"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotos y videos"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"acceder a los archivos de imagen y video en tu dispositivo"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Micrófono"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"grabar audio"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Actividad física"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 593fa2e..62514b9 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"acceder a tu calendario"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"enviar y ver mensajes SMS"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Archivos y documentos"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"acceder a archivos y documentos de tu dispositivo"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Música y otros archivos de audio"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"acceder a los archivos de audio de tu dispositivo"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotos y vídeos"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"acceder a los archivos de vídeo de tu dispositivo"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Micrófono"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"grabar audio"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Actividad física"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 737c802..33cdd9d 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"juurdepääs kalendrile"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"saata ja vaadata SMS-sõnumeid"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Failid ja dokumendid"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"juurdepääs teie seadmes olevatele failidele ja dokumentidele"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Muusika ja muud helifailid"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"pääseda juurde teie seadmes olevatele helifailidele"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotod ja videod"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"pääseda juurde teie seadmes olevatele pildi- ja videofailidele"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"heli salvestamine"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Füüsiline tegevus"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 1f3d169..cf2c028 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"atzitu egutegia"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMSak"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"bidali eta ikusi SMS mezuak"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Fitxategiak eta dokumentuak"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"gailuko fitxategiak eta dokumentuak atzitu"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musika eta bestelako audioa"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"atzitu gailuko audio-fitxategiak"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Argazkiak eta bideoak"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"atzitu gailuko irudi- eta bideo-fitxategiak"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofonoa"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"grabatu audioa"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Jarduera fisikoa"</string>
@@ -344,7 +349,7 @@
     <string name="permlab_statusBar" msgid="8798267849526214017">"desgaitu edo aldatu egoera-barra"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Egoera-barra desgaitzea edo sistema-ikonoak gehitzea edo kentzea baimentzen die aplikazioei."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"bihurtu egoera-barra"</string>
-    <string name="permdesc_statusBarService" msgid="6652917399085712557">"Egoera-barra izatea baimentzen die aplikazioei."</string>
+    <string name="permdesc_statusBarService" msgid="6652917399085712557">"Egoera-barra izateko baimena ematen die aplikazioei."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"zabaldu/tolestu egoera-barra"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Egoera-barra zabaltzeko edo tolesteko baimena ematen die aplikazioei."</string>
     <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"blokeatutako gailu batean jakinarazpenak pantaila osoko jarduera gisa bistaratzea"</string>
@@ -481,7 +486,7 @@
     <string name="permlab_exemptFromAudioRecordRestrictions" msgid="1164725468350759486">"salbuetsi audioa grabatzeko murriztapenen aurrean"</string>
     <string name="permdesc_exemptFromAudioRecordRestrictions" msgid="2425117015896871976">"Salbuetsi aplikazioa audioa grabatzeko murriztapenen aurrean."</string>
     <string name="permlab_acceptHandover" msgid="2925523073573116523">"jarraitu beste aplikazio batean hasitako deia"</string>
-    <string name="permdesc_acceptHandovers" msgid="7129026180128626870">"Beste aplikazio batean hasitako dei bat jarraitzea baimentzen dio aplikazioari."</string>
+    <string name="permdesc_acceptHandovers" msgid="7129026180128626870">"Beste aplikazio batean hasitako dei batekin jarraitzeko baimena ematen die aplikazioei."</string>
     <string name="permlab_readPhoneNumbers" msgid="5668704794723365628">"irakurri telefono-zenbakiak"</string>
     <string name="permdesc_readPhoneNumbers" msgid="7368652482818338871">"Gailuaren telefono-zenbakiak atzitzeko baimena ematen die aplikazioei."</string>
     <string name="permlab_wakeLock" product="automotive" msgid="1904736682319375676">"mantendu piztuta autoko pantaila"</string>
@@ -551,7 +556,7 @@
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"NFC bidezko ordainketa-zerbitzu lehenetsiari buruzko informazioa"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"NFC bidezko ordainketa-zerbitzu lehenetsiari buruzko informazioa jasotzeko baimena ematen die aplikazioei, hala nola erregistratutako laguntzaileak eta ibilbidearen helmuga."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"kontrolatu Near Field Communication komunikazioa"</string>
-    <string name="permdesc_nfc" msgid="8352737680695296741">"Near Field Communication (NFC) etiketekin, txartelekin eta irakurgailuekin komunikatzea baimentzen die aplikazioei."</string>
+    <string name="permdesc_nfc" msgid="8352737680695296741">"Near Field Communication (NFC) etiketekin, txartelekin eta irakurgailuekin komunikatzeko baimena ematen die aplikazioei."</string>
     <string name="permlab_disableKeyguard" msgid="3605253559020928505">"desgaitu pantailaren blokeoa"</string>
     <string name="permdesc_disableKeyguard" msgid="3223710003098573038">"Teklen blokeoa eta erlazionatutako pasahitz-segurtasuna desgaitzeko baimena ematen die aplikazioei. Adibidez, telefonoak teklen blokeoa desgaitzen du telefono-deiak jasotzen dituenean, eta berriro gaitzen du deiak amaitzean."</string>
     <string name="permlab_requestPasswordComplexity" msgid="1808977190557794109">"eskatu pantailaren blokeoa konplexua izatea"</string>
@@ -704,7 +709,7 @@
     <string name="permlab_bind_incall_service" msgid="5990625112603493016">"erabili pantaila deiak abian direnean"</string>
     <string name="permdesc_bind_incall_service" msgid="4124917526967765162">"Erabiltzaileak deiaren pantaila noiz eta nola ikusten duen kontrolatzeko baimena ematen die aplikazioei."</string>
     <string name="permlab_bind_connection_service" msgid="5409268245525024736">"jardun interakzioan telefono-zerbitzuekin"</string>
-    <string name="permdesc_bind_connection_service" msgid="6261796725253264518">"Deiak egiteko eta jasotzeko telefonia-zerbitzuekin interakzioan aritzea baimentzen die aplikazioei."</string>
+    <string name="permdesc_bind_connection_service" msgid="6261796725253264518">"Deiak egiteko eta jasotzeko telefonia-zerbitzuekin interakzioan aritzeko baimena ematen die aplikazioei."</string>
     <string name="permlab_control_incall_experience" msgid="6436863486094352987">"eskaini erabiltzaileentzako aukerak deiak abian direnean"</string>
     <string name="permdesc_control_incall_experience" msgid="5896723643771737534">"Deiak abian direnean erabiltzeko aukera eskaintzea baimentzen die aplikazioei."</string>
     <string name="permlab_readNetworkUsageHistory" msgid="8470402862501573795">"irakurri sare-erabileraren historia"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 2b79b17..5e5cdbb 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"دسترسی به تقویم شما"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"پیامک"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"ارسال و مشاهده پیامک‌ها"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"فایل‌ها و اسناد"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"دسترسی به فایل‌ها و اسناد موجود در دستگاه"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"موسیقی و فایل‌های صوتی دیگر"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"دسترسی به فایل‌های صوتی موجود در دستگاه"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"عکس‌ها و ویدیوها"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"دسترسی به فایل‌های تصویری و ویدیویی موجود در دستگاه"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"میکروفن"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ضبط صدا"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"فعالیت فیزیکی"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 52c1d26..cd462df 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"käyttää kalenteria"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"Tekstiviestit"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"lähettää ja tarkastella tekstiviestejä"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Tiedostot ja dokumentit"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"pääsyn laitteesi tiedostoihin ja dokumentteihin"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musiikki ja muu audio"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"pääsy laitteesi audiotiedostoihin"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Kuvat ja videot"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"pääsy laitteesi kuviin ja videotiedostoihin"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofoni"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"tallentaa ääntä"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Liikkuminen"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index fc7fc07..aa03c06 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"accéder à votre agenda"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"Messagerie texte"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"envoyer et afficher des messages texte"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Fichiers et documents"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"accédez aux fichiers et aux documents sur votre appareil"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musique et autres fichiers audio"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"accéder aux fichiers audio de votre appareil"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Photos et vidéos"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"accéder aux fichiers d\'image et aux fichiers vidéo de votre appareil"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Microphone"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"enregistrer des fichiers audio"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Activité physique"</string>
@@ -349,7 +354,7 @@
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Permet à l\'application de réduire ou de développer la barre d\'état."</string>
     <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"afficher les notifications en mode plein écran sur un appareil verrouillé"</string>
     <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Permet à l\'application d\'afficher les notifications en mode plein écran sur un appareil verrouillé."</string>
-    <string name="permlab_install_shortcut" msgid="7451554307502256221">"installer des raccourcis"</string>
+    <string name="permlab_install_shortcut" msgid="7451554307502256221">"Installer des raccourcis"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Permet à une application d\'ajouter des raccourcis sans l\'intervention de l\'utilisateur."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"désinstaller des raccourcis"</string>
     <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Permet à l\'application de supprimer des raccourcis de la page d\'accueil sans intervention de l\'utilisateur."</string>
@@ -427,7 +432,7 @@
     <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Permet à l\'application de lire le journal d\'appels de votre téléphone, y compris les données relatives aux appels entrants et sortants. Des applications malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string>
     <string name="permlab_bodySensors" msgid="662918578601619569">"Accéder aux données des capteurs corporels si en utilisation (fréq. card., etc.)"</string>
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permet à l\'application d\'accéder aux données des capteurs corporels telles que la fréquence cardiaque, la température et le pourcentage d\'oxygène dans le sang pendant l\'utilisation de l\'application."</string>
-    <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Accéder aux données des capteurs corporels si en arrière-plan (fréq. card., etc.)"</string>
+    <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Accéder aux données des capteurs corporels (comme la fréq. card.) en arrière-plan"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permet à l\'application d\'accéder aux données des capteurs corporels telles que la fréquence cardiaque, la température et le pourcentage d\'oxygène dans le sang pendant que l\'application s\'exécute en arrière-plan."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Lire les événements d\'agenda et leurs détails"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Cette application peut lire tous les événements d\'agenda stockés sur votre tablette et partager ou enregistrer les données de votre agenda."</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 861d6b0..7a4a10a 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -21,7 +21,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="byteShort" msgid="202579285008794431">"octet(s)"</string>
-    <string name="kilobyteShort" msgid="2214285521564195803">"Ko"</string>
+    <string name="kilobyteShort" msgid="2214285521564195803">"ko"</string>
     <string name="megabyteShort" msgid="6649361267635823443">"Mo"</string>
     <string name="gigabyteShort" msgid="7515809460261287991">"Go"</string>
     <string name="terabyteShort" msgid="1822367128583886496">"To"</string>
@@ -244,7 +244,7 @@
     <string name="global_action_power_off" msgid="4404936470711393203">"Éteindre"</string>
     <string name="global_action_power_options" msgid="1185286119330160073">"Marche/Arrêt"</string>
     <string name="global_action_restart" msgid="4678451019561687074">"Redémarrer"</string>
-    <string name="global_action_emergency" msgid="1387617624177105088">"Urgences"</string>
+    <string name="global_action_emergency" msgid="1387617624177105088">"Urgence"</string>
     <string name="global_action_bug_report" msgid="5127867163044170003">"Rapport de bug"</string>
     <string name="global_action_logout" msgid="6093581310002476511">"Fermer la session"</string>
     <string name="global_action_screenshot" msgid="2610053466156478564">"Capture d\'écran"</string>
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"accéder à votre agenda"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"envoyer et consulter des SMS"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Fichiers et documents"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"accéder aux fichiers et documents sur votre appareil"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musique et autres contenus audio"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"accès aux fichiers audio sur votre appareil"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Photos et vidéos"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"accès aux fichiers image et vidéo sur votre appareil"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Microphone"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"enregistrer des fichiers audio"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Activité physique"</string>
@@ -912,7 +917,7 @@
     <string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Appuyez sur \"Menu\" pour déverrouiller le téléphone ou appeler un numéro d\'urgence"</string>
     <string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Appuyez sur \"Menu\" pour déverrouiller le téléphone."</string>
     <string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Dessinez un schéma pour déverrouiller le téléphone"</string>
-    <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Urgences"</string>
+    <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Urgence"</string>
     <string name="lockscreen_return_to_call" msgid="3156883574692006382">"Retour à l\'appel"</string>
     <string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Combinaison correcte !"</string>
     <string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Veuillez réessayer."</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 0393c4b..e657f71 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"acceder ao teu calendario"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"enviar e consultar mensaxes de SMS"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Ficheiros e documentos"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"acceder a ficheiros e documentos do dispositivo"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Música e outro contido de audio"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"acceder a ficheiros de audio do teu dispositivo"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotos e vídeos"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"acceder a ficheiros de imaxe e de vídeo do teu dispositivo"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Micrófono"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"gravar audio"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Actividade física"</string>
@@ -2104,7 +2109,7 @@
     <string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} + # ficheiro}other{{file_name} + # ficheiros}}"</string>
     <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Non hai recomendacións de persoas coas que compartir contido"</string>
     <string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Lista de aplicacións"</string>
-    <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Esta aplicación non está autorizada a realizar gravacións, pero pode capturar audio a través deste dispositivo USB."</string>
+    <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Esta aplicación non está autorizada a realizar gravacións, pero podería capturar audio a través deste dispositivo USB."</string>
     <string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Inicio"</string>
     <string name="accessibility_system_action_back_label" msgid="4205361367345537608">"Volver"</string>
     <string name="accessibility_system_action_recents_label" msgid="4782875610281649728">"Aplicacións recentes"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 033f7ee..ba62090 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"તમારા કેલેન્ડરને ઍક્સેસ કરવાની"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS સંદેશા મોકલવાની અને જોવાની"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"ફાઇલો અને દસ્તાવેજો"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"તમારા ડિવાઇસ પર ફાઇલો અને દસ્તાવેજો ઍક્સેસ કરો"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"મ્યુઝિક અને અન્ય ઑડિયો"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"તમારા ડિવાઇસ પર ઑડિયો ફાઇલો ઍક્સેસ કરવા માટે"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ફોટા અને વીડિયો"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"તમારા ડિવાઇસ પર છબીઓ અને વીડિયો ફાઇલો ઍક્સેસ કરવા માટે"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"માઇક્રોફોન"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ઑડિઓ રેકોર્ડ કરવાની"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"શારીરિક પ્રવૃત્તિ"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index f029822..5eb0b31 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"अपने कैलेंडर को ऐक्सेस करें"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"मैसेज (एसएमएस)"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"मैसेज (एसएमएस) भेजें और देखें"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"फ़ाइलें और दस्तावेज़"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"अपने डिवाइस पर मौजूद फ़ाइलें और दस्तावेज़ ऐक्सेस करने की अनुमति दें"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"संगीत और अन्य ऑडियो"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"आपके डिवाइस पर मौजूद, ऑडियो फ़ाइलों का ऐक्सेस"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"फ़ोटो और वीडियो"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"आपके डिवाइस पर मौजूद, इमेज और वीडियो फ़ाइलों का ऐक्सेस"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"माइक्रोफ़ोन"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ऑडियो रिकॉर्ड करें"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"शारीरिक गतिविधि"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 42adb5d..0787f37 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -306,12 +306,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"pristupati kalendaru"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"slati i pregledavati SMS poruke"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Datoteke i dokumenti"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"pristup datotekama i dokumentima na vašem uređaju"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Glazba i druge audiodatoteke"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"pristup audiodatotekama na uređaju"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotografije i videozapisi"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"pristup slikama i videodatotekama na uređaju"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"snimati zvuk"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Tjelesna aktivnost"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index c02cff6..ea581394 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"hozzáférés a naptárhoz"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS-ek küldése és megtekintése"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Fájlok és dokumentumok"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"hozzáférhet fájljaihoz és dokumentumaihoz az eszközén"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Zenék és más audiotartalmak"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"hozzáférés az eszközön található hangfájlokhoz"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotók és videók"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"hozzáférés az eszközön található videófájlokhoz"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"hanganyag rögzítése"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Testmozgás"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index b983004..e483b0e 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"օգտագործել օրացույցը"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"ուղարկել և դիտել SMS-ները"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Ֆայլեր և փաստաթղթեր"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"սարքի ֆայլերի և փաստաթղթերի օգտագործման թույլտվություն"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Երաժշտություն և այլ աուդիո նյութեր"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"բացել ձեր սարքում պահված աուդիո ֆայլերը"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Լուսանկարներ և տեսանյութեր"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"բացել ձեր սարքում պահված գրաֆիկական և վիդեո ֆայլերը"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Խոսափող"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ձայնագրել"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Ֆիզիկական ակտիվություն"</string>
@@ -2140,7 +2145,7 @@
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Այս բովանդակությունը հնարավոր չէ ուղարկել անձնական հավելվածներով"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Այս բովանդակությունը հնարավոր չէ բացել անձնական հավելվածներով"</string>
     <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Աշխատանքային պրոֆիլի ծառայությունը դադարեցված է"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Հպեք՝ միացնելու համար"</string>
+    <string name="resolver_switch_on_work" msgid="463709043650610420">"Հպեք միացնելու համար"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Աշխատանքային հավելվածներ չկան"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Անձնական հավելվածներ չկան"</string>
     <string name="miniresolver_open_in_personal" msgid="3874522693661065566">"Բացե՞լ <xliff:g id="APP">%s</xliff:g> հավելվածը ձեր անձնական պրոֆիլում"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index f02a440..643d03c 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -56,7 +56,7 @@
     </plurals>
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
-    <string name="ClipMmi" msgid="4110549342447630629">"Nomor Penelepon Masuk"</string>
+    <string name="ClipMmi" msgid="4110549342447630629">"ID Penelepon Masuk"</string>
     <string name="ClirMmi" msgid="6752346475055446417">"Menyembunyikan ID Penelepon untuk Panggilan Keluar"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"ID Saluran yang Terhubung"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Batasan ID Saluran yang Terhubung"</string>
@@ -71,12 +71,12 @@
     <string name="RuacMmi" msgid="1876047385848991110">"Penolakan panggilan yang tidak diinginkan"</string>
     <string name="CndMmi" msgid="185136449405618437">"Pengiriman nomor panggilan"</string>
     <string name="DndMmi" msgid="8797375819689129800">"Jangan ganggu"</string>
-    <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Nomor penelepon default \"dibatasi\". Panggilan selanjutnya: Dibatasi"</string>
-    <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Nomor pengguna default \"dibatasi\". Panggilan selanjutnya: Tidak dibatasi."</string>
-    <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Nomor penelepon default tidak dibatasi. Panggilan selanjutnya: Dibatasi"</string>
-    <string name="CLIRDefaultOffNextCallOff" msgid="2491576172356463443">"Nomor penelepon default tidak dibatasi. Panggilan selanjutnya: Tidak dibatasi"</string>
+    <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"ID penelepon diatur default ke \"dibatasi\". Panggilan selanjutnya: Dibatasi"</string>
+    <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"ID penelepon diatur default ke \"dibatasi\". Panggilan selanjutnya: Tidak dibatasi."</string>
+    <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"ID penelepon diatur default ke tidak dibatasi. Panggilan selanjutnya: Dibatasi"</string>
+    <string name="CLIRDefaultOffNextCallOff" msgid="2491576172356463443">"ID penelepon diatur default ke tidak dibatasi. Panggilan selanjutnya: Tidak dibatasi"</string>
     <string name="serviceNotProvisioned" msgid="8289333510236766193">"Layanan tidak diperlengkapi."</string>
-    <string name="CLIRPermanent" msgid="166443681876381118">"Anda tidak dapat mengubah setelan nomor penelepon."</string>
+    <string name="CLIRPermanent" msgid="166443681876381118">"Anda tidak dapat mengubah setelan ID penelepon."</string>
     <string name="RestrictedOnDataTitle" msgid="1500576417268169774">"Tidak ada layanan data seluler"</string>
     <string name="RestrictedOnEmergencyTitle" msgid="2852916906106191866">"Panggilan darurat tidak tersedia"</string>
     <string name="RestrictedOnNormalTitle" msgid="7009474589746551737">"Tidak ada layanan panggilan suara"</string>
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"mengakses kalender"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"mengirim dan melihat pesan SMS"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"File &amp; dokumen"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"mengakses file dan dokumen di perangkat Anda"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musik &amp; audio lainnya"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"mengakses file audio di perangkat Anda"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Foto &amp; video"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"mengakses file gambar dan video di perangkat Anda"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"merekam audio"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Aktivitas fisik"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index ce84af7..d8b01c7 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"fá aðgang að dagatalinu þínu"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"senda og skoða SMS-skilaboð"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Skrár og skjöl"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"fá aðgang að skrám og skjölum í tækinu þínu"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Tónlist og annað hljóð"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"fá aðgang að hljóðskrám í tækinu þínu"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Myndir og myndskeið"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"fá aðgang að myndum og myndskeiðaskrám í tækinu þínu"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Hljóðnemi"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"taka upp hljóð"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Hreyfing"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 1db6e66..05a6b12 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"Possono accedere al calendario"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"Possono inviare e visualizzare SMS"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"File e documenti"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"Consente di accedere a file e documenti sul tuo dispositivo"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musica e altro audio"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"Accesso ai file audio sul tuo dispositivo"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Foto e video"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"Accesso ai file immagine e video sul tuo dispositivo"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Microfono"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"Possono registrare audio"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Attività fisica"</string>
@@ -349,8 +354,8 @@
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Consente all\'applicazione di espandere o comprimere la barra di stato."</string>
     <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"Visualizzazione di notifiche sotto forma di attività in modalità a schermo intero su un dispositivo bloccato"</string>
     <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Consente all\'app di visualizzare le notifiche sotto forma di attività in modalità a schermo intero su un dispositivo bloccato"</string>
-    <string name="permlab_install_shortcut" msgid="7451554307502256221">"aggiunta di scorciatoie"</string>
-    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Consente a un\'applicazione di aggiungere scorciatoie alla schermata Home automaticamente."</string>
+    <string name="permlab_install_shortcut" msgid="7451554307502256221">"Aggiunta di scorciatoie"</string>
+    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Consente a un\'applicazione di aggiungere scorciatoie alla schermata Home automaticamente"</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"eliminazione di scorciatoie"</string>
     <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Consente all\'applicazione di rimuovere le scorciatoie della schermata Home automaticamente."</string>
     <string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"reindirizzamento chiamate in uscita"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 0449349..d972e84 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -307,12 +307,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"גישה אל היומן"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"‏שליחה והצגה של הודעות SMS"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"קבצים ומסמכים"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"גישה לקבצים ולמסמכים במכשיר"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"מוזיקה וסוגי אודיו אחרים"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"גישה לקובצי אודיו במכשיר"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"תמונות וסרטונים"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"גישה לקובצי וידאו ותמונה במכשיר"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"מיקרופון"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"הקלטת אודיו"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"פעילות גופנית"</string>
@@ -352,7 +357,7 @@
     <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"הצגת התראות כפעילויות במסך מלא במכשיר נעול"</string>
     <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"מאפשרת לאפליקציה להציג התראות כפעילויות במסך מלא במכשיר נעול"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"התקנה של קיצורי דרך"</string>
-    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"מאפשרת לאפליקציה להוסיף קיצורי דרך במסך דף הבית ללא התערבות המשתמש."</string>
+    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"מאפשרת לאפליקציה להוסיף קיצורי דרך במסך הבית ללא התערבות המשתמש."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"הסרת התקנה של קיצורי דרך"</string>
     <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"מאפשרת לאפליקציה להסיר קיצורי דרך במסך דף הבית ללא התערבות המשתמש."</string>
     <string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"ניתוב מחדש של שיחות יוצאות"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 1d2def7..15c5e1d 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"カレンダーへのアクセス"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMSメッセージの送信と表示"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"ファイル、ドキュメント"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"デバイス内のファイルやドキュメントへのアクセス"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"音楽やその他の音声"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"デバイス上の音声ファイルへのアクセス"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"写真と動画"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"デバイス上の画像、動画ファイルへのアクセス"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"マイク"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"音声の録音"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"身体活動"</string>
@@ -2140,7 +2145,7 @@
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"このコンテンツを個人用アプリと共有することはできません"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"このコンテンツを個人用アプリで開くことはできません"</string>
     <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"仕事用プロファイルが一時停止しています"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"タップすると有効になります"</string>
+    <string name="resolver_switch_on_work" msgid="463709043650610420">"タップして有効化"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"仕事用アプリはありません"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"個人用アプリはありません"</string>
     <string name="miniresolver_open_in_personal" msgid="3874522693661065566">"個人用プロファイルで <xliff:g id="APP">%s</xliff:g> を開きますか?"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 7fb4833..787eac6 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"თქვენს კალენდარზე წვდომა"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS შეტყობინებების გაგზავნა და ნახვა"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"ფაილები და დოკუმენტები"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"თქვენს მოწყობილობაზე ფაილებსა და დოკუმენტებზე წვდომა"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"მუსიკა და სხვა აუდიო ფაილები"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"თქვენს მოწყობილობაზე აუდიო ფაილებზე წვდომა"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ფოტოები და ვიდეოები"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"თქვენს მოწყობილობაზე სურათის ფაილებსა და ვიდეო ფაილებზე წვდომა"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"მიკროფონი"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"აუდიოს ჩაწერა"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"ფიზიკური აქტივობა"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 4bd7c14..10459b7 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -305,16 +305,21 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"күнтізбеге кіру"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS хабарларын жіберу және көру"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Файлдар мен құжаттар"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"құрылғыдағы файлдар мен құжаттарды пайдалану"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Музыка және басқа аудио"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"құрылғыдағы аудиофайлдарды пайдалану"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Фотосуреттер және бейнелер"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"құрылғыдағы кескіндер мен бейнефайлдарды пайдалану"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Микрофон"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"аудио жазу"</string>
-    <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Іс-қимыл"</string>
-    <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"іс-қимыл дерегін алу"</string>
+    <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Қимыл-қозғалыс"</string>
+    <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"қимыл-қозғалыс дерегін алу"</string>
     <string name="permgrouplab_camera" msgid="9090413408963547706">"Камера"</string>
     <string name="permgroupdesc_camera" msgid="7585150538459320326">"суретке түсіріп, бейне жазу"</string>
     <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Маңайдағы құрылғылар"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index a344709..2b3dfa9 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"ចូលប្រើប្រិតិទិនរបស់អ្នក"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"សារ SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"ផ្ញើ និងមើលសារ SMS"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"ឯកសារ"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"ចូលប្រើ​ឯកសារ​នៅលើ​ឧបករណ៍​របស់អ្នក"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"តន្ត្រី និងសំឡេងផ្សេងទៀត"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"ចូលប្រើឯកសារសំឡេងនៅលើឧបករណ៍របស់អ្នក"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"រូបថត និងវីដេអូ"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"ចូលប្រើឯកសាររូបភាព និងវីដេអូនៅលើឧបករណ៍របស់អ្នក"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"មីក្រូ​ហ្វូន"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ថតសំឡេង"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"សកម្មភាព​រាងកាយ"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index eb1baf0..f9438ab 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"ನಿಮ್ಮ ಕ್ಯಾಲೆಂಡರ್ ಪ್ರವೇಶಿಸಲು"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು ಮತ್ತು ನಿರ್ವಹಿಸಲು"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"ಫೈಲ್‌ಗಳು ಮತ್ತು ಡಾಕ್ಯುಮೆಂಟ್‌ಗಳು"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಫೈಲ್‌ಗಳು ಮತ್ತು ಡಾಕ್ಯುಮೆಂಟ್‌ಗಳನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"ಸಂಗೀತ ಮತ್ತು ಇತರ ಆಡಿಯೋ"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಆಡಿಯೊ ಫೈಲ್‌ಗಳನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ಫೋಟೋಗಳು ಮತ್ತು ವೀಡಿಯೊಗಳು"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಚಿತ್ರಗಳು ಮತ್ತು ವೀಡಿಯೊ ಫೈಲ್‌ಗಳನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"ಮೈಕ್ರೋಫೋನ್‌"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ಆಡಿಯೊ ರೆಕಾರ್ಡ್ ಮಾಡಿ"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"ದೈಹಿಕ ಚಟುವಟಿಕೆ"</string>
@@ -1012,7 +1017,7 @@
     <string name="js_dialog_before_unload_positive_button" msgid="4274257182303565509">"ಈ ಪುಟದಿಂದ ಹೊರಬನ್ನಿ"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="3873765747622415310">"ಈ ಪುಟದಲ್ಲಿಯೇ ಇರಿ"</string>
     <string name="js_dialog_before_unload" msgid="7213364985774778744">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nನೀವು ಈ ಪುಟದಿಂದಾಚೆಗೆ ನ್ಯಾವಿಗೇಟ್ ಮಾಡಲು ಖಚಿತವಾಗಿ ಬಯಸುವಿರಾ?"</string>
-    <string name="save_password_label" msgid="9161712335355510035">"ದೃಢೀಕರಿಸು"</string>
+    <string name="save_password_label" msgid="9161712335355510035">"ದೃಢೀಕರಿಸಿ"</string>
     <string name="double_tap_toast" msgid="7065519579174882778">"ಸಲಹೆ: ಝೂಮ್ ಇನ್ ಮತ್ತು ಝೂಮ್ ಔಟ್ ಮಾಡಲು ಡಬಲ್-ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="autofill_this_form" msgid="3187132440451621492">"ಸ್ವಯಂತುಂಬುವಿಕೆ"</string>
     <string name="setup_autofill" msgid="5431369130866618567">"ಸ್ವಯಂತುಂಬುವಿಕೆಯನ್ನು ಹೊಂದಿಸಿ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index f8b9bdc..f734417 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"캘린더에 액세스"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS 메시지 전송 및 보기"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"파일 및 문서"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"기기의 파일 및 문서에 액세스"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"음악 및 기타 오디오"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"기기에 있는 오디오 파일에 액세스"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"사진 및 동영상"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"기기에 있는 이미지 및 동영상 파일에 액세스"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"마이크"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"오디오 녹음"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"신체 활동"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index b3074cb..df70a51 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"жылнаамаңызды пайдалануу"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS билдирүүлөрдү жиберүү жана көрсөтүү"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Файлдар жана документтер"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"түзмөгүңүздөгү файлдары жана документтерди колдонуу"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Музыка жана башка аудио"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"түзмөгүңүздөгү аудио файлдарга мүмкүнчүлүк алуу"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Сүрөттөр жана видеолор"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"түзмөгүңүздөгү сүрөттөр менен видеолорго мүмкүнчүлүк алуу"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Микрофон"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"аудио жаздыруу"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Кыймыл-аракет"</string>
@@ -350,7 +355,7 @@
     <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"билдирмелерди кулпуланган түзмөктүн толук экранында көрсөтүү"</string>
     <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Колдонмого билдирмелерди кулпуланган түзмөктүн толук экранында көрсөтүүгө уруксат берет"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"Ыкчам баскыч түзүү"</string>
-    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Колдонмого үй экранга колдонуучунун катышуусусуз тез чакырма кошууга мүмкүнчүлүк берет."</string>
+    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Колдонмо башкы экранга ыкчам баскычтарды өз алдынча кошо алат"</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"тез чакыргычтарды жок кылуу"</string>
     <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Колдонмого колдонуучунун катышуусусуз үй экранынын тез чакырмаларын жок кылуу мүмкүнчүлүгүн берет."</string>
     <string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"чыгыш чалууларды кайра багыттоо"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 9e8b119..e0e567e 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"ເຂົ້າ​ຫາ​ປະ​ຕິ​ທິນ​ຂອງ​ທ່ານ"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"ສົ່ງ ແລະ​ເບິ່ງ​ຂໍ້​ຄວາມ SMS"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"ໄຟລ໌ ແລະ ເອກະສານ"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"ເຂົ້າເຖິງໄຟລ໌ ແລະ ເອກະສານຢູ່ອຸປະກອນຂອງທ່ານ"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"ເພງ ແລະ ສຽງອື່ນໆ"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"ເຂົ້າເຖິງໄຟລ໌ສຽງຢູ່ອຸປະກອນຂອງທ່ານ"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ຮູບພາບ ແລະ ວິດີໂອ"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"ເຂົ້າເຖິງໄຟລ໌ຮູບ ແລະ ວິດີໂອຢູ່ອຸປະກອນຂອງທ່ານ"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"ໄມໂຄຣໂຟນ"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ບັນທຶກສຽງ"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"ກິດຈະກຳທາງກາຍະພາບ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 989d57c..3c4344d 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -307,12 +307,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"pasiekti kalendorių"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"siųsti ir peržiūrėti SMS pranešimus"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Failai ir dokumentai"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"pasiekti failus ir dokumentus jūsų įrenginyje"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Muzika ir kiti garso įrašai"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"pasiekti garso failus įrenginyje"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Nuotraukos ir vaizdo įrašai"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"pasiekti vaizdo ir vaizdo įrašo failus įrenginyje"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofonas"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"įrašyti garso įrašą"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fizinė veikla"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 076900c..6f15f3e 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -306,12 +306,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"piekļūt jūsu kalendāram"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"Īsziņas"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"sūtīt un skatīt īsziņas"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Faili un dokumenti"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"piekļuve failiem un dokumentiem jūsu ierīcē"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Mūzika un cits audio saturs"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"piekļūt audio failiem jūsu ierīcē"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotoattēli un videoklipi"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"piekļūt attēlu un video failiem jūsu ierīcē"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofons"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ierakstīt audio"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fiziskās aktivitātes"</string>
@@ -1671,10 +1676,10 @@
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Vai izmantot pieejamības saīsni?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Kad īsinājumtaustiņš ir ieslēgts, nospiežot abas skaļuma pogas un 3 sekundes turot tās, tiks aktivizēta pieejamības funkcija."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Vai ieslēgt pieejamības funkciju saīsni?"</string>
-    <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Turot nospiestus abus skaļuma taustiņus dažas sekundes, tiek ieslēgtas pieejamības funkcijas. Tas var mainīt ierīces darbību.\n\nPašreizējās funkcijas:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nAtlasītās funkcijas varat mainīt šeit: Iestatījumi &gt; Pieejamība."</string>
+    <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Turot nospiestas abas skaļuma pogas dažas sekundes, tiek ieslēgtas pieejamības funkcijas. Tas var mainīt ierīces darbību.\n\nPašreizējās funkcijas:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nAtlasītās funkcijas varat mainīt šeit: Iestatījumi &gt; Pieejamība."</string>
     <string name="accessibility_shortcut_multiple_service_list" msgid="2128323171922023762">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
     <string name="accessibility_shortcut_single_service_warning_title" msgid="1909518473488345266">"Vai ieslēgt <xliff:g id="SERVICE">%1$s</xliff:g> saīsni?"</string>
-    <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Turot nospiestus abus skaļuma taustiņus dažas sekundes, tiek ieslēgta pieejamības funkcija <xliff:g id="SERVICE">%1$s</xliff:g>. Tas var mainīt ierīces darbību.\n\nŠo saīsni uz citu funkciju varat mainīt šeit: Iestatījumi &gt; Pieejamība."</string>
+    <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Turot nospiestas abas skaļuma pogas dažas sekundes, tiek ieslēgta pieejamības funkcija <xliff:g id="SERVICE">%1$s</xliff:g>. Tas var mainīt ierīces darbību.\n\nŠo saīsni uz citu funkciju varat mainīt šeit: Iestatījumi &gt; Pieejamība."</string>
     <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Ieslēgt"</string>
     <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Neieslēgt"</string>
     <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"IESLĒGTA"</string>
@@ -1701,7 +1706,7 @@
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Papildu aptumšošana"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Turējāt nospiestas skaļuma pogas. Pakalpojums <xliff:g id="SERVICE_NAME">%1$s</xliff:g> tika ieslēgts."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Turējāt nospiestas skaļuma pogas. Pakalpojums <xliff:g id="SERVICE_NAME">%1$s</xliff:g> tika izslēgts."</string>
-    <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Lai izmantotu pakalpojumu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, nospiediet abus skaļuma taustiņus un turiet tos trīs sekundes."</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Lai izmantotu pakalpojumu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, nospiediet abus skaļuma pogas un turiet tos trīs sekundes."</string>
     <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Izvēlieties funkciju, ko izmantot, kad pieskaraties pieejamības pogai."</string>
     <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Izvēlieties funkciju, ko izmantot ar pieejamības žestu (vilkšana ar diviem pirkstiem augšup no ekrāna apakšdaļas)."</string>
     <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Izvēlieties funkciju, ko izmantot ar pieejamības žestu (vilkšana ar trīs pirkstiem augšup no ekrāna apakšdaļas)."</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 1c4b514..b437cde 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"пристапува до календарот"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"испраќа и прикажува SMS-пораки"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Датотеки и документи"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"да пристапува до датотеки и документи на уредот"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Музика и друго аудио"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"да пристапува до аудиодатотеки на вашиот уред"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Фотографии и видеа"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"да пристапува до слики и видеодатотеки на вашиот уред"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Микрофон"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"снима аудио"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Физичка активност"</string>
@@ -349,10 +354,10 @@
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Дозволува апликацијата да ја прошири или собере статусната лента."</string>
     <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"да прикажува известувања како активности на цел екран на заклучен уред"</string>
     <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Дозволува апликацијата да прикажува известувања како активности на цел екран на заклучен уред"</string>
-    <string name="permlab_install_shortcut" msgid="7451554307502256221">"инсталирај кратенки"</string>
-    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Овозможува апликацијата да додава кратенки до почетниот екран без интервенција на корисникот."</string>
+    <string name="permlab_install_shortcut" msgid="7451554307502256221">"инсталирање кратенки"</string>
+    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Овозможува апликацијата да додава кратенки на почетниот екран без интервенција на корисникот."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"деинсталирај кратенки"</string>
-    <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Овозможува апликацијата да отстранува кратенки до почетниот екран без интервенција на корисникот."</string>
+    <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Овозможува апликацијата да отстранува кратенки од почетниот екран без интервенција на корисникот."</string>
     <string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"пренасочи појдовни повици"</string>
     <string name="permdesc_processOutgoingCalls" msgid="7833149750590606334">"Дозволува апликацијата да го види бројот што се повикува за време на појдовен повик, со опција да го пренасочи повикот кон друг број или да го прекине повикот."</string>
     <string name="permlab_answerPhoneCalls" msgid="4131324833663725855">"одговара телефонски повици"</string>
@@ -1844,7 +1849,7 @@
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Трета деловна <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Побарај PIN пред откачување"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Побарај шема за откл. пред откачување"</string>
-    <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Прашај за лозинка пред откачување"</string>
+    <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Побарај лозинка пред откачување"</string>
     <string name="package_installed_device_owner" msgid="7035926868974878525">"Инсталирано од администраторот"</string>
     <string name="package_updated_device_owner" msgid="7560272363805506941">"Ажурирано од администраторот"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Избришано од администраторот"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 9169e97..92afda3 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"നിങ്ങളുടെ കലണ്ടർ ആക്‌സസ്സ് ചെയ്യുക"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS സന്ദേശങ്ങൾ അയയ്‌ക്കുകയും കാണുകയും ചെയ്യുക"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"ഫയലുകളും ഡോക്യുമെന്റുകളും"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"നിങ്ങളുടെ ഉപകരണത്തിലെ ഫയലുകളും ഡോക്യുമെന്റുകളും ആക്സസ് ചെയ്യുക"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"സംഗീതവും മറ്റ് ഓഡിയോയും"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"നിങ്ങളുടെ ഉപകരണത്തിലെ ഓഡിയോ ഫയലുകൾ ആക്‌സസ് ചെയ്യുക"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ഫോട്ടോകളും വീഡിയോകളും"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"നിങ്ങളുടെ ഉപകരണത്തിലെ വീഡിയോ ഫയലുകൾ ആക്‌സസ് ചെയ്യുക"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"മൈക്രോഫോണ്‍"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ഓഡിയോ റെക്കോർഡ് ചെയ്യുക"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"ശാരീരിക ആക്റ്റിവിറ്റി"</string>
@@ -2053,8 +2058,7 @@
     <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"\'ശല്യപ്പെടുത്തരുത്\' മാറ്റി"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"എന്തിനെയാണ് ബ്ലോക്ക് ചെയ്‌തതെന്ന് പരിശോധിക്കാൻ ടാപ്പ് ചെയ്യുക."</string>
     <string name="review_notification_settings_title" msgid="5102557424459810820">"അറിയിപ്പ് ക്രമീകരണം അവലോകനം ചെയ്യുക"</string>
-    <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
-    <skip />
+    <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13 മുതൽ, നിങ്ങൾ ഇൻസ്‌റ്റാൾ ചെയ്യുന്ന ആപ്പുകൾക്ക് അറിയിപ്പുകൾ അയയ്‌ക്കാൻ നിങ്ങളുടെ അനുമതി വേണം. നിലവിലുള്ള ആപ്പുകൾക്ക് ഈ അനുമതി മാറ്റാൻ ടാപ്പ് ചെയ്യുക."</string>
     <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"പിന്നീട് ഓർമ്മിപ്പിക്കൂ"</string>
     <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"ഡിസ്‌മിസ് ചെയ്യുക"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"സിസ്റ്റം"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 6fb8c89..891007a 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"Календарь руу хандах"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"Мессеж"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS мессежийг илгээх, харах"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Файл болон документ"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"таны төхөөрөмж дээрх файл болон документод хандах"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Хөгжим, бусад аудио"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"таны төхөөрөмж дээрх аудио файлд хандах"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Зураг, видео"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"таны төхөөрөмж дээрх зураг болон видео файлд хандах"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Микрофон"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"дуу хураах"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Дасгал хөдөлгөөн"</string>
@@ -2053,8 +2058,7 @@
     <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Бүү саад бол горимыг өөрчилсөн"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Блоклосон зүйлийг шалгахын тулд товшино уу."</string>
     <string name="review_notification_settings_title" msgid="5102557424459810820">"Мэдэгдлийн тохиргоог шалгах"</string>
-    <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
-    <skip />
+    <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13-аас эхлэн таны суулгасан аппууд мэдэгдэл илгээхийн тулд танаас зөвшөөрөл авах шаардлагатай. Одоо байгаа аппуудын уг зөвшөөрлийг өөрчлөхийн тулд товшино уу."</string>
     <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Надад дараа сануул"</string>
     <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Хаах"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Систем"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 637342d..6ba0853 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"आपल्या कॅलेंडरवर प्रवेश"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS मेसेज पाठवणे आणि पाहणे हे"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"फाइल आणि दस्तऐवज"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"तुमच्या डिव्हाइसवर फाइल आणि दस्तऐवज अ‍ॅक्सेस करा"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"संगीत &amp; इतर ऑडिओ"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"तुमच्या डिव्हाइसवर ऑडिओ फाइल अ‍ॅक्सेस करा"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"फोटो &amp; व्हिडिओ"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"तुमच्या डिव्हाइसवर इमेज आणि व्हिडिओ फाइल ॲक्सेस करा"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"मायक्रोफोन"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ऑडिओ रेकॉर्ड"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"शारीरिक अ‍ॅक्टिव्हिटी"</string>
@@ -350,7 +355,7 @@
     <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"लॉक केलेल्या डिव्हाइसवर फुल स्क्रीन अ‍ॅक्टिव्हिटी म्हणून सूचना प्रदर्शित करणे"</string>
     <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"लॉक केलेल्या डिव्हाइसवर फुल स्क्रीन अ‍ॅक्टिव्हिटी म्हणून सूचना प्रदर्शित करण्यासाठी ॲपला अनुमती द्या"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"शॉर्टकट इंस्टॉल करा"</string>
-    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"अनुप्रयोगाला वापरकर्ता हस्‍तक्षेपाशिवाय मुख्‍यस्‍क्रीन शॉर्टकट जोडण्‍याची अनुमती देते."</string>
+    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"ॲप्लिकेशनला वापरकर्ता हस्‍तक्षेपाशिवाय मुख्‍यस्‍क्रीन शॉर्टकट जोडण्‍याची अनुमती देते"</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"शॉर्टकट विस्‍थापित करा"</string>
     <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"अनुप्रयोगाला वापरकर्ता हस्‍तक्षेपाशिवाय मुख्‍यस्‍क्रीन शॉर्टकट काढण्‍याची अनुमती देते."</string>
     <string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"केले जाणारे कॉल पुन्हा मार्गस्थ करा"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 54dfc16..7b83e5e 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"mengakses kalendar"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"menghantar dan melihat mesej SMS"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Fail &amp; dokumen"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"akses fail dan dokumen pada peranti anda"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Muzik &amp; audio lain"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"berikan akses fail audio pada peranti anda"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Foto &amp; video"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"berikan akses imej dan fail video pada peranti anda"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"rakam audio"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Aktiviti fizikal"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 78cdb62..269f56d 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -248,7 +248,7 @@
     <string name="global_action_bug_report" msgid="5127867163044170003">"အမှားရှာပြင် မှတ်တမ်း"</string>
     <string name="global_action_logout" msgid="6093581310002476511">"စက်ရှင် ပြီးဆုံးပြီ"</string>
     <string name="global_action_screenshot" msgid="2610053466156478564">"ဖန်သားပြင်ဓာတ်ပုံ"</string>
-    <string name="bugreport_title" msgid="8549990811777373050">"ချွတ်ယွင်းမှုအစီရင်ခံစာ"</string>
+    <string name="bugreport_title" msgid="8549990811777373050">"ချွတ်ယွင်းမှတ်တမ်း"</string>
     <string name="bugreport_message" msgid="5212529146119624326">"သင့်ရဲ့ လက်ရှိ စက်အခြေအနေ အချက်အလက်များကို အီးမေးလ် အနေဖြင့် ပေးပို့ရန် စုဆောင်းပါမည်။ အမှားရှာဖွေပြင်ဆင်မှုမှတ်တမ်းမှ ပေးပို့ရန် အသင့်ဖြစ်သည်အထိ အချိန် အနည်းငယ်ကြာမြင့်မှာ ဖြစ်သဖြင့် သည်းခံပြီး စောင့်ပါရန်"</string>
     <string name="bugreport_option_interactive_title" msgid="7968287837902871289">"လက်ငင်းတုံ့ပြန်နိုင်သည့် အစီရင်ခံချက်"</string>
     <string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"အခြေအနေတော်တော်များများတွင် ၎င်းကိုအသုံးပြုပါ။ ၎င်းသည် အစီရင်ခံစာကို မှတ်သားခြင်း၊ ပြဿနာအကြောင်း နောက်ထပ်အသေးစိတ်များကို ထည့်သွင်းခြင်းနှင့် မျက်နှာပြင်ပုံဖမ်းယူခြင်းတို့ကို ပြုလုပ်ခွင့်ပေးပါသည်။ ပေးပို့ရန် အလွန်ကြာပြီး အသုံးပြုခြင်းနည်းပါးသည့်အပိုင်းကို ၎င်းက ချန်ခဲ့နိုင်ပါသည်။"</string>
@@ -305,12 +305,12 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"သင့်ပြက္ခဒိန်အား ဝင်ရောက်သုံးရန်"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS စာတိုစနစ်"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS စာများကို ပို့ကာ ကြည့်မည်"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"ဖိုင်နှင့် မှတ်တမ်းများ"</string>
+    <string name="permgrouplab_storage" msgid="5570124978732352858">"ဖိုင်နှင့် မှတ်တမ်းများ"</string>
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"သင့်စက်ရှိ ဖိုင်နှင့် မှတ်တမ်းများ သုံးခွင့်"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"သီချင်းနှင့် အခြားအသံဖိုင်"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"သင့်စက်ပေါ်ရှိ အသံဖိုင်များကို သုံးနိုင်သည်"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ဓာတ်ပုံနှင့် ဗီဒီယိုများ"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"သင့်စက်ပေါ်ရှိ ပုံနှင့် ဗီဒီယိုဖိုင်များကို သုံးနိုင်သည်"</string>
+    <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"တေးဂီတနှင့် အသံ"</string>
+    <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"သင့်စက်တွင် တေးဂီတနှင့် အသံများ ဖွင့်နိုင်သည်"</string>
+    <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"ဓာတ်ပုံနှင့် ဗီဒီယိုများ"</string>
+    <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"သင့်စက်တွင် ဓာတ်ပုံနှင့် ဗီဒီယိုများ ဖွင့်နိုင်သည်"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"မိုက်ခရိုဖုန်း"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"အသံဖမ်းခြင်း"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"ကိုယ်ခန္ဓာလှုပ်ရှားမှု"</string>
@@ -350,7 +350,7 @@
     <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"လော့ခ်ချထားသော စက်ပစ္စည်းပေါ်တွင် အကြောင်းကြားချက်များကို ဖန်သားပြင်အပြည့် လုပ်ဆောင်ချက်များအဖြစ် ပြခြင်း"</string>
     <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"လော့ခ်ချထားသော စက်ပစ္စည်းပေါ်တွင် အကြောင်းကြားချက်များကို ဖန်သားပြင်အပြည့် လုပ်ဆောင်ချက်များအဖြစ် ပြရန် အက်ပ်ကို ခွင့်ပြုသည်"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"ဖြတ်လမ်းလင့်ခ်များ ထည့်သွင်းခြင်း"</string>
-    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"အပလီကေးရှင်းအား အသုံးပြုသူ လုပ်ဆောင်ခြင်း မပါပဲ ပင်မ မြင်ကွင်းအား ပြောင်းလဲခွင့် ပေးခြင်း"</string>
+    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"အပလီကေးရှင်းအား အသုံးပြုသူ၏ လုပ်ဆောင်ချက်မပါဘဲ ပင်မစာမျက်နှာ ဖြတ်လမ်းလင့်ခ်များကို ထည့်သွင်းခွင့်ပေးသည်။"</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"အတိုကောက်များ ဖယ်ထုတ်ခြင်း"</string>
     <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"အပလီကေးရှင်းအား အသုံးပြုသူ လုပ်ဆောင်ခြင်း မပါပဲ ပင်မ မြင်ကွင်းအား ဖယ်ရှားခွင့် ပေးခြင်း"</string>
     <string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"အထွက် ခေါ်ဆိုမှုများအား လမ်းလွှဲပြောင်းခြင်း"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 077b768..90964eb 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"åpne kalenderen din"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"sende og lese SMS-meldinger"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Filer og dokumenter"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"åpne filer og dokumenter på enheten din"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musikk og annen lyd"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"få tilgang til lydfiler på enheten"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Bilder og videoer"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"få tilgang til bilder og videofiler på enheten"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ta opp lyd"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fysisk aktivitet"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index b12c5c0..3876af5 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"तपाईंको पात्रोमाथि पहुँच गर्नुहोस्"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS सन्देशहरू पठाउनुहोस् र हेर्नुहोस्"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"फाइल र डकुमेन्टहरू"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"आफ्नो डिभाइसमा भएका फाइल र डकुमेन्टहरू प्रयोग गर्नुहोस्"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"सङ्गीत तथा अन्य अडियो"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"तपाईंको डिभाइसमा भएका अडियो फाइलहरू प्रयोग गर्ने"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"फोटो तथा भिडियोहरू"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"तपाईंको डिभाइसमा भएका फोटो तथा भिडियो फाइलहरू प्रयोग गर्ने"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"माइक्रोफोन"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"अडियो रेकर्ड गर्नुहोस्"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"शारीरिक क्रियाकलाप"</string>
@@ -350,7 +355,7 @@
     <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"लक गरिएको डिभाइसमा स्क्रिनभरि देखिने सूचनाहरू देखाइयोस्"</string>
     <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"यो अनुमति दिइएमा एपले लक गरिएको डिभाइसमा स्क्रिनभरि देखिने सूचनाहरू देखाउन सक्छ"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"सर्टकट इन्स्टल गर्ने"</string>
-    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"प्रयोगकर्ताको हस्तक्षेप बिना एउटा एपलाई सर्टकटमा थप्नको लागि अनुमति दिन्छ।"</string>
+    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"प्रयोगकर्ताको हस्तक्षेप बिना एउटा एपलाई सर्टकटमा हाल्ने अनुमति दिन्छ।"</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"सर्टकटहरूको स्थापन रद्द गर्नुहोस्"</string>
     <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"प्रयोगकर्ताको हस्तक्षेप बिना एउटा एपलाई सर्टकटमा हटाउनको लागि अनुमति दिन्छ।"</string>
     <string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"बहिर्गमन कलहरूलाई अर्को मार्ग दिनुहोस्"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index f544804..2662952 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"toegang krijgen tot je agenda"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"Sms"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"sms\'jes verzenden en bekijken"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Bestanden en documenten"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"bestanden en documenten op je apparaat openen"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Muziek en andere audio"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"toegang krijgen tot audiobestanden op je apparaat"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Foto\'s en video\'s"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"toegang krijgen tot afbeeldingen en videobestanden op je apparaat"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Microfoon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"audio opnemen"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fysieke activiteit"</string>
@@ -1224,7 +1229,7 @@
     <string name="unsupported_display_size_show" msgid="980129850974919375">"Altijd tonen"</string>
     <string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"<xliff:g id="APP_NAME">%1$s</xliff:g> is gemaakt voor een niet-geschikte versie van het Android-besturingssysteem en kan onverwacht gedrag vertonen. Mogelijk is er een geüpdatete versie van de app beschikbaar."</string>
     <string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"Altijd tonen"</string>
-    <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Controleren op update"</string>
+    <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Checken op updates"</string>
     <string name="smv_application" msgid="3775183542777792638">"De app <xliff:g id="APPLICATION">%1$s</xliff:g> (proces <xliff:g id="PROCESS">%2$s</xliff:g>) heeft het zelf afgedwongen StrictMode-beleid geschonden."</string>
     <string name="smv_process" msgid="1398801497130695446">"Het proces <xliff:g id="PROCESS">%1$s</xliff:g> heeft het zelf afgedwongen StrictMode-beleid geschonden."</string>
     <string name="android_upgrading_title" product="default" msgid="7279077384220829683">"Telefoon wordt geüpdatet…"</string>
@@ -1949,7 +1954,7 @@
     <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Deze app vraagt om aanvullende beveiliging. Probeer het in plaats daarvan op je tablet."</string>
     <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Deze app vraagt om aanvullende beveiliging. Probeer het in plaats daarvan op je telefoon."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Deze app is ontwikkeld voor een oudere versie van Android en werkt mogelijk niet op de juiste manier. Controleer op updates of neem contact op met de ontwikkelaar."</string>
-    <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Controleren op update"</string>
+    <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Checken op updates"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Je hebt nieuwe berichten"</string>
     <string name="new_sms_notification_content" msgid="3197949934153460639">"Open je sms-app om ze te bekijken"</string>
     <string name="profile_encrypted_title" msgid="9001208667521266472">"Functionaliteit kan beperkt zijn"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index a51d2f3..c7693ca 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"ଆପଣଙ୍କ କ୍ୟାଲେଣ୍ଡର୍‍ ଆକ୍ସେସ୍‍ କରେ"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS ମେସେଜ୍‍ ପଠାନ୍ତୁ ଓ ଦେଖନ୍ତୁ"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"ଫାଇଲ ଏବଂ ଡକ୍ୟୁମେଣ୍ଟଗୁଡ଼ିକ"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"ଆପଣଙ୍କ ଡିଭାଇସରେ ଥିବା ଫାଇଲ ଏବଂ ଡକ୍ୟୁମେଣ୍ଟଗୁଡ଼ିକୁ ଆକ୍ସେସ କରନ୍ତୁ"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"ମ୍ୟୁଜିକ ଓ ଅନ୍ୟ ଅଡିଓ"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"ଆପଣଙ୍କ ଡିଭାଇସରେ ଅଡିଓ ଫାଇଲଗୁଡ଼ିକୁ ଆକ୍ସେସ କରନ୍ତୁ"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ଫଟୋ ଓ ଭିଡିଓଗୁଡ଼ିକ"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"ଆପଣଙ୍କ ଡିଭାଇସରେ ଇମେଜ ଏବଂ ଭିଡିଓ ଫାଇଲଗୁଡ଼ିକୁ ଆକ୍ସେସ କରନ୍ତୁ"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"ମାଇକ୍ରୋଫୋନ୍"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ଅଡିଓ ରେକର୍ଡ କରେ"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"ଶାରୀରିକ କାର୍ଯ୍ୟକଳାପ"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 2bc6da6..f641c3a 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਤੱਕ ਪਹੁੰਚ ਕਰਨ"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS ਸੁਨੇਹੇ ਭੇਜੋ ਅਤੇ ਦੇਖੋ"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"ਫ਼ਾਈਲਾਂ ਅਤੇ ਦਸਤਾਵੇਜ਼"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"ਆਪਣੇ ਡੀਵਾਈਸ \'ਤੇ ਫ਼ਾਈਲਾਂ ਅਤੇ ਦਸਤਾਵੇਜ਼ਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"ਸੰਗੀਤ ਅਤੇ ਹੋਰ ਆਡੀਓ"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"ਆਪਣੇ ਡੀਵਾਈਸ \'ਤੇ ਆਡੀਓ ਫ਼ਾਈਲਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ਫ਼ੋਟੋਆਂ ਅਤੇ ਵੀਡੀਓ"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"ਆਪਣੇ ਡੀਵਾਈਸ \'ਤੇ ਚਿੱਤਰਾਂ ਅਤੇ ਵੀਡੀਓ ਫ਼ਾਈਲਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"ਮਾਈਕ੍ਰੋਫ਼ੋਨ"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">" ਆਡੀਓ  ਰਿਕਾਰਡ ਕਰਨ"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"ਸਰੀਰਕ ਸਰਗਰਮੀ"</string>
@@ -1844,7 +1849,7 @@
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"ਤੀਸਰੀ ਕਾਰਜ-ਸਥਾਨ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"ਅਨਪਿੰਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਪਿੰਨ ਮੰਗੋ"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ਅਨਪਿੰਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਅਣਲਾਕ ਪੈਟਰਨ ਵਾਸਤੇ ਪੁੱਛੋ"</string>
-    <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ਅਨਪਿੰਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਪਾਸਵਰਡ ਮੰਗੋ"</string>
+    <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ਅਣਪਿੰਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਪਾਸਵਰਡ ਮੰਗੋ"</string>
     <string name="package_installed_device_owner" msgid="7035926868974878525">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਸਥਾਪਤ ਕੀਤਾ ਗਿਆ"</string>
     <string name="package_updated_device_owner" msgid="7560272363805506941">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਅੱਪਡੇਟ ਕੀਤਾ ਗਿਆ"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਮਿਟਾਇਆ ਗਿਆ"</string>
@@ -2053,8 +2058,7 @@
     <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਵਿਕਲਪ ਬਦਲ ਗਿਆ ਹੈ"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"ਟੈਪ ਕਰਕੇ ਦੋਖੋ ਕਿ ਕਿਹੜੀਆਂ ਚੀਜ਼ਾਂ ਬਲਾਕ ਕੀਤੀਆਂ ਗਈਆਂ ਹਨ।"</string>
     <string name="review_notification_settings_title" msgid="5102557424459810820">"ਸੂਚਨਾ ਸੈਟਿੰਗਾਂ ਦੀ ਸਮੀਖਿਆ ਕਰੋ"</string>
-    <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
-    <skip />
+    <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13 ਜਾਂ ਇਸ ਤੋਂ ਬਾਅਦ ਵਾਲੇ ਵਰਜਨਾਂ ਵਿੱਚ, ਤੁਹਾਡੇ ਵੱਲੋਂ ਸਥਾਪਤ ਕੀਤੀਆਂ ਜਾਣ ਵਾਲੀਆਂ ਐਪਾਂ ਨੂੰ ਸੂਚਨਾਵਾਂ ਭੇਜਣ ਲਈ ਤੁਹਾਡੀ ਇਜਾਜ਼ਤ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ। ਮੌਜੂਦਾ ਐਪਾਂ ਲਈ ਇਸ ਇਜਾਜ਼ਤ ਨੂੰ ਬਦਲਣ ਵਾਸਤੇ ਟੈਪ ਕਰੋ।"</string>
     <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"ਬਾਅਦ ਵਿੱਚ ਯਾਦ ਕਰਵਾਓ"</string>
     <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"ਖਾਰਜ ਕਰੋ"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"ਸਿਸਟਮ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 6c96e08..138ae31 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -307,12 +307,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"dostęp do kalendarza"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"wysyłanie i wyświetlanie SMS‑ów"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Pliki i dokumenty"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"dostęp do plików i dokumentów na urządzeniu"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Muzyka i inne dźwięki"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"dostęp do plików audio na urządzeniu"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Zdjęcia i filmy"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"dostęp do plików graficznych i wideo na urządzeniu"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"nagrywanie dźwięku"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Aktywność fizyczna"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index dd51ad9..47d5669 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"acesse sua agenda"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"envie e veja mensagens SMS"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Arquivos e documentos"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"acessar arquivos e documentos no seu dispositivo"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Música e outros áudios"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"acessar arquivos de áudio no seu dispositivo"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotos e vídeos"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"acessar arquivos de imagem e vídeo no seu dispositivo"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Microfone"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"grave áudio"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Atividade física"</string>
@@ -439,8 +444,8 @@
     <string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"Este app pode adicionar, remover ou alterar eventos da agenda no seu smartphone. Ele também pode enviar mensagens que aparentem ser de autoria do proprietário da agenda ou alterar eventos sem notificar o proprietário."</string>
     <string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"acessar comandos extras do provedor de localização"</string>
     <string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Permite que o app acesse comandos do provedor não relacionados à localização. Isso pode permitir que o app interfira no funcionamento do GPS ou de outras fontes de localização."</string>
-    <string name="permlab_accessFineLocation" msgid="6426318438195622966">"acessar localização precisa apenas em primeiro plano"</string>
-    <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Esse app poderá acessar sua localização exata com os Serviços de localização enquanto estiver sendo usado. Os Serviços de localização do dispositivo precisam estar ativados para que o app possa acessar o local. Isso pode aumentar o uso da bateria."</string>
+    <string name="permlab_accessFineLocation" msgid="6426318438195622966">"acessar local exato apenas em primeiro plano"</string>
+    <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Esse app poderá acessar seu local exato com os Serviços de localização enquanto estiver sendo usado. Os Serviços de localização do dispositivo precisam estar ativados para que o app possa acessar o local. Isso pode aumentar o uso da bateria."</string>
     <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"acessar local aproximado apenas em primeiro plano"</string>
     <string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"Esse app poderá acessar sua localização aproximada com os Serviços de localização enquanto estiver sendo usado. Os Serviços de localização do dispositivo precisam estar ativados para que o app possa acessar o local."</string>
     <string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"acessar a localização em segundo plano"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index c51cf86..c4d006e 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"aceder ao calendário"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"enviar e ver mensagens SMS"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Ficheiros e documentos"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"aceder a ficheiros e documentos no seu dispositivo"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Música e outro áudio"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"aceder a ficheiros de áudio no dispositivo"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotos e vídeos"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"aceder a imagens e ficheiros de áudio no dispositivo"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Microfone"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"gravar áudio"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Atividade física"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index dd51ad9..47d5669 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"acesse sua agenda"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"envie e veja mensagens SMS"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Arquivos e documentos"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"acessar arquivos e documentos no seu dispositivo"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Música e outros áudios"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"acessar arquivos de áudio no seu dispositivo"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotos e vídeos"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"acessar arquivos de imagem e vídeo no seu dispositivo"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Microfone"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"grave áudio"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Atividade física"</string>
@@ -439,8 +444,8 @@
     <string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"Este app pode adicionar, remover ou alterar eventos da agenda no seu smartphone. Ele também pode enviar mensagens que aparentem ser de autoria do proprietário da agenda ou alterar eventos sem notificar o proprietário."</string>
     <string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"acessar comandos extras do provedor de localização"</string>
     <string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Permite que o app acesse comandos do provedor não relacionados à localização. Isso pode permitir que o app interfira no funcionamento do GPS ou de outras fontes de localização."</string>
-    <string name="permlab_accessFineLocation" msgid="6426318438195622966">"acessar localização precisa apenas em primeiro plano"</string>
-    <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Esse app poderá acessar sua localização exata com os Serviços de localização enquanto estiver sendo usado. Os Serviços de localização do dispositivo precisam estar ativados para que o app possa acessar o local. Isso pode aumentar o uso da bateria."</string>
+    <string name="permlab_accessFineLocation" msgid="6426318438195622966">"acessar local exato apenas em primeiro plano"</string>
+    <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Esse app poderá acessar seu local exato com os Serviços de localização enquanto estiver sendo usado. Os Serviços de localização do dispositivo precisam estar ativados para que o app possa acessar o local. Isso pode aumentar o uso da bateria."</string>
     <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"acessar local aproximado apenas em primeiro plano"</string>
     <string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"Esse app poderá acessar sua localização aproximada com os Serviços de localização enquanto estiver sendo usado. Os Serviços de localização do dispositivo precisam estar ativados para que o app possa acessar o local."</string>
     <string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"acessar a localização em segundo plano"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index c1e6d87..e1426ec 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -306,12 +306,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"acceseze calendarul"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"trimită și să vadă mesajele SMS"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Fișiere și documente"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"să acceseze fișiere și documente de pe dispozitiv"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Muzică și alt conținut audio"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"să acceseze fișiere audio de pe dispozitiv"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotografii și videoclipuri"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"să acceseze fișiere video și imagini de pe dispozitiv"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Microfon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"înregistreze sunet"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Activitate fizică"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index ce3cfe7..dd9ff92 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -307,12 +307,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"доступ к календарю"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"отправлять и просматривать SMS-сообщения"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Файлы и документы"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"Доступ к файлам и документам на вашем устройстве"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Музыка и другие аудиозаписи"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"доступ к аудиофайлам на вашем устройстве"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Фото и видео"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"доступ к изображениям и видеофайлам на вашем устройстве"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Микрофон"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"записывать аудио"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Физическая активность"</string>
@@ -352,7 +357,7 @@
     <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"Показ уведомлений в полноэкранном режиме на заблокированном устройстве"</string>
     <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Приложение сможет показывать уведомления в полноэкранном режиме на заблокированном устройстве"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"Создание ярлыков"</string>
-    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Приложение сможет добавлять ярлыки на главный экран без вмешательства пользователя."</string>
+    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"приложения смогут добавлять ярлыки на главный экран без вмешательства пользователя."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"Удаление ярлыков"</string>
     <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Приложение сможет удалять ярлыки с главного экрана без вмешательства пользователя."</string>
     <string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"Перенаправление исходящих вызовов"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 8fdfeb7..a8b0709 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"ඔබේ දින දර්ශනයට පිවිසෙන්න"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"කෙටි පණිවිඩ"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS පණිවිඩ යැවීම සහ බැලීම"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"ගොනු සහ ලේඛන"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"ඔබගේ උපාංගයේ ගොනු සහ ලේඛන වෙත ප්‍රවේශ වන්න"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"සංගීතය සහ වෙනත් ශ්‍රව්‍ය"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"ඔබගේ උපාංගයෙහි ඇති ශ්‍රව්‍ය ගොනුවලට ප්‍රවේශ වන්න"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ඡායාරූප සහ වීඩියෝ"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"ඔබගේ උපාංගයෙහි ඇති රූප සහ වීඩියෝ ගොනුවලට ප්‍රවේශ වන්න"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"මයික්‍රොෆෝනය"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ශ්‍රව්‍ය පටිගත කරන්න"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"ශාරීරික ක්‍රියාකාරකම"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 01583c8..01c5ced 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -307,12 +307,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"prístup ku kalendáru"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"posielanie a zobrazovanie SMS"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Súbory a dokumenty"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"prístup k súborom a dokumentom vo vašom zariadení"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Hudba a iné zvuky"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"prístup k zvukovým súborom vo vašom zariadení"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotky a videá"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"prístup k súborom obrázka a videosúborom vo vašom zariadení"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofón"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"nahrávanie zvuku"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fyzická aktivita"</string>
@@ -351,7 +356,7 @@
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Umožňuje aplikácii rozbaliť alebo zbaliť stavový riadok."</string>
     <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"zobrazovanie upozornení ako aktivít na celej obrazovke v uzamknutom zariadení"</string>
     <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Táto možnosť umožňuje aplikácii zobrazovať upozornenia ako aktivity na celej obrazovke v uzamknutom zariadení"</string>
-    <string name="permlab_install_shortcut" msgid="7451554307502256221">"inštalovať odkazy"</string>
+    <string name="permlab_install_shortcut" msgid="7451554307502256221">"Inštalovať odkazy"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Povoľuje aplikácii pridať odkazy na ploche bez zásahu používateľa."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"odinštalovať odkazy"</string>
     <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Povoľuje aplikácii odstrániť odkazy na ploche bez zásahu používateľa."</string>
@@ -1846,7 +1851,7 @@
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. <xliff:g id="LABEL">%1$s</xliff:g> do práce"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Pred odopnutím požiadať o číslo PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pred uvoľnením požiadať o bezpečnostný vzor"</string>
-    <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pred uvoľnením požiadať o heslo"</string>
+    <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pred odopnutím požiadať o heslo"</string>
     <string name="package_installed_device_owner" msgid="7035926868974878525">"Nainštaloval správca"</string>
     <string name="package_updated_device_owner" msgid="7560272363805506941">"Aktualizoval správca"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Odstránil správca"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index f694428..2390aab 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -307,12 +307,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"dostop do koledarja"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"pošiljanje in ogled sporočil SMS"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Datoteke in dokumenti"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"dostop do datotek in dokumentov v napravi"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Glasba in drugi zvočni posnetki"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"dostop do zvočnih datotek v napravi"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotografije in videoposnetki"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"dostop do slik in videodatotek v napravi"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"snemanje zvoka"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Telesna dejavnost"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 52fcea3..aa4f532 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"qasje te kalendari yt"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"dërgo dhe shiko mesazhet SMS"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Skedarët dhe dokumentet"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"përfito qasje te skedarët dhe dokumentet në pajisjen tënde"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Muzikë dhe audio të tjera"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"të ketë qasje te skedarët audio në pajisjen tënde"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotografitë dhe videot"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"të ketë qasje te skedarët e imazheve dhe videove në pajisjen tënde"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofoni"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"regjistro audio"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Aktiviteti fizik"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 0dbef5a..57f7935 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -306,12 +306,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"приступи календару"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"шаље и прегледа SMS поруке"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Фајлови и документи"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"приступање фајловима и документима на уређају"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Музика и други аудио садржај"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"приступ аудио фајловима на уређају"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Слике и видео снимци"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"приступ сликама и видео фајловима на уређају"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Микрофон"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"снима звук"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Физичке активности"</string>
@@ -351,7 +356,7 @@
     <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"приказује обавештења као активности преко целог екрана на закључаном уређају"</string>
     <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Омогућава апликацији да на закључаном уређају приказује обавештења као активности преко целог екрана."</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"Инсталирање пречица"</string>
-    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Омогућава апликацији да додаје пречице на почетни екран без интервенције корисника."</string>
+    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"да додају пречице на почетни екран без интервенције корисника."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"деинсталирање пречица"</string>
     <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Омогућава апликацији да уклања пречице са почетног екрана без интервенције корисника."</string>
     <string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"преусмеравање одлазних позива"</string>
@@ -2054,8 +2059,7 @@
     <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Режим Не узнемиравај је промењен"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Додирните да бисте проверили шта је блокирано."</string>
     <string name="review_notification_settings_title" msgid="5102557424459810820">"Прегледајте подешавања обавештења"</string>
-    <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
-    <skip />
+    <string name="review_notification_settings_text" msgid="5916244866751849279">"Од Android-а 13 апликације које инсталирате морају да имају дозволу за слање обавештења. Додирните да бисте променили ову дозволу за постојеће апликације."</string>
     <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Подсети ме касније"</string>
     <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Одбаци"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Систем"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 6223b0d..6abdb8a 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"få tillgång till din kalender"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"Sms"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"skicka och visa sms"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Filer och dokument"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"visa filer och dokument på enheten"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musik och övrigt ljud"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"komma åt ljudfiler på din enhet"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Foton och videor"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"komma åt bilder och videofiler på din enhet"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"spela in ljud"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fysisk aktivitet"</string>
@@ -349,7 +354,7 @@
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Tillåter att appen expanderar eller komprimerar statusfältet."</string>
     <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"visa aviseringar som aktiviteter i helskärm på en låst enhet"</string>
     <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Tillåter att appen visar aviseringar som aktiviteter i helskärm på en låst enhet"</string>
-    <string name="permlab_install_shortcut" msgid="7451554307502256221">"installera genvägar"</string>
+    <string name="permlab_install_shortcut" msgid="7451554307502256221">"Installera genvägar"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Tillåter att en app lägger till genvägar på startskärmen utan åtgärd från användaren."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"avinstallera genvägar"</string>
     <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Tillåter att appen tar bort genvägar på startskärmen utan åtgärd från användaren."</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index aded067..ec4efff 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"ifikie kalenda yako"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"itume na iangalie SMS"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Faili na hati"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"fikia faili na hati kwenye kifaa chako"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Muziki na sauti nyingine"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"fikia faili za sauti kwenye kifaa chako"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Picha na video"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"fikia faili za picha na video kwenye kifaa chako"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Maikrofoni"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"irekodi sauti"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Mazoezi ya mwili"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index b7dd387..f3b6522 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"கேலெண்டரை அணுகலாம்"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS அனுப்பலாம், வந்த SMSகளைப் பார்க்கலாம்"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"ஃபைல்கள் &amp; ஆவணங்கள்"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"சாதனத்திலுள்ள ஃபைல்களையும் ஆவணங்களையும் அணுகும்"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"இசை &amp; பிற ஆடியோ"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"உங்கள் சாதனத்திலுள்ள ஆடியோ ஃபைல்களை அணுகும்"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"படங்கள் &amp; வீடியோக்கள்"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"உங்கள் சாதனத்திலுள்ள படங்களையும் வீடியோ ஃபைல்களையும் அணுகும்"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"மைக்ரோஃபோன்"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ஒலிப் பதிவு செய்யலாம்"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"உடல் செயல்பாடுகள்"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 3b80741..529139b 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"మీ క్యాలెండర్‌ను యాక్సెస్ చేయడానికి"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS మెసేజ్‌లను పంపడం, వీక్షించడం"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"ఫైల్స్ &amp; డాక్యుమెంట్‌లు"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"మీ పరికరంలోని ఫైల్‌లు, డాక్యుమెంట్‌లను యాక్సెస్ చేయండి"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"మ్యూజిక్ &amp; ఇతర ఆడియో"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"మీ పరికరంలోని ఆడియో ఫైల్‌లను యాక్సెస్ చేయండి"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ఫోటోలు &amp; వీడియోలు"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"మీ పరికరంలోని ఇమేజ్‌లు, వీడియో ఫైల్‌లను యాక్సెస్ చేయండి"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"మైక్రోఫోన్"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ఆడియోను రికార్డ్ చేయడానికి"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"ఫిజికల్ యాక్టివిటీ"</string>
@@ -1127,7 +1132,7 @@
     <string name="elapsed_time_short_format_h_mm_ss" msgid="2302144714803345056">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
     <string name="selectAll" msgid="1532369154488982046">"అన్నింటినీ ఎంచుకోండి"</string>
     <string name="cut" msgid="2561199725874745819">"కత్తిరించు"</string>
-    <string name="copy" msgid="5472512047143665218">"కాపీ చేయి"</string>
+    <string name="copy" msgid="5472512047143665218">"కాపీ చేయండి"</string>
     <string name="failed_to_copy_to_clipboard" msgid="725919885138539875">"క్లిప్‌బోర్డ్‌కు కాపీ చేయడంలో విఫలమైంది"</string>
     <string name="paste" msgid="461843306215520225">"అతికించు"</string>
     <string name="paste_as_plain_text" msgid="7664800665823182587">"సాదా వచనం లాగా అతికించు"</string>
@@ -1224,7 +1229,7 @@
     <string name="unsupported_display_size_show" msgid="980129850974919375">"ఎల్లప్పుడూ చూపు"</string>
     <string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"Android OS యొక్క అననుకూల వెర్షన్ కోసం <xliff:g id="APP_NAME">%1$s</xliff:g> రూపొందించబడింది మరియు ఊహించని సమస్యలు తలెత్తవచ్చు. యాప్ యొక్క అప్‌డేట్ చేసిన వెర్షన్ అందుబాటులో ఉండవచ్చు."</string>
     <string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"ఎల్లప్పుడూ చూపు"</string>
-    <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"అప్‌డేట్ కోసం చెక్ చేయి"</string>
+    <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"అప్‌డేట్ కోసం చెక్ చేయండి"</string>
     <string name="smv_application" msgid="3775183542777792638">"<xliff:g id="APPLICATION">%1$s</xliff:g> యాప్ (<xliff:g id="PROCESS">%2$s</xliff:g> ప్రాసెస్) అది స్వయంగా అమలు చేసే ఖచ్చితమైన మోడ్ విధానాన్ని ఉల్లంఘించింది."</string>
     <string name="smv_process" msgid="1398801497130695446">"ప్రక్రియ <xliff:g id="PROCESS">%1$s</xliff:g> అది స్వయంగా అమలు చేసే ఖచ్చితమైన మోడ్ విధానాన్ని ఉల్లంఘించింది."</string>
     <string name="android_upgrading_title" product="default" msgid="7279077384220829683">"ఫోన్ అప్‌డేట్‌ అవుతోంది…"</string>
@@ -1949,7 +1954,7 @@
     <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"ఈ యాప్ అదనపు సెక్యూరిటీ కోసం రిక్వెస్ట్ చేస్తోంది. బదులుగా మీ టాబ్లెట్‌లో ట్రై చేయండి."</string>
     <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"ఈ యాప్ అదనపు సెక్యూరిటీ కోసం రిక్వెస్ట్ చేస్తోంది. బదులుగా మీ ఫోన్‌లో ట్రై చేయండి."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"ఈ యాప్ పాత వెర్షన్ Android కోసం రూపొందించబడింది మరియు అది సరిగ్గా పని చేయకపోవచ్చు. అప్‌డేట్‌ల కోసం తనిఖీ చేయడానికి ప్రయత్నించండి లేదా డెవలపర్‌ని సంప్రదించండి."</string>
-    <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"అప్‌డేట్ కోసం తనిఖీ చేయండి"</string>
+    <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"అప్‌డేట్ కోసం చెక్ చేయండి"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"మీకు కొత్త మెసేజ్‌లు ఉన్నాయి"</string>
     <string name="new_sms_notification_content" msgid="3197949934153460639">"వీక్షించడానికి SMS యాప్‌ను తెరవండి"</string>
     <string name="profile_encrypted_title" msgid="9001208667521266472">"కొంత ఫంక్షనాలిటీ పరిమితం కావచ్చు"</string>
@@ -2053,8 +2058,7 @@
     <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"అంతరాయం కలిగించవద్దు మార్చబడింది"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"బ్లాక్ చేయబడిన దాన్ని తనిఖీ చేయడానికి నొక్కండి."</string>
     <string name="review_notification_settings_title" msgid="5102557424459810820">"నోటిఫికేషన్ సెట్టింగ్‌లను రివ్యూ చేయండి"</string>
-    <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
-    <skip />
+    <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13తో మొదలుకుని, మీరు ఇన్‌స్టాల్ చేసే యాప్‌లకు నోటిఫికేషన్‌లను పంపడానికి మీ అనుమతి అవసరం. ఇప్పటికే ఉన్న యాప్‌ల కోసం ఈ అనుమతిని మార్చడానికి ట్యాప్ చేయండి."</string>
     <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"తర్వాత గుర్తు చేయి"</string>
     <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"విస్మరించండి"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"సిస్టమ్"</string>
@@ -2140,7 +2144,7 @@
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"ఈ కంటెంట్ వ్యక్తిగత యాప్‌తో షేర్ చేయడం సాధ్యం కాదు"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"ఈ కంటెంట్ వ్యక్తిగత యాప్‌తో తెరవడం సాధ్యం కాదు"</string>
     <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"వర్క్ ప్రొఫైల్ పాజ్ చేయబడింది"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"ఆన్ చేయడానికి ట్యాప్ చేయి"</string>
+    <string name="resolver_switch_on_work" msgid="463709043650610420">"ఆన్ చేయడానికి ట్యాప్ చేయండి"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"వర్క్ యాప్‌లు లేవు"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"వ్యక్తిగత యాప్‌లు లేవు"</string>
     <string name="miniresolver_open_in_personal" msgid="3874522693661065566">"<xliff:g id="APP">%s</xliff:g>ను మీ వ్యక్తిగత ప్రొఫైల్‌లో తెరవాలా?"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 77e1ab1..dd1afa7 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"เข้าถึงปฏิทิน"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"ส่งและดูข้อความ SMS"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"ไฟล์และเอกสาร"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"เข้าถึงไฟล์และเอกสารในอุปกรณ์"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"เพลงและเสียงอื่นๆ"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"เข้าถึงไฟล์เสียงในอุปกรณ์"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"รูปภาพและวิดีโอ"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"เข้าถึงไฟล์ภาพและวิดีโอในอุปกรณ์"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"ไมโครโฟน"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"บันทึกเสียง"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"การเคลื่อนไหวร่างกาย"</string>
@@ -2104,7 +2109,7 @@
     <string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} + # ไฟล์}other{{file_name} + # ไฟล์}}"</string>
     <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"ไม่พบใครที่แนะนำให้แชร์ด้วย"</string>
     <string name="chooser_all_apps_button_label" msgid="3230427756238666328">"รายชื่อแอป"</string>
-    <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"แอปนี้ไม่ได้รับอนุญาตให้บันทึกเสียงแต่จะบันทึกเสียงผ่านอุปกรณ์ USB นี้ได้"</string>
+    <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"แอปนี้ไม่ได้รับอนุญาตให้บันทึกเสียงแต่อาจเก็บเสียงผ่านอุปกรณ์ USB นี้ได้"</string>
     <string name="accessibility_system_action_home_label" msgid="3234748160850301870">"หน้าแรก"</string>
     <string name="accessibility_system_action_back_label" msgid="4205361367345537608">"กลับ"</string>
     <string name="accessibility_system_action_recents_label" msgid="4782875610281649728">"แอปล่าสุด"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index bb071ad..07cb34e 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"i-access ang iyong kalendaryo"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"magpadala at tumingin ng mga mensaheng SMS"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Mga file at dokumento"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"i-access ang mga file at dokumento sa iyong device"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musika at iba pang audio"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"mag-access ng mga audio file sa iyong device"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Mga larawan at video"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"mag-access ng mga larawan at video file sa iyong device"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikropono"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"mag-record ng audio"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Pisikal na aktibidad"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index add4cc3..fd5de5f 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"takviminize erişme"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS mesajları gönderme ve görüntüleme"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Dosyalar ve dokümanlar"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"cihazınızdaki dosyalara ve dokümanlara erişme"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Müzik ve diğer sesler"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"cihazınızdaki ses dosyalarına erişme"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotoğraflar ve videolar"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"cihazınızdaki resim ve video dosyalarına erişme"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ses kaydetme"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fiziksel aktivite"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 582dc57..53dc390 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -307,12 +307,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"отримувати доступ до календаря"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"надсилати та переглядати SMS-повідомлення"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Файли та документи"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"отримувати доступ до файлів і документів на вашому пристрої"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Музика й інше аудіо"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"отримувати доступ до аудіофайлів на вашому пристрої"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Фото й відео"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"отримувати доступ до відеофайлів на вашому пристрої"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Мікрофон"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"записувати аудіо"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Фізична активність"</string>
@@ -351,7 +356,7 @@
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Дозволяє програмі розгортати чи згортати рядок стану."</string>
     <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"Показувати сповіщення як активності на весь екран заблокованого пристрою"</string>
     <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Додаток зможе показувати сповіщення як активності на весь екран заблокованого пристрою"</string>
-    <string name="permlab_install_shortcut" msgid="7451554307502256221">"створення ярликів"</string>
+    <string name="permlab_install_shortcut" msgid="7451554307502256221">"Створювати ярлики"</string>
     <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Дозволяє програмі самостійно додавати ярлики на головний екран."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"видаляти ярлики"</string>
     <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Дозволяє програмі самостійно вилучати ярлики з головного екрана."</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 20c931e5..6587d02 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"اپنے کیلنڈر تک رسائی حاصل کریں"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"‏SMS پیغامات بھیجیں اور دیکھیں"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"فائلز اور دستاویزات"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"آپ کے آلے پر فائلز اور دستاویزات تک رسائی حاصل کریں"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"موسیقی اور دیگر آڈیو"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"آپ کے آلے پر آڈیو فائلز تک رسائی حاصل کریں"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"تصاویر اور ویڈیوز"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"آپ کے آلے پر تصاویر اور ویڈیو فائلز تک رسائی حاصل کریں"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"مائیکروفون"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"آڈیو ریکارڈ کریں"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"جسمانی سرگرمی"</string>
@@ -1616,7 +1621,7 @@
     <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"اسکرین کو آلہ پر کاسٹ کریں"</string>
     <string name="media_route_chooser_searching" msgid="6119673534251329535">"آلات تلاش کر رہا ہے…"</string>
     <string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"ترتیبات"</string>
-    <string name="media_route_controller_disconnect" msgid="7362617572732576959">"غیر مربوط کریں"</string>
+    <string name="media_route_controller_disconnect" msgid="7362617572732576959">"منقطع کریں"</string>
     <string name="media_route_status_scanning" msgid="8045156315309594482">"اسکین کر رہا ہے…"</string>
     <string name="media_route_status_connecting" msgid="5845597961412010540">"مربوط ہو رہا ہے…"</string>
     <string name="media_route_status_available" msgid="1477537663492007608">"دستیاب"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 6905f90..78627d3 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -305,12 +305,12 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"taqvimingizga kirish"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS xabarlarni yuborish va ko‘rish"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Fayl va hujjatlar"</string>
+    <string name="permgrouplab_storage" msgid="5570124978732352858">"Fayl va hujjatlar"</string>
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"qurilmangizdagi fayl va hujjatlarga kirish"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musiqa va boshqa audio"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"qurilmangizdagi audio fayllarga kirish"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Suratlar va videolar"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"qurilmangizdagi rasm va video fayllarga kirish"</string>
+    <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Musiqa va audio"</string>
+    <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"qurilmadagi musiqa va audioga ruxsat"</string>
+    <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Video va suratlar"</string>
+    <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"qurilmadagi rasm va videolarga ruxsat"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ovoz yozib olish"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Jismoniy harakatlar"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 154e8db..a993ca6 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"truy cập lịch của bạn"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"Tin nhắn SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"gửi và xem tin nhắn SMS"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Tệp và tài liệu"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"truy cập vào các tệp và tài liệu trên thiết bị của bạn"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Nhạc và âm thanh khác"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"truy cập vào tệp âm thanh trên thiết bị"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Ảnh và video"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"truy cập vào tệp hình ảnh và video trên thiết bị"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Micrô"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ghi âm"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Hoạt động thể chất"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 33c78c2..8cdc606 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"访问您的日历"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"短信"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"发送和查看短信"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"文件和文档"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"访问您设备上的文件和文档"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"音乐和其他音频"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"访问您设备上的音频文件"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"照片和视频"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"访问您设备上的图片和视频文件"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"麦克风"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"录制音频"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"身体活动"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 2041011..53885b8 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"存取您的日曆"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"短訊"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"傳送和查看短訊"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"檔案和文件"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"存取裝置上的檔案和文件"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"音樂和其他音訊"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"存取裝置上的音訊檔案"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"相片和影片"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"存取裝置上的圖片和影片檔案"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"麥克風"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"錄音"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"體能活動"</string>
@@ -581,7 +586,7 @@
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"已取消驗證"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"未能識別"</string>
     <string name="biometric_error_canceled" msgid="8266582404844179778">"已取消驗證"</string>
-    <string name="biometric_error_device_not_secured" msgid="3129845065043995924">"未設定 PIN、圖案或密碼"</string>
+    <string name="biometric_error_device_not_secured" msgid="3129845065043995924">"未設定 PIN、圖形或密碼"</string>
     <string name="biometric_error_generic" msgid="6784371929985434439">"驗證時發生錯誤"</string>
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"使用螢幕鎖定"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"如要繼續操作,請輸入螢幕鎖定解鎖憑證"</string>
@@ -776,7 +781,7 @@
     <string name="policylab_setGlobalProxy" msgid="215332221188670221">"設定裝置的全域代理伺服器"</string>
     <string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"設定政策啟用時所要使用的裝置全域代理伺服器,只有裝置擁有者可以設定全域代理伺服器。"</string>
     <string name="policylab_expirePassword" msgid="6015404400532459169">"設定螢幕鎖定密碼期限"</string>
-    <string name="policydesc_expirePassword" msgid="9136524319325960675">"變更螢幕鎖定密碼、PIN 或圖案的更改頻率。"</string>
+    <string name="policydesc_expirePassword" msgid="9136524319325960675">"變更螢幕鎖定密碼、PIN 或圖形的更改頻率。"</string>
     <string name="policylab_encryptedStorage" msgid="9012936958126670110">"設定儲存裝置加密"</string>
     <string name="policydesc_encryptedStorage" msgid="1102516950740375617">"必須為儲存的應用程式資料加密。"</string>
     <string name="policylab_disableCamera" msgid="5749486347810162018">"停用相機"</string>
@@ -911,7 +916,7 @@
     <string name="lockscreen_screen_locked" msgid="7364905540516041817">"螢幕已鎖定。"</string>
     <string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"按選單鍵解鎖或撥打緊急電話。"</string>
     <string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"按選單鍵解鎖。"</string>
-    <string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"畫出解鎖圖形以解除鎖定螢幕"</string>
+    <string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"畫出解鎖圖形來為螢幕解鎖"</string>
     <string name="lockscreen_emergency_call" msgid="7500692654885445299">"緊急電話"</string>
     <string name="lockscreen_return_to_call" msgid="3156883574692006382">"返回通話"</string>
     <string name="lockscreen_pattern_correct" msgid="8050630103651508582">"正確!"</string>
@@ -940,12 +945,12 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"請參閱使用者指南或與客戶服務中心聯絡。"</string>
     <string name="lockscreen_sim_locked_message" msgid="3160196135801185938">"SIM 卡處於鎖定狀態。"</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="2286497117428409709">"正在解除 SIM 卡鎖定..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
     <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"您已輸入錯誤的密碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
     <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"您已輸入錯誤的 PIN 碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您使用您的 Google 登入資料解開上鎖的平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您使用 Google 登入資料將 Android TV 裝置解鎖。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您使用您的 Google 登入資料解開上鎖的手機。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您使用您的 Google 登入資料解開上鎖的平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您使用 Google 登入資料將 Android TV 裝置解鎖。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您使用您的 Google 登入資料解開上鎖的手機。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"您嘗試解除這部平板電腦的鎖定已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,剩餘 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次嘗試機會。如果失敗次數超過嘗試次數限制,平板電腦將恢復原廠設定,所有使用者資料均會遺失。"</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"您已 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次無法解鎖 Android TV 裝置。如果再失敗 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次,Android TV 裝置將回復原廠設定,所有使用者資料均會遺失。"</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"您嘗試解除這部手機的鎖定已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,剩餘 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次嘗試機會。如果失敗次數超過嘗試次數限制,手機將恢復原廠設定,所有使用者資料均會遺失。"</string>
@@ -955,7 +960,7 @@
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6807200118164539589">"<xliff:g id="NUMBER">%d</xliff:g> 秒後再試一次。"</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"忘記圖形?"</string>
     <string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"帳戶解鎖"</string>
-    <string name="lockscreen_glogin_too_many_attempts" msgid="3775904917743034195">"圖案嘗試次數過多"</string>
+    <string name="lockscreen_glogin_too_many_attempts" msgid="3775904917743034195">"圖形嘗試次數過多"</string>
     <string name="lockscreen_glogin_instructions" msgid="4695162942525531700">"如要解鎖,請以 Google 帳戶登入。"</string>
     <string name="lockscreen_glogin_username_hint" msgid="6916101478673157045">"使用者名稱 (電子郵件)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="3031027901286812848">"密碼"</string>
@@ -966,12 +971,12 @@
     <string name="lockscreen_unlock_label" msgid="4648257878373307582">"解除鎖定"</string>
     <string name="lockscreen_sound_on_label" msgid="1660281470535492430">"開啟音效"</string>
     <string name="lockscreen_sound_off_label" msgid="2331496559245450053">"關閉音效"</string>
-    <string name="lockscreen_access_pattern_start" msgid="3778502525702613399">"已開始繪畫解鎖圖案"</string>
-    <string name="lockscreen_access_pattern_cleared" msgid="7493849102641167049">"已清除解鎖圖案"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3778502525702613399">"已開始繪畫解鎖圖形"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="7493849102641167049">"已清除解鎖圖形"</string>
     <string name="lockscreen_access_pattern_cell_added" msgid="6746676335293144163">"已加入一格"</string>
     <string name="lockscreen_access_pattern_cell_added_verbose" msgid="2931364927622563465">"已加入 <xliff:g id="CELL_INDEX">%1$s</xliff:g> 點"</string>
-    <string name="lockscreen_access_pattern_detected" msgid="3931150554035194012">"已畫出解鎖圖案"</string>
-    <string name="lockscreen_access_pattern_area" msgid="1288780416685002841">"圖案區域。"</string>
+    <string name="lockscreen_access_pattern_detected" msgid="3931150554035194012">"已畫出解鎖圖形"</string>
+    <string name="lockscreen_access_pattern_area" msgid="1288780416685002841">"圖形區域。"</string>
     <string name="keyguard_accessibility_widget_changed" msgid="7298011259508200234">"%1$s。第 %2$d 個小工具,共 %3$d 個。"</string>
     <string name="keyguard_accessibility_add_widget" msgid="8245795023551343672">"新增小工具。"</string>
     <string name="keyguard_accessibility_widget_empty_slot" msgid="544239307077644480">"空白"</string>
@@ -987,13 +992,13 @@
     <string name="keyguard_accessibility_widget_deleted" msgid="1509738950119878705">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>小工具已刪除。"</string>
     <string name="keyguard_accessibility_expand_lock_area" msgid="4215280881346033434">"展開解鎖區域。"</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2968195219692413046">"滑動解鎖。"</string>
-    <string name="keyguard_accessibility_pattern_unlock" msgid="8669128146589233293">"圖案解鎖。"</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="8669128146589233293">"圖形解鎖。"</string>
     <string name="keyguard_accessibility_face_unlock" msgid="4533832120787386728">"面孔解鎖。"</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="4020864007967340068">"PIN 解鎖。"</string>
     <string name="keyguard_accessibility_sim_pin_unlock" msgid="4895939120871890557">"SIM 卡 PIN 碼解鎖。"</string>
     <string name="keyguard_accessibility_sim_puk_unlock" msgid="3459003464041899101">"SIM 卡 PUK 解鎖。"</string>
     <string name="keyguard_accessibility_password_unlock" msgid="6130186108581153265">"密碼解鎖。"</string>
-    <string name="keyguard_accessibility_pattern_area" msgid="1419570880512350689">"圖案區域。"</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="1419570880512350689">"圖形區域。"</string>
     <string name="keyguard_accessibility_slide_area" msgid="4331399051142520176">"滑動區域。"</string>
     <string name="password_keyboard_label_symbol_key" msgid="2716255580853511949">"?123"</string>
     <string name="password_keyboard_label_alpha_key" msgid="5294837425652726684">"ABC"</string>
@@ -1627,11 +1632,11 @@
     <string name="display_manager_overlay_display_name" msgid="5306088205181005861">"重疊效果 #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="1480158037150469170">"<xliff:g id="NAME">%1$s</xliff:g>:<xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>,<xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="2810034719482834679">"(安全)"</string>
-    <string name="kg_forgot_pattern_button_text" msgid="406145459223122537">"忘記圖案"</string>
-    <string name="kg_wrong_pattern" msgid="1342812634464179931">"圖形不對"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="406145459223122537">"忘記了圖形"</string>
+    <string name="kg_wrong_pattern" msgid="1342812634464179931">"圖形錯誤"</string>
     <string name="kg_wrong_password" msgid="2384677900494439426">"密碼錯誤"</string>
     <string name="kg_wrong_pin" msgid="3680925703673166482">"PIN 錯誤"</string>
-    <string name="kg_pattern_instructions" msgid="8366024510502517748">"畫出圖案"</string>
+    <string name="kg_pattern_instructions" msgid="8366024510502517748">"畫出圖形"</string>
     <string name="kg_sim_pin_instructions" msgid="6479401489471690359">"輸入 SIM 卡 PIN 碼"</string>
     <string name="kg_pin_instructions" msgid="7355933174673539021">"輸入 PIN 碼"</string>
     <string name="kg_password_instructions" msgid="7179782578809398050">"輸入密碼"</string>
@@ -1644,7 +1649,7 @@
     <string name="kg_invalid_sim_puk_hint" msgid="2539364558870734339">"PUK 碼應由 8 位數字組成。"</string>
     <string name="kg_invalid_puk" msgid="4809502818518963344">"請重新輸入正確的 PUK 碼。如果嘗試輸入的次數過多,SIM 卡將永久停用。"</string>
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="4705368340409816254">"PIN 碼不符"</string>
-    <string name="kg_login_too_many_attempts" msgid="699292728290654121">"圖案嘗試次數過多"</string>
+    <string name="kg_login_too_many_attempts" msgid="699292728290654121">"圖形嘗試次數過多"</string>
     <string name="kg_login_instructions" msgid="3619844310339066827">"如要解鎖,請以 Google 帳戶登入。"</string>
     <string name="kg_login_username_hint" msgid="1765453775467133251">"使用者名稱 (電子郵件)"</string>
     <string name="kg_login_password_hint" msgid="3330530727273164402">"密碼"</string>
@@ -1654,16 +1659,16 @@
     <string name="kg_login_checking_password" msgid="4676010303243317253">"正在檢查帳戶…"</string>
     <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"您已輸入錯誤的 PIN 碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"您已輸入錯誤的密碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"您嘗試了 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次仍未能成功解開這部上鎖的平板電腦。如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,平板電腦將回復原廠設定,所有使用者資料均會失去。"</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"您已 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次無法解鎖 Android TV 裝置。如果再失敗 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次,Android TV 裝置將回復原廠設定,所有使用者資料均會遺失。"</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"您嘗試了 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次仍未能成功解開這部上鎖的手機。如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,手機將回復原廠設定,所有使用者資料均會失去。"</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"您嘗試了 <xliff:g id="NUMBER">%d</xliff:g> 次仍未能成功解開這部上鎖的平板電腦。平板電腦現在將回復原廠設定。"</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"您已 <xliff:g id="NUMBER">%d</xliff:g> 次無法解鎖 Android TV 裝置,Android TV 裝置現在將回復原廠設定。"</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"您嘗試了 <xliff:g id="NUMBER">%d</xliff:g> 次仍未能成功解開這部上鎖的手機。手機現在將回復原廠設定。"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解開上鎖的平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您使用電郵帳戶解鎖 Android TV 裝置。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解開上鎖的手機。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解開上鎖的平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您使用電郵帳戶解鎖 Android TV 裝置。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解開上鎖的手機。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"移除"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"要調高音量 (比建議的音量更大聲) 嗎?\n\n長時間聆聽高分貝音量可能會導致您的聽力受損。"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 5ec0a0c..12092ef 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"存取你的日曆"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"簡訊"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"傳送及查看簡訊"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"檔案與文件"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"存取裝置上的檔案與文件"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"音樂和其他音訊"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"存取裝置上的音訊檔案"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"相片和影片"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"存取裝置上的圖片和影片檔案"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"麥克風"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"錄音"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"體能活動"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index ee1711c..9d8c8a3 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -305,12 +305,17 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"finyelela kukhalenda yakho"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"I-SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"thumela uphinde ubuke imilayezo ye-SMS"</string>
-    <string name="permgrouplab_storage" msgid="9173334109512154196">"Amafayela namadokhumenti"</string>
+    <!-- no translation found for permgrouplab_storage (5570124978732352858) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="8352226729501080525">"finyelela amafayela namadokhumenti kudivayisi yakho"</string>
-    <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Umculo neminye imisindo"</string>
-    <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"finyelela amafayela okulalelwayo edivayisini yakho"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Izithombe namavidiyo"</string>
-    <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"finyelela amafayela emifanekiso namavidiyo edivayisini yakho"</string>
+    <!-- no translation found for permgrouplab_readMediaAural (1858331312624942053) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaAural (7565467343667089595) -->
+    <skip />
+    <!-- no translation found for permgrouplab_readMediaVisual (4724874717811908660) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_readMediaVisual (4080463241903508688) -->
+    <skip />
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"I-Microphone"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"rekhoda ividiyo"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Umsebenzi womzimba"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index d2f31b0..75b1e752 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3376,6 +3376,50 @@
              <p>This is true by default.
              See {@link android.view.View#setAutoHandwritingEnabled}. -->
         <attr name="autoHandwritingEnabled" format="boolean" />
+
+        <!-- <p>The amount of offset that is applied to the left edge of the view's stylus
+             handwriting bounds, which by default is the view's visible bounds.
+
+             <p>This attribute is mainly used to enlarge the view's handwriting bounds for better
+             user experience. Note that a positive offset means the bounds is extended outwards,
+             and vice versa. See {@link android.view.View#setHandwritingBoundsOffsets}
+
+             <p> The default value is 10dp for {@link android.widget.TextView} and
+             {@link android.widget.EditText}, and 0dp for other views. -->
+        <attr name="handwritingBoundsOffsetLeft" format="dimension" />
+
+        <!-- <p>The amount of offset that is applied to the top edge of the view's stylus
+             handwriting bounds, which by default is the view's visible bounds.
+
+             <p>This attribute is mainly used to enlarge the view's handwriting bounds for better
+             user experience. Note that a positive offset means the bounds is extended outwards,
+             and vice versa. See {@link android.view.View#setHandwritingBoundsOffsets}
+
+             <p> The default value is 40dp for {@link android.widget.TextView} and
+             {@link android.widget.EditText}, and 0dp for other views. -->
+        <attr name="handwritingBoundsOffsetTop" format="dimension" />
+
+        <!-- <p>The amount of offset that is applied to the right edge of the view's stylus
+             handwriting bounds, which by default is the view's visible bounds.
+
+             <p>This attribute is mainly used to enlarge the view's handwriting bounds for better
+             user experience. Note that a positive offset means the bounds is extended outwards,
+             and vice versa. See {@link android.view.View#setHandwritingBoundsOffsets}
+
+             <p> The default value is 10dp for {@link android.widget.TextView} and
+             {@link android.widget.EditText}, and 0dp for other views. -->
+        <attr name="handwritingBoundsOffsetRight" format="dimension" />
+
+        <!-- <p>The amount of offset that is applied to the bottom edge of the view's stylus
+             handwriting bounds, which by default is the view's visible bounds.
+
+             <p>This attribute is mainly used to enlarge the view's handwriting bounds for better
+             user experience. Note that a positive offset means the bounds is extended outwards,
+             and vice versa. See {@link android.view.View#setHandwritingBoundsOffsets}
+
+             <p> The default value is 40dp for {@link android.widget.TextView} and
+             {@link android.widget.EditText}, and 0dp for all other views. -->
+        <attr name="handwritingBoundsOffsetBottom" format="dimension" />
     </declare-styleable>
 
     <!-- Attributes that can be assigned to a tag for a particular View. -->
diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml
index 77500c4..d9ac516 100644
--- a/core/res/res/values/config_telephony.xml
+++ b/core/res/res/values/config_telephony.xml
@@ -109,4 +109,12 @@
     <!-- Telephony qualified networks service class name to bind to by default. -->
     <string name="config_qualified_networks_service_class" translatable="false"></string>
     <java-symbol type="string" name="config_qualified_networks_service_class" />
+
+    <!-- Whether enhanced IWLAN handover check is enabled. If enabled, telephony frameworks
+         will not perform handover if the target transport is out of service, or VoPS not
+         supported. The network will be torn down on the source transport, and will be
+         re-established on the target transport when condition is allowed for bringing up a
+         new network. -->
+    <bool name="config_enhanced_iwlan_handover_check">true</bool>
+    <java-symbol type="bool" name="config_enhanced_iwlan_handover_check" />
 </resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index d9d1a08..c10328e 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -1008,4 +1008,10 @@
     <!-- Dimensions for the translations of the default dialog animation. -->
     <dimen name="popup_enter_animation_from_y_delta">20dp</dimen>
     <dimen name="popup_exit_animation_to_y_delta">-10dp</dimen>
+
+    <!-- Default handwriting bounds offsets for editors. -->
+    <dimen name="handwriting_bounds_offset_left">10dp</dimen>
+    <dimen name="handwriting_bounds_offset_top">40dp</dimen>
+    <dimen name="handwriting_bounds_offset_right">10dp</dimen>
+    <dimen name="handwriting_bounds_offset_bottom">40dp</dimen>
 </resources>
diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml
index f09ffbe..edebc7a 100644
--- a/core/res/res/values/public-staging.xml
+++ b/core/res/res/values/public-staging.xml
@@ -110,6 +110,10 @@
   <eat-comment/>
 
   <staging-public-group type="attr" first-id="0x01ce0000">
+    <public name="handwritingBoundsOffsetLeft" />
+    <public name="handwritingBoundsOffsetTop" />
+    <public name="handwritingBoundsOffsetRight" />
+    <public name="handwritingBoundsOffsetBottom" />
   </staging-public-group>
 
   <staging-public-group type="id" first-id="0x01cd0000">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 824dd8b..a4be0b9 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1798,45 +1798,57 @@
     <string name="fingerprint_recalibrate_notification_content">Visit a repair provider.</string>
 
     <!-- Message shown during face acquisition when the face cannot be recognized [CHAR LIMIT=50] -->
-    <string name="face_acquired_insufficient">Couldn\u2019t capture accurate face data. Try again.</string>
+    <string name="face_acquired_insufficient">Can\u2019t create your face model. Try again.</string>
     <!-- Message shown during face acquisition when the image is too bright [CHAR LIMIT=50] -->
     <string name="face_acquired_too_bright">Too bright. Try gentler lighting.</string>
     <!-- Message shown during face acquisition when the image is too dark [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_dark">Too dark. Try brighter lighting.</string>
+    <string name="face_acquired_too_dark">Try brighter lighting</string>
     <!-- Message shown during face acquisition when the user is too close to sensor [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_close">Move phone farther away.</string>
+    <string name="face_acquired_too_close">Move phone farther away</string>
     <!-- Message shown during face acquisition when the user is too far from sensor [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_far">Move phone closer.</string>
+    <string name="face_acquired_too_far">Move phone closer</string>
     <!-- Message shown during face acquisition when the user is too high relatively to sensor [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_high">Move phone higher.</string>
+    <string name="face_acquired_too_high">Move phone higher</string>
     <!-- Message shown during face acquisition when the user is too low relatively to sensor [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_low">Move phone lower.</string>
+    <string name="face_acquired_too_low">Move phone lower</string>
     <!-- Message shown during face acquisition when only the right part of the user's face was detected [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_right">Move phone to the left.</string>
+    <string name="face_acquired_too_right">Move phone to your left</string>
     <!-- Message shown during face acquisition when only the left part of the user's face was detected [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_left">Move phone to the right.</string>
+    <string name="face_acquired_too_left">Move phone to your right</string>
     <!-- Message shown during face acquisition when the user is not front facing the sensor [CHAR LIMIT=50] -->
     <string name="face_acquired_poor_gaze">Please look more directly at your device.</string>
-    <!-- Message shown during face acquisition when the user is not detected [CHAR LIMIT=50] -->
-    <string name="face_acquired_not_detected">Position your face directly in front of the phone.</string>
+    <!-- Message shown during face acquisition when the user is not detected [CHAR LIMIT=75] -->
+    <string name="face_acquired_not_detected">Can\u2019t see your face. Hold your phone at eye level.</string>
     <!-- Message shown during face acquisition when the device is not steady [CHAR LIMIT=50] -->
     <string name="face_acquired_too_much_motion">Too much motion. Hold phone steady.</string>
     <!-- Message shown during face acquisition when the sensor needs to be recalibrated [CHAR LIMIT=50] -->
     <string name="face_acquired_recalibrate">Please re-enroll your face.</string>
     <!-- Message shown during face enrollment when a different person's face is detected [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_different">No longer able to recognize face. Try again.</string>
+    <string name="face_acquired_too_different">Can\u2019t recognize face. Try again.</string>
     <!-- Message shown during face enrollment when the face is too similar to a previous acquisition [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_similar">Too similar, please change your pose.</string>
+    <string name="face_acquired_too_similar">Change the position of your head slightly</string>
     <!-- Message shown during acqusition when the user's face is turned too far left or right [CHAR LIMIT=50] -->
-    <string name="face_acquired_pan_too_extreme">Turn your head a little less.</string>
+    <string name="face_acquired_pan_too_extreme">Look more directly at your phone</string>
     <!-- Message shown during acqusition when the user's face is tilted too high or too low [CHAR LIMIT=50] -->
-    <string name="face_acquired_tilt_too_extreme">Tilt your head a little less.</string>
+    <string name="face_acquired_tilt_too_extreme">Look more directly at your phone</string>
     <!-- Message shown during acquisiton when the user's face is tilted too far left or right [CHAR LIMIT=50] -->
-    <string name="face_acquired_roll_too_extreme">Turn your head a little less.</string>
+    <string name="face_acquired_roll_too_extreme">Look more directly at your phone</string>
     <!-- Message shown during acquisition when the user's face is obscured [CHAR LIMIT=50] -->
     <string name="face_acquired_obscured">Remove anything hiding your face.</string>
     <!-- Message shown during acquisition when the sensor is dirty [CHAR LIMIT=100] -->
     <string name="face_acquired_sensor_dirty">Clean the top of your screen, including the black bar</string>
+    <!-- Message shown during acquisition when dark glasses were detected [CHAR LIMIT=75] -->
+    <string name="face_acquired_dark_glasses_detected">Your face must be fully visible</string>
+    <!-- Message shown during acquisition when a mouth covering was detected [CHAR LIMIT=75] -->
+    <string name="face_acquired_mouth_covering_detected">Your face must be fully visible</string>
+
+    <!-- Message shown during face acquisition when the sensor needs to be recalibrated [CHAR LIMIT=75] -->
+    <string name="face_acquired_recalibrate_alt">Can\u2019t create your face model. Try again.</string>
+    <!-- Message shown during acquisition when dark glasses were detected [CHAR LIMIT=100] -->
+    <string name="face_acquired_dark_glasses_detected_alt">Dark glasses detected. Your face must be fully visible.</string>
+    <!-- Message shown during acquisition when a mouth covering was detected [CHAR LIMIT=100] -->
+    <string name="face_acquired_mouth_covering_detected_alt">Face covering detected. Your face must be fully visible.</string>
+
     <!-- Array containing custom messages shown during face acquisition from vendor.  Vendor is expected to add and translate these strings -->
     <string-array name="face_acquired_vendor">
     </string-array>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index c07404b..921a057 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -505,6 +505,10 @@
         <item name="textCursorDrawable">?attr/textCursorDrawable</item>
         <item name="breakStrategy">high_quality</item>
         <item name="hyphenationFrequency">@dimen/config_preferredHyphenationFrequency</item>
+        <item name="handwritingBoundsOffsetLeft">@dimen/handwriting_bounds_offset_left</item>
+        <item name="handwritingBoundsOffsetTop">@dimen/handwriting_bounds_offset_top</item>
+        <item name="handwritingBoundsOffsetRight">@dimen/handwriting_bounds_offset_right</item>
+        <item name="handwritingBoundsOffsetBottom">@dimen/handwriting_bounds_offset_bottom</item>
     </style>
 
     <style name="Widget.CheckedTextView">
@@ -540,6 +544,10 @@
         <item name="breakStrategy">simple</item>
         <item name="hyphenationFrequency">@dimen/config_preferredHyphenationFrequency</item>
         <item name="defaultFocusHighlightEnabled">false</item>
+        <item name="handwritingBoundsOffsetLeft">@dimen/handwriting_bounds_offset_left</item>
+        <item name="handwritingBoundsOffsetTop">@dimen/handwriting_bounds_offset_top</item>
+        <item name="handwritingBoundsOffsetRight">@dimen/handwriting_bounds_offset_right</item>
+        <item name="handwritingBoundsOffsetBottom">@dimen/handwriting_bounds_offset_bottom</item>
     </style>
 
     <style name="Widget.ExpandableListView" parent="Widget.ListView">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 3a08db6..c3c656a 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2657,6 +2657,11 @@
   <java-symbol type="string" name="face_acquired_roll_too_extreme" />
   <java-symbol type="string" name="face_acquired_obscured" />
   <java-symbol type="string" name="face_acquired_sensor_dirty" />
+  <java-symbol type="string" name="face_acquired_dark_glasses_detected" />
+  <java-symbol type="string" name="face_acquired_mouth_covering_detected" />
+  <java-symbol type="string" name="face_acquired_recalibrate_alt" />
+  <java-symbol type="string" name="face_acquired_dark_glasses_detected_alt" />
+  <java-symbol type="string" name="face_acquired_mouth_covering_detected_alt" />
   <java-symbol type="array" name="face_acquired_vendor" />
   <java-symbol type="string" name="face_name_template" />
   <java-symbol type="string" name="face_app_setting_name" />
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java
index c194989..8587a35 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java
@@ -166,7 +166,8 @@
                 new HashSet<ProgramSelector.Identifier>(), true, false);
 
         // Start updates on the clients in order. The HAL filter should get updated after each
-        // client except [2].
+        // client except [2]. Client [2] should update received chunk with an empty program
+        // list
         mTunerSessions[0].startProgramListUpdates(idFilter);
         ProgramFilter halFilter = Convert.programFilterToHal(idFilter);
         verify(mHalTunerSessionMock, times(1)).startProgramListUpdates(halFilter);
@@ -177,6 +178,9 @@
 
         mTunerSessions[2].startProgramListUpdates(typeFilterWithoutModifications);
         verify(mHalTunerSessionMock, times(2)).startProgramListUpdates(any());
+        verifyAidlClientReceivedChunk(mAidlTunerCallbackMocks[2], true, Arrays.asList(),
+                null);
+        verify(mAidlTunerCallbackMocks[2], CB_TIMEOUT.times(1)).onProgramListUpdated(any());
 
         mTunerSessions[3].startProgramListUpdates(typeFilterWithModifications);
         halFilter.excludeModifications = false;
@@ -207,7 +211,7 @@
         updateHalProgramInfo(false, Arrays.asList(mDabEnsembleInfo), null);
         verify(mAidlTunerCallbackMocks[0], CB_TIMEOUT.times(1)).onProgramListUpdated(any());
         verify(mAidlTunerCallbackMocks[1], CB_TIMEOUT.times(2)).onProgramListUpdated(any());
-        verify(mAidlTunerCallbackMocks[2], CB_TIMEOUT.times(1)).onProgramListUpdated(any());
+        verify(mAidlTunerCallbackMocks[2], CB_TIMEOUT.times(2)).onProgramListUpdated(any());
         verify(mAidlTunerCallbackMocks[3], CB_TIMEOUT.times(2)).onProgramListUpdated(any());
     }
 
diff --git a/core/tests/coretests/src/android/app/KeyguardManagerTest.java b/core/tests/coretests/src/android/app/KeyguardManagerTest.java
new file mode 100644
index 0000000..7231fbd
--- /dev/null
+++ b/core/tests/coretests/src/android/app/KeyguardManagerTest.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package android.app;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.Intent;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+
+@RunWith(JUnit4.class)
+public class KeyguardManagerTest {
+
+    private static final String TITLE = "Title";
+    private static final String DESCRIPTION = "Description";
+    private static final int USER_ID = 0;
+    private static final String PASSWORD = "PASSWORD";
+    private static final boolean DISALLOW_BIOMETRICS_IF_POLICY_EXISTS = false;
+    private static final int PASSWORD_LOCK_TYPE = KeyguardManager.PASSWORD;
+    private static final int MEDIUM_PASSWORD_COMPLEXITY =
+            DevicePolicyManager.PASSWORD_COMPLEXITY_MEDIUM;
+
+
+    private final Context mContext = InstrumentationRegistry.getInstrumentation().getContext();
+
+    private final KeyguardManager mKeyguardManager = spy(
+            mContext.getSystemService(KeyguardManager.class));
+
+
+    @BeforeClass
+    public static void setup() {
+        InstrumentationRegistry
+                .getInstrumentation()
+                .getUiAutomation()
+                .adoptShellPermissionIdentity();
+    }
+
+    @AfterClass
+    public static void cleanup() {
+        InstrumentationRegistry
+                .getInstrumentation()
+                .getUiAutomation()
+                .dropShellPermissionIdentity();
+    }
+
+    @Test
+    public void createConfirmDeviceCredentialIntent_deviceSecure() {
+        when(mKeyguardManager.isDeviceSecure(USER_ID)).thenReturn(true);
+
+        Intent intent = mKeyguardManager.createConfirmDeviceCredentialIntent(TITLE, DESCRIPTION,
+                USER_ID);
+
+        assertEquals(intent.getAction(),
+                KeyguardManager.ACTION_CONFIRM_DEVICE_CREDENTIAL_WITH_USER);
+        assertEquals(intent.getStringExtra(KeyguardManager.EXTRA_TITLE), TITLE);
+        assertEquals(intent.getStringExtra(KeyguardManager.EXTRA_DESCRIPTION), DESCRIPTION);
+        assertEquals(intent.getIntExtra(Intent.EXTRA_USER_ID, /* defaultValue= */-1), USER_ID);
+        assertEquals(intent.getPackage(), "com.android.settings");
+    }
+
+    @Test
+    public void createConfirmDeviceCredentialIntent_deviceNotSecure() {
+        when(mKeyguardManager.isDeviceSecure(USER_ID)).thenReturn(false);
+
+        Intent intent = mKeyguardManager.createConfirmDeviceCredentialIntent(TITLE, DESCRIPTION,
+                USER_ID);
+
+        assertNull(intent);
+    }
+
+    @Test
+    public void createConfirmDeviceCredentialIntent() {
+        when(mKeyguardManager.isDeviceSecure(USER_ID)).thenReturn(true);
+
+        Intent intent = mKeyguardManager.createConfirmDeviceCredentialIntent(TITLE, DESCRIPTION,
+                USER_ID, DISALLOW_BIOMETRICS_IF_POLICY_EXISTS);
+
+        assertEquals(DISALLOW_BIOMETRICS_IF_POLICY_EXISTS,
+                intent.getBooleanExtra(KeyguardManager.EXTRA_DISALLOW_BIOMETRICS_IF_POLICY_EXISTS,
+                        !DISALLOW_BIOMETRICS_IF_POLICY_EXISTS));
+    }
+
+    @Test
+    public void setPrivateNotificationsAllowed_allowed() {
+        mKeyguardManager.setPrivateNotificationsAllowed(true);
+
+        assertTrue(mKeyguardManager.getPrivateNotificationsAllowed());
+    }
+
+    @Test
+    public void setPrivateNotificationsAllowed_notAllowed() {
+        mKeyguardManager.setPrivateNotificationsAllowed(false);
+
+        assertFalse(mKeyguardManager.getPrivateNotificationsAllowed());
+    }
+
+    @Test
+    public void setLock_setInitialLockPermissionGranted_validPassword() {
+        // Set to `true` to behave as if SET_INITIAL_LOCK permission had been granted.
+        doReturn(true).when(mKeyguardManager).checkInitialLockMethodUsage();
+        doReturn(true).when(mKeyguardManager).isValidLockPasswordComplexity(PASSWORD_LOCK_TYPE,
+                PASSWORD.getBytes(),
+                MEDIUM_PASSWORD_COMPLEXITY);
+
+        boolean successfullySetLock = mKeyguardManager.setLock(PASSWORD_LOCK_TYPE,
+                PASSWORD.getBytes(),
+                MEDIUM_PASSWORD_COMPLEXITY);
+
+        assertTrue(successfullySetLock);
+
+        verifyDeviceLockedAndRemoveLock();
+    }
+
+    @Test
+    public void setLock_setInitialLockPermissionGranted_invalidPassword() {
+        // Set to `true` to behave as if SET_INITIAL_LOCK permission had been granted.
+        doReturn(true).when(mKeyguardManager).checkInitialLockMethodUsage();
+        doReturn(false).when(mKeyguardManager).isValidLockPasswordComplexity(PASSWORD_LOCK_TYPE,
+                PASSWORD.getBytes(),
+                MEDIUM_PASSWORD_COMPLEXITY);
+
+        boolean successfullySetLock = mKeyguardManager.setLock(PASSWORD_LOCK_TYPE,
+                PASSWORD.getBytes(),
+                MEDIUM_PASSWORD_COMPLEXITY);
+
+        assertFalse(successfullySetLock);
+        assertFalse(mKeyguardManager.isDeviceSecure());
+    }
+
+    @Test
+    public void setLock_setInitialLockPermissionDenied() {
+        // Set to `false` to behave as if SET_INITIAL_LOCK permission had not been granted.
+        doReturn(false).when(mKeyguardManager).checkInitialLockMethodUsage();
+        assertFalse(mKeyguardManager.checkInitialLockMethodUsage());
+
+        boolean successfullySetLock = mKeyguardManager.setLock(PASSWORD_LOCK_TYPE,
+                PASSWORD.getBytes(),
+                MEDIUM_PASSWORD_COMPLEXITY);
+
+        assertFalse(successfullySetLock);
+        assertFalse(mKeyguardManager.isDeviceSecure());
+    }
+
+    @Test
+    public void checkLock_correctCredentials() {
+        // Set to `true` to behave as if SET_INITIAL_LOCK permission had been granted.
+        doReturn(true).when(mKeyguardManager).checkInitialLockMethodUsage();
+        doReturn(true).when(mKeyguardManager).isValidLockPasswordComplexity(PASSWORD_LOCK_TYPE,
+                PASSWORD.getBytes(),
+                MEDIUM_PASSWORD_COMPLEXITY);
+        mKeyguardManager.setLock(PASSWORD_LOCK_TYPE,
+                PASSWORD.getBytes(),
+                MEDIUM_PASSWORD_COMPLEXITY);
+
+        boolean correctLockCredentials = mKeyguardManager.checkLock(PASSWORD_LOCK_TYPE,
+                PASSWORD.getBytes());
+
+        assertTrue(correctLockCredentials);
+
+        verifyDeviceLockedAndRemoveLock();
+    }
+
+    @Test
+    public void checkLock_incorrectCredentials() {
+        // Set to `true` to behave as if SET_INITIAL_LOCK permission had been granted.
+        doReturn(true).when(mKeyguardManager).checkInitialLockMethodUsage();
+        doReturn(true).when(mKeyguardManager).isValidLockPasswordComplexity(PASSWORD_LOCK_TYPE,
+                PASSWORD.getBytes(),
+                MEDIUM_PASSWORD_COMPLEXITY);
+        mKeyguardManager.setLock(PASSWORD_LOCK_TYPE,
+                PASSWORD.getBytes(),
+                MEDIUM_PASSWORD_COMPLEXITY);
+
+        boolean correctLockCredentials = mKeyguardManager.checkLock(PASSWORD_LOCK_TYPE,
+                "INCORRECT PASSWORD".getBytes());
+
+        assertFalse(correctLockCredentials);
+
+        verifyDeviceLockedAndRemoveLock();
+    }
+
+    private void verifyDeviceLockedAndRemoveLock() {
+        assertTrue(mKeyguardManager.isDeviceSecure());
+        assertTrue("Failed to remove new password that was set in the test case.",
+                mKeyguardManager.setLock(-1, null, PASSWORD_LOCK_TYPE, PASSWORD.getBytes()));
+    }
+}
diff --git a/core/tests/coretests/src/android/text/TextShaperTest.java b/core/tests/coretests/src/android/text/TextShaperTest.java
index 8237cb0..77b14e6 100644
--- a/core/tests/coretests/src/android/text/TextShaperTest.java
+++ b/core/tests/coretests/src/android/text/TextShaperTest.java
@@ -16,7 +16,10 @@
 
 package android.text;
 
-import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.graphics.fonts.Font;
+import android.graphics.fonts.FontFileUtil;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -31,11 +34,16 @@
     @Test
     public void testFontWithPath() {
         TextPaint p = new TextPaint();
-        p.setFontFeatureSettings("'wght' 900");
+        p.setFontVariationSettings("'wght' 900");
         TextShaper.shapeText("a", 0, 1, TextDirectionHeuristics.LTR, p,
                 (start, end, glyphs, paint) -> {
                 // This test only passes if the font of the Latin font is variable font.
-                assertThat(glyphs.getFont(0).getFile()).isNotNull();
+                Font font = glyphs.getFont(0);
+                String psName = FontFileUtil.getPostScriptName(font.getBuffer(), 0);
+                String message = "psName = " + psName + ", file = " + font.getFile();
+                assertWithMessage(message).that(glyphs.getFont(0).getFile())
+                        .isNotNull();
+
             });
     }
 }
diff --git a/core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java b/core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java
index b3b19ce..851f917 100644
--- a/core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java
+++ b/core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java
@@ -34,8 +34,6 @@
 import android.content.Context;
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
 import android.view.HandwritingInitiator;
 import android.view.InputDevice;
 import android.view.MotionEvent;
@@ -63,14 +61,16 @@
 public class HandwritingInitiatorTest {
     private static final int TOUCH_SLOP = 8;
     private static final long TIMEOUT = ViewConfiguration.getLongPressTimeout();
-    private static final int HANDWRITING_AREA_PADDING_DIP = 20;
+    private static final int HW_BOUNDS_OFFSETS_LEFT_PX = 10;
+    private static final int HW_BOUNDS_OFFSETS_TOP_PX = 20;
+    private static  final int HW_BOUNDS_OFFSETS_RIGHT_PX = 30;
+    private static final int HW_BOUNDS_OFFSETS_BOTTOM_PX = 40;
 
     private static final Rect sHwArea = new Rect(100, 200, 500, 500);
 
     private HandwritingInitiator mHandwritingInitiator;
     private View mTestView;
     private Context mContext;
-    private int mHandwritingAreaPaddingPx;
 
     @Before
     public void setup() {
@@ -79,17 +79,15 @@
         final ViewConfiguration viewConfiguration = mock(ViewConfiguration.class);
         when(viewConfiguration.getScaledTouchSlop()).thenReturn(TOUCH_SLOP);
 
-
-        final DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
         InputMethodManager inputMethodManager = mContext.getSystemService(InputMethodManager.class);
-        mHandwritingInitiator = spy(new HandwritingInitiator(viewConfiguration, inputMethodManager,
-                displayMetrics));
+        mHandwritingInitiator =
+                spy(new HandwritingInitiator(viewConfiguration, inputMethodManager));
 
-        mHandwritingAreaPaddingPx = Math.round(TypedValue.applyDimension(
-                TypedValue.COMPLEX_UNIT_DIP,
-                HANDWRITING_AREA_PADDING_DIP,
-                displayMetrics));
-        mTestView = createView(sHwArea, true);
+        mTestView = createView(sHwArea, true,
+                HW_BOUNDS_OFFSETS_LEFT_PX,
+                HW_BOUNDS_OFFSETS_TOP_PX,
+                HW_BOUNDS_OFFSETS_RIGHT_PX,
+                HW_BOUNDS_OFFSETS_BOTTOM_PX);
         mHandwritingInitiator.updateHandwritingAreasForView(mTestView);
     }
 
@@ -140,8 +138,8 @@
     @Test
     public void onTouchEvent_startHandwriting_when_stylusMove_withinExtendedHWArea() {
         mHandwritingInitiator.onInputConnectionCreated(mTestView);
-        final int x1 = sHwArea.left - mHandwritingAreaPaddingPx / 2;
-        final int y1 = sHwArea.top - mHandwritingAreaPaddingPx / 2;
+        final int x1 = sHwArea.left - HW_BOUNDS_OFFSETS_LEFT_PX / 2;
+        final int y1 = sHwArea.top - HW_BOUNDS_OFFSETS_TOP_PX / 2;
         MotionEvent stylusEvent1 = createStylusEvent(ACTION_DOWN, x1, y1, 0);
         mHandwritingInitiator.onTouchEvent(stylusEvent1);
 
@@ -175,8 +173,8 @@
 
     @Test
     public void onTouchEvent_startHandwriting_inputConnectionBuilt_stylusMoveInExtendedHWArea() {
-        final int x1 = sHwArea.right + mHandwritingAreaPaddingPx / 2;
-        final int y1 = sHwArea.bottom + mHandwritingAreaPaddingPx / 2;
+        final int x1 = sHwArea.right + HW_BOUNDS_OFFSETS_RIGHT_PX / 2;
+        final int y1 = sHwArea.bottom + HW_BOUNDS_OFFSETS_BOTTOM_PX / 2;
         MotionEvent stylusEvent1 = createStylusEvent(ACTION_DOWN, x1, y1, 0);
         mHandwritingInitiator.onTouchEvent(stylusEvent1);
 
@@ -261,8 +259,8 @@
 
     @Test
     public void onTouchEvent_focusView_stylusMoveOnce_withinExtendedHWArea() {
-        final int x1 = sHwArea.left - mHandwritingAreaPaddingPx / 2;
-        final int y1 = sHwArea.top - mHandwritingAreaPaddingPx / 2;
+        final int x1 = sHwArea.left - HW_BOUNDS_OFFSETS_LEFT_PX / 2;
+        final int y1 = sHwArea.top - HW_BOUNDS_OFFSETS_TOP_PX / 2;
         MotionEvent stylusEvent1 = createStylusEvent(ACTION_DOWN, x1, y1, 0);
         mHandwritingInitiator.onTouchEvent(stylusEvent1);
 
diff --git a/core/tests/coretests/src/android/view/stylus/HandwritingTestUtil.java b/core/tests/coretests/src/android/view/stylus/HandwritingTestUtil.java
index 6daf880..e6e50e9 100644
--- a/core/tests/coretests/src/android/view/stylus/HandwritingTestUtil.java
+++ b/core/tests/coretests/src/android/view/stylus/HandwritingTestUtil.java
@@ -33,6 +33,12 @@
     }
 
     public static View createView(Rect handwritingArea, boolean autoHandwritingEnabled) {
+        return createView(handwritingArea, autoHandwritingEnabled, 0, 0, 0, 0);
+    }
+
+    public static View createView(Rect handwritingArea, boolean autoHandwritingEnabled,
+            float handwritingBoundsOffsetLeft, float handwritingBoundsOffsetTop,
+            float handwritingBoundsOffsetRight, float handwritingBoundsOffsetBottom) {
         final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
         final Context context = instrumentation.getTargetContext();
         // mock a parent so that HandwritingInitiator can get
@@ -52,6 +58,10 @@
         when(view.isAttachedToWindow()).thenReturn(true);
         when(view.isAggregatedVisible()).thenReturn(true);
         when(view.getHandwritingArea()).thenReturn(handwritingArea);
+        when(view.getHandwritingBoundsOffsetLeft()).thenReturn(handwritingBoundsOffsetLeft);
+        when(view.getHandwritingBoundsOffsetTop()).thenReturn(handwritingBoundsOffsetTop);
+        when(view.getHandwritingBoundsOffsetRight()).thenReturn(handwritingBoundsOffsetRight);
+        when(view.getHandwritingBoundsOffsetBottom()).thenReturn(handwritingBoundsOffsetBottom);
         view.setAutoHandwritingEnabled(autoHandwritingEnabled);
         parent.addView(view);
         return view;
diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java
index b04b826..a76d74e 100644
--- a/graphics/java/android/graphics/drawable/Icon.java
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -128,6 +128,7 @@
     // TYPE_RESOURCE: Resources
     // TYPE_DATA: DataBytes
     private Object          mObj1;
+    private boolean mCachedAshmem = false;
 
     // TYPE_RESOURCE: package name
     // TYPE_URI: uri string
@@ -156,6 +157,8 @@
     /**
      * @return The {@link android.graphics.Bitmap} held by this {@link #TYPE_BITMAP} or
      * {@link #TYPE_ADAPTIVE_BITMAP} Icon.
+     *
+     * Note that this will always return an immutable Bitmap.
      * @hide
      */
     @UnsupportedAppUsage
@@ -166,8 +169,20 @@
         return (Bitmap) mObj1;
     }
 
+    /**
+     * Sets the Icon's contents to a particular Bitmap. Note that this may make a copy of the Bitmap
+     * if the supplied Bitmap is mutable. In that case, the value returned by getBitmap() may not
+     * equal the Bitmap passed to setBitmap().
+     *
+     * @hide
+     */
     private void setBitmap(Bitmap b) {
-        mObj1 = b;
+        if (b.isMutable()) {
+            mObj1 = b.copy(b.getConfig(), false);
+        } else {
+            mObj1 = b;
+        }
+        mCachedAshmem = false;
     }
 
     /**
@@ -488,6 +503,7 @@
             getBitmap().getAllocationByteCount() >= MIN_ASHMEM_ICON_SIZE) {
             setBitmap(getBitmap().asShared());
         }
+        mCachedAshmem = true;
     }
 
     /**
@@ -913,7 +929,10 @@
         switch (mType) {
             case TYPE_BITMAP:
             case TYPE_ADAPTIVE_BITMAP:
-                final Bitmap bits = getBitmap();
+                if (!mCachedAshmem) {
+                    mObj1 = ((Bitmap) mObj1).asShared();
+                    mCachedAshmem = true;
+                }
                 getBitmap().writeToParcel(dest, flags);
                 break;
             case TYPE_RESOURCE:
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index 9f33cbc..2328f76 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -112,9 +112,10 @@
      */
     public void startActivityToSide(@NonNull Activity launchingActivity, @NonNull Intent intent,
             @Nullable Bundle options, @NonNull SplitRule sideRule,
-            @Nullable Consumer<Exception> failureCallback) {
+            @Nullable Consumer<Exception> failureCallback, boolean isPlaceholder) {
         try {
-            mPresenter.startActivityToSide(launchingActivity, intent, options, sideRule);
+            mPresenter.startActivityToSide(launchingActivity, intent, options, sideRule,
+                    isPlaceholder);
         } catch (Exception e) {
             if (failureCallback != null) {
                 failureCallback.accept(e);
@@ -710,8 +711,8 @@
         }
 
         // TODO(b/190433398): Handle failed request
-        startActivityToSide(activity, placeholderRule.getPlaceholderIntent(), null,
-                placeholderRule, null);
+        startActivityToSide(activity, placeholderRule.getPlaceholderIntent(), null /* options */,
+                placeholderRule, null /* failureCallback */, true /* isPlaceholder */);
         return true;
     }
 
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
index 716a087..ee5a322 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
@@ -217,12 +217,13 @@
      * @param launchingActivity An activity that should be in the primary container. If it is not
      *                          currently in an existing container, a new one will be created and
      *                          the activity will be re-parented to it.
-     * @param activityIntent The intent to start the new activity.
-     * @param activityOptions The options to apply to new activity start.
-     * @param rule The split rule to be applied to the container.
+     * @param activityIntent    The intent to start the new activity.
+     * @param activityOptions   The options to apply to new activity start.
+     * @param rule              The split rule to be applied to the container.
+     * @param isPlaceholder     Whether the launch is a placeholder.
      */
     void startActivityToSide(@NonNull Activity launchingActivity, @NonNull Intent activityIntent,
-            @Nullable Bundle activityOptions, @NonNull SplitRule rule) {
+            @Nullable Bundle activityOptions, @NonNull SplitRule rule, boolean isPlaceholder) {
         final Rect parentBounds = getParentContainerBounds(launchingActivity);
         final Rect primaryRectBounds = getBoundsForPosition(POSITION_START, parentBounds, rule,
                 isLtr(launchingActivity, rule));
@@ -244,6 +245,10 @@
         startActivityToSide(wct, primaryContainer.getTaskFragmentToken(), primaryRectBounds,
                 launchingActivity, secondaryContainer.getTaskFragmentToken(), secondaryRectBounds,
                 activityIntent, activityOptions, rule);
+        if (isPlaceholder) {
+            // When placeholder is launched in split, we should keep the focus on the primary.
+            wct.requestFocusOnTaskFragment(primaryContainer.getTaskFragmentToken());
+        }
         applyTransaction(wct);
 
         primaryContainer.setLastRequestedBounds(primaryRectBounds);
@@ -272,14 +277,21 @@
                 isLtr);
         final Rect secondaryRectBounds = getBoundsForPosition(POSITION_END, parentBounds, rule,
                 isLtr);
+        final TaskFragmentContainer secondaryContainer = splitContainer.getSecondaryContainer();
+        // Whether the placeholder is becoming side-by-side with the primary from fullscreen.
+        final boolean isPlaceholderBecomingSplit = splitContainer.isPlaceholderContainer()
+                && secondaryContainer.areLastRequestedBoundsEqual(null /* bounds */)
+                && !secondaryRectBounds.isEmpty();
 
         // If the task fragments are not registered yet, the positions will be updated after they
         // are created again.
         resizeTaskFragmentIfRegistered(wct, primaryContainer, primaryRectBounds);
-        final TaskFragmentContainer secondaryContainer = splitContainer.getSecondaryContainer();
         resizeTaskFragmentIfRegistered(wct, secondaryContainer, secondaryRectBounds);
-
         setAdjacentTaskFragments(wct, primaryContainer, secondaryContainer, rule);
+        if (isPlaceholderBecomingSplit) {
+            // When placeholder is shown in split, we should keep the focus on the primary.
+            wct.requestFocusOnTaskFragment(primaryContainer.getTaskFragmentToken());
+        }
     }
 
     private void setAdjacentTaskFragments(@NonNull WindowContainerTransaction wct,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
index cfd0624..ced36a7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
@@ -211,7 +211,8 @@
         } else if (action == MotionEvent.ACTION_MOVE) {
             onMove(event, swipeEdge);
         } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
-            ProtoLog.d(WM_SHELL_BACK_PREVIEW, "Finishing gesture with event: %s", event);
+            ProtoLog.d(WM_SHELL_BACK_PREVIEW,
+                    "Finishing gesture with event action: %d", action);
             onGestureFinished();
         }
     }
diff --git a/core/java/com/android/internal/policy/KidsModeSettingsObserver.java b/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeSettingsObserver.java
similarity index 98%
rename from core/java/com/android/internal/policy/KidsModeSettingsObserver.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeSettingsObserver.java
index 8a1d407..f8f9d6b 100644
--- a/core/java/com/android/internal/policy/KidsModeSettingsObserver.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeSettingsObserver.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.policy;
+package com.android.wm.shell.kidsmode;
 
 import android.content.ContentResolver;
 import android.content.Context;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java
index 2868152..dc70358 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java
@@ -40,7 +40,6 @@
 import androidx.annotation.NonNull;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.policy.KidsModeSettingsObserver;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayInsetsController;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
index 5d17f85b..195923c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
@@ -225,6 +225,12 @@
         // For transition that we don't animate, but contains the PIP leash, we need to update the
         // PIP surface, otherwise it will be reset after the transition.
         if (currentPipTaskChange != null) {
+            // Set the "end" bounds of pip. The default setup uses the start bounds. Since this is
+            // changing the *finish*Transaction, we need to use the end bounds. This will also
+            // make sure that the fade-in animation (below) uses the end bounds as well.
+            if (!currentPipTaskChange.getEndAbsBounds().isEmpty()) {
+                mPipBoundsState.setBounds(currentPipTaskChange.getEndAbsBounds());
+            }
             updatePipForUnhandledTransition(currentPipTaskChange, startTransaction,
                     finishTransaction);
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt
index 09d202a..07dccd5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt
@@ -131,10 +131,10 @@
 
         val pipSizeWithAllDecors = addDecors(pipSize)
         val pipAnchorBoundsWithAllDecors =
-                getNormalPipAnchorBounds(pipSizeWithAllDecors, transformedMovementBounds)
+            getNormalPipAnchorBounds(pipSizeWithAllDecors, transformedMovementBounds)
 
         val pipAnchorBoundsWithPermanentDecors =
-                removeTemporaryDecorsTransformed(pipAnchorBoundsWithAllDecors)
+            removeTemporaryDecorsTransformed(pipAnchorBoundsWithAllDecors)
         val result = calculatePipPositionTransformed(
             pipAnchorBoundsWithPermanentDecors,
             transformedRestrictedAreas,
@@ -150,7 +150,7 @@
         return Placement(
             pipBounds,
             anchorBounds,
-            getStashType(pipBounds, movementBounds),
+            getStashType(pipBounds, unstashedDestBounds),
             unstashedDestBounds,
             result.unstashTime
         )
@@ -185,7 +185,10 @@
         restrictedAreas: Set<Rect>,
         unrestrictedAreas: Set<Rect>
     ): Placement {
-        if (restrictedAreas.isEmpty() && unrestrictedAreas.isEmpty()) {
+        // If PiP is not covered by any keep clear areas, we can leave it at the anchor bounds
+        val keepClearAreas = restrictedAreas + unrestrictedAreas
+        if (keepClearAreas.none { it.intersects(pipAnchorBounds) }) {
+            lastAreasOverlappingUnstashPosition = emptySet()
             return Placement(pipAnchorBounds, pipAnchorBounds)
         }
 
@@ -204,9 +207,8 @@
                 ?: findFreeMovePosition(pipAnchorBounds, emptySet(), unrestrictedAreas)
                 ?: pipAnchorBounds
 
-        val keepClearAreas = restrictedAreas + unrestrictedAreas
         val areasOverlappingUnstashPosition =
-            keepClearAreas.filter { Rect.intersects(it, unstashBounds) }.toSet()
+            keepClearAreas.filterTo(mutableSetOf()) { it.intersects(unstashBounds) }
         val areasOverlappingUnstashPositionChanged =
             !lastAreasOverlappingUnstashPosition.containsAll(areasOverlappingUnstashPosition)
         lastAreasOverlappingUnstashPosition = areasOverlappingUnstashPosition
@@ -228,19 +230,22 @@
         return Placement(
             stashedBounds,
             pipAnchorBounds,
-            getStashType(stashedBounds, transformedMovementBounds),
+            getStashType(stashedBounds, unstashBounds),
             unstashBounds,
             unstashTime
         )
     }
 
     @PipBoundsState.StashType
-    private fun getStashType(stashedBounds: Rect, movementBounds: Rect): Int {
+    private fun getStashType(stashedBounds: Rect, unstashedDestBounds: Rect?): Int {
+        if (unstashedDestBounds == null) {
+            return STASH_TYPE_NONE
+        }
         return when {
-            stashedBounds.left < movementBounds.left -> STASH_TYPE_LEFT
-            stashedBounds.right > movementBounds.right -> STASH_TYPE_RIGHT
-            stashedBounds.top < movementBounds.top -> STASH_TYPE_TOP
-            stashedBounds.bottom > movementBounds.bottom -> STASH_TYPE_BOTTOM
+            stashedBounds.left < unstashedDestBounds.left -> STASH_TYPE_LEFT
+            stashedBounds.right > unstashedDestBounds.right -> STASH_TYPE_RIGHT
+            stashedBounds.top < unstashedDestBounds.top -> STASH_TYPE_TOP
+            stashedBounds.bottom > unstashedDestBounds.bottom -> STASH_TYPE_BOTTOM
             else -> STASH_TYPE_NONE
         }
     }
@@ -368,57 +373,69 @@
         val areasOverlappingPipX = keepClearAreas.filter { it.intersectsX(bounds) }
         val areasOverlappingPipY = keepClearAreas.filter { it.intersectsY(bounds) }
 
-        if (screenBounds.bottom - bounds.bottom <= bounds.top - screenBounds.top) {
-            val fullStashTop = screenBounds.bottom - stashOffset
+        if (areasOverlappingPipX.isNotEmpty()) {
+            if (screenBounds.bottom - bounds.bottom <= bounds.top - screenBounds.top) {
+                val fullStashTop = screenBounds.bottom - stashOffset
 
-            val maxBottom = areasOverlappingPipX.maxByOrNull { it.bottom }!!.bottom
-            val partialStashTop = maxBottom + pipAreaPadding
+                val maxBottom = areasOverlappingPipX.maxByOrNull { it.bottom }!!.bottom
+                val partialStashTop = maxBottom + pipAreaPadding
 
-            val downPosition = Rect(bounds)
-            downPosition.offsetTo(bounds.left, min(fullStashTop, partialStashTop))
-            stashCandidates += downPosition
-        }
-        if (screenBounds.bottom - bounds.bottom >= bounds.top - screenBounds.top) {
-            val fullStashBottom = screenBounds.top - bounds.height() + stashOffset
+                val newTop = min(fullStashTop, partialStashTop)
+                if (newTop > bounds.top) {
+                    val downPosition = Rect(bounds)
+                    downPosition.offsetTo(bounds.left, newTop)
+                    stashCandidates += downPosition
+                }
+            }
+            if (screenBounds.bottom - bounds.bottom >= bounds.top - screenBounds.top) {
+                val fullStashBottom = screenBounds.top - bounds.height() + stashOffset
 
-            val minTop = areasOverlappingPipX.minByOrNull { it.top }!!.top
-            val partialStashBottom = minTop - bounds.height() - pipAreaPadding
+                val minTop = areasOverlappingPipX.minByOrNull { it.top }!!.top
+                val partialStashBottom = minTop - bounds.height() - pipAreaPadding
 
-            val upPosition = Rect(bounds)
-            upPosition.offsetTo(bounds.left, max(fullStashBottom, partialStashBottom))
-            stashCandidates += upPosition
+                val newTop = max(fullStashBottom, partialStashBottom)
+                if (newTop < bounds.top) {
+                    val upPosition = Rect(bounds)
+                    upPosition.offsetTo(bounds.left, newTop)
+                    stashCandidates += upPosition
+                }
+            }
         }
 
-        if (screenBounds.right - bounds.right <= bounds.left - screenBounds.left) {
-            val fullStashRight = screenBounds.right - stashOffset
+        if (areasOverlappingPipY.isNotEmpty()) {
+            if (screenBounds.right - bounds.right <= bounds.left - screenBounds.left) {
+                val fullStashRight = screenBounds.right - stashOffset
 
-            val maxRight = areasOverlappingPipY.maxByOrNull { it.right }!!.right
-            val partialStashRight = maxRight + pipAreaPadding
+                val maxRight = areasOverlappingPipY.maxByOrNull { it.right }!!.right
+                val partialStashRight = maxRight + pipAreaPadding
 
-            val rightPosition = Rect(bounds)
-            rightPosition.offsetTo(min(fullStashRight, partialStashRight), bounds.top)
-            stashCandidates += rightPosition
-        }
-        if (screenBounds.right - bounds.right >= bounds.left - screenBounds.left) {
-            val fullStashLeft = screenBounds.left - bounds.width() + stashOffset
+                val newLeft = min(fullStashRight, partialStashRight)
+                if (newLeft > bounds.left) {
+                    val rightPosition = Rect(bounds)
+                    rightPosition.offsetTo(newLeft, bounds.top)
+                    stashCandidates += rightPosition
+                }
+            }
+            if (screenBounds.right - bounds.right >= bounds.left - screenBounds.left) {
+                val fullStashLeft = screenBounds.left - bounds.width() + stashOffset
 
-            val minLeft = areasOverlappingPipY.minByOrNull { it.left }!!.left
-            val partialStashLeft = minLeft - bounds.width() - pipAreaPadding
+                val minLeft = areasOverlappingPipY.minByOrNull { it.left }!!.left
+                val partialStashLeft = minLeft - bounds.width() - pipAreaPadding
 
-            val leftPosition = Rect(bounds)
-            leftPosition.offsetTo(max(fullStashLeft, partialStashLeft), bounds.top)
-            stashCandidates += leftPosition
-        }
-
-        if (stashCandidates.isEmpty()) {
-            return bounds
+                val newLeft = max(fullStashLeft, partialStashLeft)
+                if (newLeft < bounds.left) {
+                    val leftPosition = Rect(bounds)
+                    leftPosition.offsetTo(newLeft, bounds.top)
+                    stashCandidates += leftPosition
+                }
+            }
         }
 
         return stashCandidates.minByOrNull {
             val dx = abs(it.left - bounds.left)
             val dy = abs(it.top - bounds.top)
             return@minByOrNull dx + dy
-        }!!
+        } ?: bounds
     }
 
     /**
@@ -768,7 +785,7 @@
     }
 
     /**
-     * Adds space around [size] to leave space for decorations that will be drawn around the pip
+     * Adds space around [size] to leave space for decorations that will be drawn around the PiP
      */
     private fun addDecors(size: Size): Size {
         val bounds = Rect(0, 0, size.width, size.height)
@@ -779,7 +796,7 @@
     }
 
     /**
-     * Removes the space that was reserved for permanent decorations around the pip
+     * Removes the space that was reserved for permanent decorations around the PiP
      * @param bounds the bounds (in screen space) to remove the insets from
      */
     private fun removePermanentDecors(bounds: Rect): Rect {
@@ -789,19 +806,20 @@
     }
 
     /**
-     * Removes the space that was reserved for temporary decorations around the pip
+     * Removes the space that was reserved for temporary decorations around the PiP
      * @param bounds the bounds (in base case) to remove the insets from
      */
     private fun removeTemporaryDecorsTransformed(bounds: Rect): Rect {
         if (pipTemporaryDecorInsets == Insets.NONE) return bounds
 
-        var reverseInsets = Insets.subtract(Insets.NONE, pipTemporaryDecorInsets)
-        var boundsInScreenSpace = fromTransformedSpace(bounds)
+        val reverseInsets = Insets.subtract(Insets.NONE, pipTemporaryDecorInsets)
+        val boundsInScreenSpace = fromTransformedSpace(bounds)
         boundsInScreenSpace.inset(reverseInsets)
         return toTransformedSpace(boundsInScreenSpace)
     }
 
     private fun Rect.offsetCopy(dx: Int, dy: Int) = Rect(this).apply { offset(dx, dy) }
-    private fun Rect.intersectsY(other: Rect) = bottom >= other.top && top <= other.bottom
     private fun Rect.intersectsX(other: Rect) = right >= other.left && left <= other.right
+    private fun Rect.intersectsY(other: Rect) = bottom >= other.top && top <= other.bottom
+    private fun Rect.intersects(other: Rect) = intersectsX(other) && intersectsY(other)
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
index c1ee1a7..4618fb3 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
@@ -27,12 +27,10 @@
 import com.android.server.wm.flicker.dsl.FlickerBuilder
 import com.android.server.wm.flicker.entireScreenCovered
 import com.android.server.wm.flicker.helpers.WindowUtils
-import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
 import com.android.server.wm.flicker.helpers.setRotation
 import com.android.server.wm.flicker.navBarLayerRotatesAndScales
 import com.android.server.wm.flicker.statusBarLayerRotatesScales
 import com.android.wm.shell.flicker.helpers.FixedAppHelper
-import org.junit.Assume
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -141,14 +139,6 @@
     @Presubmit
     @Test
     fun pipLayerRotates_StartingBounds() {
-        Assume.assumeFalse(isShellTransitionsEnabled)
-        pipLayerRotates_StartingBounds_internal()
-    }
-
-    @FlakyTest(bugId = 228024285)
-    @Test
-    fun pipLayerRotates_StartingBounds_ShellTransit() {
-        Assume.assumeTrue(isShellTransitionsEnabled)
         pipLayerRotates_StartingBounds_internal()
     }
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java
index 5526d5b..440a6f8 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java
@@ -44,7 +44,6 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
-import com.android.internal.policy.KidsModeSettingsObserver;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayInsetsController;
 import com.android.wm.shell.common.ShellExecutor;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithmTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithmTest.kt
index 9919214..46f388d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithmTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithmTest.kt
@@ -25,6 +25,7 @@
 import com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_NONE
 import com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_BOTTOM
 import com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_RIGHT
+import com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_TOP
 import com.android.wm.shell.pip.tv.TvPipKeepClearAlgorithm.Placement
 import org.junit.Before
 import org.junit.Test
@@ -434,6 +435,28 @@
     }
 
     @Test
+    fun test_ExpandedPiPHeightExceedsMovementBounds_AtAnchor() {
+        gravity = Gravity.RIGHT or Gravity.CENTER_VERTICAL
+        pipSize = Size(DEFAULT_PIP_SIZE.width, SCREEN_SIZE.height)
+        testAnchorPosition()
+    }
+
+    @Test
+    fun test_ExpandedPiPHeightExceedsMovementBounds_BottomBar_StashedUp() {
+        gravity = Gravity.RIGHT or Gravity.CENTER_VERTICAL
+        pipSize = Size(DEFAULT_PIP_SIZE.width, SCREEN_SIZE.height)
+        val bottomBar = makeBottomBar(96)
+        unrestrictedAreas.add(bottomBar)
+
+        val expectedBounds = getExpectedAnchorBounds()
+        expectedBounds.offset(0, -bottomBar.height() - PADDING)
+        val placement = getActualPlacement()
+        assertEquals(expectedBounds, placement.bounds)
+        assertEquals(STASH_TYPE_TOP, placement.stashType)
+        assertEquals(getExpectedAnchorBounds(), placement.unstashDestinationBounds)
+    }
+
+    @Test
     fun test_PipInsets() {
         val permInsets = Insets.of(-1, -2, -3, -4)
         algorithm.setPipPermanentDecorInsets(permInsets)
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index da04762..bdc48e9 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -16,7 +16,6 @@
 
 #pragma once
 
-#include <SkCamera.h>
 #include <SkMatrix.h>
 
 #include <utils/LinearAllocator.h>
diff --git a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
index 7cfccb5..11977bd 100644
--- a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
+++ b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
@@ -19,8 +19,15 @@
 #include "SkiaDisplayList.h"
 #include "LightingInfo.h"
 
+#include <SkColor.h>
+#include <SkMatrix.h>
+#include <SkPath.h>
 #include <SkPathOps.h>
+#include <SkPoint3.h>
+#include <SkRect.h>
+#include <SkScalar.h>
 #include <SkShadowUtils.h>
+#include <include/private/SkShadowFlags.h>
 
 namespace android {
 namespace uirenderer {
diff --git a/media/jni/audioeffect/Visualizer.cpp b/media/jni/audioeffect/Visualizer.cpp
index 193a5d4..d0f1ec6 100644
--- a/media/jni/audioeffect/Visualizer.cpp
+++ b/media/jni/audioeffect/Visualizer.cpp
@@ -60,6 +60,7 @@
             SL_IID_VISUALIZATION, nullptr, priority, cbf, user, sessionId, io, device, probe);
     if (status == NO_ERROR || status == ALREADY_EXISTS) {
         initCaptureSize();
+        initSampleRate();
     }
     return status;
 }
@@ -413,6 +414,16 @@
     return size;
 }
 
+void Visualizer::initSampleRate()
+{
+    audio_config_base_t inputConfig, outputConfig;
+    status_t status = getConfigs(&inputConfig, &outputConfig);
+    if (status == NO_ERROR) {
+        mSampleRate = outputConfig.sample_rate * 1000;
+    }
+    ALOGV("%s sample rate %d status %d", __func__, mSampleRate, status);
+}
+
 void Visualizer::controlStatusChanged(bool controlGranted) {
     if (controlGranted) {
         // this Visualizer instance regained control of the effect, reset the scaling mode
diff --git a/media/jni/audioeffect/Visualizer.h b/media/jni/audioeffect/Visualizer.h
index c402c10..3d5d74a 100644
--- a/media/jni/audioeffect/Visualizer.h
+++ b/media/jni/audioeffect/Visualizer.h
@@ -170,6 +170,7 @@
     status_t doFft(uint8_t *fft, uint8_t *waveform);
     void periodicCapture();
     uint32_t initCaptureSize();
+    void initSampleRate();
 
     Mutex mCaptureLock;
     uint32_t mCaptureRate = CAPTURE_RATE_DEF;
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 061b1ae..6188dc1 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -95,7 +95,7 @@
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Адключэнне..."</string>
     <string name="bluetooth_connecting" msgid="5871702668260192755">"Злучэнне..."</string>
     <string name="bluetooth_connected" msgid="8065345572198502293">"Падключана прылада <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_pairing" msgid="4269046942588193600">"Спарванне..."</string>
+    <string name="bluetooth_pairing" msgid="4269046942588193600">"Спалучэнне..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Падключана прылада <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (без званкоў)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Падключана прылада <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (без аўдыя)"</string>
     <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Падключана прылада <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (без паведамленняў)"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 8dcaa40..dc74450 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -664,7 +664,7 @@
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Fizička tastatura"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Odaberite raspored tastature"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Zadano"</string>
-    <string name="turn_screen_on_title" msgid="3266937298097573424">"Uključi ekran"</string>
+    <string name="turn_screen_on_title" msgid="3266937298097573424">"Uključivanje ekrana"</string>
     <string name="allow_turn_screen_on" msgid="6194845766392742639">"Dozvolite uključivanje ekrana"</string>
     <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Dozvolite aplikaciji da uključi ekran. Ako se odobri, aplikacija može uključiti ekran bilo kada bez vaše izričite namjere."</string>
     <string name="bt_le_audio_scan_qr_code" msgid="3521809854780392679">"Skenirajte QR kôd"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 17e7ce3a..a0ce5e0 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -255,12 +255,12 @@
     <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Párovací kód Wi‑Fi"</string>
     <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"Spárování se nezdařilo"</string>
     <string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"Zkontrolujte, zda je zařízení připojeno ke stejné síti."</string>
-    <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Spárovat zařízení přes Wi-Fi naskenováním QR kódu"</string>
+    <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Spárujte zařízení přes Wi-Fi naskenováním QR kódu"</string>
     <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Párování zařízení…"</string>
     <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Spárování zařízení se nezdařilo. Buď byl QR kód chybný, nebo zařízení není připojeno ke stejné síti."</string>
     <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP adresa a port"</string>
     <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Naskenování QR kódu"</string>
-    <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Spárovat zařízení přes Wi-Fi naskenováním QR kódu"</string>
+    <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Spárujte zařízení přes Wi-Fi naskenováním QR kódu"</string>
     <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Připojte se k síti Wi-Fi"</string>
     <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, ladění, vývoj"</string>
     <string name="bugreport_in_power" msgid="8664089072534638709">"Zástupce hlášení chyb"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index c28a459..ba723ac 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -529,7 +529,7 @@
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmas y recordatorios"</string>
     <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Permitir la programación de alarmas y recordatorios"</string>
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmas y recordatorios"</string>
-    <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permite que esta aplicación programe alarmas y otras acciones que se llevan a cabo a una hora determinada. Esto hace que la aplicación siga activa en segundo plano, lo que puede usar más batería.\n\nSi este permiso está desactivado, no funcionarán las alarmas ni los eventos que se activan a una hora determinada que programe esta aplicación."</string>
+    <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permite que esta aplicación programe alarmas y otras acciones que se llevan a cabo a una hora determinada. Esto hace que la aplicación pueda seguir activa en segundo plano, lo que puede usar más batería.\n\nSi este permiso está desactivado, no funcionarán las alarmas ni los eventos que se activan a una hora determinada que programe esta aplicación."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programar, alarma, recordatorio, reloj"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activar"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activar el modo No molestar"</string>
diff --git a/packages/SettingsLib/res/values-eu/arrays.xml b/packages/SettingsLib/res/values-eu/arrays.xml
index 23bb76d..cc47e27 100644
--- a/packages/SettingsLib/res/values-eu/arrays.xml
+++ b/packages/SettingsLib/res/values-eu/arrays.xml
@@ -192,7 +192,7 @@
   <string-array name="window_animation_scale_entries">
     <item msgid="2675263395797191850">"Animazioa desaktibatuta"</item>
     <item msgid="5790132543372767872">"Animazio-eskala: 0,5x"</item>
-    <item msgid="2529692189302148746">"Animazio-eskala: 1x"</item>
+    <item msgid="2529692189302148746">"Animazio-eskala: 1×"</item>
     <item msgid="8072785072237082286">"Animazio-eskala: 1,5x"</item>
     <item msgid="3531560925718232560">"Animazio-eskala 2x"</item>
     <item msgid="4542853094898215187">"Animazio-eskala: 5x"</item>
@@ -201,7 +201,7 @@
   <string-array name="transition_animation_scale_entries">
     <item msgid="3376676813923486384">"Animazioa desaktibatuta"</item>
     <item msgid="753422683600269114">"Animazio-eskala: 0,5x"</item>
-    <item msgid="3695427132155563489">"Animazio-eskala: 1x"</item>
+    <item msgid="3695427132155563489">"Animazio-eskala: 1×"</item>
     <item msgid="9032615844198098981">"Animazio-eskala: 1,5x"</item>
     <item msgid="8473868962499332073">"Animazio-eskala: 2x"</item>
     <item msgid="4403482320438668316">"Animazio-eskala: 5x"</item>
@@ -210,7 +210,7 @@
   <string-array name="animator_duration_scale_entries">
     <item msgid="6416998593844817378">"Animazioa desaktibatuta"</item>
     <item msgid="875345630014338616">"Animazio-eskala: 0,5x"</item>
-    <item msgid="2753729231187104962">"Animazio-eskala: 1x"</item>
+    <item msgid="2753729231187104962">"Animazio-eskala: 1×"</item>
     <item msgid="1368370459723665338">"Animazio-eskala: 1,5x"</item>
     <item msgid="5768005350534383389">"Animazio-eskala: 2x"</item>
     <item msgid="3728265127284005444">"Animazio-eskala: 5x"</item>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 61b9e03..7597147 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -151,7 +151,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Utzi"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Gailuak parekatzen badituzu, batetik besteko kontaktuak eta deien historia atzitu ahal izango dituzu."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Ezin izan da <xliff:g id="DEVICE_NAME">%1$s</xliff:g> gailuarekin parekatu."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Ezin izan da <xliff:g id="DEVICE_NAME">%1$s</xliff:g> gailuarekin parekatu PIN edo pasakode okerra idatzi delako."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Ezin izan da parekatu <xliff:g id="DEVICE_NAME">%1$s</xliff:g> gailuarekin, PIN edo pasakode okerra idatzi delako."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Ezin da <xliff:g id="DEVICE_NAME">%1$s</xliff:g> gailuarekin komunikatu."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> gailuak bikotetzea ukatu du."</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Ordenagailua"</string>
@@ -338,7 +338,7 @@
     <string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Egiaztatu USB bidezko aplik."</string>
     <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Egiaztatu ADB/ADT bidez instalatutako aplikazioak portaera kaltegarriak atzemateko"</string>
     <string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Bluetooth bidezko gailuak izenik gabe (MAC helbideak soilik) erakutsiko dira"</string>
-    <string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Bluetooth bidezko bolumen absolutuaren eginbidea desgaitu egiten du urruneko gailuetan arazoak hautematen badira; esaterako, bolumena ozenegia bada edo ezin bada kontrolatu"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Bluetooth bidezko bolumen absolutuaren eginbidea desgaitu egiten du urruneko gailuetan arazoak hautematen badira; esaterako, bolumena ozenegia bada edo kontrolatu ezin bada"</string>
     <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Bluetooth Gabeldorsche eginbide sorta gaitzen du."</string>
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Konexioak hobetzeko eginbidea gaitzen du."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Tokiko terminala"</string>
@@ -630,7 +630,7 @@
     <string name="carrier_network_change_mode" msgid="4257621815706644026">"Operadorearen sarea aldatzen"</string>
     <string name="data_connection_3g" msgid="931852552688157407">"3G"</string>
     <string name="data_connection_edge" msgid="4625509456544797637">"EDGE"</string>
-    <string name="data_connection_cdma" msgid="9098161966701934334">"1X"</string>
+    <string name="data_connection_cdma" msgid="9098161966701934334">"1×"</string>
     <string name="data_connection_gprs" msgid="1251945769006770189">"GPRS"</string>
     <string name="data_connection_3_5g" msgid="4298721462047921400">"H"</string>
     <string name="data_connection_3_5g_plus" msgid="6683055858295918170">"H+"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 34bed45..15a8f3e 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -529,7 +529,7 @@
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"زنگ‌های هشدار و یادآوری‌ها"</string>
     <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"مجاز کردن تنظیم زنگ ساعت و یادآوری"</string>
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"زنگ‌های ساعت و یادآوری‌ها"</string>
-    <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"به این برنامه اجازه می‌دهد زنگ ساعت تنظیم کند و کنش‌های حساس به زمان زمان‌بندی کند. این تنظیم به برنامه اجازه می‌دهد در پس‌زمینه اجرا شود که ممکن است باتری بیشتری مصرف کند.\n\nاگر این اجازه خاموش باشد، زنگ‌های ساعت موجود و رویدادهای مبتنی بر زمان که این برنامه زمان‌بندی کرده است کار نخواهند کرد."</string>
+    <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"به این برنامه اجازه می‌دهد زنگ ساعت تنظیم کند و کنش‌های حساس به زمان را زمان‌بندی کند. این تنظیم به برنامه اجازه می‌دهد در پس‌زمینه اجرا شود که ممکن است باتری بیشتری مصرف کند.\n\nاگر این اجازه خاموش باشد، زنگ‌های ساعت موجود و رویدادهای مبتنی بر زمان که این برنامه زمان‌بندی کرده است کار نخواهند کرد."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"زمان‌بندی، زنگ ساعت، یادآوری، ساعت"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"روشن کردن"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"روشن کردن «مزاحم نشوید»"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 8ca7c42..565439a 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -151,7 +151,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Annuler"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"L\'association vous permet d\'accéder à vos contacts et à l\'historique des appels lorsque vous êtes connecté."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Impossible d\'associer à <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Impossible d\'établir l\'association avec <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. NIP ou d\'une clé d\'accès incorrects."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Impossible d\'établir l\'association avec <xliff:g id="DEVICE_NAME">%1$s</xliff:g> en raison d\'un NIP ou d\'une clé d\'accès incorrects."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Impossible d\'établir la communication avec <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Association refusée par <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Ordinateur"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 69d643c..a1722d7 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -255,12 +255,12 @@
     <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Kôd za uparivanje putem Wi-Fija"</string>
     <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"Uparivanje nije uspjelo"</string>
     <string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"Provjerite je li uređaj povezan na istu mrežu."</string>
-    <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Uparivanje uređaja putem Wi-Fija skeniranjem QR koda"</string>
+    <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Uparite uređaj putem Wi-Fija skeniranjem QR koda"</string>
     <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Uparivanje uređaja…"</string>
     <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Uparivanje uređaja nije uspjelo. QR kôd je neispravan ili uređaj nije povezan na istu mrežu."</string>
     <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP adresa i priključak"</string>
     <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Skenirajte QR kôd"</string>
-    <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Uparivanje uređaja putem Wi-Fija skeniranjem QR koda"</string>
+    <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Uparite uređaj putem Wi-Fija skeniranjem QR koda"</string>
     <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Povežite se s Wifi mrežom"</string>
     <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, otklanjanje pogrešaka, razvoj"</string>
     <string name="bugreport_in_power" msgid="8664089072534638709">"Prečac izvješća o pogreškama"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index d8c49eb..ca77e7a 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -151,7 +151,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Annulla"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"L\'accoppiamento consente l\'accesso ai tuoi contatti e alla cronologia chiamate quando i dispositivi sono connessi."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Impossibile eseguire l\'accoppiamento con <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Impossibile eseguire l\'accoppiamento con <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. La passkey o il PIN sono errati."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Impossibile eseguire l\'accoppiamento con <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. La password o il PIN sono errati."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Impossibile comunicare con <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Accoppiamento rifiutato da <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Computer"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index c42cca6..6f0759d 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -569,8 +569,8 @@
     <string name="user_add_user_item_title" msgid="2394272381086965029">"ユーザー"</string>
     <string name="user_add_profile_item_title" msgid="3111051717414643029">"制限付きプロファイル"</string>
     <string name="user_add_user_title" msgid="5457079143694924885">"新しいユーザーを追加しますか?"</string>
-    <string name="user_add_user_message_long" msgid="1527434966294733380">"追加ユーザーを作成して、このデバイスを他のユーザーと共有できます。各ユーザーは各自のスペースを所有して、アプリや壁紙などのカスタマイズを行うことができます。Wi-Fi など、すべてのユーザーに影響するデバイス設定を変更することもできます。\n\n新しいユーザーを追加したら、そのユーザーは自分のスペースをセットアップする必要があります。\n\nすべてのユーザーは他のユーザーに代わってアプリを更新できます。ユーザー補助機能の設定とサービスは新しいユーザーに適用されないことがあります。"</string>
-    <string name="user_add_user_message_short" msgid="3295959985795716166">"新しいユーザーを追加したら、そのユーザーは自分のスペースをセットアップする必要があります。\n\nすべてのユーザーは他のユーザーに代わってアプリを更新できます。"</string>
+    <string name="user_add_user_message_long" msgid="1527434966294733380">"追加ユーザーを作成して、このデバイスを他のユーザーと共有できます。各ユーザーは各自のスペースを所有して、アプリや壁紙などのカスタマイズを行うことができます。Wi-Fi など、すべてのユーザーに影響するデバイス設定を変更することもできます。\n\n新しく追加したユーザーは各自でスペースをセットアップする必要があります。\n\nすべてのユーザーは他のユーザーに代わってアプリを更新できます。ユーザー補助機能の設定とサービスは新しいユーザーに適用されないことがあります。"</string>
+    <string name="user_add_user_message_short" msgid="3295959985795716166">"新しく追加したユーザーは各自でスペースをセットアップする必要があります。\n\nすべてのユーザーは他のユーザーに代わってアプリを更新できます。"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"ユーザーを今すぐセットアップ"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"ユーザーがデバイスを使って各自のスペースをセットアップできるようにします"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"プロファイルを今すぐセットアップしますか?"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 692d82f..b8e61df 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -489,7 +489,7 @@
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Әкімші басқарады"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Шектелген параметрлер арқылы басқарылады."</string>
     <string name="disabled" msgid="8017887509554714950">"Өшірілген"</string>
-    <string name="external_source_trusted" msgid="1146522036773132905">"Рұқсат етілген"</string>
+    <string name="external_source_trusted" msgid="1146522036773132905">"Рұқсат берілген"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Рұқсат етілмеген"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Белгісіз қолданбаларды орнату"</string>
     <string name="home" msgid="973834627243661438">"Параметрлер негізгі беті"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 5e5221f..9e7a9a3 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -260,7 +260,7 @@
     <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"ಸಾಧನವನ್ನು ಜೋಡಿಸಲು ವಿಫಲವಾಗಿದೆ. QR ಕೋಡ್ ತಪ್ಪಾಗಿದೆ ಅಥವಾ ಸಾಧನವು ಒಂದೇ ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಕನೆಕ್ಟ್ ಆಗಿಲ್ಲ."</string>
     <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP ವಿಳಾಸ ಮತ್ತು ಪೋರ್ಟ್"</string>
     <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR ಕೋಡ್ ಸ್ಕ್ಯಾನ್ ಮಾಡಿ"</string>
-    <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR ಕೋಡ್ ಅನ್ನು ಸ್ಕ್ಯಾನ್ ಮಾಡುವ ಮೂಲಕ ವೈ-ಫೈನಲ್ಲಿ ಸಾಧನವನ್ನು ಜೋಡಿಸಿ"</string>
+    <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR ಕೋಡ್ ಅನ್ನು ಸ್ಕ್ಯಾನ್ ಮಾಡುವ ಮೂಲಕ ವೈ-ಫೈ ಮೂಲಕ ಸಾಧನವನ್ನು ಜೋಡಿಸಿ"</string>
     <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸಂಪರ್ಕಿಸಿ"</string>
     <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, ಡೀಬಗ್, dev"</string>
     <string name="bugreport_in_power" msgid="8664089072534638709">"ಬಗ್ ವರದಿಯ ಶಾರ್ಟ್‌ಕಟ್‌‌"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 9a28691..50ea056 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -95,7 +95,7 @@
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Се исклучува..."</string>
     <string name="bluetooth_connecting" msgid="5871702668260192755">"Се поврзува..."</string>
     <string name="bluetooth_connected" msgid="8065345572198502293">"Поврзан со <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_pairing" msgid="4269046942588193600">"Поврзување..."</string>
+    <string name="bluetooth_pairing" msgid="4269046942588193600">"Се спарува..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Поврзан со <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (без телефон)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Поврзан со <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (без аудиовизуелни содржини)"</string>
     <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Поврзан со <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (без пристап до пораките)"</string>
@@ -255,12 +255,12 @@
     <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Код за спарување преку Wi‑Fi"</string>
     <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"Спарувањето е неуспешно"</string>
     <string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"Погрижете се уредот да биде поврзан на истата мрежа."</string>
-    <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Спарете го уредот преку Wi‑Fi со скенирање QR-код"</string>
-    <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Се спарува уред…"</string>
+    <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Скенирајте QR-код за да го спарите уредот преку Wi‑Fi"</string>
+    <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Се спарува уредот…"</string>
     <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Уредот не успеа да се спари. Или QR-кодот беше погрешен или уредот не е поврзан на истата мрежа."</string>
     <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP-адреса и порта"</string>
     <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Скенирајте QR-код"</string>
-    <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Спарете го уредот преку Wi‑Fi со скенирање QR-код"</string>
+    <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Скенирајте QR-код за да го спарите уредот преку Wi‑Fi"</string>
     <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Поврзете се на Wi-Fi мрежа"</string>
     <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, отстранува грешка, програмер"</string>
     <string name="bugreport_in_power" msgid="8664089072534638709">"Кратенка за извештај за грешка"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 013737c..e016a34 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -554,7 +554,7 @@
     <string name="shared_data_title" msgid="1017034836800864953">"Delte data"</string>
     <string name="shared_data_summary" msgid="5516326713822885652">"Se og endre delte data"</string>
     <string name="shared_data_no_blobs_text" msgid="3108114670341737434">"Det finnes ingen delte data for denne brukeren."</string>
-    <string name="shared_data_query_failure_text" msgid="3489828881998773687">"Det har oppstått en feil ved henting av delte data. Prøv igjen."</string>
+    <string name="shared_data_query_failure_text" msgid="3489828881998773687">"Det har oppstått en feil ved henting av delte data. Prøv på nytt."</string>
     <string name="blob_id_text" msgid="8680078988996308061">"Delt data-ID: <xliff:g id="BLOB_ID">%d</xliff:g>"</string>
     <string name="blob_expires_text" msgid="7882727111491739331">"Utløper <xliff:g id="DATE">%s</xliff:g>"</string>
     <string name="shared_data_delete_failure_text" msgid="3842701391009628947">"Det har oppstått en feil ved sletting av de delte dataene."</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 90fb798..e81f36b 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -256,7 +256,7 @@
     <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"कनेक्ट गर्न सकिएन"</string>
     <string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"यन्त्र उही नेटवर्कमा जोडिएको कुरा सुनिश्चित गर्नुहोस्।"</string>
     <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"QR कोड स्क्यान गरेर Wi‑Fi प्रयोग गरी डिभाइस कनेक्ट गर्नुहोस्"</string>
-    <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"डिभाइस कनेक्ट गर्दै…"</string>
+    <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"डिभाइस कनेक्ट गरिँदै छ…"</string>
     <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"यन्त्रसँग जोडा बनाउन सकिएन। कि त QR कोड गलत छ कि यन्त्र उही नेटवर्कमा जोडिएको छैन।"</string>
     <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP एड्रेस र पोर्ट"</string>
     <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR कोड स्क्यान गर्नुहोस्"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 20fe502..4050a8a 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -312,7 +312,7 @@
     <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Toon opties voor certificering van draadloze weergave"</string>
     <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Verhoog het logniveau voor wifi, toon per SSID RSSI in wifi-kiezer"</string>
     <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Verlaag het batterijverbruik en verbeter de netwerkprestaties"</string>
-    <string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"Als dit aanstaat, kan het MAC-adres van dit apparaat veranderen telkens als het apparaat verbinding maakt met een netwerk waarvoor MAC-herschikking aanstaat."</string>
+    <string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"Als dit aanstaat, kan het MAC-adres van dit apparaat veranderen telkens als het apparaat verbinding maakt met een netwerk waarvoor MAC-herschikking aanstaat"</string>
     <string name="wifi_metered_label" msgid="8737187690304098638">"Met datalimiet"</string>
     <string name="wifi_unmetered_label" msgid="6174142840934095093">"Gratis"</string>
     <string name="select_logd_size_title" msgid="1604578195914595173">"Logger-buffergrootten"</string>
@@ -326,7 +326,7 @@
     <string name="allow_mock_location" msgid="2102650981552527884">"Neplocaties toestaan"</string>
     <string name="allow_mock_location_summary" msgid="179780881081354579">"Neplocaties toestaan"</string>
     <string name="debug_view_attributes" msgid="3539609843984208216">"Inspectie van weergavekenmerk aanzetten"</string>
-    <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"Houd mobiele data altijd actief, ook als wifi actief is (voor sneller schakelen tussen netwerken)."</string>
+    <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"Houd mobiele data altijd actief, ook als wifi actief is (voor sneller schakelen tussen netwerken)"</string>
     <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Gebruik hardwareversnelling voor tethering indien beschikbaar"</string>
     <string name="adb_warning_title" msgid="7708653449506485728">"USB-foutopsporing toestaan?"</string>
     <string name="adb_warning_message" msgid="8145270656419669221">"USB-foutopsporing is alleen bedoeld voor ontwikkeldoeleinden. Het kan worden gebruikt om gegevens te kopiëren tussen je computer en je apparaat, apps zonder melding op je apparaat te installeren en loggegevens te lezen."</string>
@@ -621,8 +621,8 @@
     <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Te veel onjuiste pogingen. Dit werkprofiel en de bijbehorende gegevens worden verwijderd."</string>
     <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Sluiten"</string>
     <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Apparaatstandaard"</string>
-    <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Uitgezet"</string>
-    <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aangezet"</string>
+    <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Uit"</string>
+    <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aan"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Je apparaat moet opnieuw worden opgestart om deze wijziging toe te passen. Start nu opnieuw op of annuleer de wijziging."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Bedrade hoofdtelefoon"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Aan"</string>
diff --git a/packages/SettingsLib/res/values-sl/arrays.xml b/packages/SettingsLib/res/values-sl/arrays.xml
index c16d638..8db3e99 100644
--- a/packages/SettingsLib/res/values-sl/arrays.xml
+++ b/packages/SettingsLib/res/values-sl/arrays.xml
@@ -247,7 +247,7 @@
     <item msgid="5023908510820531131">"Čez <xliff:g id="AS_TYPED_COMMAND">adb shell dumpsys gfxinfo</xliff:g>"</item>
   </string-array>
   <string-array name="debug_hw_overdraw_entries">
-    <item msgid="1968128556747588800">"Izklop"</item>
+    <item msgid="1968128556747588800">"Izklopljeno"</item>
     <item msgid="3033215374382962216">"Pokaži risanje zunaj vidnega območja"</item>
     <item msgid="3474333938380896988">"Pokaži območja za devteranomalijo"</item>
   </string-array>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index e2586be..631e15e 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -255,12 +255,12 @@
     <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"‏Wi-Fi سے جوڑا بنانے کا کوڈ"</string>
     <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"جوڑا بنانے میں ناکام"</string>
     <string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"یقینی بنائیں کہ آلہ اسی نیٹ ورک سے منسلک ہے۔"</string>
-    <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"‏QR کوڈ اسکین کر کے Wi-Fi پر آلہ کا جوڑا بنائیں"</string>
-    <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"آلہ کا جوڑا بنایا جا رہا ہے…"</string>
+    <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"‏QR کوڈ اسکین کر کے Wi-Fi پر آلے سے جوڑا بنائیں"</string>
+    <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"آلے سے جوڑا بنایا جا رہا ہے…"</string>
     <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"‏آلہ کا جوڑا بنانے میں ناکام۔ یا تو QR کوڈ غلط تھا، یا آلہ اسی نیٹ ورک سے منسلک نہیں ہے۔"</string>
     <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"‏IP پتہ اور پورٹ"</string>
     <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"‏QR کوڈ اسکین کریں"</string>
-    <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"‏QR کوڈ اسکین کر کے Wi-Fi پر آلہ کا جوڑا بنائیں"</string>
+    <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"‏QR کوڈ اسکین کر کے Wi-Fi پر آلے سے جوڑا بنائیں"</string>
     <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"‏براہ کرم ایک Wi-Fi نیٹ ورک سے منسلک ہوں"</string>
     <string name="keywords_adb_wireless" msgid="6507505581882171240">"‏adb، ڈیبگ، dev"</string>
     <string name="bugreport_in_power" msgid="8664089072534638709">"بگ رپورٹ کا شارٹ کٹ"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 19500f8..c003838 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -95,7 +95,7 @@
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Uzilyapti…"</string>
     <string name="bluetooth_connecting" msgid="5871702668260192755">"Ulanmoqda…"</string>
     <string name="bluetooth_connected" msgid="8065345572198502293">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> ulandi"</string>
-    <string name="bluetooth_pairing" msgid="4269046942588193600">"Biriktirilmoqda"</string>
+    <string name="bluetooth_pairing" msgid="4269046942588193600">"Juftlanmoqda…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> ulandi (telefondan tashqari)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> ulandi (mediadan tashqari)"</string>
     <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> ulandi (xabarlarga ruxsatsiz)"</string>
@@ -151,7 +151,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Bekor qilish"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Agar ulanishga ruxsat bersangiz, ulangan vaqtda kontakt va qo‘ng‘iroqlaringiz tarixiga kirishi mumkin."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> bilan biriktirib bo‘lmadi."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> qurilmasiga ulanilmadi, chunki PIN kod yoki parol xato kiritildi."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"PIN kod yoki parol xato kiritilgani sababli <xliff:g id="DEVICE_NAME">%1$s</xliff:g> qurilmasiga juftlanmadi."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"“<xliff:g id="DEVICE_NAME">%1$s</xliff:g>” qurilmasi bilan aloqa o‘rnatib bo‘lmayapti."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> biriktirish so‘rovini rad qildi."</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Kompyuter"</string>
@@ -255,12 +255,12 @@
     <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Wi‑Fi ulanish kodi"</string>
     <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"Ulanmadi"</string>
     <string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"Qurilma bir xil tarmoqqa ulanganini tekshiring."</string>
-    <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"QR kodni skanerlab, Wi-Fi orqali qurilmani ulang"</string>
-    <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Qurilma ulanmoqda…"</string>
+    <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"QR kodni skanerlab, Wi-Fi orqali qurilmani juftlang"</string>
+    <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Qurilma juftlanmoqda…"</string>
     <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Qurilma ulanmadi. QR kod xato yoki qurilma bir xil tarmoqqa ulanmagan."</string>
     <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP manzil va port"</string>
     <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR kodni skanerlash"</string>
-    <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR kodni skanerlab, Wi-Fi orqali qurilmani ulang"</string>
+    <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR kodni skanerlab, Wi-Fi orqali qurilmani juftlang"</string>
     <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Wi-Fi tarmoqqa ulaning"</string>
     <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debag, dev"</string>
     <string name="bugreport_in_power" msgid="8664089072534638709">"Xatoliklar hisoboti"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 904d2a4..3dcf61c 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -591,10 +591,10 @@
     <string name="user_nickname" msgid="262624187455825083">"Biệt hiệu"</string>
     <string name="user_add_user" msgid="7876449291500212468">"Thêm người dùng"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Thêm khách"</string>
-    <string name="guest_exit_guest" msgid="5908239569510734136">"Xóa phiên khách"</string>
+    <string name="guest_exit_guest" msgid="5908239569510734136">"Xóa khách"</string>
     <string name="guest_reset_guest" msgid="6110013010356013758">"Đặt lại phiên khách"</string>
     <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Đặt lại phiên khách?"</string>
-    <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Loại bỏ khách?"</string>
+    <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Xoá khách?"</string>
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Đặt lại"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Xoá"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Đang đặt lại phiên khách…"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiPermissionChecker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiPermissionChecker.java
new file mode 100644
index 0000000..2fe6e46
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiPermissionChecker.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.wifi;
+
+import static android.Manifest.permission.ACCESS_FINE_LOCATION;
+import static android.Manifest.permission.ACCESS_WIFI_STATE;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.IActivityManager;
+import android.content.pm.PackageManager;
+import android.os.RemoteException;
+import android.text.TextUtils;
+import android.util.Log;
+
+/**
+ * Helper class to check Wi-Fi permissions.
+ */
+public class WifiPermissionChecker {
+
+    private static final String TAG = "WifiPermChecker";
+
+    private IActivityManager mActivityManager;
+    private PackageManager mPackageManager;
+    private String mLaunchedPackage;
+
+    public WifiPermissionChecker(Activity activity) {
+        this(activity, ActivityManager.getService());
+    }
+
+    public WifiPermissionChecker(Activity activity, IActivityManager activityManager) {
+        mActivityManager = activityManager;
+        mPackageManager = activity.getPackageManager();
+        mLaunchedPackage = getLaunchedFromPackage(activity);
+    }
+
+    /**
+     * Returns the launched package name
+     */
+    public String getLaunchedPackage() {
+        return mLaunchedPackage;
+    }
+
+    /**
+     * Returns whether the launched package can access Wi-Fi information
+     */
+    public boolean canAccessWifiState() {
+        return checkPermission(ACCESS_WIFI_STATE);
+    }
+
+    /**
+     * Returns whether the launched package can access precise location
+     */
+    public boolean canAccessFineLocation() {
+        return checkPermission(ACCESS_FINE_LOCATION);
+    }
+
+    private boolean checkPermission(String permission) {
+        if (mPackageManager == null || TextUtils.isEmpty(mLaunchedPackage)) {
+            Log.e(TAG, "Failed to check package permission!"
+                    + " {PackageManager:" + mPackageManager
+                    + ", LaunchedPackage:" + mLaunchedPackage + "}");
+            return false;
+        }
+
+        if (mPackageManager.checkPermission(permission, mLaunchedPackage) == PERMISSION_GRANTED) {
+            return true;
+        }
+
+        Log.w(TAG, "The launched package does not have the required permission!"
+                + " {LaunchedPackage:" + mLaunchedPackage + ", Permission:" + permission + "}");
+        return false;
+    }
+
+    private String getLaunchedFromPackage(Activity activity) {
+        try {
+            return mActivityManager.getLaunchedFromPackage(activity.getActivityToken());
+        } catch (RemoteException e) {
+            Log.e(TAG, "Can not get the launched package from activity manager!");
+            return null;
+        }
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiPermissionCheckerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiPermissionCheckerTest.java
new file mode 100644
index 0000000..ec84141
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiPermissionCheckerTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.wifi;
+
+import static android.Manifest.permission.ACCESS_FINE_LOCATION;
+import static android.Manifest.permission.ACCESS_WIFI_STATE;
+import static android.content.pm.PackageManager.PERMISSION_DENIED;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import android.app.Activity;
+import android.app.IActivityManager;
+import android.content.pm.PackageManager;
+import android.os.RemoteException;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public class WifiPermissionCheckerTest {
+
+    static final String LAUNCHED_PACKAGE = "TestPackage";
+
+    @Rule
+    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+    @Mock
+    PackageManager mPackageManager;
+    @Mock
+    IActivityManager mActivityManager;
+    @Mock
+    Activity mActivity;
+
+    WifiPermissionChecker mWifiPermissionChecker;
+
+    @Before
+    public void setUp() {
+        when(mActivity.getPackageManager()).thenReturn(mPackageManager);
+        fakeGetLaunchedFromPackage(LAUNCHED_PACKAGE);
+
+        mWifiPermissionChecker = new WifiPermissionChecker(mActivity, mActivityManager);
+    }
+
+    @Test
+    public void getLaunchedPackage_returnLaunchedFromPackage() {
+        assertThat(mWifiPermissionChecker.getLaunchedPackage()).isEqualTo(LAUNCHED_PACKAGE);
+    }
+
+    @Test
+    public void canAccessWifiState_noPermission_returnFalse() {
+        when(mPackageManager.checkPermission(ACCESS_WIFI_STATE, LAUNCHED_PACKAGE))
+                .thenReturn(PERMISSION_DENIED);
+
+        assertThat(mWifiPermissionChecker.canAccessWifiState()).isFalse();
+    }
+
+    @Test
+    public void canAccessWifiState_hasPermission_returnTrue() {
+        when(mPackageManager.checkPermission(ACCESS_WIFI_STATE, LAUNCHED_PACKAGE))
+                .thenReturn(PERMISSION_GRANTED);
+
+        assertThat(mWifiPermissionChecker.canAccessWifiState()).isTrue();
+    }
+
+    @Test
+    public void canAccessFineLocation_noPermission_returnFalse() {
+        when(mPackageManager.checkPermission(ACCESS_FINE_LOCATION, LAUNCHED_PACKAGE))
+                .thenReturn(PERMISSION_DENIED);
+
+        assertThat(mWifiPermissionChecker.canAccessFineLocation()).isFalse();
+    }
+
+    @Test
+    public void canAccessFineLocation_hasPermission_returnTrue() {
+        when(mPackageManager.checkPermission(ACCESS_FINE_LOCATION, LAUNCHED_PACKAGE))
+                .thenReturn(PERMISSION_GRANTED);
+
+        assertThat(mWifiPermissionChecker.canAccessFineLocation()).isTrue();
+    }
+
+    void fakeGetLaunchedFromPackage(String packageName) {
+        try {
+            when(mActivityManager.getLaunchedFromPackage(any())).thenReturn(packageName);
+        } catch (RemoteException e) {
+            // Do nothing
+        }
+    }
+}
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 791930d..fac32aa 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -155,7 +155,6 @@
                     Settings.Global.BLE_SCAN_LOW_LATENCY_WINDOW_MS,
                     Settings.Global.BLE_SCAN_LOW_LATENCY_INTERVAL_MS,
                     Settings.Global.BLE_SCAN_BACKGROUND_MODE,
-                    Settings.Global.BLOCK_UNTRUSTED_TOUCHES_MODE,
                     Settings.Global.BLOCKED_SLICES,
                     Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT,
                     Settings.Global.BLOCKING_HELPER_STREAK_LIMIT,
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index 2264671..21e5697 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -65,6 +65,8 @@
     <dimen name="qs_security_footer_single_line_height">48dp</dimen>
     <dimen name="qs_security_footer_background_inset">0dp</dimen>
 
+    <dimen name="qs_panel_padding_top">8dp</dimen>
+
     <!-- The width of large/content heavy dialogs (e.g. Internet, Media output, etc) -->
     <dimen name="large_dialog_width">472dp</dimen>
 
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 9e6b277..4b6c0dc 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -714,4 +714,10 @@
         <item>@*android:string/status_bar_alarm_clock</item>
         <item>@*android:string/status_bar_call_strength</item>
     </string-array>
+
+    <!-- Packages of SystemUI -->
+    <string-array name="system_ui_packages" translatable="false">
+        <item>com.android.keyguard</item>
+        <item>com.android.systemui</item>
+    </string-array>
 </resources>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/smartspace/ILauncherUnlockAnimationController.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/system/smartspace/ILauncherUnlockAnimationController.aidl
index b2295b9..5a30901 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/smartspace/ILauncherUnlockAnimationController.aidl
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/smartspace/ILauncherUnlockAnimationController.aidl
@@ -16,17 +16,20 @@
 
 package com.android.systemui.shared.system.smartspace;
 
+import android.graphics.Rect;
 import com.android.systemui.shared.system.smartspace.SmartspaceState;
 
 // Methods for System UI to interface with Launcher to perform the unlock animation.
 interface ILauncherUnlockAnimationController {
     // Prepares Launcher for the unlock animation by setting scale/alpha/etc. to their starting
     // values.
-    void prepareForUnlock(boolean willAnimateSmartspace, int selectedPage);
+    void prepareForUnlock(boolean animateSmartspace, in Rect lockscreenSmartspaceBounds,
+        int selectedPage);
 
     // Set the unlock percentage. This is used when System UI is controlling each frame of the
-    // unlock animation, such as during a swipe to unlock touch gesture.
-    oneway void setUnlockAmount(float amount);
+    // unlock animation, such as during a swipe to unlock touch gesture. Will not apply this change
+    // if the unlock amount is animating unless forceIfAnimating is true.
+    oneway void setUnlockAmount(float amount, boolean forceIfAnimating);
 
     // Play a full unlock animation from 0f to 1f. This is used when System UI is unlocking from a
     // single action, such as biometric auth, and doesn't need to control individual frames.
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index 04c9a45..ea14b64 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -58,9 +58,7 @@
 import com.android.systemui.util.settings.SecureSettings;
 
 import java.io.PrintWriter;
-import java.util.HashSet;
 import java.util.Locale;
-import java.util.Set;
 import java.util.TimeZone;
 import java.util.concurrent.Executor;
 
@@ -134,14 +132,6 @@
             mKeyguardUnlockAnimationListener =
             new KeyguardUnlockAnimationController.KeyguardUnlockAnimationListener() {
                 @Override
-                public void onSmartspaceSharedElementTransitionStarted() {
-                    // The smartspace needs to be able to translate out of bounds in order to
-                    // end up where the launcher's smartspace is, while its container is being
-                    // swiped off the top of the screen.
-                    setClipChildrenForUnlock(false);
-                }
-
-                @Override
                 public void onUnlockAnimationFinished() {
                     // For performance reasons, reset this once the unlock animation ends.
                     setClipChildrenForUnlock(true);
@@ -390,41 +380,6 @@
         if (mStatusArea != null) {
             PropertyAnimator.setProperty(mStatusArea, AnimatableProperty.TRANSLATION_X,
                     x, props, animate);
-
-            // If we're unlocking with the SmartSpace shared element transition, let the controller
-            // know that it should re-position our SmartSpace.
-            if (mKeyguardUnlockAnimationController.isUnlockingWithSmartSpaceTransition()) {
-                mKeyguardUnlockAnimationController.updateLockscreenSmartSpacePosition();
-            }
-        }
-    }
-
-    /** Sets an alpha value on every child view except for the smartspace. */
-    public void setChildrenAlphaExcludingSmartspace(float alpha) {
-        final Set<View> excludedViews = new HashSet<>();
-
-        if (mSmartspaceView != null) {
-            excludedViews.add(mStatusArea);
-        }
-
-        // Don't change the alpha of the invisible clock.
-        if (mCurrentClockSize == LARGE) {
-            excludedViews.add(mClockFrame);
-        } else {
-            excludedViews.add(mLargeClockFrame);
-        }
-
-        setChildrenAlphaExcluding(alpha, excludedViews);
-    }
-
-    /** Sets an alpha value on every child view except for the views in the provided set. */
-    public void setChildrenAlphaExcluding(float alpha, Set<View> excludedViews) {
-        for (int i = 0; i < mView.getChildCount(); i++) {
-            final View child = mView.getChildAt(i);
-
-            if (!excludedViews.contains(child)) {
-                child.setAlpha(alpha);
-            }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index 853d740..cb3172d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -47,7 +47,6 @@
 
     private float mDarkAmount = 0;
     private int mTextColor;
-    private float mChildrenAlphaExcludingSmartSpace = 1f;
 
     public KeyguardStatusView(Context context) {
         this(context, null, 0);
@@ -95,23 +94,6 @@
         mClockView.setTextColor(blendedTextColor);
     }
 
-    public void setChildrenAlphaExcludingClockView(float alpha) {
-        setChildrenAlphaExcluding(alpha, Set.of(mClockView));
-    }
-
-    /** Sets an alpha value on every view except for the views in the provided set. */
-    public void setChildrenAlphaExcluding(float alpha, Set<View> excludedViews) {
-        mChildrenAlphaExcludingSmartSpace = alpha;
-
-        for (int i = 0; i < mStatusViewContainer.getChildCount(); i++) {
-            final View child = mStatusViewContainer.getChildAt(i);
-
-            if (!excludedViews.contains(child)) {
-                child.setAlpha(alpha);
-            }
-        }
-    }
-
     /** Sets a translationY value on every child view except for the media view. */
     public void setChildrenTranslationYExcludingMediaView(float translationY) {
         setChildrenTranslationYExcluding(translationY, Set.of(mMediaHostContainer));
@@ -128,10 +110,6 @@
         }
     }
 
-    public float getChildrenAlphaExcludingSmartSpace() {
-        return mChildrenAlphaExcludingSmartSpace;
-    }
-
     public void dump(PrintWriter pw, String[] args) {
         pw.println("KeyguardStatusView:");
         pw.println("  mDarkAmount: " + mDarkAmount);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
index 14c9cb2..083f2fe 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
@@ -20,7 +20,6 @@
 import android.util.Slog;
 
 import com.android.keyguard.KeyguardClockSwitch.ClockSize;
-import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
 import com.android.systemui.statusbar.notification.AnimatableProperty;
 import com.android.systemui.statusbar.notification.PropertyAnimator;
 import com.android.systemui.statusbar.notification.stack.AnimationProperties;
@@ -49,10 +48,7 @@
     private final KeyguardClockSwitchController mKeyguardClockSwitchController;
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     private final ConfigurationController mConfigurationController;
-    private final DozeParameters mDozeParameters;
     private final KeyguardVisibilityHelper mKeyguardVisibilityHelper;
-    private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
-    private final KeyguardStateController mKeyguardStateController;
     private final Rect mClipBounds = new Rect();
 
     @Inject
@@ -64,18 +60,14 @@
             KeyguardUpdateMonitor keyguardUpdateMonitor,
             ConfigurationController configurationController,
             DozeParameters dozeParameters,
-            KeyguardUnlockAnimationController keyguardUnlockAnimationController,
             ScreenOffAnimationController screenOffAnimationController) {
         super(keyguardStatusView);
         mKeyguardSliceViewController = keyguardSliceViewController;
         mKeyguardClockSwitchController = keyguardClockSwitchController;
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mConfigurationController = configurationController;
-        mDozeParameters = dozeParameters;
-        mKeyguardStateController = keyguardStateController;
         mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, keyguardStateController,
                 dozeParameters, screenOffAnimationController, /* animateYPos= */ true);
-        mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
     }
 
     @Override
@@ -87,14 +79,12 @@
     protected void onViewAttached() {
         mKeyguardUpdateMonitor.registerCallback(mInfoCallback);
         mConfigurationController.addCallback(mConfigurationListener);
-        mKeyguardStateController.addCallback(mKeyguardStateControllerCallback);
     }
 
     @Override
     protected void onViewDetached() {
         mKeyguardUpdateMonitor.removeCallback(mInfoCallback);
         mConfigurationController.removeCallback(mConfigurationListener);
-        mKeyguardStateController.removeCallback(mKeyguardStateControllerCallback);
     }
 
     /**
@@ -148,24 +138,7 @@
      */
     public void setAlpha(float alpha) {
         if (!mKeyguardVisibilityHelper.isVisibilityAnimating()) {
-            // If we're capable of performing the SmartSpace shared element transition, and we are
-            // going to (we're swiping to dismiss vs. bringing up the PIN screen), then fade out
-            // everything except for the SmartSpace.
-            if (mKeyguardUnlockAnimationController.isUnlockingWithSmartSpaceTransition()) {
-                mView.setChildrenAlphaExcludingClockView(alpha);
-                mKeyguardClockSwitchController.setChildrenAlphaExcludingSmartspace(alpha);
-            } else if (!mKeyguardVisibilityHelper.isVisibilityAnimating()) {
-                // Otherwise, we can just set the alpha for the entire container.
-                mView.setAlpha(alpha);
-
-                // If we previously unlocked with the shared element transition, some child views
-                // might still have alpha = 0f. Set them back to 1f since we're just using the
-                // parent container's alpha.
-                if (mView.getChildrenAlphaExcludingSmartSpace() < 1f) {
-                    mView.setChildrenAlphaExcludingClockView(1f);
-                    mKeyguardClockSwitchController.setChildrenAlphaExcludingSmartspace(1f);
-                }
-            }
+            mView.setAlpha(alpha);
         }
     }
 
@@ -289,19 +262,6 @@
         }
     };
 
-    private KeyguardStateController.Callback mKeyguardStateControllerCallback =
-            new KeyguardStateController.Callback() {
-        @Override
-        public void onKeyguardShowingChanged() {
-            // If we explicitly re-show the keyguard, make sure that all the child views are
-            // visible. They might have been animating out as part of the SmartSpace shared
-            // element transition.
-            if (mKeyguardStateController.isShowing()) {
-                mView.setChildrenAlphaExcludingClockView(1f);
-            }
-        }
-    };
-
     /**
      * Rect that specifies how KSV should be clipped, on its parent's coordinates.
      */
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index dc19585..171dee6 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -1496,6 +1496,20 @@
                 handleFingerprintAuthenticated(userId, isStrongBiometric);
             };
 
+    /**
+     * Propagates a pointer down event to keyguard.
+     */
+    public void onUdfpsPointerDown(int sensorId) {
+        mFingerprintAuthenticationCallback.onUdfpsPointerDown(sensorId);
+    }
+
+    /**
+     * Propagates a pointer up event to keyguard.
+     */
+    public void onUdfpsPointerUp(int sensorId) {
+        mFingerprintAuthenticationCallback.onUdfpsPointerUp(sensorId);
+    }
+
     @VisibleForTesting
     final FingerprintManager.AuthenticationCallback mFingerprintAuthenticationCallback
             = new AuthenticationCallback() {
@@ -1537,6 +1551,9 @@
                     Trace.endSection();
                 }
 
+                /**
+                 * Note, this is currently called from UdfpsController.
+                 */
                 @Override
                 public void onUdfpsPointerDown(int sensorId) {
                     Log.d(TAG, "onUdfpsPointerDown, sensorId: " + sensorId);
@@ -1546,6 +1563,9 @@
                     }
                 }
 
+                /**
+                 * Note, this is currently called from UdfpsController.
+                 */
                 @Override
                 public void onUdfpsPointerUp(int sensorId) {
                     Log.d(TAG, "onUdfpsPointerUp, sensorId: " + sensorId);
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index 9d5b93c..7c2673c 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -187,6 +187,14 @@
                     }
 
                     @Override
+                    public void onVoiceSessionWindowVisibilityChanged(boolean visible)
+                            throws RemoteException {
+                        if (VERBOSE) {
+                            Log.v(TAG, "Window visibility changed: " + visible);
+                        }
+                    }
+
+                    @Override
                     public void onSetUiHints(Bundle hints) {
                         if (VERBOSE) {
                             Log.v(TAG, "UI hints received");
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 0096032..09d9792 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -796,6 +796,11 @@
         mOnFingerDown = true;
         if (mAlternateTouchProvider != null) {
             mAlternateTouchProvider.onPointerDown(requestId, x, y, minor, major);
+            mFgExecutor.execute(() -> {
+                if (mKeyguardUpdateMonitor.isFingerprintDetectionRunning()) {
+                    mKeyguardUpdateMonitor.onUdfpsPointerDown((int) requestId);
+                }
+            });
         } else {
             mFingerprintManager.onPointerDown(requestId, mSensorId, x, y, minor, major);
         }
@@ -821,6 +826,11 @@
         if (mOnFingerDown) {
             if (mAlternateTouchProvider != null) {
                 mAlternateTouchProvider.onPointerUp(requestId);
+                mFgExecutor.execute(() -> {
+                    if (mKeyguardUpdateMonitor.isFingerprintDetectionRunning()) {
+                        mKeyguardUpdateMonitor.onUdfpsPointerUp((int) requestId);
+                    }
+                });
             } else {
                 mFingerprintManager.onPointerUp(requestId, mSensorId);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java
index dbfce2e..2f09792 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java
@@ -112,17 +112,16 @@
             if (child.getId() == R.id.biometric_icon_frame) {
                 final FrameLayout iconFrame = (FrameLayout) child;
                 final View icon = iconFrame.getChildAt(0);
-
-                // Ensure that the icon is never larger than the sensor.
-                icon.measure(
-                        MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.AT_MOST),
-                        MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.AT_MOST));
-
                 // Create a frame that's exactly the height of the sensor circle.
                 iconFrame.measure(
                         MeasureSpec.makeMeasureSpec(
                                 child.getLayoutParams().width, MeasureSpec.EXACTLY),
                         MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.EXACTLY));
+
+                // Ensure that the icon is never larger than the sensor.
+                icon.measure(
+                        MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.AT_MOST),
+                        MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.AT_MOST));
             } else if (child.getId() == R.id.space_above_icon) {
                 child.measure(
                         MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
@@ -208,16 +207,15 @@
             if (child.getId() == R.id.biometric_icon_frame) {
                 final FrameLayout iconFrame = (FrameLayout) child;
                 final View icon = iconFrame.getChildAt(0);
+                // Create a frame that's exactly the height of the sensor circle.
+                iconFrame.measure(
+                        MeasureSpec.makeMeasureSpec(remeasuredWidth, MeasureSpec.EXACTLY),
+                        MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.EXACTLY));
 
                 // Ensure that the icon is never larger than the sensor.
                 icon.measure(
                         MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.AT_MOST),
                         MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.AT_MOST));
-
-                // Create a frame that's exactly the height of the sensor circle.
-                iconFrame.measure(
-                        MeasureSpec.makeMeasureSpec(remeasuredWidth, MeasureSpec.EXACTLY),
-                        MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.EXACTLY));
             } else if (child.getId() == R.id.space_above_icon) {
                 // Adjust the width and height of the top spacer if necessary.
                 final int newTopSpacerHeight = child.getLayoutParams().height
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollProgressBarDrawable.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollProgressBarDrawable.java
index 59c658f..49e378e 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollProgressBarDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollProgressBarDrawable.java
@@ -22,6 +22,10 @@
 import android.graphics.ColorFilter;
 import android.graphics.Paint;
 import android.graphics.drawable.Drawable;
+import android.os.Process;
+import android.os.VibrationAttributes;
+import android.os.VibrationEffect;
+import android.os.Vibrator;
 import android.view.accessibility.AccessibilityManager;
 import android.view.animation.DecelerateInterpolator;
 import android.view.animation.Interpolator;
@@ -46,6 +50,17 @@
     private static final float STROKE_WIDTH_DP = 12f;
     private static final Interpolator DEACCEL = new DecelerateInterpolator();
 
+    private static final VibrationEffect VIBRATE_EFFECT_ERROR =
+            VibrationEffect.createWaveform(new long[] {0, 5, 55, 60}, -1);
+    private static final VibrationAttributes FINGERPRINT_ENROLLING_SONFICATION_ATTRIBUTES =
+            VibrationAttributes.createForUsage(VibrationAttributes.USAGE_ACCESSIBILITY);
+
+    private static final VibrationAttributes HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES =
+            VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK);
+
+    private static final VibrationEffect SUCCESS_VIBRATION_EFFECT =
+            VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
+
     private final float mStrokeWidthPx;
     @ColorInt private final int mProgressColor;
     @ColorInt private final int mHelpColor;
@@ -54,6 +69,9 @@
     @NonNull private final Interpolator mCheckmarkInterpolator;
     @NonNull private final Paint mBackgroundPaint;
     @NonNull private final Paint mFillPaint;
+    @NonNull private final Vibrator mVibrator;
+    @NonNull private final boolean mIsAccessibilityEnabled;
+    @NonNull private final Context mContext;
 
     private boolean mAfterFirstTouch;
 
@@ -76,11 +94,12 @@
     @NonNull private final ValueAnimator.AnimatorUpdateListener mCheckmarkUpdateListener;
 
     public UdfpsEnrollProgressBarDrawable(@NonNull Context context) {
+        mContext = context;
         mStrokeWidthPx = Utils.dpToPixels(context, STROKE_WIDTH_DP);
         mProgressColor = context.getColor(R.color.udfps_enroll_progress);
         final AccessibilityManager am = context.getSystemService(AccessibilityManager.class);
-        final boolean isAccessbilityEnabled = am.isTouchExplorationEnabled();
-        if (!isAccessbilityEnabled) {
+        mIsAccessibilityEnabled = am.isTouchExplorationEnabled();
+        if (!mIsAccessibilityEnabled) {
             mHelpColor = context.getColor(R.color.udfps_enroll_progress_help);
             mOnFirstBucketFailedColor = context.getColor(R.color.udfps_moving_target_fill_error);
         } else {
@@ -106,6 +125,8 @@
         mFillPaint.setStyle(Paint.Style.STROKE);
         mFillPaint.setStrokeCap(Paint.Cap.ROUND);
 
+        mVibrator = mContext.getSystemService(Vibrator.class);
+
         mProgressUpdateListener = animation -> {
             mProgress = (float) animation.getAnimatedValue();
             invalidateSelf();
@@ -141,14 +162,41 @@
     }
 
     private void updateState(int remainingSteps, int totalSteps, boolean showingHelp) {
-        updateProgress(remainingSteps, totalSteps);
+        updateProgress(remainingSteps, totalSteps, showingHelp);
         updateFillColor(showingHelp);
     }
 
-    private void updateProgress(int remainingSteps, int totalSteps) {
+    private void updateProgress(int remainingSteps, int totalSteps, boolean showingHelp) {
         if (mRemainingSteps == remainingSteps && mTotalSteps == totalSteps) {
             return;
         }
+
+        if (mShowingHelp) {
+            if (mVibrator != null && mIsAccessibilityEnabled) {
+                mVibrator.vibrate(Process.myUid(), mContext.getOpPackageName(),
+                        VIBRATE_EFFECT_ERROR, getClass().getSimpleName() + "::onEnrollmentHelp",
+                        FINGERPRINT_ENROLLING_SONFICATION_ATTRIBUTES);
+            }
+        } else {
+            // If the first touch is an error, remainingSteps will be -1 and the callback
+            // doesn't come from onEnrollmentHelp. If we are in the accessibility flow,
+            // we still would like to vibrate.
+            if (mVibrator != null) {
+                if (remainingSteps == -1 && mIsAccessibilityEnabled) {
+                    mVibrator.vibrate(Process.myUid(), mContext.getOpPackageName(),
+                            VIBRATE_EFFECT_ERROR,
+                            getClass().getSimpleName() + "::onFirstTouchError",
+                            FINGERPRINT_ENROLLING_SONFICATION_ATTRIBUTES);
+                } else if (remainingSteps != -1 && !mIsAccessibilityEnabled) {
+                    mVibrator.vibrate(Process.myUid(),
+                            mContext.getOpPackageName(),
+                            SUCCESS_VIBRATION_EFFECT,
+                            getClass().getSimpleName() + "::OnEnrollmentProgress",
+                            HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES);
+                }
+            }
+        }
+
         mRemainingSteps = remainingSteps;
         mTotalSteps = totalSteps;
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
index 842791f..937b813 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
@@ -127,17 +127,19 @@
         mBurnInProgress = MathUtils.lerp(0f, getBurnInProgressOffset(), darkAmountForAnimation);
 
         if (mAnimatingBetweenAodAndLockscreen && !mPauseAuth) {
+            mLockScreenFp.setTranslationX(mBurnInOffsetX);
+            mLockScreenFp.setTranslationY(mBurnInOffsetY);
             mBgProtection.setAlpha(1f - mInterpolatedDarkAmount);
             mLockScreenFp.setAlpha(1f - mInterpolatedDarkAmount);
         } else if (mInterpolatedDarkAmount == 0f) {
+            mLockScreenFp.setTranslationX(0);
+            mLockScreenFp.setTranslationY(0);
             mBgProtection.setAlpha(mAlpha / 255f);
             mLockScreenFp.setAlpha(mAlpha / 255f);
         } else {
             mBgProtection.setAlpha(0f);
             mLockScreenFp.setAlpha(0f);
         }
-        mLockScreenFp.setTranslationX(mBurnInOffsetX);
-        mLockScreenFp.setTranslationY(mBurnInOffsetY);
         mLockScreenFp.setProgress(1f - mInterpolatedDarkAmount);
 
         mAodFp.setTranslationX(mBurnInOffsetX);
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
index f5575a2..f769a23 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
@@ -44,6 +44,7 @@
 import com.android.wm.shell.animation.FlingAnimationUtils;
 
 import java.util.Optional;
+
 import javax.inject.Inject;
 import javax.inject.Named;
 
@@ -153,8 +154,6 @@
 
     private void setPanelExpansion(float expansion, float dragDownAmount) {
         mCurrentExpansion = expansion;
-        mCentralSurfaces.ifPresent(centralSurfaces -> centralSurfaces.setBouncerShowingOverDream(
-                mCurrentExpansion != KeyguardBouncer.EXPANSION_HIDDEN));
         PanelExpansionChangeEvent event =
                 new PanelExpansionChangeEvent(
                         /* fraction= */ mCurrentExpansion,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
index a8c2862..f7d1fd8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
@@ -23,7 +23,7 @@
 import android.graphics.Matrix
 import android.graphics.Rect
 import android.os.Handler
-import android.provider.Settings
+import android.os.RemoteException
 import android.util.Log
 import android.view.RemoteAnimationTarget
 import android.view.SyncRtSurfaceTransactionApplier
@@ -47,7 +47,6 @@
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import dagger.Lazy
 import javax.inject.Inject
-import kotlin.math.min
 
 const val TAG = "KeyguardUnlock"
 
@@ -77,7 +76,7 @@
  * The dismiss amount is the inverse of the notification panel expansion, which decreases as the
  * lock screen is swiped away.
  */
-const val DISMISS_AMOUNT_SHOW_SURFACE_THRESHOLD = 0.25f
+const val DISMISS_AMOUNT_SHOW_SURFACE_THRESHOLD = 0.15f
 
 /**
  * Dismiss amount at which to complete the keyguard exit animation and hide the keyguard.
@@ -85,7 +84,7 @@
  * The dismiss amount is the inverse of the notification panel expansion, which decreases as the
  * lock screen is swiped away.
  */
-const val DISMISS_AMOUNT_EXIT_KEYGUARD_THRESHOLD = 0.4f
+const val DISMISS_AMOUNT_EXIT_KEYGUARD_THRESHOLD = 0.3f
 
 /**
  * How long the canned unlock animation takes. This is used if we are unlocking from biometric auth,
@@ -112,7 +111,7 @@
  * Duration for the alpha animation on the surface behind. This plays to fade in the surface during
  * a swipe to unlock (and to fade it back out if the swipe is cancelled).
  */
-const val SURFACE_BEHIND_SWIPE_FADE_DURATION_MS = 150L
+const val SURFACE_BEHIND_SWIPE_FADE_DURATION_MS = 175L
 
 /**
  * Start delay for the surface behind animation, used so that the lockscreen can get out of the way
@@ -151,12 +150,21 @@
          * [playingCannedAnimation] indicates whether we are playing a canned animation to show the
          * app/launcher behind the keyguard, vs. this being a swipe to unlock where the dismiss
          * amount drives the animation.
+         *
          * [fromWakeAndUnlock] tells us whether we are unlocking directly from AOD - in this case,
          * the lockscreen is dismissed instantly, so we shouldn't run any animations that rely on it
          * being visible.
+         *
+         * [unlockAnimationStartDelay] and [unlockAnimationDuration] provide the timing parameters
+         * for the canned animation (if applicable) so interested parties can sync with it. If no
+         * canned animation is playing, these are both 0.
          */
         @JvmDefault
-        fun onUnlockAnimationStarted(playingCannedAnimation: Boolean, fromWakeAndUnlock: Boolean) {}
+        fun onUnlockAnimationStarted(
+            playingCannedAnimation: Boolean,
+            fromWakeAndUnlock: Boolean,
+            unlockAnimationStartDelay: Long,
+            unlockAnimationDuration: Long) {}
 
         /**
          * Called when the remote unlock animation ends, in all cases, canned or swipe-to-unlock.
@@ -165,19 +173,6 @@
          */
         @JvmDefault
         fun onUnlockAnimationFinished() {}
-
-        /**
-         * Called when we begin the smartspace shared element transition, either due to an unlock
-         * action (biometric, etc.) or a swipe to unlock.
-         *
-         * This transition can begin BEFORE [onUnlockAnimationStarted] is called, if we are swiping
-         * to unlock and the surface behind the keyguard has not yet been made visible. This is
-         * because the lockscreen smartspace immediately begins moving towards the launcher
-         * smartspace location when a swipe begins, even before we start the keyguard exit remote
-         * animation and show the launcher itself.
-         */
-        @JvmDefault
-        fun onSmartspaceSharedElementTransitionStarted() {}
     }
 
     /** The SmartSpace view on the lockscreen, provided by [KeyguardClockSwitchController]. */
@@ -259,8 +254,9 @@
      * animation plays.
      */
     private var surfaceBehindAlpha = 1f
-    private var surfaceBehindAlphaAnimator = ValueAnimator.ofFloat(0f, 1f)
-    private var smartspaceAnimator = ValueAnimator.ofFloat(0f, 1f)
+
+    @VisibleForTesting
+    var surfaceBehindAlphaAnimator = ValueAnimator.ofFloat(0f, 1f)
 
     /**
      * Matrix applied to [surfaceBehindRemoteAnimationTarget], which is the surface of the
@@ -281,59 +277,38 @@
     private var roundedCornerRadius = 0f
 
     /**
-     * Whether we tried to start the SmartSpace shared element transition for this unlock swipe.
-     * It's possible we were unable to do so (if the Launcher SmartSpace is not available), and we
-     * need to keep track of that so that we don't start doing it halfway through the swipe if
-     * Launcher becomes available suddenly.
+     * Whether we decided in [prepareForInWindowLauncherAnimations] that we are able to and want to
+     * play the in-window launcher unlock animations rather than simply animating the Launcher
+     * window like any other app. This can be true while [willUnlockWithSmartspaceTransition] is
+     * false, if the smartspace is not available or was not ready in time.
      */
-    private var attemptedSmartSpaceTransitionForThisSwipe = false
+    private var willUnlockWithInWindowLauncherAnimations: Boolean = false
 
     /**
-     * The original location of the lockscreen smartspace on the screen.
+     * Whether we decided in [prepareForInWindowLauncherAnimations] that we are able to and want to
+     * play the smartspace shared element animation. If true,
+     * [willUnlockWithInWindowLauncherAnimations] will also always be true since in-window
+     * animations are a prerequisite for the smartspace transition.
      */
-    private val smartspaceOriginBounds = Rect()
-
-    /**
-     * The bounds to which the lockscreen smartspace is moving. This is set to the bounds of the
-     * launcher's smartspace prior to the transition starting.
-     */
-    private val smartspaceDestBounds = Rect()
-
-    /**
-     * From 0f to 1f, the progress of the smartspace shared element animation. 0f means the
-     * smartspace is at its normal position within the lock screen hierarchy, and 1f means it has
-     * fully animated to the location of the Launcher's smartspace.
-     */
-    private var smartspaceUnlockProgress = 0f
-
-    /**
-     * Whether we're currently unlocking, and we're talking to Launcher to perform in-window
-     * animations rather than simply animating the Launcher window like any other app. This can be
-     * true while [unlockingWithSmartspaceTransition] is false, if the smartspace is not available
-     * or was not ready in time.
-     */
-    private var unlockingToLauncherWithInWindowAnimations: Boolean = false
-
-    /**
-     * Whether we are currently unlocking, and the smartspace shared element transition is in
-     * progress. If true, we're also [unlockingToLauncherWithInWindowAnimations].
-     */
-    private var unlockingWithSmartspaceTransition: Boolean = false
+    private var willUnlockWithSmartspaceTransition: Boolean = false
 
     private val handler = Handler()
 
     init {
         with(surfaceBehindAlphaAnimator) {
             duration = SURFACE_BEHIND_SWIPE_FADE_DURATION_MS
-            interpolator = Interpolators.TOUCH_RESPONSE
+            interpolator = Interpolators.LINEAR
             addUpdateListener { valueAnimator: ValueAnimator ->
                 surfaceBehindAlpha = valueAnimator.animatedValue as Float
                 updateSurfaceBehindAppearAmount()
             }
             addListener(object : AnimatorListenerAdapter() {
                 override fun onAnimationEnd(animation: Animator) {
-                    // If the surface alpha is 0f, it's no longer visible so we can safely be done
-                    // with the animation even if other properties are still animating.
+                    // If we animated the surface alpha to 0f, it means we cancelled a swipe to
+                    // dismiss. In this case, we should ask the KeyguardViewMediator to end the
+                    // remote animation to hide the surface behind the keyguard, but should *not*
+                    // call onKeyguardExitRemoteAnimationFinished since that will hide the keyguard
+                    // and unlock the device as well as hiding the surface.
                     if (surfaceBehindAlpha == 0f) {
                         keyguardViewMediator.get().finishSurfaceBehindRemoteAnimation(
                             false /* cancelled */)
@@ -360,21 +335,6 @@
             })
         }
 
-        with(smartspaceAnimator) {
-            duration = UNLOCK_ANIMATION_DURATION_MS
-            interpolator = Interpolators.TOUCH_RESPONSE
-            addUpdateListener {
-                smartspaceUnlockProgress = it.animatedValue as Float
-            }
-            addListener(object : AnimatorListenerAdapter() {
-                override fun onAnimationEnd(animation: Animator?) {
-                    launcherUnlockController?.setSmartspaceVisibility(View.VISIBLE)
-                    keyguardViewMediator.get().onKeyguardExitRemoteAnimationFinished(
-                        false /* cancelled */)
-                }
-            })
-        }
-
         // Listen for changes in the dismiss amount.
         keyguardStateController.addCallback(this)
 
@@ -394,6 +354,74 @@
     }
 
     /**
+     * Whether we should be able to do the in-window launcher animations given the current state of
+     * the device.
+     */
+    fun canPerformInWindowLauncherAnimations(): Boolean {
+        return isNexusLauncherUnderneath() &&
+                launcherUnlockController != null &&
+                !keyguardStateController.isDismissingFromSwipe &&
+                // Temporarily disable for foldables since foldable launcher has two first pages,
+                // which breaks the in-window animation.
+                !isFoldable(context)
+    }
+
+    /**
+     * Called from [KeyguardStateController] to let us know that the keyguard going away state has
+     * changed.
+     */
+    override fun onKeyguardGoingAwayChanged() {
+        if (keyguardStateController.isKeyguardGoingAway) {
+            prepareForInWindowLauncherAnimations()
+        }
+    }
+
+    /**
+     * Prepare for in-window Launcher unlock animations, if we're able to do so.
+     *
+     * The in-window animations consist of the staggered ring icon unlock animation, and optionally
+     * the shared element smartspace transition.
+     */
+    fun prepareForInWindowLauncherAnimations() {
+        willUnlockWithInWindowLauncherAnimations = canPerformInWindowLauncherAnimations()
+
+        if (!willUnlockWithInWindowLauncherAnimations) {
+            return
+        }
+
+        // There are additional conditions under which we should not perform the smartspace
+        // transition specifically, so check those.
+        willUnlockWithSmartspaceTransition = shouldPerformSmartspaceTransition()
+
+        var lockscreenSmartspaceBounds = Rect()
+
+        // Grab the bounds of our lockscreen smartspace and send them to launcher so they can
+        // position their smartspace there initially, then animate it to its resting position.
+        if (willUnlockWithSmartspaceTransition) {
+            lockscreenSmartspaceBounds = Rect().apply {
+                lockscreenSmartspace!!.getBoundsOnScreen(this)
+                offset(lockscreenSmartspace!!.paddingLeft, lockscreenSmartspace!!.paddingTop)
+            }
+        }
+
+        // Currently selected lockscreen smartspace page, or -1 if it's not available.
+        val selectedPage =
+            (lockscreenSmartspace as BcSmartspaceDataPlugin.SmartspaceView?)?.selectedPage ?: -1
+
+        try {
+
+            // Let the launcher know to prepare for this animation.
+            launcherUnlockController?.prepareForUnlock(
+                willUnlockWithSmartspaceTransition, /* willAnimateSmartspace */
+                lockscreenSmartspaceBounds, /* lockscreenSmartspaceBounds */
+                selectedPage, /* selectedPage */
+            )
+        } catch (e: RemoteException) {
+            Log.e(TAG, "Remote exception in prepareForInWindowUnlockAnimations.", e)
+        }
+    }
+
+    /**
      * Called from [KeyguardViewMediator] to tell us that the RemoteAnimation on the surface behind
      * the keyguard has started successfully. We can use these parameters to directly manipulate the
      * surface for the unlock gesture/animation.
@@ -404,7 +432,8 @@
      *
      * [requestedShowSurfaceBehindKeyguard] indicates whether the animation started because of a
      * call to [KeyguardViewMediator.showSurfaceBehindKeyguard], as happens during a swipe gesture,
-     * as opposed to being called because the device was unlocked and the keyguard is going away.
+     * as opposed to being called because the device was unlocked instantly by some other means
+     * (fingerprint, tap, etc.) and the keyguard is going away.
      */
     fun notifyStartSurfaceBehindRemoteAnimation(
         target: RemoteAnimationTarget,
@@ -434,7 +463,9 @@
         listeners.forEach {
             it.onUnlockAnimationStarted(
                 playingCannedUnlockAnimation /* playingCannedAnimation */,
-                biometricUnlockControllerLazy.get().isWakeAndUnlock /* isWakeAndUnlock */) }
+                biometricUnlockControllerLazy.get().isWakeAndUnlock /* isWakeAndUnlock */,
+                CANNED_UNLOCK_START_DELAY /* unlockStartDelay */,
+                LAUNCHER_ICONS_ANIMATION_DURATION_MS /* unlockAnimationDuration */) }
 
         // Finish the keyguard remote animation if the dismiss amount has crossed the threshold.
         // Check it here in case there is no more change to the dismiss amount after the last change
@@ -443,57 +474,32 @@
     }
 
     /**
-     * Called by [KeyguardViewMediator] to let us know that the remote animation has finished, and
-     * we should clean up all of our state.
-     */
-    fun notifyFinishedKeyguardExitAnimation(cancelled: Boolean) {
-        // Cancel any pending actions.
-        handler.removeCallbacksAndMessages(null)
-
-        // Make sure we made the surface behind fully visible, just in case. It should already be
-        // fully visible.
-        setSurfaceBehindAppearAmount(1f)
-        launcherUnlockController?.setUnlockAmount(1f)
-        smartspaceDestBounds.setEmpty()
-
-        // That target is no longer valid since the animation finished, null it out.
-        surfaceBehindRemoteAnimationTarget = null
-        surfaceBehindParams = null
-
-        playingCannedUnlockAnimation = false
-        unlockingToLauncherWithInWindowAnimations = false
-        unlockingWithSmartspaceTransition = false
-        resetSmartspaceTransition()
-
-        listeners.forEach { it.onUnlockAnimationFinished() }
-    }
-
-    /**
      * Play a canned unlock animation to unlock the device. This is used when we were *not* swiping
      * to unlock using a touch gesture. If we were swiping to unlock, the animation will be driven
      * by the dismiss amount via [onKeyguardDismissAmountChanged].
      */
-    fun playCannedUnlockAnimation() {
+    private fun playCannedUnlockAnimation() {
         playingCannedUnlockAnimation = true
 
-        if (canPerformInWindowLauncherAnimations()) {
-            // If possible, use the neat in-window animations to unlock to the launcher.
-            unlockToLauncherWithInWindowAnimations()
-        } else if (!biometricUnlockControllerLazy.get().isWakeAndUnlock) {
-            // If the launcher isn't behind the keyguard, or the launcher unlock controller is not
-            // available, animate in the entire window.
-            surfaceBehindEntryAnimator.start()
-        } else {
-            setSurfaceBehindAppearAmount(1f)
-            keyguardViewMediator.get().onKeyguardExitRemoteAnimationFinished(false)
-        }
 
-        // If this is a wake and unlock, hide the lockscreen immediately. In the future, we should
-        // animate it out nicely instead, but to the current state of wake and unlock, not hiding it
-        // causes a lot of issues.
-        // TODO(b/210016643): Not this, it looks not-ideal!
-        if (biometricUnlockControllerLazy.get().isWakeAndUnlock) {
-            keyguardViewController.hide(surfaceBehindRemoteAnimationStartTime, 350)
+        when {
+            // If we're set up for in-window launcher animations, ask Launcher to play its in-window
+            // canned animation.
+            willUnlockWithInWindowLauncherAnimations -> unlockToLauncherWithInWindowAnimations()
+
+            // If we're waking and unlocking to a non-Launcher app surface (or Launcher in-window
+            // animations are not available), show it immediately and end the remote animation. The
+            // circular light reveal will show the app surface, and it looks weird if it's moving
+            // around behind that.
+            biometricUnlockControllerLazy.get().isWakeAndUnlock -> {
+                setSurfaceBehindAppearAmount(1f)
+                keyguardViewMediator.get().onKeyguardExitRemoteAnimationFinished(
+                    false /* cancelled */)
+            }
+
+            // Otherwise, we're doing a normal full-window unlock. Start this animator, which will
+            // scale/translate the window underneath the lockscreen.
+            else -> surfaceBehindEntryAnimator.start()
         }
     }
 
@@ -502,205 +508,31 @@
      * transition if possible.
      */
     private fun unlockToLauncherWithInWindowAnimations() {
-        // See if we can do the smartspace transition, and if so, do it!
-        if (prepareForSmartspaceTransition()) {
-            animateSmartspaceToDestination()
-            listeners.forEach { it.onSmartspaceSharedElementTransitionStarted() }
-        }
-
-        val startDelay = Settings.Secure.getLong(
-            context.contentResolver, "unlock_start_delay", CANNED_UNLOCK_START_DELAY)
-        val duration = Settings.Secure.getLong(
-            context.contentResolver, "unlock_duration", LAUNCHER_ICONS_ANIMATION_DURATION_MS)
-
-        unlockingToLauncherWithInWindowAnimations = true
-        prepareLauncherWorkspaceForUnlockAnimation()
+        setSurfaceBehindAppearAmount(1f)
 
         // Begin the animation, waiting for the shade to animate out.
         launcherUnlockController?.playUnlockAnimation(
             true /* unlocked */,
-            duration /* duration */,
-            startDelay /* startDelay */)
+            LAUNCHER_ICONS_ANIMATION_DURATION_MS /* duration */,
+            CANNED_UNLOCK_START_DELAY /* startDelay */)
 
+        // Now that the Launcher surface (with its smartspace positioned identically to ours) is
+        // visible, hide our smartspace.
+        lockscreenSmartspace!!.visibility = View.INVISIBLE
+
+        // As soon as the shade has animated out of the way, finish the keyguard exit animation. The
+        // in-window animations in the Launcher window will end on their own.
         handler.postDelayed({
-            applyParamsToSurface(
-                SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(
-                    surfaceBehindRemoteAnimationTarget!!.leash)
-                    .withAlpha(1f)
-                    .build())
-        }, startDelay)
-
-        if (!unlockingWithSmartspaceTransition) {
-            // If we are not unlocking with the smartspace transition, wait for the unlock animation
-            // to end and then finish the remote animation. If we are using the smartspace
-            // transition, it will finish the remote animation once it ends.
-            handler.postDelayed({
-                keyguardViewMediator.get().onKeyguardExitRemoteAnimationFinished(
-                    false /* cancelled */)
-            }, UNLOCK_ANIMATION_DURATION_MS)
-        }
-    }
-
-    /**
-     * Asks Launcher to prepare the workspace to be unlocked. This sets up the animation and makes
-     * the page invisible.
-     */
-    private fun prepareLauncherWorkspaceForUnlockAnimation() {
-        // Tell the launcher to prepare for the animation by setting its views invisible and
-        // syncing the selected smartspace pages.
-        launcherUnlockController?.prepareForUnlock(
-            unlockingWithSmartspaceTransition /* willAnimateSmartspace */,
-            (lockscreenSmartspace as BcSmartspaceDataPlugin.SmartspaceView?)?.selectedPage ?: -1)
-    }
-
-    /**
-     * Animates the lockscreen smartspace all the way to the launcher's smartspace location, then
-     * makes the launcher smartspace visible and ends the remote animation.
-     */
-    private fun animateSmartspaceToDestination() {
-        smartspaceAnimator.start()
-    }
-
-    /**
-     * Reset the lockscreen smartspace's position, and reset all state involving the smartspace
-     * transition.
-     */
-    public fun resetSmartspaceTransition() {
-        unlockingWithSmartspaceTransition = false
-        smartspaceUnlockProgress = 0f
-
-        lockscreenSmartspace?.post {
-            lockscreenSmartspace!!.translationX = 0f
-            lockscreenSmartspace!!.translationY = 0f
-        }
-    }
-
-    /**
-     * Moves the lockscreen smartspace towards the launcher smartspace's position.
-     */
-    private fun setSmartspaceProgressToDestinationBounds(progress: Float) {
-        if (smartspaceDestBounds.isEmpty) {
-            return
-        }
-
-        val progressClamped = min(1f, progress)
-
-        // Calculate the distance (relative to the origin) that we need to be for the current
-        // progress value.
-        val progressX =
-                (smartspaceDestBounds.left - smartspaceOriginBounds.left) * progressClamped
-        val progressY =
-                (smartspaceDestBounds.top - smartspaceOriginBounds.top) * progressClamped
-
-        val lockscreenSmartspaceCurrentBounds = Rect().also {
-            lockscreenSmartspace!!.getBoundsOnScreen(it)
-        }
-
-        // Figure out how far that is from our present location on the screen. This approach
-        // compensates for the fact that our parent container is also translating to animate out.
-        val dx = smartspaceOriginBounds.left + progressX -
-                lockscreenSmartspaceCurrentBounds.left
-        val dy = smartspaceOriginBounds.top + progressY -
-                lockscreenSmartspaceCurrentBounds.top
-
-        with(lockscreenSmartspace!!) {
-            translationX += dx
-            translationY += dy
-        }
-    }
-
-    /**
-     * Update the lockscreen SmartSpace to be positioned according to the current dismiss amount. As
-     * the dismiss amount increases, we will increase our SmartSpace's progress to the destination
-     * bounds (the location of the Launcher SmartSpace).
-     *
-     * This is used by [KeyguardClockSwitchController] to keep the smartspace position updated as
-     * the clock is swiped away.
-     */
-    fun updateLockscreenSmartSpacePosition() {
-        setSmartspaceProgressToDestinationBounds(smartspaceUnlockProgress)
-    }
-
-    /**
-     * Asks the keyguard view to hide, using the start time from the beginning of the remote
-     * animation.
-     */
-    fun hideKeyguardViewAfterRemoteAnimation() {
-        if (keyguardViewController.isShowing) {
-            // Hide the keyguard, with no fade out since we animated it away during the unlock.
-            keyguardViewController.hide(
-                surfaceBehindRemoteAnimationStartTime,
-                0 /* fadeOutDuration */
-            )
-        } else {
-            Log.e(TAG, "#hideKeyguardViewAfterRemoteAnimation called when keyguard view is not " +
-                    "showing. Ignoring...")
-        }
-    }
-
-    private fun applyParamsToSurface(params: SyncRtSurfaceTransactionApplier.SurfaceParams) {
-        surfaceTransactionApplier!!.scheduleApply(params)
-        surfaceBehindParams = params
-    }
-
-    /**
-     * Scales in and translates up the surface behind the keyguard. This is used during unlock
-     * animations and swipe gestures to animate the surface's entry (and exit, if the swipe is
-     * cancelled).
-     */
-    fun setSurfaceBehindAppearAmount(amount: Float) {
-        if (surfaceBehindRemoteAnimationTarget == null) {
-            return
-        }
-
-        if (unlockingToLauncherWithInWindowAnimations) {
-            // If we aren't using the canned unlock animation (which would be setting the unlock
-            // amount in its update listener), do it here.
-            if (!isPlayingCannedUnlockAnimation()) {
-                launcherUnlockController?.setUnlockAmount(amount)
-
-                if (surfaceBehindParams?.alpha?.let { it < 1f } != false) {
-                    applyParamsToSurface(
-                        SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(
-                            surfaceBehindRemoteAnimationTarget!!.leash)
-                            .withAlpha(1f)
-                            .build())
-                }
+            if (keyguardViewMediator.get().isShowingAndNotOccluded &&
+                !keyguardStateController.isKeyguardGoingAway) {
+                    Log.e(TAG, "Finish keyguard exit animation delayed Runnable ran, but we are " +
+                            "showing and not going away.")
+                return@postDelayed
             }
-        } else {
-            // Otherwise, animate in the surface's scale/transltion.
-            val surfaceHeight: Int = surfaceBehindRemoteAnimationTarget!!.screenSpaceBounds.height()
-            val scaleFactor = (SURFACE_BEHIND_START_SCALE_FACTOR +
-                    (1f - SURFACE_BEHIND_START_SCALE_FACTOR) *
-                    MathUtils.clamp(amount, 0f, 1f))
 
-            // Scale up from a point at the center-bottom of the surface.
-            surfaceBehindMatrix.setScale(
-                scaleFactor,
-                scaleFactor,
-                surfaceBehindRemoteAnimationTarget!!.screenSpaceBounds.width() / 2f,
-                surfaceHeight * SURFACE_BEHIND_SCALE_PIVOT_Y
-            )
-
-            // Translate up from the bottom.
-            surfaceBehindMatrix.postTranslate(
-                0f,
-                surfaceHeight * SURFACE_BEHIND_START_TRANSLATION_Y * (1f - amount)
-            )
-
-            // If we're snapping the keyguard back, immediately begin fading it out.
-            val animationAlpha =
-                if (keyguardStateController.isSnappingKeyguardBackAfterSwipe) amount
-                else surfaceBehindAlpha
-
-            applyParamsToSurface(
-                SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(
-                    surfaceBehindRemoteAnimationTarget!!.leash)
-                .withMatrix(surfaceBehindMatrix)
-                .withCornerRadius(roundedCornerRadius)
-                .withAlpha(animationAlpha)
-                .build())
-        }
+            keyguardViewMediator.get().onKeyguardExitRemoteAnimationFinished(
+                false /* cancelled */)
+        }, CANNED_UNLOCK_START_DELAY)
     }
 
     /**
@@ -738,7 +570,7 @@
             return
         }
 
-        if (keyguardViewController.isShowing) {
+        if (keyguardViewController.isShowing && !playingCannedUnlockAnimation) {
             showOrHideSurfaceIfDismissAmountThresholdsReached()
 
             // If the surface is visible or it's about to be, start updating its appearance to
@@ -750,11 +582,6 @@
                 updateSurfaceBehindAppearAmount()
             }
         }
-
-        // The end of the SmartSpace transition can occur after the keyguard is hidden (when we tell
-        // Launcher's SmartSpace to become visible again), so update it even if the keyguard view is
-        // no longer showing.
-        applyDismissAmountToSmartspaceTransition()
     }
 
     /**
@@ -775,16 +602,15 @@
             return
         }
 
+        if (!keyguardStateController.isShowing) {
+            return
+        }
+
         val dismissAmount = keyguardStateController.dismissAmount
+
         if (dismissAmount >= DISMISS_AMOUNT_SHOW_SURFACE_THRESHOLD &&
-                !keyguardViewMediator.get().requestedShowSurfaceBehindKeyguard()) {
-            // We passed the threshold, and we're not yet showing the surface behind the
-            // keyguard. Animate it in.
-            if (!unlockingToLauncherWithInWindowAnimations &&
-                canPerformInWindowLauncherAnimations()) {
-                unlockingToLauncherWithInWindowAnimations = true
-                prepareLauncherWorkspaceForUnlockAnimation()
-            }
+            !keyguardViewMediator.get().requestedShowSurfaceBehindKeyguard()) {
+
             keyguardViewMediator.get().showSurfaceBehindKeyguard()
             fadeInSurfaceBehind()
         } else if (dismissAmount < DISMISS_AMOUNT_SHOW_SURFACE_THRESHOLD &&
@@ -828,58 +654,101 @@
     }
 
     /**
-     * Updates flags related to the SmartSpace transition in response to a change in keyguard
-     * dismiss amount, and also updates the SmartSpaceTransitionController, which will let Launcher
-     * know if it needs to do something as a result.
+     * Scales in and translates up the surface behind the keyguard. This is used during unlock
+     * animations and swipe gestures to animate the surface's entry (and exit, if the swipe is
+     * cancelled).
      */
-    private fun applyDismissAmountToSmartspaceTransition() {
-        if (!featureFlags.isEnabled(Flags.SMARTSPACE_SHARED_ELEMENT_TRANSITION_ENABLED)) {
+    fun setSurfaceBehindAppearAmount(amount: Float) {
+        if (surfaceBehindRemoteAnimationTarget == null) {
             return
         }
 
-        // If we are playing the canned animation, the smartspace is being animated directly between
-        // its original location and the location of the launcher smartspace by smartspaceAnimator.
-        // We can ignore the dismiss amount, which is caused by panel height changes as the panel is
-        // flung away.
-        if (playingCannedUnlockAnimation) {
-            return
+        // Otherwise, animate in the surface's scale/transltion.
+        val surfaceHeight: Int = surfaceBehindRemoteAnimationTarget!!.screenSpaceBounds.height()
+        val scaleFactor = (SURFACE_BEHIND_START_SCALE_FACTOR +
+                (1f - SURFACE_BEHIND_START_SCALE_FACTOR) *
+                MathUtils.clamp(amount, 0f, 1f))
+
+        // Scale up from a point at the center-bottom of the surface.
+        surfaceBehindMatrix.setScale(
+            scaleFactor,
+            scaleFactor,
+            surfaceBehindRemoteAnimationTarget!!.screenSpaceBounds.width() / 2f,
+            surfaceHeight * SURFACE_BEHIND_SCALE_PIVOT_Y
+        )
+
+        // Translate up from the bottom.
+        surfaceBehindMatrix.postTranslate(
+            0f,
+            surfaceHeight * SURFACE_BEHIND_START_TRANSLATION_Y * (1f - amount)
+        )
+
+        // If we're snapping the keyguard back, immediately begin fading it out.
+        val animationAlpha =
+            if (keyguardStateController.isSnappingKeyguardBackAfterSwipe) amount
+            else surfaceBehindAlpha
+
+        applyParamsToSurface(
+            SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(
+                surfaceBehindRemoteAnimationTarget!!.leash)
+                .withMatrix(surfaceBehindMatrix)
+                .withCornerRadius(roundedCornerRadius)
+                .withAlpha(animationAlpha)
+                .build())
+    }
+
+    /**
+     * Called by [KeyguardViewMediator] to let us know that the remote animation has finished, and
+     * we should clean up all of our state.
+     *
+     * This is generally triggered by us, calling
+     * [KeyguardViewMediator.finishSurfaceBehindRemoteAnimation].
+     */
+    fun notifyFinishedKeyguardExitAnimation(cancelled: Boolean) {
+        // Cancel any pending actions.
+        handler.removeCallbacksAndMessages(null)
+
+        // Make sure we made the surface behind fully visible, just in case. It should already be
+        // fully visible. If the launcher is doing its own animation, let it continue without
+        // forcing it to 1f.
+        setSurfaceBehindAppearAmount(1f)
+        launcherUnlockController?.setUnlockAmount(1f, false /* forceIfAnimating */)
+
+        // That target is no longer valid since the animation finished, null it out.
+        surfaceBehindRemoteAnimationTarget = null
+        surfaceBehindParams = null
+
+        playingCannedUnlockAnimation = false
+        willUnlockWithInWindowLauncherAnimations = false
+        willUnlockWithSmartspaceTransition = false
+
+        // The lockscreen surface is gone, so it is now safe to re-show the smartspace.
+        lockscreenSmartspace!!.visibility = View.VISIBLE
+
+        listeners.forEach { it.onUnlockAnimationFinished() }
+    }
+
+    /**
+     * Asks the keyguard view to hide, using the start time from the beginning of the remote
+     * animation.
+     */
+    fun hideKeyguardViewAfterRemoteAnimation() {
+        if (keyguardViewController.isShowing) {
+            // Hide the keyguard, with no fade out since we animated it away during the unlock.
+
+            keyguardViewController.hide(
+                surfaceBehindRemoteAnimationStartTime,
+                0 /* fadeOutDuration */
+            )
+        } else {
+            Log.e(TAG, "#hideKeyguardViewAfterRemoteAnimation called when keyguard view is not " +
+                    "showing. Ignoring...")
         }
+    }
 
-        val dismissAmount = keyguardStateController.dismissAmount
-
-        // If we've begun a swipe, and haven't yet tried doing the SmartSpace transition, do that
-        // now.
-        if (!attemptedSmartSpaceTransitionForThisSwipe &&
-            keyguardViewController.isShowing &&
-            dismissAmount > 0f &&
-            dismissAmount < 1f) {
-            attemptedSmartSpaceTransitionForThisSwipe = true
-
-            if (prepareForSmartspaceTransition()) {
-                unlockingWithSmartspaceTransition = true
-
-                // Ensure that the smartspace is invisible if we're doing the transition, and
-                // visible if we aren't.
-                launcherUnlockController?.setSmartspaceVisibility(
-                    if (unlockingWithSmartspaceTransition) View.INVISIBLE else View.VISIBLE)
-
-                if (unlockingWithSmartspaceTransition) {
-                    listeners.forEach { it.onSmartspaceSharedElementTransitionStarted() }
-                }
-            }
-        } else if (attemptedSmartSpaceTransitionForThisSwipe &&
-            (dismissAmount == 0f || dismissAmount == 1f)) {
-            attemptedSmartSpaceTransitionForThisSwipe = false
-            unlockingWithSmartspaceTransition = false
-            launcherUnlockController?.setSmartspaceVisibility(View.VISIBLE)
-        }
-
-        if (unlockingWithSmartspaceTransition) {
-            val swipedFraction: Float = keyguardStateController.dismissAmount
-            val progress = swipedFraction / DISMISS_AMOUNT_EXIT_KEYGUARD_THRESHOLD
-            smartspaceUnlockProgress = progress
-            setSmartspaceProgressToDestinationBounds(smartspaceUnlockProgress)
-        }
+    private fun applyParamsToSurface(params: SyncRtSurfaceTransactionApplier.SurfaceParams) {
+        surfaceTransactionApplier!!.scheduleApply(params)
+        surfaceBehindParams = params
     }
 
     private fun fadeInSurfaceBehind() {
@@ -892,14 +761,8 @@
         surfaceBehindAlphaAnimator.reverse()
     }
 
-    /**
-     * Prepare for the smartspace shared element transition, if possible, by figuring out where we
-     * are animating from/to.
-     *
-     * Return true if we'll be able to do the smartspace transition, or false if conditions are not
-     * right to do it right now.
-     */
-    private fun prepareForSmartspaceTransition(): Boolean {
+
+    private fun shouldPerformSmartspaceTransition(): Boolean {
         // Feature is disabled, so we don't want to.
         if (!featureFlags.isEnabled(Flags.SMARTSPACE_SHARED_ELEMENT_TRANSITION_ENABLED)) {
             return false
@@ -940,45 +803,22 @@
             return false
         }
 
-        unlockingWithSmartspaceTransition = true
-        smartspaceDestBounds.setEmpty()
-
-        // Assuming we were able to retrieve the launcher's state, start the lockscreen
-        // smartspace at 0, 0, and save its starting bounds.
-        with(lockscreenSmartspace!!) {
-            translationX = 0f
-            translationY = 0f
-            getBoundsOnScreen(smartspaceOriginBounds)
-        }
-
-        // Set the destination bounds to the launcher smartspace's bounds, offset by any
-        // padding on our smartspace.
-        with(smartspaceDestBounds) {
-            set(launcherSmartspaceState!!.boundsOnScreen)
-            offset(-lockscreenSmartspace!!.paddingLeft, -lockscreenSmartspace!!.paddingTop)
+        // We started to swipe to dismiss, but now we're doing a fling animation to complete the
+        // dismiss. In this case, the smartspace swiped away with the rest of the keyguard, so don't
+        // do the shared element transition.
+        if (keyguardStateController.isFlingingToDismissKeyguardDuringSwipeGesture) {
+            return false
         }
 
         return true
     }
 
     /**
-     * Whether we should be able to do the in-window launcher animations given the current state of
-     * the device.
-     */
-    fun canPerformInWindowLauncherAnimations(): Boolean {
-        return isNexusLauncherUnderneath() &&
-                launcherUnlockController != null &&
-                // Temporarily disable for foldables since foldable launcher has two first pages,
-                // which breaks the in-window animation.
-                !isFoldable(context)
-    }
-
-    /**
      * Whether we are currently in the process of unlocking the keyguard, and we are performing the
      * shared element SmartSpace transition.
      */
     fun isUnlockingWithSmartSpaceTransition(): Boolean {
-        return unlockingWithSmartspaceTransition
+        return willUnlockWithSmartspaceTransition
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index bcb440b..5cd2029 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -849,7 +849,8 @@
 
                 @Override
                 public void onLaunchAnimationCancelled() {
-                    setOccluded(true /* occluded */, false /* animate */);
+                    Log.d(TAG, "Occlude launch animation cancelled. "
+                            + "Occluded state is now: " + mOccluded);
                 }
 
                 @NonNull
@@ -894,7 +895,7 @@
             };
 
     private IRemoteAnimationRunner mOccludeAnimationRunner =
-            new ActivityLaunchRemoteAnimationRunner(mOccludeAnimationController);
+            new OccludeActivityLaunchRemoteAnimationRunner(mOccludeAnimationController);
 
     /**
      * Animation controller for activities that unocclude the keyguard. This does not use the
@@ -919,13 +920,17 @@
                         RemoteAnimationTarget[] wallpapers,
                         RemoteAnimationTarget[] nonApps,
                         IRemoteAnimationFinishedCallback finishedCallback) throws RemoteException {
-                    final RemoteAnimationTarget primary = apps[0];
+                    if (apps == null || apps.length == 0 || apps[0] == null) {
+                        Log.d(TAG, "No apps provided to unocclude runner; "
+                                + "skipping animation and unoccluding.");
 
-                    if (primary == null) {
                         finishedCallback.onAnimationFinished();
+                        setOccluded(false /* isOccluded */, true /* animate */);
                         return;
                     }
 
+                    final RemoteAnimationTarget primary = apps[0];
+
                     final SyncRtSurfaceTransactionApplier applier =
                             new SyncRtSurfaceTransactionApplier(
                                     mKeyguardViewControllerLazy.get().getViewRootImpl().getView());
@@ -965,6 +970,7 @@
                             @Override
                             public void onAnimationEnd(Animator animation) {
                                 try {
+                                    setOccluded(false /* isOccluded */, true /* animate */);
                                     finishedCallback.onAnimationFinished();
                                     mUnoccludeAnimator = null;
                                 } catch (RemoteException e) {
@@ -2648,7 +2654,7 @@
     }
 
     /** If it's running, finishes the RemoteAnimation on the surface behind the keyguard. */
-    public void finishSurfaceBehindRemoteAnimation(boolean cancelled) {
+    void finishSurfaceBehindRemoteAnimation(boolean cancelled) {
         if (!mSurfaceBehindRemoteAnimationRunning) {
             return;
         }
@@ -3119,4 +3125,36 @@
             mRunner.onAnimationStart(transit, apps, wallpapers, nonApps, finishedCallback);
         }
     }
+
+    /**
+     * Subclass of {@link ActivityLaunchRemoteAnimationRunner} that calls {@link #setOccluded} when
+     * onAnimationStart is called.
+     */
+    private class OccludeActivityLaunchRemoteAnimationRunner
+            extends ActivityLaunchRemoteAnimationRunner {
+
+        OccludeActivityLaunchRemoteAnimationRunner(
+                ActivityLaunchAnimator.Controller controller) {
+            super(controller);
+        }
+
+        @Override
+        public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
+                RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
+                IRemoteAnimationFinishedCallback finishedCallback) throws RemoteException {
+            super.onAnimationStart(transit, apps, wallpapers, nonApps, finishedCallback);
+
+            // This is the first signal we have from WM that we're going to be occluded. Set our
+            // internal state to reflect that immediately, vs. waiting for the launch animator to
+            // begin. Otherwise, calls to setShowingLocked, etc. will not know that we're about to
+            // be occluded and might re-show the keyguard.
+            setOccluded(true /* isOccluded */, false /* animate */);
+        }
+
+        @Override
+        public void onAnimationCancelled() throws RemoteException {
+            super.onAnimationCancelled();
+            Log.d(TAG, "Occlude launch animation cancelled. Occluded state is now: " + mOccluded);
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index d2c35bd..d9ee8f3 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -30,10 +30,12 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.res.ColorStateList;
+import android.graphics.Color;
 import android.graphics.ColorMatrix;
 import android.graphics.ColorMatrixColorFilter;
 import android.graphics.Rect;
 import android.graphics.drawable.Animatable;
+import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
 import android.graphics.drawable.TransitionDrawable;
@@ -159,6 +161,7 @@
     private MetadataAnimationHandler mMetadataAnimationHandler;
     private ColorSchemeTransition mColorSchemeTransition;
     private Drawable mPrevArtwork = null;
+    private boolean mIsArtworkBound = false;
     private int mArtworkBoundId = 0;
     private int mArtworkNextBindRequestId = 0;
 
@@ -586,6 +589,9 @@
 
     private void bindArtworkAndColors(MediaData data, boolean updateBackground) {
         final int reqId = mArtworkNextBindRequestId++;
+        if (updateBackground) {
+            mIsArtworkBound = false;
+        }
 
         // Capture width & height from views in foreground for artwork scaling in background
         int width = mMediaViewHolder.getPlayer().getWidth();
@@ -597,15 +603,18 @@
             // Album art
             ColorScheme mutableColorScheme = null;
             Drawable artwork;
+            boolean isArtworkBound;
             Icon artworkIcon = data.getArtwork();
             if (artworkIcon != null) {
                 WallpaperColors wallpaperColors = WallpaperColors
                         .fromBitmap(artworkIcon.getBitmap());
                 mutableColorScheme = new ColorScheme(wallpaperColors, true);
                 artwork = getScaledBackground(artworkIcon, width, height);
+                isArtworkBound = true;
             } else {
                 // If there's no artwork, use colors from the app icon
-                artwork = null;
+                artwork = new ColorDrawable(Color.TRANSPARENT);
+                isArtworkBound = false;
                 try {
                     Drawable icon = mContext.getPackageManager()
                             .getApplicationIcon(data.getPackageName());
@@ -625,16 +634,20 @@
                 ImageView albumView = mMediaViewHolder.getAlbumView();
                 albumView.setPadding(0, 0, 0, 0);
                 albumView.setClipToOutline(true);
-                if (updateBackground) {
-                    if (mPrevArtwork == null || artwork == null) {
+                if (updateBackground || (!mIsArtworkBound && isArtworkBound)) {
+                    if (mPrevArtwork == null) {
                         albumView.setImageDrawable(artwork);
                     } else {
+                        // Since we throw away the last transition, this'll pop if you backgrounds
+                        // are cycled too fast (or the correct background arrives very soon after
+                        // the metadata changes).
                         TransitionDrawable transitionDrawable = new TransitionDrawable(
-                                new Drawable[] { mPrevArtwork, artwork });
+                                new Drawable[]{mPrevArtwork, artwork});
                         albumView.setImageDrawable(transitionDrawable);
-                        transitionDrawable.startTransition(333);
+                        transitionDrawable.startTransition(isArtworkBound ? 333 : 80);
                     }
                     mPrevArtwork = artwork;
+                    mIsArtworkBound = isArtworkBound;
                 }
 
                 // Transition Colors to current color scheme
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
index 72488f3..357ff38 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
@@ -197,6 +197,7 @@
     private final Optional<Pip> mPipOptional;
     private final Optional<Recents> mRecentsOptional;
     private final DeviceConfigProxy mDeviceConfigProxy;
+    private final NavigationBarTransitions mNavigationBarTransitions;
     private final Optional<BackAnimation> mBackAnimation;
     private final Handler mHandler;
     private final NavigationBarOverlayController mNavbarOverlayController;
@@ -329,7 +330,8 @@
         @Override
         public void onConnectionChanged(boolean isConnected) {
             mView.onOverviewProxyConnectionChange(
-                    mOverviewProxyService.isEnabled(), mOverviewProxyService.shouldShowSwipeUpUI());
+                    mOverviewProxyService.isEnabled());
+            mView.setShouldShowSwipeUpUi(mOverviewProxyService.shouldShowSwipeUpUI());
             updateScreenPinningGestures();
         }
 
@@ -513,6 +515,7 @@
             InputMethodManager inputMethodManager,
             DeadZone deadZone,
             DeviceConfigProxy deviceConfigProxy,
+            NavigationBarTransitions navigationBarTransitions,
             Optional<BackAnimation> backAnimation) {
         super(navigationBarView);
         mFrame = navigationBarFrame;
@@ -537,6 +540,7 @@
         mRecentsOptional = recentsOptional;
         mDeadZone = deadZone;
         mDeviceConfigProxy = deviceConfigProxy;
+        mNavigationBarTransitions = navigationBarTransitions;
         mBackAnimation = backAnimation;
         mHandler = mainHandler;
         mNavbarOverlayController = navbarOverlayController;
@@ -561,6 +565,7 @@
     public void onInit() {
         // TODO: A great deal of this code should probably live in onViewAttached.
         // It should also has corresponding cleanup in onViewDetached.
+        mView.setBarTransitions(mNavigationBarTransitions);
         mView.setTouchHandler(mTouchHandler);
         mView.setNavBarMode(mNavBarMode);
         mView.updateRotationButton();
@@ -632,7 +637,7 @@
         mView.setOnVerticalChangedListener(this::onVerticalChanged);
         mView.setOnTouchListener(this::onNavigationTouch);
         if (mSavedState != null) {
-            mView.getLightTransitionsController().restoreState(mSavedState);
+            getBarTransitions().getLightTransitionsController().restoreState(mSavedState);
         }
         setNavigationIconHints(mNavigationIconHints);
         mView.setWindowVisible(isNavBarWindowVisible());
@@ -705,8 +710,7 @@
                 mView.getRotationButtonController();
         rotationButtonController.setRotationCallback(null);
         mView.setUpdateActiveTouchRegionsCallback(null);
-        mView.getBarTransitions().destroy();
-        mView.getLightTransitionsController().destroy(mContext);
+        getBarTransitions().destroy();
         mOverviewProxyService.removeCallback(mOverviewProxyListener);
         mBroadcastDispatcher.unregisterReceiver(mBroadcastReceiver);
         if (mOrientationHandle != null) {
@@ -732,7 +736,7 @@
         outState.putInt(EXTRA_APPEARANCE, mAppearance);
         outState.putInt(EXTRA_BEHAVIOR, mBehavior);
         outState.putBoolean(EXTRA_TRANSIENT_STATE, mTransientShown);
-        mView.getLightTransitionsController().saveState(outState);
+        getBarTransitions().getLightTransitionsController().saveState(outState);
     }
 
     /**
@@ -893,7 +897,7 @@
         pw.println("  mTransientShown=" + mTransientShown);
         pw.println("  mTransientShownFromGestureOnSystemBar="
                 + mTransientShownFromGestureOnSystemBar);
-        dumpBarTransitions(pw, "mNavigationBarView", mView.getBarTransitions());
+        dumpBarTransitions(pw, "mNavigationBarView", getBarTransitions());
         mView.dump(pw);
     }
 
@@ -1430,7 +1434,7 @@
         mLightBarController = lightBarController;
         if (mLightBarController != null) {
             mLightBarController.setNavigationBar(
-                    mView.getLightTransitionsController());
+                    getBarTransitions().getLightTransitionsController());
         }
     }
 
@@ -1472,7 +1476,7 @@
                 mCentralSurfacesOptionalLazy.get().map(CentralSurfaces::isDeviceInteractive)
                         .orElse(false)
                 && mNavigationBarWindowState != WINDOW_STATE_HIDDEN;
-        mView.getBarTransitions().transitionTo(mTransitionMode, anim);
+        getBarTransitions().transitionTo(mTransitionMode, anim);
     }
 
     public void disableAnimationsDuringHide(long delay) {
@@ -1492,11 +1496,11 @@
     }
 
     public NavigationBarTransitions getBarTransitions() {
-        return mView.getBarTransitions();
+        return mNavigationBarTransitions;
     }
 
     public void finishBarAnimations() {
-        mView.getBarTransitions().finishAnimations();
+        getBarTransitions().finishAnimations();
     }
 
     private WindowManager.LayoutParams getBarLayoutParams(int rotation) {
@@ -1654,6 +1658,7 @@
             }
             if (mView != null) {
                 mView.setNavBarMode(mode);
+                mView.setShouldShowSwipeUpUi(mOverviewProxyService.shouldShowSwipeUpUI());
             }
         }
     };
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java
index 58e07db..11a4b3b 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java
@@ -29,19 +29,20 @@
 import android.view.IWindowManager;
 import android.view.View;
 
-import com.android.systemui.Dependency;
 import com.android.systemui.R;
+import com.android.systemui.navigationbar.NavigationBarComponent.NavigationBarScope;
 import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.BarTransitions;
 import com.android.systemui.statusbar.phone.LightBarTransitionsController;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.inject.Inject;
+
+/** */
+@NavigationBarScope
 public final class NavigationBarTransitions extends BarTransitions implements
         LightBarTransitionsController.DarkIntensityApplier {
 
@@ -60,6 +61,8 @@
     }
 
     private final NavigationBarView mView;
+    @org.jetbrains.annotations.NotNull
+    private final IWindowManager mWindowManagerService;
     private final LightBarTransitionsController mLightTransitionsController;
     private final boolean mAllowAutoDimWallpaperNotVisible;
     private boolean mWallpaperVisible;
@@ -81,22 +84,21 @@
         }
     };
 
-    public NavigationBarTransitions(NavigationBarView view, CommandQueue commandQueue) {
+    @Inject
+    public NavigationBarTransitions(
+            NavigationBarView view,
+            IWindowManager windowManagerService,
+            LightBarTransitionsController.Factory lightBarTransitionsControllerFactory) {
         super(view, R.drawable.nav_background);
         mView = view;
-        mLightTransitionsController = new LightBarTransitionsController(
-                view.getContext(),
-                this,
-                commandQueue,
-                Dependency.get(KeyguardStateController.class),
-                Dependency.get(StatusBarStateController.class));
+        mWindowManagerService = windowManagerService;
+        mLightTransitionsController = lightBarTransitionsControllerFactory.create(this);
         mAllowAutoDimWallpaperNotVisible = view.getContext().getResources()
                 .getBoolean(R.bool.config_navigation_bar_enable_auto_dim_no_visible_wallpaper);
         mDarkIntensityListeners = new ArrayList();
 
-        IWindowManager windowManagerService = Dependency.get(IWindowManager.class);
         try {
-            mWallpaperVisible = windowManagerService.registerWallpaperVisibilityListener(
+            mWallpaperVisible = mWindowManagerService.registerWallpaperVisibilityListener(
                     mWallpaperVisibilityListener, Display.DEFAULT_DISPLAY);
         } catch (RemoteException e) {
         }
@@ -121,12 +123,12 @@
 
     @Override
     public void destroy() {
-        IWindowManager windowManagerService = Dependency.get(IWindowManager.class);
         try {
-            windowManagerService.unregisterWallpaperVisibilityListener(mWallpaperVisibilityListener,
+            mWindowManagerService.unregisterWallpaperVisibilityListener(mWallpaperVisibilityListener,
                     Display.DEFAULT_DISPLAY);
         } catch (RemoteException e) {
         }
+        mLightTransitionsController.destroy();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
index abff914..f3a3f10 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
@@ -85,7 +85,6 @@
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.shared.system.WindowManagerWrapper;
-import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.AutoHideController;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.LightBarTransitionsController;
@@ -140,7 +139,7 @@
     private EdgeBackGestureHandler mEdgeBackGestureHandler;
     private final DeadZone mDeadZone;
     private boolean mDeadZoneConsuming = false;
-    private final NavigationBarTransitions mBarTransitions;
+    private NavigationBarTransitions mBarTransitions;
     @Nullable
     private AutoHideController mAutoHideController;
 
@@ -370,7 +369,6 @@
         mConfiguration.updateFrom(context.getResources().getConfiguration());
 
         mScreenPinningNotify = new ScreenPinningNotify(mContext);
-        mBarTransitions = new NavigationBarTransitions(this, Dependency.get(CommandQueue.class));
 
         mButtonDispatchers.put(R.id.back, new ButtonDispatcher(R.id.back));
         mButtonDispatchers.put(R.id.home, new ButtonDispatcher(R.id.home));
@@ -418,12 +416,12 @@
         }
     }
 
-    public void setAutoHideController(AutoHideController autoHideController) {
-        mAutoHideController = autoHideController;
+    void setBarTransitions(NavigationBarTransitions navigationBarTransitions) {
+        mBarTransitions = navigationBarTransitions;
     }
 
-    public NavigationBarTransitions getBarTransitions() {
-        return mBarTransitions;
+    public void setAutoHideController(AutoHideController autoHideController) {
+        mAutoHideController = autoHideController;
     }
 
     public LightBarTransitionsController getLightTransitionsController() {
@@ -888,8 +886,11 @@
         }
     }
 
-    void onOverviewProxyConnectionChange(boolean enabled, boolean showSwipeUpUi) {
+    void onOverviewProxyConnectionChange(boolean enabled) {
         mOverviewProxyEnabled = enabled;
+    }
+
+    void setShouldShowSwipeUpUi(boolean showSwipeUpUi) {
         mShowSwipeUpUi = showSwipeUpUi;
         updateStates();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
index cdc6b3b..363baaa 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
@@ -264,7 +264,7 @@
             mWindowContext = null;
         }
         mAutoHideController.setNavigationBar(null);
-        mLightBarTransitionsController.destroy(mContext);
+        mLightBarTransitionsController.destroy();
         mLightBarController.setNavigationBar(null);
         mPipOptional.ifPresent(this::removePipExclusionBoundsChangeListener);
         mInitialized = false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
index 83290af..29411e6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
@@ -61,6 +61,7 @@
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
+import com.android.systemui.statusbar.phone.CentralSurfacesImpl;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.ManagedProfileController;
 import com.android.systemui.statusbar.phone.ManagedProfileControllerImpl;
@@ -87,7 +88,7 @@
 import dagger.Provides;
 
 /**
- * This module provides instances needed to construct {@link CentralSurfaces}. These are moved to
+ * This module provides instances needed to construct {@link CentralSurfacesImpl}. These are moved to
  * this separate from {@link CentralSurfacesModule} module so that components that wish to build
  * their own version of CentralSurfaces can include just dependencies, without injecting
  * CentralSurfaces itself.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StartCentralSurfacesModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StartCentralSurfacesModule.kt
index fe55dea7..e84d31d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StartCentralSurfacesModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StartCentralSurfacesModule.kt
@@ -18,6 +18,7 @@
 
 import com.android.systemui.CoreStartable
 import com.android.systemui.statusbar.phone.CentralSurfaces
+import com.android.systemui.statusbar.phone.CentralSurfacesImpl
 import dagger.Binds
 import dagger.Module
 import dagger.multibindings.ClassKey
@@ -29,5 +30,5 @@
     @Binds
     @IntoMap
     @ClassKey(CentralSurfaces::class)
-    abstract fun bindsCentralSurfaces(centralSurfaces: CentralSurfaces): CoreStartable
+    abstract fun bindsCentralSurfaces(centralSurfaces: CentralSurfacesImpl): CoreStartable
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index cf3783e..36cd173 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -85,8 +85,8 @@
 import com.android.systemui.statusbar.NotificationShelf;
 import com.android.systemui.statusbar.NotificationShelfController;
 import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.notification.LaunchAnimationParameters;
 import com.android.systemui.statusbar.notification.FakeShadowView;
+import com.android.systemui.statusbar.notification.LaunchAnimationParameters;
 import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorController;
 import com.android.systemui.statusbar.notification.NotificationUtils;
 import com.android.systemui.statusbar.notification.ShadeViewRefactor;
@@ -415,6 +415,10 @@
     private boolean mForwardScrollable;
     private boolean mBackwardScrollable;
     private NotificationShelf mShelf;
+    /**
+     * Limits the number of visible notifications. The remaining are collapsed in the notification
+     * shelf. -1 when there is no limit.
+     */
     private int mMaxDisplayedNotifications = -1;
     private float mKeyguardBottomPadding = -1;
     @VisibleForTesting int mStatusBarHeight;
@@ -1323,7 +1327,14 @@
     }
 
     private float updateStackEndHeight(float height, float bottomMargin, float topPadding) {
-        final float stackEndHeight = Math.max(0f, height - bottomMargin - topPadding);
+        final float stackEndHeight;
+        if (mMaxDisplayedNotifications != -1) {
+            // The stack intrinsic height already contains the correct value when there is a limit
+            // in the max number of notifications (e.g. as in keyguard).
+            stackEndHeight = mIntrinsicContentHeight;
+        } else {
+            stackEndHeight = Math.max(0f, height - bottomMargin - topPadding);
+        }
         mAmbientState.setStackEndHeight(stackEndHeight);
         return stackEndHeight;
     }
@@ -3615,7 +3626,7 @@
     @ShadeViewRefactor(RefactorComponent.INPUT)
     protected boolean isInsideQsHeader(MotionEvent ev) {
         mQsHeader.getBoundsOnScreen(mQsHeaderBound);
-        return mQsHeaderBound.contains((int) ev.getX(), (int) ev.getY());
+        return mQsHeaderBound.contains((int) ev.getRawX(), (int) ev.getRawY());
     }
 
     @ShadeViewRefactor(RefactorComponent.INPUT)
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 f047832..39d6b6e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2022 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,2351 +16,89 @@
 
 package com.android.systemui.statusbar.phone;
 
-import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
-import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
-import static android.app.StatusBarManager.WindowVisibleState;
-import static android.app.StatusBarManager.windowStateToString;
-import static android.view.InsetsState.ITYPE_STATUS_BAR;
-import static android.view.InsetsState.containsType;
-import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
-import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_STATUS_BARS;
-import static android.view.WindowInsetsController.APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS;
-
-import static androidx.core.view.ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_AUTO;
-import static androidx.core.view.ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS;
-import static androidx.lifecycle.Lifecycle.State.RESUMED;
-
-import static com.android.systemui.Dependency.TIME_TICK_HANDLER_NAME;
-import static com.android.systemui.charging.WirelessChargingLayout.UNKNOWN_BATTERY_LEVEL;
-import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP;
-import static com.android.systemui.statusbar.NotificationLockscreenUserManager.PERMISSION_SELF;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
-import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
 import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS;
 
 import android.annotation.Nullable;
-import android.app.ActivityManager;
 import android.app.ActivityOptions;
-import android.app.ActivityTaskManager;
-import android.app.IWallpaperManager;
-import android.app.KeyguardManager;
-import android.app.Notification;
-import android.app.NotificationManager;
 import android.app.PendingIntent;
-import android.app.StatusBarManager;
-import android.app.TaskInfo;
-import android.app.TaskStackBuilder;
-import android.app.UiModeManager;
-import android.app.WallpaperInfo;
-import android.app.WallpaperManager;
-import android.app.admin.DevicePolicyManager;
-import android.content.BroadcastReceiver;
-import android.content.ComponentCallbacks2;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ResolveInfo;
-import android.content.res.Configuration;
-import android.graphics.Point;
-import android.graphics.PointF;
-import android.hardware.devicestate.DeviceStateManager;
-import android.metrics.LogMaker;
-import android.net.Uri;
 import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.os.Trace;
 import android.os.UserHandle;
-import android.provider.Settings;
-import android.service.dreams.DreamService;
-import android.service.dreams.IDreamManager;
 import android.service.notification.StatusBarNotification;
-import android.text.TextUtils;
-import android.util.ArraySet;
-import android.util.DisplayMetrics;
-import android.util.EventLog;
-import android.util.IndentingPrintWriter;
-import android.util.Log;
-import android.util.MathUtils;
-import android.util.Slog;
-import android.view.Display;
-import android.view.IRemoteAnimationRunner;
-import android.view.IWindowManager;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.RemoteAnimationAdapter;
-import android.view.ThreadedRenderer;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.WindowInsetsController.Appearance;
-import android.view.WindowManager;
-import android.view.WindowManagerGlobal;
-import android.view.accessibility.AccessibilityManager;
-import android.widget.DateTimeView;
+import android.window.SplashScreen;
 
 import androidx.annotation.NonNull;
 import androidx.lifecycle.Lifecycle;
 import androidx.lifecycle.LifecycleOwner;
-import androidx.lifecycle.LifecycleRegistry;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.colorextraction.ColorExtractor;
-import com.android.internal.jank.InteractionJankMonitor;
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.UiEvent;
-import com.android.internal.logging.UiEventLogger;
-import com.android.internal.logging.UiEventLoggerImpl;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.statusbar.RegisterStatusBarResult;
-import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.keyguard.ViewMediatorCallback;
-import com.android.systemui.ActivityIntentHelper;
-import com.android.systemui.AutoReinflateContainer;
-import com.android.systemui.CoreStartable;
-import com.android.systemui.DejankUtils;
-import com.android.systemui.EventLogTags;
-import com.android.systemui.InitController;
-import com.android.systemui.Prefs;
-import com.android.systemui.R;
-import com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuController;
+import com.android.systemui.Dumpable;
 import com.android.systemui.animation.ActivityLaunchAnimator;
-import com.android.systemui.animation.DelegateLaunchAnimatorController;
 import com.android.systemui.animation.RemoteTransitionAdapter;
-import com.android.systemui.assist.AssistManager;
-import com.android.systemui.biometrics.AuthRippleController;
-import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.camera.CameraIntents;
-import com.android.systemui.charging.WirelessChargingAnimation;
-import com.android.systemui.classifier.FalsingCollector;
-import com.android.systemui.colorextraction.SysuiColorExtractor;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.dagger.qualifiers.UiBackground;
-import com.android.systemui.demomode.DemoMode;
-import com.android.systemui.demomode.DemoModeController;
-import com.android.systemui.dreams.DreamOverlayStateController;
-import com.android.systemui.emergency.EmergencyGesture;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
-import com.android.systemui.fragments.ExtensionFragmentListener;
-import com.android.systemui.fragments.FragmentHostManager;
-import com.android.systemui.fragments.FragmentService;
-import com.android.systemui.keyguard.KeyguardService;
-import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
-import com.android.systemui.keyguard.KeyguardViewMediator;
-import com.android.systemui.keyguard.ScreenLifecycle;
-import com.android.systemui.keyguard.WakefulnessLifecycle;
-import com.android.systemui.navigationbar.NavigationBarController;
 import com.android.systemui.navigationbar.NavigationBarView;
 import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.plugins.DarkIconDispatcher;
-import com.android.systemui.plugins.FalsingManager;
-import com.android.systemui.plugins.OverlayPlugin;
-import com.android.systemui.plugins.PluginDependencyProvider;
-import com.android.systemui.plugins.PluginListener;
-import com.android.systemui.plugins.qs.QS;
-import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.qs.QSFragment;
+import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
 import com.android.systemui.qs.QSPanelController;
-import com.android.systemui.recents.ScreenPinningRequest;
-import com.android.systemui.scrim.ScrimView;
-import com.android.systemui.settings.brightness.BrightnessSliderController;
-import com.android.systemui.shared.plugins.PluginManager;
-import com.android.systemui.statusbar.AutoHideUiElement;
-import com.android.systemui.statusbar.BackDropView;
-import com.android.systemui.statusbar.CircleReveal;
-import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.GestureRecorder;
-import com.android.systemui.statusbar.KeyboardShortcuts;
-import com.android.systemui.statusbar.KeyguardIndicationController;
-import com.android.systemui.statusbar.LiftReveal;
 import com.android.systemui.statusbar.LightRevealScrim;
-import com.android.systemui.statusbar.LockscreenShadeTransitionController;
-import com.android.systemui.statusbar.NotificationLockscreenUserManager;
-import com.android.systemui.statusbar.NotificationMediaManager;
 import com.android.systemui.statusbar.NotificationPresenter;
-import com.android.systemui.statusbar.NotificationRemoteInputManager;
-import com.android.systemui.statusbar.NotificationShadeDepthController;
-import com.android.systemui.statusbar.NotificationShadeWindowController;
-import com.android.systemui.statusbar.NotificationShelfController;
-import com.android.systemui.statusbar.NotificationViewHierarchyManager;
-import com.android.systemui.statusbar.PowerButtonReveal;
-import com.android.systemui.statusbar.PulseExpansionHandler;
-import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.SysuiStatusBarStateController;
-import com.android.systemui.statusbar.charging.WiredChargingRippleController;
-import com.android.systemui.statusbar.connectivity.NetworkController;
-import com.android.systemui.statusbar.core.StatusBarInitializer;
-import com.android.systemui.statusbar.notification.DynamicPrivacyController;
-import com.android.systemui.statusbar.notification.NotifPipelineFlags;
-import com.android.systemui.statusbar.notification.NotificationActivityStarter;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider;
-import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
-import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
-import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
-import com.android.systemui.statusbar.notification.init.NotificationsController;
-import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
-import com.android.systemui.statusbar.notification.logging.NotificationLogger;
-import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
-import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
-import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
-import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
-import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
-import com.android.systemui.statusbar.phone.dagger.StatusBarPhoneModule;
-import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
-import com.android.systemui.statusbar.phone.panelstate.PanelExpansionChangeEvent;
-import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
-import com.android.systemui.statusbar.policy.BatteryController;
-import com.android.systemui.statusbar.policy.BrightnessMirrorController;
-import com.android.systemui.statusbar.policy.ConfigurationController;
-import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
-import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
-import com.android.systemui.statusbar.policy.ExtensionController;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
-import com.android.systemui.statusbar.policy.UserSwitcherController;
-import com.android.systemui.statusbar.window.StatusBarWindowController;
-import com.android.systemui.statusbar.window.StatusBarWindowStateController;
-import com.android.systemui.util.DumpUtilsKt;
-import com.android.systemui.util.WallpaperController;
-import com.android.systemui.util.concurrency.DelayableExecutor;
-import com.android.systemui.util.concurrency.MessageRouter;
-import com.android.systemui.volume.VolumeComponent;
-import com.android.systemui.wmshell.BubblesManager;
-import com.android.wm.shell.bubbles.Bubbles;
-import com.android.wm.shell.startingsurface.SplashscreenContentDrawer;
-import com.android.wm.shell.startingsurface.StartingSurface;
 
 import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.concurrent.Executor;
 
-import javax.inject.Named;
-
-import dagger.Lazy;
-
-/**
- * A class handling initialization and coordination between some of the key central surfaces in
- * System UI: The notification shade, the keyguard (lockscreen), and the status bar.
- *
- * This class is not our ideal architecture because it doesn't enforce much isolation between these
- * three mostly disparate surfaces. In an ideal world, this class would not exist. Instead, we would
- * break it up into three modules -- one for each of those three surfaces -- and we would define any
- * APIs that are needed for these surfaces to communicate with each other when necessary.
- *
- * <b>If at all possible, please avoid adding additional code to this monstrous class! Our goal is
- * to break up this class into many small classes, and any code added here will slow down that goal.
- * </b>
- */
-public class CentralSurfaces extends CoreStartable implements
-        ActivityStarter,
-        LifecycleOwner {
-    public static final boolean MULTIUSER_DEBUG = false;
-
-    protected static final int MSG_DISMISS_KEYBOARD_SHORTCUTS_MENU = 1027;
-
+public interface CentralSurfaces extends Dumpable, ActivityStarter, LifecycleOwner {
+    boolean MULTIUSER_DEBUG = false;
     // Should match the values in PhoneWindowManager
-    public static final String SYSTEM_DIALOG_REASON_KEY = "reason";
-    public static final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
-    public static final String SYSTEM_DIALOG_REASON_DREAM = "dream";
-    static public final String SYSTEM_DIALOG_REASON_SCREENSHOT = "screenshot";
-
-    private static final String BANNER_ACTION_CANCEL =
-            "com.android.systemui.statusbar.banner_action_cancel";
-    private static final String BANNER_ACTION_SETUP =
-            "com.android.systemui.statusbar.banner_action_setup";
-    public static final String TAG = "CentralSurfaces";
-    public static final boolean DEBUG = false;
-    public static final boolean SPEW = false;
-    public static final boolean DUMPTRUCK = true; // extra dumpsys info
-    public static final boolean DEBUG_GESTURES = false;
-    public static final boolean DEBUG_MEDIA_FAKE_ARTWORK = false;
-    public static final boolean DEBUG_CAMERA_LIFT = false;
-
-    public static final boolean DEBUG_WINDOW_STATE = false;
-
+    String SYSTEM_DIALOG_REASON_KEY = "reason";
+    String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
+    String SYSTEM_DIALOG_REASON_DREAM = "dream";
+    String SYSTEM_DIALOG_REASON_SCREENSHOT = "screenshot";
+    String TAG = "CentralSurfaces";
+    boolean DEBUG = false;
+    boolean SPEW = false;
+    boolean DUMPTRUCK = true; // extra dumpsys info
+    boolean DEBUG_GESTURES = false;
+    boolean DEBUG_MEDIA_FAKE_ARTWORK = false;
+    boolean DEBUG_CAMERA_LIFT = false;
+    boolean DEBUG_WINDOW_STATE = false;
     // additional instrumentation for testing purposes; intended to be left on during development
-    public static final boolean CHATTY = DEBUG;
-
-    public static final boolean SHOW_LOCKSCREEN_MEDIA_ARTWORK = true;
-
-    public static final String ACTION_FAKE_ARTWORK = "fake_artwork";
-
-    private static final int MSG_OPEN_SETTINGS_PANEL = 1002;
-    private static final int MSG_LAUNCH_TRANSITION_TIMEOUT = 1003;
-    // 1020-1040 reserved for BaseStatusBar
-
-    // Time after we abort the launch transition.
-    static final long LAUNCH_TRANSITION_TIMEOUT_MS = 5000;
-
-    protected static final boolean CLOSE_PANEL_WHEN_EMPTIED = true;
-
-    /**
-     * The delay to reset the hint text when the hint animation is finished running.
-     */
-    private static final int HINT_RESET_DELAY_MS = 1200;
-
-    public static final int FADE_KEYGUARD_START_DELAY = 100;
-    public static final int FADE_KEYGUARD_DURATION = 300;
-    public static final int FADE_KEYGUARD_DURATION_PULSING = 96;
-
-    public static final long[] CAMERA_LAUNCH_GESTURE_VIBRATION_TIMINGS =
+    boolean CHATTY = DEBUG;
+    boolean SHOW_LOCKSCREEN_MEDIA_ARTWORK = true;
+    String ACTION_FAKE_ARTWORK = "fake_artwork";
+    int FADE_KEYGUARD_START_DELAY = 100;
+    int FADE_KEYGUARD_DURATION = 300;
+    int FADE_KEYGUARD_DURATION_PULSING = 96;
+    long[] CAMERA_LAUNCH_GESTURE_VIBRATION_TIMINGS =
             new long[]{20, 20, 20, 20, 100, 20};
-    public static final int[] CAMERA_LAUNCH_GESTURE_VIBRATION_AMPLITUDES =
+    int[] CAMERA_LAUNCH_GESTURE_VIBRATION_AMPLITUDES =
             new int[]{39, 82, 139, 213, 0, 127};
 
     /** If true, the lockscreen will show a distinct wallpaper */
-    public static final boolean ENABLE_LOCKSCREEN_WALLPAPER = true;
+    boolean ENABLE_LOCKSCREEN_WALLPAPER = true;
+    // Time after we abort the launch transition.
+    long LAUNCH_TRANSITION_TIMEOUT_MS = 5000;
+    int MSG_DISMISS_KEYBOARD_SHORTCUTS_MENU = 1027;
 
-    private static final UiEventLogger sUiEventLogger = new UiEventLoggerImpl();
+    static final boolean CLOSE_PANEL_WHEN_EMPTIED = true;
 
-    private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
-    private final DreamOverlayStateController mDreamOverlayStateController;
-    private CentralSurfacesCommandQueueCallbacks mCommandQueueCallbacks;
-    private float mTransitionToFullShadeProgress = 0f;
-    private NotificationListContainer mNotifListContainer;
-
-    private final KeyguardStateController.Callback mKeyguardStateControllerCallback =
-            new KeyguardStateController.Callback() {
-                @Override
-                public void onKeyguardShowingChanged() {
-                    boolean occluded = mKeyguardStateController.isOccluded();
-                    mStatusBarHideIconsForBouncerManager.setIsOccludedAndTriggerUpdate(occluded);
-                    mScrimController.setKeyguardOccluded(occluded);
-                }
-            };
-
-    void onStatusBarWindowStateChanged(@WindowVisibleState int state) {
-        updateBubblesVisibility();
-        mStatusBarWindowState = state;
-    }
-
-    void acquireGestureWakeLock(long time) {
-        mGestureWakeLock.acquire(time);
-    }
-
-    boolean setAppearance(int appearance) {
-        if (mAppearance != appearance) {
-            mAppearance = appearance;
-            return updateBarMode(barMode(isTransientShown(), appearance));
-        }
-
-        return false;
-    }
-
-    int getBarMode() {
-        return mStatusBarMode;
-    }
-
-    void resendMessage(int msg) {
-        mMessageRouter.cancelMessages(msg);
-        mMessageRouter.sendMessage(msg);
-    }
-
-    void resendMessage(Object msg) {
-        mMessageRouter.cancelMessages(msg.getClass());
-        mMessageRouter.sendMessage(msg);
-    }
-
-    int getDisabled1() {
-        return mDisabled1;
-    }
-
-    void setDisabled1(int disabled) {
-        mDisabled1 = disabled;
-    }
-
-    int getDisabled2() {
-        return mDisabled2;
-    }
-
-    void setDisabled2(int disabled) {
-        mDisabled2 = disabled;
-    }
-
-    void setLastCameraLaunchSource(int source) {
-        mLastCameraLaunchSource = source;
-    }
-
-    void setLaunchCameraOnFinishedGoingToSleep(boolean launch) {
-        mLaunchCameraOnFinishedGoingToSleep = launch;
-    }
-
-    void setLaunchCameraOnFinishedWaking(boolean launch) {
-        mLaunchCameraWhenFinishedWaking = launch;
-    }
-
-    void setLaunchEmergencyActionOnFinishedGoingToSleep(boolean launch) {
-        mLaunchEmergencyActionOnFinishedGoingToSleep = launch;
-    }
-
-    void setLaunchEmergencyActionOnFinishedWaking(boolean launch) {
-        mLaunchEmergencyActionWhenFinishedWaking = launch;
-    }
-
-    void setTopHidesStatusBar(boolean hides) {
-        mTopHidesStatusBar = hides;
-    }
-
-    QSPanelController getQSPanelController() {
-        return mQSPanelController;
-    }
-
-    /** */
-    public void animateExpandNotificationsPanel() {
-        mCommandQueueCallbacks.animateExpandNotificationsPanel();
-    }
-
-    /** */
-    public void animateExpandSettingsPanel(@Nullable String subpanel) {
-        mCommandQueueCallbacks.animateExpandSettingsPanel(subpanel);
-    }
-
-    /** */
-    public void animateCollapsePanels(int flags, boolean force) {
-        mCommandQueueCallbacks.animateCollapsePanels(flags, force);
-    }
-
-    /** */
-    public void togglePanel() {
-        mCommandQueueCallbacks.togglePanel();
-    }
-    /**
-     * The {@link StatusBarState} of the status bar.
-     */
-    protected int mState; // TODO: remove this. Just use StatusBarStateController
-    protected boolean mBouncerShowing;
-    private boolean mBouncerShowingOverDream;
-
-    private final PhoneStatusBarPolicy mIconPolicy;
-
-    private final VolumeComponent mVolumeComponent;
-    private BrightnessMirrorController mBrightnessMirrorController;
-    private boolean mBrightnessMirrorVisible;
-    private BiometricUnlockController mBiometricUnlockController;
-    private final LightBarController mLightBarController;
-    private final Lazy<LockscreenWallpaper> mLockscreenWallpaperLazy;
-    private final LockscreenGestureLogger mLockscreenGestureLogger;
-    @Nullable
-    protected LockscreenWallpaper mLockscreenWallpaper;
-    private final AutoHideController mAutoHideController;
-
-    private final Point mCurrentDisplaySize = new Point();
-
-    protected NotificationShadeWindowView mNotificationShadeWindowView;
-    protected PhoneStatusBarView mStatusBarView;
-    private PhoneStatusBarViewController mPhoneStatusBarViewController;
-    private PhoneStatusBarTransitions mStatusBarTransitions;
-    private AuthRippleController mAuthRippleController;
-    @WindowVisibleState private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
-    protected final NotificationShadeWindowController mNotificationShadeWindowController;
-    private final StatusBarWindowController mStatusBarWindowController;
-    private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
-    @VisibleForTesting
-    DozeServiceHost mDozeServiceHost;
-    private boolean mWakeUpComingFromTouch;
-    private PointF mWakeUpTouchLocation;
-    private LightRevealScrim mLightRevealScrim;
-    private PowerButtonReveal mPowerButtonReveal;
-
-    private final Object mQueueLock = new Object();
-
-    private final PulseExpansionHandler mPulseExpansionHandler;
-    private final NotificationWakeUpCoordinator mWakeUpCoordinator;
-    private final KeyguardBypassController mKeyguardBypassController;
-    private final KeyguardStateController mKeyguardStateController;
-    private final HeadsUpManagerPhone mHeadsUpManager;
-    private final StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
-    private final DynamicPrivacyController mDynamicPrivacyController;
-    private final FalsingCollector mFalsingCollector;
-    private final FalsingManager mFalsingManager;
-    private final BroadcastDispatcher mBroadcastDispatcher;
-    private final ConfigurationController mConfigurationController;
-    protected NotificationShadeWindowViewController mNotificationShadeWindowViewController;
-    private final DozeParameters mDozeParameters;
-    private final Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy;
-    private final CentralSurfacesComponent.Factory mCentralSurfacesComponentFactory;
-    private final PluginManager mPluginManager;
-    private final ShadeController mShadeController;
-    private final InitController mInitController;
-
-    private final PluginDependencyProvider mPluginDependencyProvider;
-    private final KeyguardDismissUtil mKeyguardDismissUtil;
-    private final ExtensionController mExtensionController;
-    private final UserInfoControllerImpl mUserInfoControllerImpl;
-    private final DemoModeController mDemoModeController;
-    private final NotificationsController mNotificationsController;
-    private final OngoingCallController mOngoingCallController;
-    private final StatusBarSignalPolicy mStatusBarSignalPolicy;
-    private final StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
-
-    // expanded notifications
-    // the sliding/resizing panel within the notification window
-    protected NotificationPanelViewController mNotificationPanelViewController;
-
-    // settings
-    private QSPanelController mQSPanelController;
-
-    KeyguardIndicationController mKeyguardIndicationController;
-
-    private View mReportRejectedTouch;
-
-    private boolean mExpandedVisible;
-
-    private final int[] mAbsPos = new int[2];
-
-    private final NotifShadeEventSource mNotifShadeEventSource;
-    protected final NotificationEntryManager mEntryManager;
-    private final NotificationGutsManager mGutsManager;
-    private final NotificationLogger mNotificationLogger;
-    private final NotificationViewHierarchyManager mViewHierarchyManager;
-    private final PanelExpansionStateManager mPanelExpansionStateManager;
-    private final KeyguardViewMediator mKeyguardViewMediator;
-    protected final NotificationInterruptStateProvider mNotificationInterruptStateProvider;
-    private final BrightnessSliderController.Factory mBrightnessSliderFactory;
-    private final FeatureFlags mFeatureFlags;
-    private final FragmentService mFragmentService;
-    private final ScreenOffAnimationController mScreenOffAnimationController;
-    private final WallpaperController mWallpaperController;
-    private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
-    private final MessageRouter mMessageRouter;
-    private final WallpaperManager mWallpaperManager;
-
-    private CentralSurfacesComponent mCentralSurfacesComponent;
-
-    // Flags for disabling the status bar
-    // Two variables becaseu the first one evidently ran out of room for new flags.
-    private int mDisabled1 = 0;
-    private int mDisabled2 = 0;
-
-    /** @see android.view.WindowInsetsController#setSystemBarsAppearance(int, int) */
-    private @Appearance int mAppearance;
-
-    private boolean mTransientShown;
-
-    private final DisplayMetrics mDisplayMetrics;
-
-    // XXX: gesture research
-    private final GestureRecorder mGestureRec = DEBUG_GESTURES
-        ? new GestureRecorder("/sdcard/statusbar_gestures.dat")
-        : null;
-
-    private final ScreenPinningRequest mScreenPinningRequest;
-
-    private final MetricsLogger mMetricsLogger;
-
-    // ensure quick settings is disabled until the current user makes it through the setup wizard
-    @VisibleForTesting
-    protected boolean mUserSetup = false;
-
-    @VisibleForTesting
-    public enum StatusBarUiEvent implements UiEventLogger.UiEventEnum {
-        @UiEvent(doc = "Secured lockscreen is opened.")
-        LOCKSCREEN_OPEN_SECURE(405),
-
-        @UiEvent(doc = "Lockscreen without security is opened.")
-        LOCKSCREEN_OPEN_INSECURE(406),
-
-        @UiEvent(doc = "Secured lockscreen is closed.")
-        LOCKSCREEN_CLOSE_SECURE(407),
-
-        @UiEvent(doc = "Lockscreen without security is closed.")
-        LOCKSCREEN_CLOSE_INSECURE(408),
-
-        @UiEvent(doc = "Secured bouncer is opened.")
-        BOUNCER_OPEN_SECURE(409),
-
-        @UiEvent(doc = "Bouncer without security is opened.")
-        BOUNCER_OPEN_INSECURE(410),
-
-        @UiEvent(doc = "Secured bouncer is closed.")
-        BOUNCER_CLOSE_SECURE(411),
-
-        @UiEvent(doc = "Bouncer without security is closed.")
-        BOUNCER_CLOSE_INSECURE(412);
-
-        private final int mId;
-
-        StatusBarUiEvent(int id) {
-            mId = id;
-        }
-
-        @Override
-        public int getId() {
-            return mId;
-        }
-    }
-
-    private Handler mMainHandler;
-    private final DelayableExecutor mMainExecutor;
-
-    private int mInteractingWindows;
-    private @TransitionMode int mStatusBarMode;
-
-    private final ViewMediatorCallback mKeyguardViewMediatorCallback;
-    private final ScrimController mScrimController;
-    protected DozeScrimController mDozeScrimController;
-    private final Executor mUiBgExecutor;
-
-    protected boolean mDozing;
-    private boolean mIsFullscreen;
-
-    boolean mCloseQsBeforeScreenOff;
-
-    private final NotificationMediaManager mMediaManager;
-    private final NotificationLockscreenUserManager mLockscreenUserManager;
-    private final NotificationRemoteInputManager mRemoteInputManager;
-    private boolean mWallpaperSupported;
-
-    private Runnable mLaunchTransitionEndRunnable;
-    private Runnable mLaunchTransitionCancelRunnable;
-    private boolean mLaunchCameraWhenFinishedWaking;
-    private boolean mLaunchCameraOnFinishedGoingToSleep;
-    private boolean mLaunchEmergencyActionWhenFinishedWaking;
-    private boolean mLaunchEmergencyActionOnFinishedGoingToSleep;
-    private int mLastCameraLaunchSource;
-    protected PowerManager.WakeLock mGestureWakeLock;
-
-    private final int[] mTmpInt2 = new int[2];
-
-    // Fingerprint (as computed by getLoggingFingerprint() of the last logged state.
-    private int mLastLoggedStateFingerprint;
-    private boolean mTopHidesStatusBar;
-    private boolean mStatusBarWindowHidden;
-    private boolean mIsLaunchingActivityOverLockscreen;
-
-    private final UserSwitcherController mUserSwitcherController;
-    private final NetworkController mNetworkController;
-    private final LifecycleRegistry mLifecycle = new LifecycleRegistry(this);
-    protected final BatteryController mBatteryController;
-    protected boolean mPanelExpanded;
-    private UiModeManager mUiModeManager;
-    private LogMaker mStatusBarStateLog;
-    protected final NotificationIconAreaController mNotificationIconAreaController;
-    @Nullable private View mAmbientIndicationContainer;
-    private final SysuiColorExtractor mColorExtractor;
-    private final ScreenLifecycle mScreenLifecycle;
-    private final WakefulnessLifecycle mWakefulnessLifecycle;
-
-    private boolean mNoAnimationOnNextBarModeChange;
-    private final SysuiStatusBarStateController mStatusBarStateController;
-
-    private final ActivityLaunchAnimator mActivityLaunchAnimator;
-    private NotificationLaunchAnimatorControllerProvider mNotificationAnimationProvider;
-    protected NotificationPresenter mPresenter;
-    private NotificationActivityStarter mNotificationActivityStarter;
-    private final Lazy<NotificationShadeDepthController> mNotificationShadeDepthControllerLazy;
-    private final Optional<BubblesManager> mBubblesManagerOptional;
-    private final Optional<Bubbles> mBubblesOptional;
-    private final Bubbles.BubbleExpandListener mBubbleExpandListener;
-    private final Optional<StartingSurface> mStartingSurfaceOptional;
-    private final NotifPipelineFlags mNotifPipelineFlags;
-
-    private final ActivityIntentHelper mActivityIntentHelper;
-    private NotificationStackScrollLayoutController mStackScrollerController;
-
-    private final ColorExtractor.OnColorsChangedListener mOnColorsChangedListener =
-            (extractor, which) -> updateTheme();
-
-    private final InteractionJankMonitor mJankMonitor;
-
-
-    /**
-     * Public constructor for CentralSurfaces.
-     *
-     * CentralSurfaces is considered optional, and therefore can not be marked as @Inject directly.
-     * Instead, an @Provide method is included. See {@link StatusBarPhoneModule}.
-     */
-    @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
-    public CentralSurfaces(
-            Context context,
-            NotificationsController notificationsController,
-            FragmentService fragmentService,
-            LightBarController lightBarController,
-            AutoHideController autoHideController,
-            StatusBarWindowController statusBarWindowController,
-            StatusBarWindowStateController statusBarWindowStateController,
-            KeyguardUpdateMonitor keyguardUpdateMonitor,
-            StatusBarSignalPolicy statusBarSignalPolicy,
-            PulseExpansionHandler pulseExpansionHandler,
-            NotificationWakeUpCoordinator notificationWakeUpCoordinator,
-            KeyguardBypassController keyguardBypassController,
-            KeyguardStateController keyguardStateController,
-            HeadsUpManagerPhone headsUpManagerPhone,
-            DynamicPrivacyController dynamicPrivacyController,
-            FalsingManager falsingManager,
-            FalsingCollector falsingCollector,
-            BroadcastDispatcher broadcastDispatcher,
-            NotifShadeEventSource notifShadeEventSource,
-            NotificationEntryManager notificationEntryManager,
-            NotificationGutsManager notificationGutsManager,
-            NotificationLogger notificationLogger,
-            NotificationInterruptStateProvider notificationInterruptStateProvider,
-            NotificationViewHierarchyManager notificationViewHierarchyManager,
-            PanelExpansionStateManager panelExpansionStateManager,
-            KeyguardViewMediator keyguardViewMediator,
-            DisplayMetrics displayMetrics,
-            MetricsLogger metricsLogger,
-            @UiBackground Executor uiBgExecutor,
-            NotificationMediaManager notificationMediaManager,
-            NotificationLockscreenUserManager lockScreenUserManager,
-            NotificationRemoteInputManager remoteInputManager,
-            UserSwitcherController userSwitcherController,
-            NetworkController networkController,
-            BatteryController batteryController,
-            SysuiColorExtractor colorExtractor,
-            ScreenLifecycle screenLifecycle,
-            WakefulnessLifecycle wakefulnessLifecycle,
-            SysuiStatusBarStateController statusBarStateController,
-            Optional<BubblesManager> bubblesManagerOptional,
-            Optional<Bubbles> bubblesOptional,
-            VisualStabilityManager visualStabilityManager,
-            DeviceProvisionedController deviceProvisionedController,
-            NavigationBarController navigationBarController,
-            AccessibilityFloatingMenuController accessibilityFloatingMenuController,
-            Lazy<AssistManager> assistManagerLazy,
-            ConfigurationController configurationController,
-            NotificationShadeWindowController notificationShadeWindowController,
-            DozeParameters dozeParameters,
-            ScrimController scrimController,
-            Lazy<LockscreenWallpaper> lockscreenWallpaperLazy,
-            LockscreenGestureLogger lockscreenGestureLogger,
-            Lazy<BiometricUnlockController> biometricUnlockControllerLazy,
-            DozeServiceHost dozeServiceHost,
-            PowerManager powerManager,
-            ScreenPinningRequest screenPinningRequest,
-            DozeScrimController dozeScrimController,
-            VolumeComponent volumeComponent,
-            CommandQueue commandQueue,
-            CentralSurfacesComponent.Factory centralSurfacesComponentFactory,
-            PluginManager pluginManager,
-            ShadeController shadeController,
-            StatusBarKeyguardViewManager statusBarKeyguardViewManager,
-            ViewMediatorCallback viewMediatorCallback,
-            InitController initController,
-            @Named(TIME_TICK_HANDLER_NAME) Handler timeTickHandler,
-            PluginDependencyProvider pluginDependencyProvider,
-            KeyguardDismissUtil keyguardDismissUtil,
-            ExtensionController extensionController,
-            UserInfoControllerImpl userInfoControllerImpl,
-            PhoneStatusBarPolicy phoneStatusBarPolicy,
-            KeyguardIndicationController keyguardIndicationController,
-            DemoModeController demoModeController,
-            Lazy<NotificationShadeDepthController> notificationShadeDepthControllerLazy,
-            StatusBarTouchableRegionManager statusBarTouchableRegionManager,
-            NotificationIconAreaController notificationIconAreaController,
-            BrightnessSliderController.Factory brightnessSliderFactory,
-            ScreenOffAnimationController screenOffAnimationController,
-            WallpaperController wallpaperController,
-            OngoingCallController ongoingCallController,
-            StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager,
-            LockscreenShadeTransitionController lockscreenShadeTransitionController,
-            FeatureFlags featureFlags,
-            KeyguardUnlockAnimationController keyguardUnlockAnimationController,
-            @Main Handler mainHandler,
-            @Main DelayableExecutor delayableExecutor,
-            @Main MessageRouter messageRouter,
-            WallpaperManager wallpaperManager,
-            Optional<StartingSurface> startingSurfaceOptional,
-            ActivityLaunchAnimator activityLaunchAnimator,
-            NotifPipelineFlags notifPipelineFlags,
-            InteractionJankMonitor jankMonitor,
-            DeviceStateManager deviceStateManager,
-            DreamOverlayStateController dreamOverlayStateController,
-            WiredChargingRippleController wiredChargingRippleController) {
-        super(context);
-        mNotificationsController = notificationsController;
-        mFragmentService = fragmentService;
-        mLightBarController = lightBarController;
-        mAutoHideController = autoHideController;
-        mStatusBarWindowController = statusBarWindowController;
-        mKeyguardUpdateMonitor = keyguardUpdateMonitor;
-        mPulseExpansionHandler = pulseExpansionHandler;
-        mWakeUpCoordinator = notificationWakeUpCoordinator;
-        mKeyguardBypassController = keyguardBypassController;
-        mKeyguardStateController = keyguardStateController;
-        mHeadsUpManager = headsUpManagerPhone;
-        mKeyguardIndicationController = keyguardIndicationController;
-        mStatusBarTouchableRegionManager = statusBarTouchableRegionManager;
-        mDynamicPrivacyController = dynamicPrivacyController;
-        mFalsingCollector = falsingCollector;
-        mFalsingManager = falsingManager;
-        mBroadcastDispatcher = broadcastDispatcher;
-        mNotifShadeEventSource = notifShadeEventSource;
-        mEntryManager = notificationEntryManager;
-        mGutsManager = notificationGutsManager;
-        mNotificationLogger = notificationLogger;
-        mNotificationInterruptStateProvider = notificationInterruptStateProvider;
-        mViewHierarchyManager = notificationViewHierarchyManager;
-        mPanelExpansionStateManager = panelExpansionStateManager;
-        mKeyguardViewMediator = keyguardViewMediator;
-        mDisplayMetrics = displayMetrics;
-        mMetricsLogger = metricsLogger;
-        mUiBgExecutor = uiBgExecutor;
-        mMediaManager = notificationMediaManager;
-        mLockscreenUserManager = lockScreenUserManager;
-        mRemoteInputManager = remoteInputManager;
-        mUserSwitcherController = userSwitcherController;
-        mNetworkController = networkController;
-        mBatteryController = batteryController;
-        mColorExtractor = colorExtractor;
-        mScreenLifecycle = screenLifecycle;
-        mWakefulnessLifecycle = wakefulnessLifecycle;
-        mStatusBarStateController = statusBarStateController;
-        mBubblesManagerOptional = bubblesManagerOptional;
-        mBubblesOptional = bubblesOptional;
-        mVisualStabilityManager = visualStabilityManager;
-        mDeviceProvisionedController = deviceProvisionedController;
-        mNavigationBarController = navigationBarController;
-        mAccessibilityFloatingMenuController = accessibilityFloatingMenuController;
-        mAssistManagerLazy = assistManagerLazy;
-        mConfigurationController = configurationController;
-        mNotificationShadeWindowController = notificationShadeWindowController;
-        mDozeServiceHost = dozeServiceHost;
-        mPowerManager = powerManager;
-        mDozeParameters = dozeParameters;
-        mScrimController = scrimController;
-        mLockscreenWallpaperLazy = lockscreenWallpaperLazy;
-        mLockscreenGestureLogger = lockscreenGestureLogger;
-        mScreenPinningRequest = screenPinningRequest;
-        mDozeScrimController = dozeScrimController;
-        mBiometricUnlockControllerLazy = biometricUnlockControllerLazy;
-        mNotificationShadeDepthControllerLazy = notificationShadeDepthControllerLazy;
-        mVolumeComponent = volumeComponent;
-        mCommandQueue = commandQueue;
-        mCentralSurfacesComponentFactory = centralSurfacesComponentFactory;
-        mPluginManager = pluginManager;
-        mShadeController = shadeController;
-        mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
-        mKeyguardViewMediatorCallback = viewMediatorCallback;
-        mInitController = initController;
-        mPluginDependencyProvider = pluginDependencyProvider;
-        mKeyguardDismissUtil = keyguardDismissUtil;
-        mExtensionController = extensionController;
-        mUserInfoControllerImpl = userInfoControllerImpl;
-        mIconPolicy = phoneStatusBarPolicy;
-        mDemoModeController = demoModeController;
-        mNotificationIconAreaController = notificationIconAreaController;
-        mBrightnessSliderFactory = brightnessSliderFactory;
-        mWallpaperController = wallpaperController;
-        mOngoingCallController = ongoingCallController;
-        mStatusBarSignalPolicy = statusBarSignalPolicy;
-        mStatusBarHideIconsForBouncerManager = statusBarHideIconsForBouncerManager;
-        mFeatureFlags = featureFlags;
-        mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
-        mMainHandler = mainHandler;
-        mMainExecutor = delayableExecutor;
-        mMessageRouter = messageRouter;
-        mWallpaperManager = wallpaperManager;
-        mJankMonitor = jankMonitor;
-        mDreamOverlayStateController = dreamOverlayStateController;
-
-        mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
-        mStartingSurfaceOptional = startingSurfaceOptional;
-        mNotifPipelineFlags = notifPipelineFlags;
-        lockscreenShadeTransitionController.setCentralSurfaces(this);
-        statusBarWindowStateController.addListener(this::onStatusBarWindowStateChanged);
-
-        mScreenOffAnimationController = screenOffAnimationController;
-
-        mPanelExpansionStateManager.addExpansionListener(this::onPanelExpansionChanged);
-
-        mBubbleExpandListener =
-                (isExpanding, key) -> mContext.getMainExecutor().execute(() -> {
-                    mNotificationsController.requestNotificationUpdate("onBubbleExpandChanged");
-                    updateScrimController();
-                });
-
-        mActivityIntentHelper = new ActivityIntentHelper(mContext);
-        mActivityLaunchAnimator = activityLaunchAnimator;
-
-        // The status bar background may need updating when the ongoing call status changes.
-        mOngoingCallController.addCallback((animate) -> maybeUpdateBarMode());
-
-        // TODO(b/190746471): Find a better home for this.
-        DateTimeView.setReceiverHandler(timeTickHandler);
-
-        mMessageRouter.subscribeTo(KeyboardShortcutsMessage.class,
-                data -> toggleKeyboardShortcuts(data.mDeviceId));
-        mMessageRouter.subscribeTo(MSG_DISMISS_KEYBOARD_SHORTCUTS_MENU,
-                id -> dismissKeyboardShortcuts());
-        mMessageRouter.subscribeTo(AnimateExpandSettingsPanelMessage.class,
-                data -> mCommandQueueCallbacks.animateExpandSettingsPanel(data.mSubpanel));
-        mMessageRouter.subscribeTo(MSG_LAUNCH_TRANSITION_TIMEOUT,
-                id -> onLaunchTransitionTimeout());
-
-        deviceStateManager.registerCallback(mMainExecutor,
-                new FoldStateListener(mContext, this::onFoldedStateChanged));
-        wiredChargingRippleController.registerCallbacks();
-    }
-
-    @Override
-    public void start() {
-        mScreenLifecycle.addObserver(mScreenObserver);
-        mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
-        mUiModeManager = mContext.getSystemService(UiModeManager.class);
-        if (mBubblesOptional.isPresent()) {
-            mBubblesOptional.get().setExpandListener(mBubbleExpandListener);
-        }
-
-        mStatusBarSignalPolicy.init();
-        mKeyguardIndicationController.init();
-
-        mColorExtractor.addOnColorsChangedListener(mOnColorsChangedListener);
-        mStatusBarStateController.addCallback(mStateListener,
-                SysuiStatusBarStateController.RANK_STATUS_BAR);
-
-        mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
-        mDreamManager = IDreamManager.Stub.asInterface(
-                ServiceManager.checkService(DreamService.DREAM_SERVICE));
-
-        mDisplay = mContext.getDisplay();
-        mDisplayId = mDisplay.getDisplayId();
-        updateDisplaySize();
-        mStatusBarHideIconsForBouncerManager.setDisplayId(mDisplayId);
-
-        // start old BaseStatusBar.start().
-        mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
-        mDevicePolicyManager = (DevicePolicyManager) mContext.getSystemService(
-                Context.DEVICE_POLICY_SERVICE);
-
-        mAccessibilityManager = (AccessibilityManager)
-                mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
-
-        mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController);
-        mBarService = IStatusBarService.Stub.asInterface(
-                ServiceManager.getService(Context.STATUS_BAR_SERVICE));
-
-        mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
-        mWallpaperSupported = mWallpaperManager.isWallpaperSupported();
-
-        RegisterStatusBarResult result = null;
-        try {
-            result = mBarService.registerStatusBar(mCommandQueue);
-        } catch (RemoteException ex) {
-            ex.rethrowFromSystemServer();
-        }
-
-        createAndAddWindows(result);
-
-        if (mWallpaperSupported) {
-            // Make sure we always have the most current wallpaper info.
-            IntentFilter wallpaperChangedFilter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
-            mBroadcastDispatcher.registerReceiver(mWallpaperChangedReceiver, wallpaperChangedFilter,
-                    null /* handler */, UserHandle.ALL);
-            mWallpaperChangedReceiver.onReceive(mContext, null);
-        } else if (DEBUG) {
-            Log.v(TAG, "start(): no wallpaper service ");
-        }
-
-        // Set up the initial notification state. This needs to happen before CommandQueue.disable()
-        setUpPresenter();
-
-        if (containsType(result.mTransientBarTypes, ITYPE_STATUS_BAR)) {
-            showTransientUnchecked();
-        }
-        mCommandQueueCallbacks.onSystemBarAttributesChanged(mDisplayId, result.mAppearance,
-                result.mAppearanceRegions, result.mNavbarColorManagedByIme, result.mBehavior,
-                result.mRequestedVisibilities, result.mPackageName);
-
-        // StatusBarManagerService has a back up of IME token and it's restored here.
-        mCommandQueueCallbacks.setImeWindowStatus(mDisplayId, result.mImeToken,
-                result.mImeWindowVis, result.mImeBackDisposition, result.mShowImeSwitcher);
-
-        // Set up the initial icon state
-        int numIcons = result.mIcons.size();
-        for (int i = 0; i < numIcons; i++) {
-            mCommandQueue.setIcon(result.mIcons.keyAt(i), result.mIcons.valueAt(i));
-        }
-
-        if (DEBUG) {
-            Log.d(TAG, String.format(
-                    "init: icons=%d disabled=0x%08x lights=0x%08x imeButton=0x%08x",
-                    numIcons,
-                    result.mDisabledFlags1,
-                    result.mAppearance,
-                    result.mImeWindowVis));
-        }
-
-        IntentFilter internalFilter = new IntentFilter();
-        internalFilter.addAction(BANNER_ACTION_CANCEL);
-        internalFilter.addAction(BANNER_ACTION_SETUP);
-        mContext.registerReceiver(mBannerActionBroadcastReceiver, internalFilter, PERMISSION_SELF,
-                null, Context.RECEIVER_EXPORTED_UNAUDITED);
-
-        if (mWallpaperSupported) {
-            IWallpaperManager wallpaperManager = IWallpaperManager.Stub.asInterface(
-                    ServiceManager.getService(Context.WALLPAPER_SERVICE));
-            try {
-                wallpaperManager.setInAmbientMode(false /* ambientMode */, 0L /* duration */);
-            } catch (RemoteException e) {
-                // Just pass, nothing critical.
-            }
-        }
-
-        // end old BaseStatusBar.start().
-
-        // Lastly, call to the icon policy to install/update all the icons.
-        mIconPolicy.init();
-
-        mKeyguardStateController.addCallback(new KeyguardStateController.Callback() {
-            @Override
-            public void onUnlockedChanged() {
-                logStateToEventlog();
-            }
-        });
-        startKeyguard();
-
-        mKeyguardUpdateMonitor.registerCallback(mUpdateCallback);
-        mDozeServiceHost.initialize(
-                this,
-                mStatusBarKeyguardViewManager,
-                mNotificationShadeWindowViewController,
-                mNotificationPanelViewController,
-                mAmbientIndicationContainer);
-        updateLightRevealScrimVisibility();
-
-        mConfigurationController.addCallback(mConfigurationListener);
-
-        mBatteryController.observe(mLifecycle, mBatteryStateChangeCallback);
-        mLifecycle.setCurrentState(RESUMED);
-
-        mAccessibilityFloatingMenuController.init();
-
-        // set the initial view visibility
-        int disabledFlags1 = result.mDisabledFlags1;
-        int disabledFlags2 = result.mDisabledFlags2;
-        mInitController.addPostInitTask(
-                () -> setUpDisableFlags(disabledFlags1, disabledFlags2));
-
-        mFalsingManager.addFalsingBeliefListener(mFalsingBeliefListener);
-
-        mPluginManager.addPluginListener(
-                new PluginListener<OverlayPlugin>() {
-                    private final ArraySet<OverlayPlugin> mOverlays = new ArraySet<>();
-
-                    @Override
-                    public void onPluginConnected(OverlayPlugin plugin, Context pluginContext) {
-                        mMainExecutor.execute(
-                                () -> plugin.setup(getNotificationShadeWindowView(),
-                                        getNavigationBarView(),
-                                        new Callback(plugin), mDozeParameters));
-                    }
-
-                    @Override
-                    public void onPluginDisconnected(OverlayPlugin plugin) {
-                        mMainExecutor.execute(() -> {
-                            mOverlays.remove(plugin);
-                            mNotificationShadeWindowController
-                                    .setForcePluginOpen(mOverlays.size() != 0, this);
-                        });
-                    }
-
-                    class Callback implements OverlayPlugin.Callback {
-                        private final OverlayPlugin mPlugin;
-
-                        Callback(OverlayPlugin plugin) {
-                            mPlugin = plugin;
-                        }
-
-                        @Override
-                        public void onHoldStatusBarOpenChange() {
-                            if (mPlugin.holdStatusBarOpen()) {
-                                mOverlays.add(mPlugin);
-                            } else {
-                                mOverlays.remove(mPlugin);
-                            }
-                            mMainExecutor.execute(() -> {
-                                mNotificationShadeWindowController
-                                        .setStateListener(b -> mOverlays.forEach(
-                                                o -> o.setCollapseDesired(b)));
-                                mNotificationShadeWindowController
-                                        .setForcePluginOpen(mOverlays.size() != 0, this);
-                            });
-                        }
-                    }
-                }, OverlayPlugin.class, true /* Allow multiple plugins */);
-
-        mStartingSurfaceOptional.ifPresent(startingSurface -> startingSurface.setSysuiProxy(
-                (requestTopUi, componentTag) -> mMainExecutor.execute(() ->
-                        mNotificationShadeWindowController.setRequestTopUi(
-                                requestTopUi, componentTag))));
-    }
-
-    private void onFoldedStateChanged(boolean isFolded, boolean willGoToSleep) {
-        Trace.beginSection("CentralSurfaces#onFoldedStateChanged");
-        onFoldedStateChangedInternal(isFolded, willGoToSleep);
-        Trace.endSection();
-    }
-
-    private void onFoldedStateChangedInternal(boolean isFolded, boolean willGoToSleep) {
-        // Folded state changes are followed by a screen off event.
-        // By default turning off the screen also closes the shade.
-        // We want to make sure that the shade status is kept after
-        // folding/unfolding.
-        boolean isShadeOpen = mShadeController.isShadeOpen();
-        boolean leaveOpen = isShadeOpen && !willGoToSleep;
-        if (DEBUG) {
-            Log.d(TAG, String.format(
-                    "#onFoldedStateChanged(): "
-                            + "isFolded=%s, "
-                            + "willGoToSleep=%s, "
-                            + "isShadeOpen=%s, "
-                            + "leaveOpen=%s",
-                    isFolded, willGoToSleep, isShadeOpen, leaveOpen));
-        }
-        if (leaveOpen) {
-            mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
-            if (mKeyguardStateController.isShowing()) {
-                // When device state changes on keyguard we don't want to keep the state of
-                // the shade and instead we open clean state of keyguard with shade closed.
-                // Normally some parts of QS state (like expanded/collapsed) are persisted and
-                // that causes incorrect UI rendering, especially when changing state with QS
-                // expanded. To prevent that we can close QS which resets QS and some parts of
-                // the shade to its default state. Read more in b/201537421
-                mCloseQsBeforeScreenOff = true;
-            }
-        }
-    }
-
-    // ================================================================================
-    // Constructing the view
-    // ================================================================================
-    protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {
-        updateDisplaySize(); // populates mDisplayMetrics
-        updateResources();
-        updateTheme();
-
-        inflateStatusBarWindow();
-        mNotificationShadeWindowView.setOnTouchListener(getStatusBarWindowTouchListener());
-        mWallpaperController.setRootView(mNotificationShadeWindowView);
-
-        // TODO: Deal with the ugliness that comes from having some of the status bar broken out
-        // into fragments, but the rest here, it leaves some awkward lifecycle and whatnot.
-        mNotificationLogger.setUpWithContainer(mNotifListContainer);
-        mNotificationIconAreaController.setupShelf(mNotificationShelfController);
-        mPanelExpansionStateManager.addExpansionListener(mWakeUpCoordinator);
-        mUserSwitcherController.init(mNotificationShadeWindowView);
-
-        // Allow plugins to reference DarkIconDispatcher and StatusBarStateController
-        mPluginDependencyProvider.allowPluginDependency(DarkIconDispatcher.class);
-        mPluginDependencyProvider.allowPluginDependency(StatusBarStateController.class);
-
-        // Set up CollapsedStatusBarFragment and PhoneStatusBarView
-        StatusBarInitializer initializer = mCentralSurfacesComponent.getStatusBarInitializer();
-        initializer.setStatusBarViewUpdatedListener(
-                (statusBarView, statusBarViewController, statusBarTransitions) -> {
-                    mStatusBarView = statusBarView;
-                    mPhoneStatusBarViewController = statusBarViewController;
-                    mStatusBarTransitions = statusBarTransitions;
-                    mNotificationShadeWindowViewController
-                            .setStatusBarViewController(mPhoneStatusBarViewController);
-                    // Ensure we re-propagate panel expansion values to the panel controller and
-                    // any listeners it may have, such as PanelBar. This will also ensure we
-                    // re-display the notification panel if necessary (for example, if
-                    // a heads-up notification was being displayed and should continue being
-                    // displayed).
-                    mNotificationPanelViewController.updatePanelExpansionAndVisibility();
-                    setBouncerShowingForStatusBarComponents(mBouncerShowing);
-                    checkBarModes();
-                });
-        initializer.initializeStatusBar(mCentralSurfacesComponent);
-
-        mStatusBarTouchableRegionManager.setup(this, mNotificationShadeWindowView);
-        mHeadsUpManager.addListener(mNotificationPanelViewController.getOnHeadsUpChangedListener());
-        if (!mNotifPipelineFlags.isNewPipelineEnabled()) {
-            mHeadsUpManager.addListener(mVisualStabilityManager);
-        }
-        mNotificationPanelViewController.setHeadsUpManager(mHeadsUpManager);
-
-        createNavigationBar(result);
-
-        if (ENABLE_LOCKSCREEN_WALLPAPER && mWallpaperSupported) {
-            mLockscreenWallpaper = mLockscreenWallpaperLazy.get();
-        }
-
-        mNotificationPanelViewController.setKeyguardIndicationController(
-                mKeyguardIndicationController);
-
-        mAmbientIndicationContainer = mNotificationShadeWindowView.findViewById(
-                R.id.ambient_indication_container);
-
-        mAutoHideController.setStatusBar(new AutoHideUiElement() {
-            @Override
-            public void synchronizeState() {
-                checkBarModes();
-            }
-
-            @Override
-            public boolean shouldHideOnTouch() {
-                return !mRemoteInputManager.isRemoteInputActive();
-            }
-
-            @Override
-            public boolean isVisible() {
-                return isTransientShown();
-            }
-
-            @Override
-            public void hide() {
-                clearTransient();
-            }
-        });
-
-        ScrimView scrimBehind = mNotificationShadeWindowView.findViewById(R.id.scrim_behind);
-        ScrimView notificationsScrim = mNotificationShadeWindowView
-                .findViewById(R.id.scrim_notifications);
-        ScrimView scrimInFront = mNotificationShadeWindowView.findViewById(R.id.scrim_in_front);
-
-        mScrimController.setScrimVisibleListener(scrimsVisible -> {
-            mNotificationShadeWindowController.setScrimsVisibility(scrimsVisible);
-        });
-        mScrimController.attachViews(scrimBehind, notificationsScrim, scrimInFront);
-
-        mLightRevealScrim = mNotificationShadeWindowView.findViewById(R.id.light_reveal_scrim);
-        mLightRevealScrim.setScrimOpaqueChangedListener((opaque) -> {
-            Runnable updateOpaqueness = () -> {
-                mNotificationShadeWindowController.setLightRevealScrimOpaque(
-                        mLightRevealScrim.isScrimOpaque());
-                mScreenOffAnimationController
-                        .onScrimOpaqueChanged(mLightRevealScrim.isScrimOpaque());
-            };
-            if (opaque) {
-                // Delay making the view opaque for a frame, because it needs some time to render
-                // otherwise this can lead to a flicker where the scrim doesn't cover the screen
-                mLightRevealScrim.post(updateOpaqueness);
-            } else {
-                updateOpaqueness.run();
-            }
-        });
-
-        mScreenOffAnimationController.initialize(this, mLightRevealScrim);
-        updateLightRevealScrimVisibility();
-
-        mNotificationPanelViewController.initDependencies(
-                this,
-                this::makeExpandedInvisible,
-                mNotificationShelfController);
-
-        BackDropView backdrop = mNotificationShadeWindowView.findViewById(R.id.backdrop);
-        mMediaManager.setup(backdrop, backdrop.findViewById(R.id.backdrop_front),
-                backdrop.findViewById(R.id.backdrop_back), mScrimController, mLockscreenWallpaper);
-        float maxWallpaperZoom = mContext.getResources().getFloat(
-                com.android.internal.R.dimen.config_wallpaperMaxScale);
-        mNotificationShadeDepthControllerLazy.get().addListener(depth -> {
-            float scale = MathUtils.lerp(maxWallpaperZoom, 1f, depth);
-            backdrop.setPivotX(backdrop.getWidth() / 2f);
-            backdrop.setPivotY(backdrop.getHeight() / 2f);
-            backdrop.setScaleX(scale);
-            backdrop.setScaleY(scale);
-        });
-
-        mNotificationPanelViewController.setUserSetupComplete(mUserSetup);
-
-        // Set up the quick settings tile panel
-        final View container = mNotificationShadeWindowView.findViewById(R.id.qs_frame);
-        if (container != null) {
-            FragmentHostManager fragmentHostManager = FragmentHostManager.get(container);
-            ExtensionFragmentListener.attachExtensonToFragment(container, QS.TAG, R.id.qs_frame,
-                    mExtensionController
-                            .newExtension(QS.class)
-                            .withPlugin(QS.class)
-                            .withDefault(this::createDefaultQSFragment)
-                            .build());
-            mBrightnessMirrorController = new BrightnessMirrorController(
-                    mNotificationShadeWindowView,
-                    mNotificationPanelViewController,
-                    mNotificationShadeDepthControllerLazy.get(),
-                    mBrightnessSliderFactory,
-                    (visible) -> {
-                        mBrightnessMirrorVisible = visible;
-                        updateScrimController();
-                    });
-            fragmentHostManager.addTagListener(QS.TAG, (tag, f) -> {
-                QS qs = (QS) f;
-                if (qs instanceof QSFragment) {
-                    mQSPanelController = ((QSFragment) qs).getQSPanelController();
-                    ((QSFragment) qs).setBrightnessMirrorController(mBrightnessMirrorController);
-                }
-            });
-        }
-
-        mReportRejectedTouch = mNotificationShadeWindowView
-                .findViewById(R.id.report_rejected_touch);
-        if (mReportRejectedTouch != null) {
-            updateReportRejectedTouchVisibility();
-            mReportRejectedTouch.setOnClickListener(v -> {
-                Uri session = mFalsingManager.reportRejectedTouch();
-                if (session == null) { return; }
-
-                StringWriter message = new StringWriter();
-                message.write("Build info: ");
-                message.write(SystemProperties.get("ro.build.description"));
-                message.write("\nSerial number: ");
-                message.write(SystemProperties.get("ro.serialno"));
-                message.write("\n");
-
-                startActivityDismissingKeyguard(Intent.createChooser(new Intent(Intent.ACTION_SEND)
-                                .setType("*/*")
-                                .putExtra(Intent.EXTRA_SUBJECT, "Rejected touch report")
-                                .putExtra(Intent.EXTRA_STREAM, session)
-                                .putExtra(Intent.EXTRA_TEXT, message.toString()),
-                        "Share rejected touch report")
-                                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
-                        true /* onlyProvisioned */, true /* dismissShade */);
-            });
-        }
-
-        if (!mPowerManager.isInteractive()) {
-            mBroadcastReceiver.onReceive(mContext, new Intent(Intent.ACTION_SCREEN_OFF));
-        }
-        mGestureWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
-                "sysui:GestureWakeLock");
-
-        // receive broadcasts
-        registerBroadcastReceiver();
-
-        IntentFilter demoFilter = new IntentFilter();
-        if (DEBUG_MEDIA_FAKE_ARTWORK) {
-            demoFilter.addAction(ACTION_FAKE_ARTWORK);
-        }
-        mContext.registerReceiverAsUser(mDemoReceiver, UserHandle.ALL, demoFilter,
-                android.Manifest.permission.DUMP, null,
-                Context.RECEIVER_EXPORTED_UNAUDITED);
-
-        // listen for USER_SETUP_COMPLETE setting (per-user)
-        mDeviceProvisionedController.addCallback(mUserSetupObserver);
-        mUserSetupObserver.onUserSetupChanged();
-
-        // disable profiling bars, since they overlap and clutter the output on app windows
-        ThreadedRenderer.overrideProperty("disableProfileBars", "true");
-
-        // Private API call to make the shadows look better for Recents
-        ThreadedRenderer.overrideProperty("ambientRatio", String.valueOf(1.5f));
-    }
-
-
-    /**
-     * When swiping up to dismiss the lock screen, the panel expansion fraction goes from 1f to 0f.
-     * This results in the clock/notifications/other content disappearing off the top of the screen.
-     *
-     * We also use the expansion fraction to animate in the app/launcher surface from the bottom of
-     * the screen, 'pushing' off the notifications and other content. To do this, we dispatch the
-     * expansion fraction to the KeyguardViewMediator if we're in the process of dismissing the
-     * keyguard.
-     */
-    private void dispatchPanelExpansionForKeyguardDismiss(float fraction, boolean trackingTouch) {
-        // Things that mean we're not swiping to dismiss the keyguard, and should ignore this
-        // expansion:
-        // - Keyguard isn't even visible.
-        // - Keyguard is occluded. Expansion changes here are the shade being expanded over the
-        //   occluding activity.
-        // - Keyguard is visible, but can't be dismissed (swiping up will show PIN/password prompt).
-        // - The SIM is locked, you can't swipe to unlock. If the SIM is locked but there is no
-        //   device lock set, canDismissLockScreen returns true even though you should not be able
-        //   to dismiss the lock screen until entering the SIM PIN.
-        // - QS is expanded and we're swiping - swiping up now will hide QS, not dismiss the
-        //   keyguard.
-        if (!isKeyguardShowing()
-                || isOccluded()
-                || !mKeyguardStateController.canDismissLockScreen()
-                || mKeyguardViewMediator.isAnySimPinSecure()
-                || (mNotificationPanelViewController.isQsExpanded() && trackingTouch)) {
-            return;
-        }
-
-        // Otherwise, we should let the keyguard know about this if we're tracking touch, or if we
-        // are already animating the keyguard dismiss (since we will need to either finish or cancel
-        // the animation).
-        if (trackingTouch
-                || mKeyguardViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehindOrWillBe()
-                || mKeyguardUnlockAnimationController.isUnlockingWithSmartSpaceTransition()) {
-            mKeyguardStateController.notifyKeyguardDismissAmountChanged(
-                    1f - fraction, trackingTouch);
-        }
-    }
-
-    private void onPanelExpansionChanged(PanelExpansionChangeEvent event) {
-        float fraction = event.getFraction();
-        boolean tracking = event.getTracking();
-        dispatchPanelExpansionForKeyguardDismiss(fraction, tracking);
-
-        if (fraction == 0 || fraction == 1) {
-            if (getNavigationBarView() != null) {
-                getNavigationBarView().onStatusBarPanelStateChanged();
-            }
-            if (getNotificationPanelViewController() != null) {
-                getNotificationPanelViewController().updateSystemUiStateFlags();
-            }
-        }
-    }
-
-    @NonNull
-    @Override
-    public Lifecycle getLifecycle() {
-        return mLifecycle;
-    }
-
-    @VisibleForTesting
-    protected void registerBroadcastReceiver() {
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
-        filter.addAction(Intent.ACTION_SCREEN_OFF);
-        mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, null, UserHandle.ALL);
-    }
-
-    protected QS createDefaultQSFragment() {
-        return FragmentHostManager.get(mNotificationShadeWindowView).create(QSFragment.class);
-    }
-
-    private void setUpPresenter() {
-        // Set up the initial notification state.
-        mActivityLaunchAnimator.setCallback(mActivityLaunchAnimatorCallback);
-        mActivityLaunchAnimator.addListener(mActivityLaunchAnimatorListener);
-        mNotificationAnimationProvider = new NotificationLaunchAnimatorControllerProvider(
-                mNotificationShadeWindowViewController,
-                mNotifListContainer,
-                mHeadsUpManager,
-                mJankMonitor);
-        mNotificationShelfController.setOnActivatedListener(mPresenter);
-        mRemoteInputManager.addControllerCallback(mNotificationShadeWindowController);
-        mStackScrollerController.setNotificationActivityStarter(mNotificationActivityStarter);
-        mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);
-        mNotificationsController.initialize(
-                mPresenter,
-                mNotifListContainer,
-                mStackScrollerController.getNotifStackController(),
-                mNotificationActivityStarter,
-                mCentralSurfacesComponent.getBindRowCallback());
-    }
-
-    /**
-     * Post-init task of {@link #start()}
-     * @param state1 disable1 flags
-     * @param state2 disable2 flags
-     */
-    protected void setUpDisableFlags(int state1, int state2) {
-        mCommandQueue.disable(mDisplayId, state1, state2, false /* animate */);
-    }
-
-    /**
-     * Ask the display to wake up if currently dozing, else do nothing
-     *
-     * @param time when to wake up
-     * @param where the view requesting the wakeup
-     * @param why the reason for the wake up
-     */
-    public void wakeUpIfDozing(long time, View where, String why) {
-        if (mDozing && mScreenOffAnimationController.allowWakeUpIfDozing()) {
-            mPowerManager.wakeUp(
-                    time, PowerManager.WAKE_REASON_GESTURE, "com.android.systemui:" + why);
-            mWakeUpComingFromTouch = true;
-            where.getLocationInWindow(mTmpInt2);
-
-            // NOTE, the incoming view can sometimes be the entire container... unsure if
-            // this location is valuable enough
-            mWakeUpTouchLocation = new PointF(mTmpInt2[0] + where.getWidth() / 2,
-                    mTmpInt2[1] + where.getHeight() / 2);
-            mFalsingCollector.onScreenOnFromTouch();
-        }
-    }
-
-    // TODO(b/117478341): This was left such that CarStatusBar can override this method.
-    // Try to remove this.
-    protected void createNavigationBar(@Nullable RegisterStatusBarResult result) {
-        mNavigationBarController.createNavigationBars(true /* includeDefaultDisplay */, result);
-    }
-
-    /**
-     * Returns the {@link android.view.View.OnTouchListener} that will be invoked when the
-     * background window of the status bar is clicked.
-     */
-    protected View.OnTouchListener getStatusBarWindowTouchListener() {
-        return (v, event) -> {
-            mAutoHideController.checkUserAutoHide(event);
-            mRemoteInputManager.checkRemoteInputOutside(event);
-            if (event.getAction() == MotionEvent.ACTION_UP) {
-                if (mExpandedVisible) {
-                    mShadeController.animateCollapsePanels();
-                }
-            }
-            return mNotificationShadeWindowView.onTouchEvent(event);
-        };
-    }
-
-    private void inflateStatusBarWindow() {
-        if (mCentralSurfacesComponent != null) {
-            // Tear down
-            for (CentralSurfacesComponent.Startable s : mCentralSurfacesComponent.getStartables()) {
-                s.stop();
-            }
-        }
-        mCentralSurfacesComponent = mCentralSurfacesComponentFactory.create();
-        mFragmentService.addFragmentInstantiationProvider(mCentralSurfacesComponent);
-
-        mNotificationShadeWindowView = mCentralSurfacesComponent.getNotificationShadeWindowView();
-        mNotificationShadeWindowViewController = mCentralSurfacesComponent
-                .getNotificationShadeWindowViewController();
-        mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView);
-        mNotificationShadeWindowViewController.setupExpandedStatusBar();
-        mNotificationPanelViewController =
-                mCentralSurfacesComponent.getNotificationPanelViewController();
-        mCentralSurfacesComponent.getLockIconViewController().init();
-        mStackScrollerController =
-                mCentralSurfacesComponent.getNotificationStackScrollLayoutController();
-        mStackScroller = mStackScrollerController.getView();
-        mNotifListContainer = mCentralSurfacesComponent.getNotificationListContainer();
-        mPresenter = mCentralSurfacesComponent.getNotificationPresenter();
-        mNotificationActivityStarter = mCentralSurfacesComponent.getNotificationActivityStarter();
-        mNotificationShelfController = mCentralSurfacesComponent.getNotificationShelfController();
-        mAuthRippleController = mCentralSurfacesComponent.getAuthRippleController();
-        mAuthRippleController.init();
-
-        mHeadsUpManager.addListener(mCentralSurfacesComponent.getStatusBarHeadsUpChangeListener());
-
-        // Listen for demo mode changes
-        mDemoModeController.addCallback(mDemoModeCallback);
-
-        if (mCommandQueueCallbacks != null) {
-            mCommandQueue.removeCallback(mCommandQueueCallbacks);
-        }
-        mCommandQueueCallbacks =
-                mCentralSurfacesComponent.getCentralSurfacesCommandQueueCallbacks();
-        // Connect in to the status bar manager service
-        mCommandQueue.addCallback(mCommandQueueCallbacks);
-
-        // Perform all other initialization for CentralSurfacesScope
-        for (CentralSurfacesComponent.Startable s : mCentralSurfacesComponent.getStartables()) {
-            s.start();
-        }
-    }
-
-    protected void startKeyguard() {
-        Trace.beginSection("CentralSurfaces#startKeyguard");
-        mBiometricUnlockController = mBiometricUnlockControllerLazy.get();
-        mBiometricUnlockController.setBiometricModeListener(
-                new BiometricUnlockController.BiometricModeListener() {
-                    @Override
-                    public void onResetMode() {
-                        setWakeAndUnlocking(false);
-                    }
-
-                    @Override
-                    public void onModeChanged(int mode) {
-                        switch (mode) {
-                            case BiometricUnlockController.MODE_WAKE_AND_UNLOCK_FROM_DREAM:
-                            case BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING:
-                            case BiometricUnlockController.MODE_WAKE_AND_UNLOCK:
-                                setWakeAndUnlocking(true);
-                        }
-                    }
-
-                    @Override
-                    public void notifyBiometricAuthModeChanged() {
-                        CentralSurfaces.this.notifyBiometricAuthModeChanged();
-                    }
-
-                    private void setWakeAndUnlocking(boolean wakeAndUnlocking) {
-                        if (getNavigationBarView() != null) {
-                            getNavigationBarView().setWakeAndUnlocking(wakeAndUnlocking);
-                        }
-                    }
-                });
-        mStatusBarKeyguardViewManager.registerCentralSurfaces(
-                /* statusBar= */ this,
-                mNotificationPanelViewController,
-                mPanelExpansionStateManager,
-                mBiometricUnlockController,
-                mStackScroller,
-                mKeyguardBypassController);
-        mKeyguardStateController.addCallback(mKeyguardStateControllerCallback);
-        mKeyguardIndicationController
-                .setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
-        mBiometricUnlockController.setKeyguardViewController(mStatusBarKeyguardViewManager);
-        mRemoteInputManager.addControllerCallback(mStatusBarKeyguardViewManager);
-        mDynamicPrivacyController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
-
-        mLightBarController.setBiometricUnlockController(mBiometricUnlockController);
-        mMediaManager.setBiometricUnlockController(mBiometricUnlockController);
-        mKeyguardDismissUtil.setDismissHandler(this::executeWhenUnlocked);
-        Trace.endSection();
-    }
-
-    public NotificationShadeWindowView getNotificationShadeWindowView() {
-        return mNotificationShadeWindowView;
-    }
-
-    public NotificationShadeWindowViewController getNotificationShadeWindowViewController() {
-        return mNotificationShadeWindowViewController;
-    }
-
-    public NotificationPanelViewController getNotificationPanelViewController() {
-        return mNotificationPanelViewController;
-    }
-
-    public ViewGroup getBouncerContainer() {
-        return mNotificationShadeWindowViewController.getBouncerContainer();
-    }
-
-    public int getStatusBarHeight() {
-        return mStatusBarWindowController.getStatusBarHeight();
-    }
-
-    /**
-     * Disable QS if device not provisioned.
-     * If the user switcher is simple then disable QS during setup because
-     * the user intends to use the lock screen user switcher, QS in not needed.
-     */
-    void updateQsExpansionEnabled() {
-        final boolean expandEnabled = mDeviceProvisionedController.isDeviceProvisioned()
-                && (mUserSetup || mUserSwitcherController == null
-                        || !mUserSwitcherController.isSimpleUserSwitcher())
-                && !isShadeDisabled()
-                && ((mDisabled2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) == 0)
-                && !mDozing;
-        mNotificationPanelViewController.setQsExpansionEnabledPolicy(expandEnabled);
-        Log.d(TAG, "updateQsExpansionEnabled - QS Expand enabled: " + expandEnabled);
-    }
-
-    public boolean isShadeDisabled() {
-        return (mDisabled2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) != 0;
-    }
-
-    /**
-     * Request a notification update
-     * @param reason why we're requesting a notification update
-     */
-    public void requestNotificationUpdate(String reason) {
-        mNotificationsController.requestNotificationUpdate(reason);
-    }
-
-    /**
-     * Asks {@link KeyguardUpdateMonitor} to run face auth.
-     */
-    public void requestFaceAuth(boolean userInitiatedRequest) {
-        if (!mKeyguardStateController.canDismissLockScreen()) {
-            mKeyguardUpdateMonitor.requestFaceAuth(userInitiatedRequest);
-        }
-    }
-
-    private void updateReportRejectedTouchVisibility() {
-        if (mReportRejectedTouch == null) {
-            return;
-        }
-        mReportRejectedTouch.setVisibility(mState == StatusBarState.KEYGUARD && !mDozing
-                && mFalsingCollector.isReportingEnabled() ? View.VISIBLE : View.INVISIBLE);
-    }
-
-    boolean areNotificationAlertsDisabled() {
-        return (mDisabled1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
-    }
-
-    @Override
-    public void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade,
-            int flags) {
-        startActivityDismissingKeyguard(intent, onlyProvisioned, dismissShade, flags);
-    }
-
-    @Override
-    public void startActivity(Intent intent, boolean dismissShade) {
-        startActivityDismissingKeyguard(intent, false /* onlyProvisioned */, dismissShade);
-    }
-
-    @Override
-    public void startActivity(Intent intent, boolean dismissShade,
-            @Nullable ActivityLaunchAnimator.Controller animationController,
-            boolean showOverLockscreenWhenLocked) {
-        startActivity(intent, dismissShade, animationController, showOverLockscreenWhenLocked,
-                getActivityUserHandle(intent));
-    }
-
-    @Override
-    public void startActivity(Intent intent, boolean dismissShade,
-            @Nullable ActivityLaunchAnimator.Controller animationController,
-            boolean showOverLockscreenWhenLocked, UserHandle userHandle) {
-        // Make sure that we dismiss the keyguard if it is directly dismissable or when we don't
-        // want to show the activity above it.
-        if (mKeyguardStateController.isUnlocked() || !showOverLockscreenWhenLocked) {
-            startActivityDismissingKeyguard(intent, false, dismissShade,
-                    false /* disallowEnterPictureInPictureWhileLaunching */, null /* callback */,
-                    0 /* flags */, animationController, userHandle);
-            return;
-        }
-
-        boolean animate =
-                animationController != null && shouldAnimateLaunch(true /* isActivityIntent */,
-                        showOverLockscreenWhenLocked);
-
-        ActivityLaunchAnimator.Controller controller = null;
-        if (animate) {
-            // Wrap the animation controller to dismiss the shade and set
-            // mIsLaunchingActivityOverLockscreen during the animation.
-            ActivityLaunchAnimator.Controller delegate = wrapAnimationController(
-                    animationController, dismissShade);
-            controller = new DelegateLaunchAnimatorController(delegate) {
-                @Override
-                public void onIntentStarted(boolean willAnimate) {
-                    getDelegate().onIntentStarted(willAnimate);
-
-                    if (willAnimate) {
-                        CentralSurfaces.this.mIsLaunchingActivityOverLockscreen = true;
-                    }
-                }
-
-                @Override
-                public void onLaunchAnimationEnd(boolean isExpandingFullyAbove) {
-                    // Set mIsLaunchingActivityOverLockscreen to false before actually finishing the
-                    // animation so that we can assume that mIsLaunchingActivityOverLockscreen
-                    // being true means that we will collapse the shade (or at least run the
-                    // post collapse runnables) later on.
-                    CentralSurfaces.this.mIsLaunchingActivityOverLockscreen = false;
-                    getDelegate().onLaunchAnimationEnd(isExpandingFullyAbove);
-                }
-
-                @Override
-                public void onLaunchAnimationCancelled() {
-                    // Set mIsLaunchingActivityOverLockscreen to false before actually finishing the
-                    // animation so that we can assume that mIsLaunchingActivityOverLockscreen
-                    // being true means that we will collapse the shade (or at least run the
-                    // post collapse runnables) later on.
-                    CentralSurfaces.this.mIsLaunchingActivityOverLockscreen = false;
-                    getDelegate().onLaunchAnimationCancelled();
-                }
-            };
-        } else if (dismissShade) {
-            // The animation will take care of dismissing the shade at the end of the animation. If
-            // we don't animate, collapse it directly.
-            collapseShade();
-        }
-
-        mActivityLaunchAnimator.startIntentWithAnimation(controller, animate,
-                intent.getPackage(), showOverLockscreenWhenLocked, (adapter) -> TaskStackBuilder
-                        .create(mContext)
-                        .addNextIntent(intent)
-                        .startActivities(getActivityOptions(getDisplayId(), adapter),
-                                userHandle));
-    }
-
-    /**
-     * Whether we are currently animating an activity launch above the lockscreen (occluding
-     * activity).
-     */
-    public boolean isLaunchingActivityOverLockscreen() {
-        return mIsLaunchingActivityOverLockscreen;
-    }
-
-    @Override
-    public void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade) {
-        startActivityDismissingKeyguard(intent, onlyProvisioned, dismissShade);
-    }
-
-    @Override
-    public void startActivity(Intent intent, boolean dismissShade, Callback callback) {
-        startActivityDismissingKeyguard(intent, false, dismissShade,
-                false /* disallowEnterPictureInPictureWhileLaunching */, callback, 0,
-                null /* animationController */, getActivityUserHandle(intent));
-    }
-
-    public void setQsExpanded(boolean expanded) {
-        mNotificationShadeWindowController.setQsExpanded(expanded);
-        mNotificationPanelViewController.setStatusAccessibilityImportance(expanded
-                ? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
-                : View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
-        mNotificationPanelViewController.updateSystemUiStateFlags();
-        if (getNavigationBarView() != null) {
-            getNavigationBarView().onStatusBarPanelStateChanged();
-        }
-    }
-
-    public boolean isWakeUpComingFromTouch() {
-        return mWakeUpComingFromTouch;
-    }
-
-    public boolean isFalsingThresholdNeeded() {
-        return true;
-    }
-
-    /**
-     * To be called when there's a state change in StatusBarKeyguardViewManager.
-     */
-    public void onKeyguardViewManagerStatesUpdated() {
-        logStateToEventlog();
-    }
-
-    public void setPanelExpanded(boolean isExpanded) {
-        if (mPanelExpanded != isExpanded) {
-            mNotificationLogger.onPanelExpandedChanged(isExpanded);
-        }
-        mPanelExpanded = isExpanded;
-        mStatusBarHideIconsForBouncerManager.setPanelExpandedAndTriggerUpdate(isExpanded);
-        mNotificationShadeWindowController.setPanelExpanded(isExpanded);
-        mStatusBarStateController.setPanelExpanded(isExpanded);
-        if (isExpanded && mStatusBarStateController.getState() != StatusBarState.KEYGUARD) {
-            if (DEBUG) {
-                Log.v(TAG, "clearing notification effects from Height");
-            }
-            clearNotificationEffects();
-        }
-
-        if (!isExpanded) {
-            mRemoteInputManager.onPanelCollapsed();
-        }
-    }
-
-    public ViewGroup getNotificationScrollLayout() {
-        return mStackScroller;
-    }
-
-    public boolean isPulsing() {
-        return mDozeServiceHost.isPulsing();
-    }
-
-    @Nullable
-    public View getAmbientIndicationContainer() {
-        return mAmbientIndicationContainer;
-    }
-
-    /**
-     * When the keyguard is showing and covered by a "showWhenLocked" activity it
-     * is occluded. This is controlled by {@link com.android.server.policy.PhoneWindowManager}
-     *
-     * @return whether the keyguard is currently occluded
-     */
-    public boolean isOccluded() {
-        return mKeyguardStateController.isOccluded();
-    }
-
-    /** A launch animation was cancelled. */
-    //TODO: These can / should probably be moved to NotificationPresenter or ShadeController
-    public void onLaunchAnimationCancelled(boolean isLaunchForActivity) {
-        if (mPresenter.isPresenterFullyCollapsed() && !mPresenter.isCollapsing()
-                && isLaunchForActivity) {
-            onClosingFinished();
-        } else {
-            mShadeController.collapsePanel(true /* animate */);
-        }
-    }
-
-    /** A launch animation ended. */
-    public void onLaunchAnimationEnd(boolean launchIsFullScreen) {
-        if (!mPresenter.isCollapsing()) {
-            onClosingFinished();
-        }
-        if (launchIsFullScreen) {
-            instantCollapseNotificationPanel();
-        }
-    }
-
-    /**
-     * Whether we should animate an activity launch.
-     *
-     * Note: This method must be called *before* dismissing the keyguard.
-     */
-    public boolean shouldAnimateLaunch(boolean isActivityIntent, boolean showOverLockscreen) {
-        // TODO(b/184121838): Support launch animations when occluded.
-        if (isOccluded()) {
-            return false;
-        }
-
-        // Always animate if we are not showing the keyguard or if we animate over the lockscreen
-        // (without unlocking it).
-        if (showOverLockscreen || !mKeyguardStateController.isShowing()) {
-            return true;
-        }
-
-        // If we are locked and have to dismiss the keyguard, only animate if remote unlock
-        // animations are enabled. We also don't animate non-activity launches as they can break the
-        // animation.
-        // TODO(b/184121838): Support non activity launches on the lockscreen.
-        return isActivityIntent && KeyguardService.sEnableRemoteKeyguardGoingAwayAnimation;
-    }
-
-    /** Whether we should animate an activity launch. */
-    public boolean shouldAnimateLaunch(boolean isActivityIntent) {
-        return shouldAnimateLaunch(isActivityIntent, false /* showOverLockscreen */);
-    }
-
-    public boolean isDeviceInVrMode() {
-        return mPresenter.isDeviceInVrMode();
-    }
-
-    public NotificationPresenter getPresenter() {
-        return mPresenter;
-    }
-
-    @VisibleForTesting
-    void setBarStateForTest(int state) {
-        mState = state;
-    }
-
-    static class KeyboardShortcutsMessage {
-        final int mDeviceId;
-
-        KeyboardShortcutsMessage(int deviceId) {
-            mDeviceId = deviceId;
-        }
-    }
-
-    static class AnimateExpandSettingsPanelMessage {
-        final String mSubpanel;
-
-        AnimateExpandSettingsPanelMessage(String subpanel) {
-            mSubpanel = subpanel;
-        }
-    }
-
-    private void maybeEscalateHeadsUp() {
-        mHeadsUpManager.getAllEntries().forEach(entry -> {
-            final StatusBarNotification sbn = entry.getSbn();
-            final Notification notification = sbn.getNotification();
-            if (notification.fullScreenIntent != null) {
-                if (DEBUG) {
-                    Log.d(TAG, "converting a heads up to fullScreen");
-                }
-                try {
-                    EventLog.writeEvent(EventLogTags.SYSUI_HEADS_UP_ESCALATION,
-                            sbn.getKey());
-                    wakeUpForFullScreenIntent();
-                    notification.fullScreenIntent.send();
-                    entry.notifyFullScreenIntentLaunched();
-                } catch (PendingIntent.CanceledException e) {
-                }
-            }
-        });
-        mHeadsUpManager.releaseAllImmediately();
-    }
-
-    void wakeUpForFullScreenIntent() {
-        if (isGoingToSleep() || mDozing) {
-            mPowerManager.wakeUp(
-                    SystemClock.uptimeMillis(),
-                    PowerManager.WAKE_REASON_APPLICATION,
-                    "com.android.systemui:full_screen_intent");
-            mWakeUpComingFromTouch = false;
-            mWakeUpTouchLocation = null;
-        }
-    }
-
-    void makeExpandedVisible(boolean force) {
-        if (SPEW) Log.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
-        if (!force && (mExpandedVisible || !mCommandQueue.panelsEnabled())) {
-            return;
-        }
-
-        mExpandedVisible = true;
-
-        // Expand the window to encompass the full screen in anticipation of the drag.
-        // This is only possible to do atomically because the status bar is at the top of the screen!
-        mNotificationShadeWindowController.setPanelVisible(true);
-
-        visibilityChanged(true);
-        mCommandQueue.recomputeDisableFlags(mDisplayId, !force /* animate */);
-        setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
-    }
-
-    public void postAnimateCollapsePanels() {
-        mMainExecutor.execute(mShadeController::animateCollapsePanels);
-    }
-
-    public void postAnimateForceCollapsePanels() {
-        mMainExecutor.execute(
-                () -> mShadeController.animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE,
-                true /* force */));
-    }
-
-    public void postAnimateOpenPanels() {
-        mMessageRouter.sendMessage(MSG_OPEN_SETTINGS_PANEL);
-    }
-
-    public boolean isExpandedVisible() {
-        return mExpandedVisible;
-    }
-
-    public boolean isPanelExpanded() {
-        return mPanelExpanded;
-    }
-
-    /**
-     * Called when another window is about to transfer it's input focus.
-     */
-    public void onInputFocusTransfer(boolean start, boolean cancel, float velocity) {
-        if (!mCommandQueue.panelsEnabled()) {
-            return;
-        }
-
-        if (start) {
-            mNotificationPanelViewController.startWaitingForOpenPanelGesture();
-        } else {
-            mNotificationPanelViewController.stopWaitingForOpenPanelGesture(cancel, velocity);
-        }
-    }
-
-    public void animateCollapseQuickSettings() {
-        if (mState == StatusBarState.SHADE) {
-            mNotificationPanelViewController.collapsePanel(
-                    true, false /* delayed */, 1.0f /* speedUpFactor */);
-        }
-    }
-
-    void makeExpandedInvisible() {
-        if (SPEW) Log.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible
-                + " mExpandedVisible=" + mExpandedVisible);
-
-        if (!mExpandedVisible || mNotificationShadeWindowView == null) {
-            return;
-        }
-
-        // Ensure the panel is fully collapsed (just in case; bug 6765842, 7260868)
-        mNotificationPanelViewController.collapsePanel(/*animate=*/ false, false /* delayed*/,
-                1.0f /* speedUpFactor */);
-
-        mNotificationPanelViewController.closeQs();
-
-        mExpandedVisible = false;
-        visibilityChanged(false);
-
-        // Update the visibility of notification shade and status bar window.
-        mNotificationShadeWindowController.setPanelVisible(false);
-        mStatusBarWindowController.setForceStatusBarVisible(false);
-
-        // Close any guts that might be visible
-        mGutsManager.closeAndSaveGuts(true /* removeLeavebehind */, true /* force */,
-                true /* removeControls */, -1 /* x */, -1 /* y */, true /* resetMenu */);
-
-        mShadeController.runPostCollapseRunnables();
-        setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
-        if (!mNotificationActivityStarter.isCollapsingToShowActivityOverLockscreen()) {
-            showBouncerOrLockScreenIfKeyguard();
-        } else if (DEBUG) {
-            Log.d(TAG, "Not showing bouncer due to activity showing over lockscreen");
-        }
-        mCommandQueue.recomputeDisableFlags(
-                mDisplayId,
-                mNotificationPanelViewController.hideStatusBarIconsWhenExpanded() /* animate */);
-
-        // Trimming will happen later if Keyguard is showing - doing it here might cause a jank in
-        // the bouncer appear animation.
-        if (!mStatusBarKeyguardViewManager.isShowing()) {
-            WindowManagerGlobal.getInstance().trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
-        }
-    }
-
-    /** Called when a touch event occurred on {@link PhoneStatusBarView}. */
-    public void onTouchEvent(MotionEvent event) {
-        // TODO(b/202981994): Move this touch debugging to a central location. (Right now, it's
-        //   split between NotificationPanelViewController and here.)
-        if (DEBUG_GESTURES) {
-            if (event.getActionMasked() != MotionEvent.ACTION_MOVE) {
-                EventLog.writeEvent(EventLogTags.SYSUI_STATUSBAR_TOUCH,
-                        event.getActionMasked(), (int) event.getX(), (int) event.getY(),
-                        mDisabled1, mDisabled2);
-            }
-
-        }
-
-        if (SPEW) {
-            Log.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled1="
-                    + mDisabled1 + " mDisabled2=" + mDisabled2);
-        } else if (CHATTY) {
-            if (event.getAction() != MotionEvent.ACTION_MOVE) {
-                Log.d(TAG, String.format(
-                            "panel: %s at (%f, %f) mDisabled1=0x%08x mDisabled2=0x%08x",
-                            MotionEvent.actionToString(event.getAction()),
-                            event.getRawX(), event.getRawY(), mDisabled1, mDisabled2));
-            }
-        }
-
-        if (DEBUG_GESTURES) {
-            mGestureRec.add(event);
-        }
-
-        if (mStatusBarWindowState == WINDOW_STATE_SHOWING) {
-            final boolean upOrCancel =
-                    event.getAction() == MotionEvent.ACTION_UP ||
-                    event.getAction() == MotionEvent.ACTION_CANCEL;
-            setInteracting(StatusBarManager.WINDOW_STATUS_BAR, !upOrCancel || mExpandedVisible);
-        }
-    }
-
-    public GestureRecorder getGestureRecorder() {
-        return mGestureRec;
-    }
-
-    public BiometricUnlockController getBiometricUnlockController() {
-        return mBiometricUnlockController;
-    }
-
-    void showTransientUnchecked() {
-        if (!mTransientShown) {
-            mTransientShown = true;
-            mNoAnimationOnNextBarModeChange = true;
-            maybeUpdateBarMode();
-        }
-    }
-
-
-    void clearTransient() {
-        if (mTransientShown) {
-            mTransientShown = false;
-            maybeUpdateBarMode();
-        }
-    }
-
-    private void maybeUpdateBarMode() {
-        final int barMode = barMode(mTransientShown, mAppearance);
-        if (updateBarMode(barMode)) {
-            mLightBarController.onStatusBarModeChanged(barMode);
-            updateBubblesVisibility();
-        }
-    }
-
-    private boolean updateBarMode(int barMode) {
-        if (mStatusBarMode != barMode) {
-            mStatusBarMode = barMode;
-            checkBarModes();
-            mAutoHideController.touchAutoHide();
-            return true;
-        }
-        return false;
-    }
-
-    private @TransitionMode int barMode(boolean isTransient, int appearance) {
-        final int lightsOutOpaque = APPEARANCE_LOW_PROFILE_BARS | APPEARANCE_OPAQUE_STATUS_BARS;
-        if (mOngoingCallController.hasOngoingCall() && mIsFullscreen) {
-            return MODE_SEMI_TRANSPARENT;
-        } else if (isTransient) {
-            return MODE_SEMI_TRANSPARENT;
-        } else if ((appearance & lightsOutOpaque) == lightsOutOpaque) {
-            return MODE_LIGHTS_OUT;
-        } else if ((appearance & APPEARANCE_LOW_PROFILE_BARS) != 0) {
-            return MODE_LIGHTS_OUT_TRANSPARENT;
-        } else if ((appearance & APPEARANCE_OPAQUE_STATUS_BARS) != 0) {
-            return MODE_OPAQUE;
-        } else if ((appearance & APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS) != 0) {
-            return MODE_SEMI_TRANSPARENT;
-        } else {
-            return MODE_TRANSPARENT;
-        }
-    }
-
-    protected void showWirelessChargingAnimation(int batteryLevel) {
-        showChargingAnimation(batteryLevel, UNKNOWN_BATTERY_LEVEL, 0);
-    }
-
-    protected void showChargingAnimation(int batteryLevel, int transmittingBatteryLevel,
-            long animationDelay) {
-        WirelessChargingAnimation.makeWirelessChargingAnimation(mContext, null,
-                transmittingBatteryLevel, batteryLevel,
-                new WirelessChargingAnimation.Callback() {
-                    @Override
-                    public void onAnimationStarting() {
-                        mNotificationShadeWindowController.setRequestTopUi(true, TAG);
-                    }
-
-                    @Override
-                    public void onAnimationEnded() {
-                        mNotificationShadeWindowController.setRequestTopUi(false, TAG);
-                    }
-                }, false, sUiEventLogger).show(animationDelay);
-    }
-
-    public void checkBarModes() {
-        if (mDemoModeController.isInDemoMode()) return;
-        if (mStatusBarTransitions != null) {
-            checkBarMode(mStatusBarMode, mStatusBarWindowState, mStatusBarTransitions);
-        }
-        mNavigationBarController.checkNavBarModes(mDisplayId);
-        mNoAnimationOnNextBarModeChange = false;
-    }
-
-    // Called by NavigationBarFragment
-    public void setQsScrimEnabled(boolean scrimEnabled) {
-        mNotificationPanelViewController.setQsScrimEnabled(scrimEnabled);
-    }
-
-    /** Temporarily hides Bubbles if the status bar is hidden. */
-    void updateBubblesVisibility() {
-        mBubblesOptional.ifPresent(bubbles -> bubbles.onStatusBarVisibilityChanged(
-                mStatusBarMode != MODE_LIGHTS_OUT
-                        && mStatusBarMode != MODE_LIGHTS_OUT_TRANSPARENT
-                        && !mStatusBarWindowHidden));
-    }
-
-    void checkBarMode(@TransitionMode int mode, @WindowVisibleState int windowState,
-            BarTransitions transitions) {
-        final boolean anim = !mNoAnimationOnNextBarModeChange && mDeviceInteractive
-                && windowState != WINDOW_STATE_HIDDEN;
-        transitions.transitionTo(mode, anim);
-    }
-
-    private void finishBarAnimations() {
-        if (mStatusBarTransitions != null) {
-            mStatusBarTransitions.finishAnimations();
-        }
-        mNavigationBarController.finishBarAnimations(mDisplayId);
-    }
-
-    private final Runnable mCheckBarModes = this::checkBarModes;
-
-    public void setInteracting(int barWindow, boolean interacting) {
-        mInteractingWindows = interacting
-                ? (mInteractingWindows | barWindow)
-                : (mInteractingWindows & ~barWindow);
-        if (mInteractingWindows != 0) {
-            mAutoHideController.suspendAutoHide();
-        } else {
-            mAutoHideController.resumeSuspendedAutoHide();
-        }
-        checkBarModes();
-    }
-
-    private void dismissVolumeDialog() {
-        if (mVolumeComponent != null) {
-            mVolumeComponent.dismissNow();
-        }
-    }
-
-    public static String viewInfo(View v) {
+    static String viewInfo(View v) {
         return "[(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()
                 + ") " + v.getWidth() + "x" + v.getHeight() + "]";
     }
 
-    @Override
-    public void dump(PrintWriter pwOriginal, String[] args) {
-        IndentingPrintWriter pw = DumpUtilsKt.asIndenting(pwOriginal);
-        synchronized (mQueueLock) {
-            pw.println("Current Status Bar state:");
-            pw.println("  mExpandedVisible=" + mExpandedVisible);
-            pw.println("  mDisplayMetrics=" + mDisplayMetrics);
-            pw.println("  mStackScroller: " + viewInfo(mStackScroller));
-            pw.println("  mStackScroller: " + viewInfo(mStackScroller)
-                    + " scroll " + mStackScroller.getScrollX()
-                    + "," + mStackScroller.getScrollY());
-        }
-
-        pw.print("  mInteractingWindows="); pw.println(mInteractingWindows);
-        pw.print("  mStatusBarWindowState=");
-        pw.println(windowStateToString(mStatusBarWindowState));
-        pw.print("  mStatusBarMode=");
-        pw.println(BarTransitions.modeToString(mStatusBarMode));
-        pw.print("  mDozing="); pw.println(mDozing);
-        pw.print("  mWallpaperSupported= "); pw.println(mWallpaperSupported);
-
-        pw.println("  ShadeWindowView: ");
-        if (mNotificationShadeWindowViewController != null) {
-            mNotificationShadeWindowViewController.dump(pw, args);
-            dumpBarTransitions(pw, "PhoneStatusBarTransitions", mStatusBarTransitions);
-        }
-
-        pw.println("  mMediaManager: ");
-        if (mMediaManager != null) {
-            mMediaManager.dump(pw, args);
-        }
-
-        pw.println("  Panels: ");
-        if (mNotificationPanelViewController != null) {
-            pw.println("    mNotificationPanel="
-                    + mNotificationPanelViewController.getView() + " params="
-                    + mNotificationPanelViewController.getView().getLayoutParams().debug(""));
-            pw.print  ("      ");
-            mNotificationPanelViewController.dump(pw, args);
-        }
-        pw.println("  mStackScroller: ");
-        if (mStackScroller != null) {
-            // Double indent until we rewrite the rest of this dump()
-            pw.increaseIndent();
-            pw.increaseIndent();
-            mStackScroller.dump(pw, args);
-            pw.decreaseIndent();
-            pw.decreaseIndent();
-        }
-        pw.println("  Theme:");
-        String nightMode = mUiModeManager == null ? "null" : mUiModeManager.getNightMode() + "";
-        pw.println("    dark theme: " + nightMode +
-                " (auto: " + UiModeManager.MODE_NIGHT_AUTO +
-                ", yes: " + UiModeManager.MODE_NIGHT_YES +
-                ", no: " + UiModeManager.MODE_NIGHT_NO + ")");
-        final boolean lightWpTheme = mContext.getThemeResId()
-                == R.style.Theme_SystemUI_LightWallpaper;
-        pw.println("    light wallpaper theme: " + lightWpTheme);
-
-        if (mKeyguardIndicationController != null) {
-            mKeyguardIndicationController.dump(pw, args);
-        }
-
-        if (mScrimController != null) {
-            mScrimController.dump(pw, args);
-        }
-
-        if (mLightRevealScrim != null) {
-            pw.println(
-                    "mLightRevealScrim.getRevealEffect(): " + mLightRevealScrim.getRevealEffect());
-            pw.println(
-                    "mLightRevealScrim.getRevealAmount(): " + mLightRevealScrim.getRevealAmount());
-        }
-
-        if (mStatusBarKeyguardViewManager != null) {
-            mStatusBarKeyguardViewManager.dump(pw);
-        }
-
-        mNotificationsController.dump(pw, args, DUMPTRUCK);
-
-        if (DEBUG_GESTURES) {
-            pw.print("  status bar gestures: ");
-            mGestureRec.dump(pw, args);
-        }
-
-        if (mHeadsUpManager != null) {
-            mHeadsUpManager.dump(pw, args);
-        } else {
-            pw.println("  mHeadsUpManager: null");
-        }
-
-        if (mStatusBarTouchableRegionManager != null) {
-            mStatusBarTouchableRegionManager.dump(pw, args);
-        } else {
-            pw.println("  mStatusBarTouchableRegionManager: null");
-        }
-
-        if (mLightBarController != null) {
-            mLightBarController.dump(pw, args);
-        }
-
-        pw.println("SharedPreferences:");
-        for (Map.Entry<String, ?> entry : Prefs.getAll(mContext).entrySet()) {
-            pw.print("  "); pw.print(entry.getKey()); pw.print("="); pw.println(entry.getValue());
-        }
-
-        pw.println("Camera gesture intents:");
-        pw.println("   Insecure camera: " + CameraIntents.getInsecureCameraIntent(mContext));
-        pw.println("   Secure camera: " + CameraIntents.getSecureCameraIntent(mContext));
-        pw.println("   Override package: "
-                + CameraIntents.getOverrideCameraPackage(mContext));
-    }
-
-    public static void dumpBarTransitions(
+    static void dumpBarTransitions(
             PrintWriter pw, String var, @Nullable BarTransitions transitions) {
-        pw.print("  "); pw.print(var); pw.print(".BarTransitions.mMode=");
+        pw.print("  ");
+        pw.print(var);
+        pw.print(".BarTransitions.mMode=");
         if (transitions != null) {
             pw.println(BarTransitions.modeToString(transitions.getMode()));
         } else {
@@ -2368,1691 +106,15 @@
         }
     }
 
-    public void createAndAddWindows(@Nullable RegisterStatusBarResult result) {
-        makeStatusBarView(result);
-        mNotificationShadeWindowController.attach();
-        mStatusBarWindowController.attach();
-    }
-
-    // called by makeStatusbar and also by PhoneStatusBarView
-    void updateDisplaySize() {
-        mDisplay.getMetrics(mDisplayMetrics);
-        mDisplay.getSize(mCurrentDisplaySize);
-        if (DEBUG_GESTURES) {
-            mGestureRec.tag("display",
-                    String.format("%dx%d", mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels));
-        }
-    }
-
-    float getDisplayDensity() {
-        return mDisplayMetrics.density;
-    }
-
-    public float getDisplayWidth() {
-        return mDisplayMetrics.widthPixels;
-    }
-
-    public float getDisplayHeight() {
-        return mDisplayMetrics.heightPixels;
-    }
-
-    int getRotation() {
-        return mDisplay.getRotation();
-    }
-
-    int getDisplayId() {
-        return mDisplayId;
-    }
-
-    public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
-            boolean dismissShade, int flags) {
-        startActivityDismissingKeyguard(intent, onlyProvisioned, dismissShade,
-                false /* disallowEnterPictureInPictureWhileLaunching */, null /* callback */,
-                flags, null /* animationController */, getActivityUserHandle(intent));
-    }
-
-    public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
-            boolean dismissShade) {
-        startActivityDismissingKeyguard(intent, onlyProvisioned, dismissShade, 0);
-    }
-
-    void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
-            final boolean dismissShade, final boolean disallowEnterPictureInPictureWhileLaunching,
-            final Callback callback, int flags,
-            @Nullable ActivityLaunchAnimator.Controller animationController,
-            final UserHandle userHandle) {
-        if (onlyProvisioned && !mDeviceProvisionedController.isDeviceProvisioned()) return;
-
-        final boolean willLaunchResolverActivity =
-                mActivityIntentHelper.wouldLaunchResolverActivity(intent,
-                        mLockscreenUserManager.getCurrentUserId());
-
-        boolean animate =
-                animationController != null && !willLaunchResolverActivity && shouldAnimateLaunch(
-                        true /* isActivityIntent */);
-        ActivityLaunchAnimator.Controller animController =
-                animationController != null ? wrapAnimationController(animationController,
-                        dismissShade) : null;
-
-        // If we animate, we will dismiss the shade only once the animation is done. This is taken
-        // care of by the StatusBarLaunchAnimationController.
-        boolean dismissShadeDirectly = dismissShade && animController == null;
-
-        Runnable runnable = () -> {
-            mAssistManagerLazy.get().hideAssist();
-            intent.setFlags(
-                    Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
-            intent.addFlags(flags);
-            int[] result = new int[]{ActivityManager.START_CANCELED};
-
-            mActivityLaunchAnimator.startIntentWithAnimation(animController,
-                    animate, intent.getPackage(), (adapter) -> {
-                        ActivityOptions options = new ActivityOptions(
-                                getActivityOptions(mDisplayId, adapter));
-                        options.setDisallowEnterPictureInPictureWhileLaunching(
-                                disallowEnterPictureInPictureWhileLaunching);
-                        if (CameraIntents.isInsecureCameraIntent(intent)) {
-                            // Normally an activity will set it's requested rotation
-                            // animation on its window. However when launching an activity
-                            // causes the orientation to change this is too late. In these cases
-                            // the default animation is used. This doesn't look good for
-                            // the camera (as it rotates the camera contents out of sync
-                            // with physical reality). So, we ask the WindowManager to
-                            // force the crossfade animation if an orientation change
-                            // happens to occur during the launch.
-                            options.setRotationAnimationHint(
-                                    WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS);
-                        }
-                        if (Settings.Panel.ACTION_VOLUME.equals(intent.getAction())) {
-                            // Settings Panel is implemented as activity(not a dialog), so
-                            // underlying app is paused and may enter picture-in-picture mode
-                            // as a result.
-                            // So we need to disable picture-in-picture mode here
-                            // if it is volume panel.
-                            options.setDisallowEnterPictureInPictureWhileLaunching(true);
-                        }
-
-                        try {
-                            result[0] = ActivityTaskManager.getService().startActivityAsUser(
-                                    null, mContext.getBasePackageName(),
-                                    mContext.getAttributionTag(),
-                                    intent,
-                                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
-                                    null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null,
-                                    options.toBundle(), userHandle.getIdentifier());
-                        } catch (RemoteException e) {
-                            Log.w(TAG, "Unable to start activity", e);
-                        }
-                        return result[0];
-                    });
-
-            if (callback != null) {
-                callback.onActivityStarted(result[0]);
-            }
-        };
-        Runnable cancelRunnable = () -> {
-            if (callback != null) {
-                callback.onActivityStarted(ActivityManager.START_CANCELED);
-            }
-        };
-        executeRunnableDismissingKeyguard(runnable, cancelRunnable, dismissShadeDirectly,
-                willLaunchResolverActivity, true /* deferred */, animate);
-    }
-
-    @Nullable
-    private ActivityLaunchAnimator.Controller wrapAnimationController(
-            ActivityLaunchAnimator.Controller animationController, boolean dismissShade) {
-        View rootView = animationController.getLaunchContainer().getRootView();
-
-        Optional<ActivityLaunchAnimator.Controller> controllerFromStatusBar =
-                mStatusBarWindowController.wrapAnimationControllerIfInStatusBar(
-                        rootView, animationController);
-        if (controllerFromStatusBar.isPresent()) {
-            return controllerFromStatusBar.get();
-        }
-
-        if (dismissShade) {
-            // If the view is not in the status bar, then we are animating a view in the shade.
-            // We have to make sure that we collapse it when the animation ends or is cancelled.
-            return new StatusBarLaunchAnimatorController(animationController, this,
-                    true /* isLaunchForActivity */);
-        }
-
-        return animationController;
-    }
-
-    public void readyForKeyguardDone() {
-        mStatusBarKeyguardViewManager.readyForKeyguardDone();
-    }
-
-    public void executeRunnableDismissingKeyguard(final Runnable runnable,
-            final Runnable cancelAction,
-            final boolean dismissShade,
-            final boolean afterKeyguardGone,
-            final boolean deferred) {
-        executeRunnableDismissingKeyguard(runnable, cancelAction, dismissShade, afterKeyguardGone,
-                deferred, false /* willAnimateOnKeyguard */);
-    }
-
-    public void executeRunnableDismissingKeyguard(final Runnable runnable,
-            final Runnable cancelAction,
-            final boolean dismissShade,
-            final boolean afterKeyguardGone,
-            final boolean deferred,
-            final boolean willAnimateOnKeyguard) {
-        OnDismissAction onDismissAction = new OnDismissAction() {
-            @Override
-            public boolean onDismiss() {
-                if (runnable != null) {
-                    if (mStatusBarKeyguardViewManager.isShowing()
-                            && mStatusBarKeyguardViewManager.isOccluded()) {
-                        mStatusBarKeyguardViewManager.addAfterKeyguardGoneRunnable(runnable);
-                    } else {
-                        mMainExecutor.execute(runnable);
-                    }
-                }
-                if (dismissShade) {
-                    if (mExpandedVisible && !mBouncerShowing) {
-                        mShadeController.animateCollapsePanels(
-                                CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
-                                true /* force */, true /* delayed*/);
-                    } else {
-
-                        // Do it after DismissAction has been processed to conserve the needed
-                        // ordering.
-                        mMainExecutor.execute(mShadeController::runPostCollapseRunnables);
-                    }
-                } else if (CentralSurfaces.this.isInLaunchTransition()
-                        && mNotificationPanelViewController.isLaunchTransitionFinished()) {
-
-                    // We are not dismissing the shade, but the launch transition is already
-                    // finished,
-                    // so nobody will call readyForKeyguardDone anymore. Post it such that
-                    // keyguardDonePending gets called first.
-                    mMainExecutor.execute(mStatusBarKeyguardViewManager::readyForKeyguardDone);
-                }
-                return deferred;
-            }
-
-            @Override
-            public boolean willRunAnimationOnKeyguard() {
-                return willAnimateOnKeyguard;
-            }
-        };
-        dismissKeyguardThenExecute(onDismissAction, cancelAction, afterKeyguardGone);
-    }
-
-    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            Trace.beginSection("CentralSurfaces#onReceive");
-            if (DEBUG) Log.v(TAG, "onReceive: " + intent);
-            String action = intent.getAction();
-            String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
-            if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
-                KeyboardShortcuts.dismiss();
-                mRemoteInputManager.closeRemoteInputs();
-                if (mLockscreenUserManager.isCurrentProfile(getSendingUserId())) {
-                    int flags = CommandQueue.FLAG_EXCLUDE_NONE;
-                    if (reason != null) {
-                        if (reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
-                            flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
-                        }
-                        // Do not collapse notifications when starting dreaming if the notifications
-                        // shade is used for the screen off animation. It might require expanded
-                        // state for the scrims to be visible
-                        if (reason.equals(SYSTEM_DIALOG_REASON_DREAM)
-                                && mScreenOffAnimationController.shouldExpandNotifications()) {
-                            flags |= CommandQueue.FLAG_EXCLUDE_NOTIFICATION_PANEL;
-                        }
-                    }
-                    mShadeController.animateCollapsePanels(flags);
-                }
-            } else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
-                if (mNotificationShadeWindowController != null) {
-                    mNotificationShadeWindowController.setNotTouchable(false);
-                }
-                finishBarAnimations();
-                resetUserExpandedStates();
-            }
-            Trace.endSection();
-        }
-    };
-
-    private final BroadcastReceiver mDemoReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (DEBUG) Log.v(TAG, "onReceive: " + intent);
-            String action = intent.getAction();
-            if (ACTION_FAKE_ARTWORK.equals(action)) {
-                if (DEBUG_MEDIA_FAKE_ARTWORK) {
-                    mPresenter.updateMediaMetaData(true, true);
-                }
-            }
-        }
-    };
-
-    public void resetUserExpandedStates() {
-        mNotificationsController.resetUserExpandedStates();
-    }
-
-    private void executeWhenUnlocked(OnDismissAction action, boolean requiresShadeOpen,
-            boolean afterKeyguardGone) {
-        if (mStatusBarKeyguardViewManager.isShowing() && requiresShadeOpen) {
-            mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
-        }
-        dismissKeyguardThenExecute(action, null /* cancelAction */,
-                afterKeyguardGone /* afterKeyguardGone */);
-    }
-
-    protected void dismissKeyguardThenExecute(OnDismissAction action, boolean afterKeyguardGone) {
-        dismissKeyguardThenExecute(action, null /* cancelRunnable */, afterKeyguardGone);
-    }
-
-    @Override
-    public void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancelAction,
-            boolean afterKeyguardGone) {
-        if (mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_ASLEEP
-                && mKeyguardStateController.canDismissLockScreen()
-                && !mStatusBarStateController.leaveOpenOnKeyguardHide()
-                && mDozeServiceHost.isPulsing()) {
-            // Reuse the biometric wake-and-unlock transition if we dismiss keyguard from a pulse.
-            // TODO: Factor this transition out of BiometricUnlockController.
-            mBiometricUnlockController.startWakeAndUnlock(
-                    BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING);
-        }
-        if (mStatusBarKeyguardViewManager.isShowing()) {
-            mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction,
-                    afterKeyguardGone);
-        } else {
-            action.onDismiss();
-        }
-    }
-    /**
-     * Notify the shade controller that the current user changed
-     *
-     * @param newUserId userId of the new user
-     */
-    public void setLockscreenUser(int newUserId) {
-        if (mLockscreenWallpaper != null) {
-            mLockscreenWallpaper.setCurrentUser(newUserId);
-        }
-        mScrimController.setCurrentUser(newUserId);
-        if (mWallpaperSupported) {
-            mWallpaperChangedReceiver.onReceive(mContext, null);
-        }
-    }
-
-    /**
-     * Reload some of our resources when the configuration changes.
-     *
-     * We don't reload everything when the configuration changes -- we probably
-     * should, but getting that smooth is tough.  Someday we'll fix that.  In the
-     * meantime, just update the things that we know change.
-     */
-    void updateResources() {
-        // Update the quick setting tiles
-        if (mQSPanelController != null) {
-            mQSPanelController.updateResources();
-        }
-
-        if (mStatusBarWindowController != null) {
-            mStatusBarWindowController.refreshStatusBarHeight();
-        }
-
-        if (mNotificationPanelViewController != null) {
-            mNotificationPanelViewController.updateResources();
-        }
-        if (mBrightnessMirrorController != null) {
-            mBrightnessMirrorController.updateResources();
-        }
-        if (mStatusBarKeyguardViewManager != null) {
-            mStatusBarKeyguardViewManager.updateResources();
-        }
-
-        mPowerButtonReveal = new PowerButtonReveal(mContext.getResources().getDimensionPixelSize(
-                com.android.systemui.R.dimen.physical_power_button_center_screen_location_y));
-    }
-
-    // Visibility reporting
-    protected void handleVisibleToUserChanged(boolean visibleToUser) {
-        if (visibleToUser) {
-            handleVisibleToUserChangedImpl(visibleToUser);
-            mNotificationLogger.startNotificationLogging();
-        } else {
-            mNotificationLogger.stopNotificationLogging();
-            handleVisibleToUserChangedImpl(visibleToUser);
-        }
-    }
-
-    // Visibility reporting
-    void handleVisibleToUserChangedImpl(boolean visibleToUser) {
-        if (visibleToUser) {
-            /* The LEDs are turned off when the notification panel is shown, even just a little bit.
-             * See also CentralSurfaces.setPanelExpanded for another place where we attempt to do
-             * this.
-             */
-            boolean pinnedHeadsUp = mHeadsUpManager.hasPinnedHeadsUp();
-            boolean clearNotificationEffects =
-                    !mPresenter.isPresenterFullyCollapsed() &&
-                            (mState == StatusBarState.SHADE
-                                    || mState == StatusBarState.SHADE_LOCKED);
-            int notificationLoad = mNotificationsController.getActiveNotificationsCount();
-            if (pinnedHeadsUp && mPresenter.isPresenterFullyCollapsed()) {
-                notificationLoad = 1;
-            }
-            final int finalNotificationLoad = notificationLoad;
-            mUiBgExecutor.execute(() -> {
-                try {
-                    mBarService.onPanelRevealed(clearNotificationEffects,
-                            finalNotificationLoad);
-                } catch (RemoteException ex) {
-                    // Won't fail unless the world has ended.
-                }
-            });
-        } else {
-            mUiBgExecutor.execute(() -> {
-                try {
-                    mBarService.onPanelHidden();
-                } catch (RemoteException ex) {
-                    // Won't fail unless the world has ended.
-                }
-            });
-        }
-
-    }
-
-    private void logStateToEventlog() {
-        boolean isShowing = mStatusBarKeyguardViewManager.isShowing();
-        boolean isOccluded = mStatusBarKeyguardViewManager.isOccluded();
-        boolean isBouncerShowing = mStatusBarKeyguardViewManager.isBouncerShowing();
-        boolean isSecure = mKeyguardStateController.isMethodSecure();
-        boolean unlocked = mKeyguardStateController.canDismissLockScreen();
-        int stateFingerprint = getLoggingFingerprint(mState,
-                isShowing,
-                isOccluded,
-                isBouncerShowing,
-                isSecure,
-                unlocked);
-        if (stateFingerprint != mLastLoggedStateFingerprint) {
-            if (mStatusBarStateLog == null) {
-                mStatusBarStateLog = new LogMaker(MetricsEvent.VIEW_UNKNOWN);
-            }
-            mMetricsLogger.write(mStatusBarStateLog
-                    .setCategory(isBouncerShowing ? MetricsEvent.BOUNCER : MetricsEvent.LOCKSCREEN)
-                    .setType(isShowing ? MetricsEvent.TYPE_OPEN : MetricsEvent.TYPE_CLOSE)
-                    .setSubtype(isSecure ? 1 : 0));
-            EventLogTags.writeSysuiStatusBarState(mState,
-                    isShowing ? 1 : 0,
-                    isOccluded ? 1 : 0,
-                    isBouncerShowing ? 1 : 0,
-                    isSecure ? 1 : 0,
-                    unlocked ? 1 : 0);
-            mLastLoggedStateFingerprint = stateFingerprint;
-
-            StringBuilder uiEventValueBuilder = new StringBuilder();
-            uiEventValueBuilder.append(isBouncerShowing ? "BOUNCER" : "LOCKSCREEN");
-            uiEventValueBuilder.append(isShowing ? "_OPEN" : "_CLOSE");
-            uiEventValueBuilder.append(isSecure ? "_SECURE" : "_INSECURE");
-            sUiEventLogger.log(StatusBarUiEvent.valueOf(uiEventValueBuilder.toString()));
-        }
-    }
-
-    /**
-     * Returns a fingerprint of fields logged to eventlog
-     */
-    private static int getLoggingFingerprint(int statusBarState, boolean keyguardShowing,
-            boolean keyguardOccluded, boolean bouncerShowing, boolean secure,
-            boolean currentlyInsecure) {
-        // Reserve 8 bits for statusBarState. We'll never go higher than
-        // that, right? Riiiight.
-        return (statusBarState & 0xFF)
-                | ((keyguardShowing   ? 1 : 0) <<  8)
-                | ((keyguardOccluded  ? 1 : 0) <<  9)
-                | ((bouncerShowing    ? 1 : 0) << 10)
-                | ((secure            ? 1 : 0) << 11)
-                | ((currentlyInsecure ? 1 : 0) << 12);
-    }
-
-    @Override
-    public void postQSRunnableDismissingKeyguard(final Runnable runnable) {
-        mMainExecutor.execute(() -> {
-            mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
-            executeRunnableDismissingKeyguard(
-                    () -> mMainExecutor.execute(runnable), null, false, false, false);
-        });
-    }
-
-    @Override
-    public void postStartActivityDismissingKeyguard(PendingIntent intent) {
-        postStartActivityDismissingKeyguard(intent, null /* animationController */);
-    }
-
-    @Override
-    public void postStartActivityDismissingKeyguard(final PendingIntent intent,
-            @Nullable ActivityLaunchAnimator.Controller animationController) {
-        mMainExecutor.execute(() -> startPendingIntentDismissingKeyguard(intent,
-                null /* intentSentUiThreadCallback */, animationController));
-    }
-
-    @Override
-    public void postStartActivityDismissingKeyguard(final Intent intent, int delay) {
-        postStartActivityDismissingKeyguard(intent, delay, null /* animationController */);
-    }
-
-    @Override
-    public void postStartActivityDismissingKeyguard(Intent intent, int delay,
-            @Nullable ActivityLaunchAnimator.Controller animationController) {
-        mMainExecutor.executeDelayed(
-                () ->
-                        startActivityDismissingKeyguard(intent, true /* onlyProvisioned */,
-                                true /* dismissShade */,
-                                false /* disallowEnterPictureInPictureWhileLaunching */,
-                                null /* callback */,
-                                0 /* flags */,
-                                animationController,
-                                getActivityUserHandle(intent)),
-                delay);
-    }
-
-    public void showKeyguard() {
-        mStatusBarStateController.setKeyguardRequested(true);
-        mStatusBarStateController.setLeaveOpenOnKeyguardHide(false);
-        updateIsKeyguard();
-        mAssistManagerLazy.get().onLockscreenShown();
-    }
-
-    public boolean hideKeyguard() {
-        mStatusBarStateController.setKeyguardRequested(false);
-        return updateIsKeyguard();
-    }
-
-    boolean updateIsKeyguard() {
-        return updateIsKeyguard(false /* forceStateChange */);
-    }
-
-    boolean updateIsKeyguard(boolean forceStateChange) {
-        boolean wakeAndUnlocking = mBiometricUnlockController.isWakeAndUnlock();
-
-        // For dozing, keyguard needs to be shown whenever the device is non-interactive. Otherwise
-        // there's no surface we can show to the user. Note that the device goes fully interactive
-        // late in the transition, so we also allow the device to start dozing once the screen has
-        // turned off fully.
-        boolean keyguardForDozing = mDozeServiceHost.getDozingRequested()
-                && (!mDeviceInteractive || (isGoingToSleep()
-                    && (isScreenFullyOff()
-                        || (mKeyguardStateController.isShowing() && !isOccluded()))));
-        boolean isWakingAndOccluded = isOccluded() && isWakingOrAwake();
-        boolean shouldBeKeyguard = (mStatusBarStateController.isKeyguardRequested()
-                || keyguardForDozing) && !wakeAndUnlocking && !isWakingAndOccluded;
-        if (keyguardForDozing) {
-            updatePanelExpansionForKeyguard();
-        }
-        if (shouldBeKeyguard) {
-            if (mScreenOffAnimationController.isKeyguardShowDelayed()
-                    || (isGoingToSleep()
-                    && mScreenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_TURNING_OFF)) {
-                // Delay showing the keyguard until screen turned off.
-            } else {
-                showKeyguardImpl();
-            }
-        } else {
-            // During folding a foldable device this might be called as a result of
-            // 'onScreenTurnedOff' call for the inner display.
-            // In this case:
-            //  * When phone is locked on folding: it doesn't make sense to hide keyguard as it
-            //    will be immediately locked again
-            //  * When phone is unlocked: we still don't want to execute hiding of the keyguard
-            //    as the animation could prepare 'fake AOD' interface (without actually
-            //    transitioning to keyguard state) and this might reset the view states
-            if (!mScreenOffAnimationController.isKeyguardHideDelayed()) {
-                return hideKeyguardImpl(forceStateChange);
-            }
-        }
-        return false;
-    }
-
-    public void showKeyguardImpl() {
-        Trace.beginSection("CentralSurfaces#showKeyguard");
-        // In case we're locking while a smartspace transition is in progress, reset it.
-        mKeyguardUnlockAnimationController.resetSmartspaceTransition();
-        if (mKeyguardStateController.isLaunchTransitionFadingAway()) {
-            mNotificationPanelViewController.cancelAnimation();
-            onLaunchTransitionFadingEnded();
-        }
-        mMessageRouter.cancelMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
-        if (!mLockscreenShadeTransitionController.isWakingToShadeLocked()) {
-            mStatusBarStateController.setState(StatusBarState.KEYGUARD);
-        }
-        updatePanelExpansionForKeyguard();
-        Trace.endSection();
-    }
-
-    private void updatePanelExpansionForKeyguard() {
-        if (mState == StatusBarState.KEYGUARD && mBiometricUnlockController.getMode()
-                != BiometricUnlockController.MODE_WAKE_AND_UNLOCK && !mBouncerShowing) {
-            mShadeController.instantExpandNotificationsPanel();
-        }
-    }
-
-    private void onLaunchTransitionFadingEnded() {
-        mNotificationPanelViewController.resetAlpha();
-        mNotificationPanelViewController.onAffordanceLaunchEnded();
-        releaseGestureWakeLock();
-        runLaunchTransitionEndRunnable();
-        mKeyguardStateController.setLaunchTransitionFadingAway(false);
-        mPresenter.updateMediaMetaData(true /* metaDataChanged */, true);
-    }
-
-    public boolean isInLaunchTransition() {
-        return mNotificationPanelViewController.isLaunchTransitionRunning()
-                || mNotificationPanelViewController.isLaunchTransitionFinished();
-    }
-
-    /**
-     * Fades the content of the keyguard away after the launch transition is done.
-     *
-     * @param beforeFading the runnable to be run when the circle is fully expanded and the fading
-     *                     starts
-     * @param endRunnable the runnable to be run when the transition is done. Will not run
-     *                    if the transition is cancelled, instead cancelRunnable will run
-     * @param cancelRunnable the runnable to be run if the transition is cancelled
-     */
-    public void fadeKeyguardAfterLaunchTransition(final Runnable beforeFading,
-            Runnable endRunnable, Runnable cancelRunnable) {
-        mMessageRouter.cancelMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
-        mLaunchTransitionEndRunnable = endRunnable;
-        mLaunchTransitionCancelRunnable = cancelRunnable;
-        Runnable hideRunnable = () -> {
-            mKeyguardStateController.setLaunchTransitionFadingAway(true);
-            if (beforeFading != null) {
-                beforeFading.run();
-            }
-            updateScrimController();
-            mPresenter.updateMediaMetaData(false, true);
-            mNotificationPanelViewController.resetAlpha();
-            mNotificationPanelViewController.fadeOut(
-                    FADE_KEYGUARD_START_DELAY, FADE_KEYGUARD_DURATION,
-                    this::onLaunchTransitionFadingEnded);
-            mCommandQueue.appTransitionStarting(mDisplayId, SystemClock.uptimeMillis(),
-                    LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION, true);
-        };
-        if (mNotificationPanelViewController.isLaunchTransitionRunning()) {
-            mNotificationPanelViewController.setLaunchTransitionEndRunnable(hideRunnable);
-        } else {
-            hideRunnable.run();
-        }
-    }
-
-    private void cancelAfterLaunchTransitionRunnables() {
-        if (mLaunchTransitionCancelRunnable != null) {
-            mLaunchTransitionCancelRunnable.run();
-        }
-        mLaunchTransitionEndRunnable = null;
-        mLaunchTransitionCancelRunnable = null;
-        mNotificationPanelViewController.setLaunchTransitionEndRunnable(null);
-    }
-
-    /**
-     * Fades the content of the Keyguard while we are dozing and makes it invisible when finished
-     * fading.
-     */
-    public void fadeKeyguardWhilePulsing() {
-        mNotificationPanelViewController.fadeOut(0, FADE_KEYGUARD_DURATION_PULSING,
-                ()-> {
-                hideKeyguard();
-                mStatusBarKeyguardViewManager.onKeyguardFadedAway();
-            }).start();
-    }
-
-    /**
-     * Plays the animation when an activity that was occluding Keyguard goes away.
-     */
-    public void animateKeyguardUnoccluding() {
-        mNotificationPanelViewController.setExpandedFraction(0f);
-        mCommandQueueCallbacks.animateExpandNotificationsPanel();
-        mScrimController.setUnocclusionAnimationRunning(true);
-    }
-
-    /**
-     * Starts the timeout when we try to start the affordances on Keyguard. We usually rely that
-     * Keyguard goes away via fadeKeyguardAfterLaunchTransition, however, that might not happen
-     * because the launched app crashed or something else went wrong.
-     */
-    public void startLaunchTransitionTimeout() {
-        mMessageRouter.sendMessageDelayed(
-                MSG_LAUNCH_TRANSITION_TIMEOUT, LAUNCH_TRANSITION_TIMEOUT_MS);
-    }
-
-    private void onLaunchTransitionTimeout() {
-        Log.w(TAG, "Launch transition: Timeout!");
-        mNotificationPanelViewController.onAffordanceLaunchEnded();
-        releaseGestureWakeLock();
-        mNotificationPanelViewController.resetViews(false /* animate */);
-    }
-
-    private void runLaunchTransitionEndRunnable() {
-        mLaunchTransitionCancelRunnable = null;
-        if (mLaunchTransitionEndRunnable != null) {
-            Runnable r = mLaunchTransitionEndRunnable;
-
-            // mLaunchTransitionEndRunnable might call showKeyguard, which would execute it again,
-            // which would lead to infinite recursion. Protect against it.
-            mLaunchTransitionEndRunnable = null;
-            r.run();
-        }
-    }
-
-    /**
-     * @return true if we would like to stay in the shade, false if it should go away entirely
-     */
-    public boolean hideKeyguardImpl(boolean forceStateChange) {
-        Trace.beginSection("CentralSurfaces#hideKeyguard");
-        boolean staying = mStatusBarStateController.leaveOpenOnKeyguardHide();
-        int previousState = mStatusBarStateController.getState();
-        if (!(mStatusBarStateController.setState(StatusBarState.SHADE, forceStateChange))) {
-            //TODO: StatusBarStateController should probably know about hiding the keyguard and
-            // notify listeners.
-
-            // If the state didn't change, we may still need to update public mode
-            mLockscreenUserManager.updatePublicMode();
-        }
-        if (mStatusBarStateController.leaveOpenOnKeyguardHide()) {
-            if (!mStatusBarStateController.isKeyguardRequested()) {
-                mStatusBarStateController.setLeaveOpenOnKeyguardHide(false);
-            }
-            long delay = mKeyguardStateController.calculateGoingToFullShadeDelay();
-            mLockscreenShadeTransitionController.onHideKeyguard(delay, previousState);
-
-            // Disable layout transitions in navbar for this transition because the load is just
-            // too heavy for the CPU and GPU on any device.
-            mNavigationBarController.disableAnimationsDuringHide(mDisplayId, delay);
-        } else if (!mNotificationPanelViewController.isCollapsing()) {
-            instantCollapseNotificationPanel();
-        }
-
-        // Keyguard state has changed, but QS is not listening anymore. Make sure to update the tile
-        // visibilities so next time we open the panel we know the correct height already.
-        if (mQSPanelController != null) {
-            mQSPanelController.refreshAllTiles();
-        }
-        mMessageRouter.cancelMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
-        releaseGestureWakeLock();
-        mNotificationPanelViewController.onAffordanceLaunchEnded();
-        mNotificationPanelViewController.resetAlpha();
-        mNotificationPanelViewController.resetTranslation();
-        mNotificationPanelViewController.resetViewGroupFade();
-        updateDozingState();
-        updateScrimController();
-        Trace.endSection();
-        return staying;
-    }
-
-    private void releaseGestureWakeLock() {
-        if (mGestureWakeLock.isHeld()) {
-            mGestureWakeLock.release();
-        }
-    }
-
-    /**
-     * Notifies the status bar that Keyguard is going away very soon.
-     */
-    public void keyguardGoingAway() {
-        // Treat Keyguard exit animation as an app transition to achieve nice transition for status
-        // bar.
-        mKeyguardStateController.notifyKeyguardGoingAway(true);
-        mCommandQueue.appTransitionPending(mDisplayId, true /* forced */);
-        updateScrimController();
-    }
-
-    /**
-     * Notifies the status bar the Keyguard is fading away with the specified timings.
-     *  @param startTime the start time of the animations in uptime millis
-     * @param delay the precalculated animation delay in milliseconds
-     * @param fadeoutDuration the duration of the exit animation, in milliseconds
-     * @param isBypassFading is this a fading away animation while bypassing
-     */
-    public void setKeyguardFadingAway(long startTime, long delay, long fadeoutDuration,
-            boolean isBypassFading) {
-        mCommandQueue.appTransitionStarting(mDisplayId, startTime + fadeoutDuration
-                        - LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION,
-                LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION, true);
-        mCommandQueue.recomputeDisableFlags(mDisplayId, fadeoutDuration > 0 /* animate */);
-        mCommandQueue.appTransitionStarting(mDisplayId,
-                    startTime - LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION,
-                    LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION, true);
-        mKeyguardStateController.notifyKeyguardFadingAway(delay, fadeoutDuration, isBypassFading);
-    }
-
-    /**
-     * Notifies that the Keyguard fading away animation is done.
-     */
-    public void finishKeyguardFadingAway() {
-        mKeyguardStateController.notifyKeyguardDoneFading();
-        mScrimController.setExpansionAffectsAlpha(true);
-
-        // If the device was re-locked while unlocking, we might have a pending lock that was
-        // delayed because the keyguard was in the middle of going away.
-        mKeyguardViewMediator.maybeHandlePendingLock();
-    }
-
-    /**
-     * Switches theme from light to dark and vice-versa.
-     */
-    protected void updateTheme() {
-        // Set additional scrim only if the lock and system wallpaper are different to prevent
-        // applying the dimming effect twice.
-        mUiBgExecutor.execute(() -> {
-            float dimAmount = 0f;
-            if (mWallpaperManager.lockScreenWallpaperExists()) {
-                dimAmount = mWallpaperManager.getWallpaperDimAmount();
-            }
-            final float scrimDimAmount = dimAmount;
-            mMainExecutor.execute(() -> {
-                mScrimController.setAdditionalScrimBehindAlphaKeyguard(scrimDimAmount);
-                mScrimController.applyCompositeAlphaOnScrimBehindKeyguard();
-            });
-        });
-
-        // Lock wallpaper defines the color of the majority of the views, hence we'll use it
-        // to set our default theme.
-        final boolean lockDarkText = mColorExtractor.getNeutralColors().supportsDarkText();
-        final int themeResId = lockDarkText ? R.style.Theme_SystemUI_LightWallpaper
-                : R.style.Theme_SystemUI;
-        if (mContext.getThemeResId() != themeResId) {
-            mContext.setTheme(themeResId);
-            mConfigurationController.notifyThemeChanged();
-        }
-    }
-
-    private void updateDozingState() {
-        Trace.traceCounter(Trace.TRACE_TAG_APP, "dozing", mDozing ? 1 : 0);
-        Trace.beginSection("CentralSurfaces#updateDozingState");
-
-        boolean visibleNotOccluded = mStatusBarKeyguardViewManager.isShowing()
-                && !mStatusBarKeyguardViewManager.isOccluded();
-        // If we're dozing and we'll be animating the screen off, the keyguard isn't currently
-        // visible but will be shortly for the animation, so we should proceed as if it's visible.
-        boolean visibleNotOccludedOrWillBe =
-                visibleNotOccluded || (mDozing && mDozeParameters.shouldDelayKeyguardShow());
-
-        boolean wakeAndUnlock = mBiometricUnlockController.getMode()
-                == BiometricUnlockController.MODE_WAKE_AND_UNLOCK;
-        boolean animate = (!mDozing && mDozeServiceHost.shouldAnimateWakeup() && !wakeAndUnlock)
-                || (mDozing && mDozeParameters.shouldControlScreenOff()
-                && visibleNotOccludedOrWillBe);
-
-        mNotificationPanelViewController.setDozing(mDozing, animate, mWakeUpTouchLocation);
-        updateQsExpansionEnabled();
-        Trace.endSection();
-    }
-
-    public void userActivity() {
-        if (mState == StatusBarState.KEYGUARD) {
-            mKeyguardViewMediatorCallback.userActivity();
-        }
-    }
-
-    public boolean interceptMediaKey(KeyEvent event) {
-        return mState == StatusBarState.KEYGUARD
-                && mStatusBarKeyguardViewManager.interceptMediaKey(event);
-    }
-
-    /**
-     * While IME is active and a BACK event is detected, check with
-     * {@link StatusBarKeyguardViewManager#dispatchBackKeyEventPreIme()} to see if the event
-     * should be handled before routing to IME, in order to prevent the user having to hit back
-     * twice to exit bouncer.
-     */
-    public boolean dispatchKeyEventPreIme(KeyEvent event) {
-        switch (event.getKeyCode()) {
-            case KeyEvent.KEYCODE_BACK:
-                if (mState == StatusBarState.KEYGUARD
-                        && mStatusBarKeyguardViewManager.dispatchBackKeyEventPreIme()) {
-                    return onBackPressed();
-                }
-        }
-        return false;
-    }
-
-    protected boolean shouldUnlockOnMenuPressed() {
-        return mDeviceInteractive && mState != StatusBarState.SHADE
-            && mStatusBarKeyguardViewManager.shouldDismissOnMenuPressed();
-    }
-
-    public boolean onMenuPressed() {
-        if (shouldUnlockOnMenuPressed()) {
-            mShadeController.animateCollapsePanels(
-                    CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL /* flags */, true /* force */);
-            return true;
-        }
-        return false;
-    }
-
-    public void endAffordanceLaunch() {
-        releaseGestureWakeLock();
-        mNotificationPanelViewController.onAffordanceLaunchEnded();
-    }
-
-    public boolean onBackPressed() {
-        final boolean isScrimmedBouncer =
-                mScrimController.getState() == ScrimState.BOUNCER_SCRIMMED;
-        final boolean isBouncerOverDream = isBouncerShowingOverDream();
-
-        if (mStatusBarKeyguardViewManager.onBackPressed(
-                isScrimmedBouncer || isBouncerOverDream /* hideImmediately */)) {
-            if (isScrimmedBouncer || isBouncerOverDream) {
-                mStatusBarStateController.setLeaveOpenOnKeyguardHide(false);
-            } else {
-                mNotificationPanelViewController.expandWithoutQs();
-            }
-            return true;
-        }
-        if (mNotificationPanelViewController.isQsCustomizing()) {
-            mNotificationPanelViewController.closeQsCustomizer();
-            return true;
-        }
-        if (mNotificationPanelViewController.isQsExpanded()) {
-            if (mNotificationPanelViewController.isQsDetailShowing()) {
-                mNotificationPanelViewController.closeQsDetail();
-            } else {
-                mNotificationPanelViewController.animateCloseQs(false /* animateAway */);
-            }
-            return true;
-        }
-        if (mNotificationPanelViewController.closeUserSwitcherIfOpen()) {
-            return true;
-        }
-        if (mState != StatusBarState.KEYGUARD && mState != StatusBarState.SHADE_LOCKED
-                && !isBouncerOverDream) {
-            if (mNotificationPanelViewController.canPanelBeCollapsed()) {
-                mShadeController.animateCollapsePanels();
-            }
-            return true;
-        }
-        return false;
-    }
-
-    public boolean onSpacePressed() {
-        if (mDeviceInteractive && mState != StatusBarState.SHADE) {
-            mShadeController.animateCollapsePanels(
-                    CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL /* flags */, true /* force */);
-            return true;
-        }
-        return false;
-    }
-
-    private void showBouncerOrLockScreenIfKeyguard() {
-        // If the keyguard is animating away, we aren't really the keyguard anymore and should not
-        // show the bouncer/lockscreen.
-        if (!mKeyguardViewMediator.isHiding()
-                && !mKeyguardUnlockAnimationController.isPlayingCannedUnlockAnimation()) {
-            if (mState == StatusBarState.SHADE_LOCKED
-                    && mKeyguardUpdateMonitor.isUdfpsEnrolled()) {
-                // shade is showing while locked on the keyguard, so go back to showing the
-                // lock screen where users can use the UDFPS affordance to enter the device
-                mStatusBarKeyguardViewManager.reset(true);
-            } else if ((mState == StatusBarState.KEYGUARD
-                    && !mStatusBarKeyguardViewManager.bouncerIsOrWillBeShowing())
-                    || mState == StatusBarState.SHADE_LOCKED) {
-                mStatusBarKeyguardViewManager.showGenericBouncer(true /* scrimmed */);
-            }
-        }
-    }
-
-    /**
-     * Show the bouncer if we're currently on the keyguard or shade locked and aren't hiding.
-     * @param performAction the action to perform when the bouncer is dismissed.
-     * @param cancelAction the action to perform when unlock is aborted.
-     */
-    public void showBouncerWithDimissAndCancelIfKeyguard(OnDismissAction performAction,
-            Runnable cancelAction) {
-        if ((mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)
-                && !mKeyguardViewMediator.isHiding()) {
-            mStatusBarKeyguardViewManager.dismissWithAction(performAction, cancelAction,
-                    false /* afterKeyguardGone */);
-        } else if (cancelAction != null) {
-            cancelAction.run();
-        }
-    }
-
-    void instantCollapseNotificationPanel() {
-        mNotificationPanelViewController.instantCollapse();
-        mShadeController.runPostCollapseRunnables();
-    }
-
-    /**
-     * Collapse the panel directly if we are on the main thread, post the collapsing on the main
-     * thread if we are not.
-     */
-    void collapsePanelOnMainThread() {
-        if (Looper.getMainLooper().isCurrentThread()) {
-            mShadeController.collapsePanel();
-        } else {
-            mContext.getMainExecutor().execute(mShadeController::collapsePanel);
-        }
-    }
-
-    /** Collapse the panel. The collapsing will be animated for the given {@code duration}. */
-    void collapsePanelWithDuration(int duration) {
-        mNotificationPanelViewController.collapseWithDuration(duration);
-    }
-
-    /**
-     * Updates the light reveal effect to reflect the reason we're waking or sleeping (for example,
-     * from the power button).
-     * @param wakingUp Whether we're updating because we're waking up (true) or going to sleep
-     *                 (false).
-     */
-    private void updateRevealEffect(boolean wakingUp) {
-        if (mLightRevealScrim == null) {
-            return;
-        }
-
-        final boolean wakingUpFromPowerButton = wakingUp
-                && !(mLightRevealScrim.getRevealEffect() instanceof CircleReveal)
-                && mWakefulnessLifecycle.getLastWakeReason()
-                == PowerManager.WAKE_REASON_POWER_BUTTON;
-        final boolean sleepingFromPowerButton = !wakingUp
-                && mWakefulnessLifecycle.getLastSleepReason()
-                == PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON;
-
-        if (wakingUpFromPowerButton || sleepingFromPowerButton) {
-            mLightRevealScrim.setRevealEffect(mPowerButtonReveal);
-            mLightRevealScrim.setRevealAmount(1f - mStatusBarStateController.getDozeAmount());
-        } else if (!wakingUp || !(mLightRevealScrim.getRevealEffect() instanceof CircleReveal)) {
-            // If we're going to sleep, but it's not from the power button, use the default reveal.
-            // If we're waking up, only use the default reveal if the biometric controller didn't
-            // already set it to the circular reveal because we're waking up from a fingerprint/face
-            // auth.
-            mLightRevealScrim.setRevealEffect(LiftReveal.INSTANCE);
-            mLightRevealScrim.setRevealAmount(1f - mStatusBarStateController.getDozeAmount());
-        }
-    }
-
-    public LightRevealScrim getLightRevealScrim() {
-        return mLightRevealScrim;
-    }
-
-    public void onTrackingStarted() {
-        mShadeController.runPostCollapseRunnables();
-    }
-
-    public void onClosingFinished() {
-        mShadeController.runPostCollapseRunnables();
-        if (!mPresenter.isPresenterFullyCollapsed()) {
-            // if we set it not to be focusable when collapsing, we have to undo it when we aborted
-            // the closing
-            mNotificationShadeWindowController.setNotificationShadeFocusable(true);
-        }
-    }
-
-    public void onUnlockHintStarted() {
-        mFalsingCollector.onUnlockHintStarted();
-        mKeyguardIndicationController.showActionToUnlock();
-    }
-
-    public void onHintFinished() {
-        // Delay the reset a bit so the user can read the text.
-        mKeyguardIndicationController.hideTransientIndicationDelayed(HINT_RESET_DELAY_MS);
-    }
-
-    public void onCameraHintStarted() {
-        mFalsingCollector.onCameraHintStarted();
-        mKeyguardIndicationController.showTransientIndication(R.string.camera_hint);
-    }
-
-    public void onVoiceAssistHintStarted() {
-        mFalsingCollector.onLeftAffordanceHintStarted();
-        mKeyguardIndicationController.showTransientIndication(R.string.voice_hint);
-    }
-
-    public void onPhoneHintStarted() {
-        mFalsingCollector.onLeftAffordanceHintStarted();
-        mKeyguardIndicationController.showTransientIndication(R.string.phone_hint);
-    }
-
-    public void onTrackingStopped(boolean expand) {
-        if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
-            if (!expand && !mKeyguardStateController.canDismissLockScreen()) {
-                mStatusBarKeyguardViewManager.showBouncer(false /* scrimmed */);
-            }
-        }
-    }
-
-    // TODO: Figure out way to remove these.
-    public NavigationBarView getNavigationBarView() {
-        return mNavigationBarController.getNavigationBarView(mDisplayId);
-    }
-
-    public boolean isOverviewEnabled() {
-        return mNavigationBarController.isOverviewEnabled(mDisplayId);
-    }
-
-    public void showPinningEnterExitToast(boolean entering) {
-        mNavigationBarController.showPinningEnterExitToast(mDisplayId, entering);
-    }
-
-    public void showPinningEscapeToast() {
-        mNavigationBarController.showPinningEscapeToast(mDisplayId);
-    }
-
-    /**
-     * TODO: Remove this method. Views should not be passed forward. Will cause theme issues.
-     * @return bottom area view
-     */
-    public KeyguardBottomAreaView getKeyguardBottomAreaView() {
-        return mNotificationPanelViewController.getKeyguardBottomAreaView();
-    }
-
-    /**
-     * Propagation of the bouncer state, indicating that it's fully visible.
-     */
-    public void setBouncerShowing(boolean bouncerShowing) {
-        mBouncerShowing = bouncerShowing;
-        mKeyguardBypassController.setBouncerShowing(bouncerShowing);
-        mPulseExpansionHandler.setBouncerShowing(bouncerShowing);
-        setBouncerShowingForStatusBarComponents(bouncerShowing);
-        mStatusBarHideIconsForBouncerManager.setBouncerShowingAndTriggerUpdate(bouncerShowing);
-        mCommandQueue.recomputeDisableFlags(mDisplayId, true /* animate */);
-        updateScrimController();
-        if (!mBouncerShowing) {
-            updatePanelExpansionForKeyguard();
-        }
-    }
-
-    /**
-     * Sets whether the bouncer over dream is showing. Note that the bouncer over dream is handled
-     * independently of the rest of the notification panel. As a result, setting this state via
-     * {@link #setBouncerShowing(boolean)} leads to unintended side effects from states modified
-     * behind the dream.
-     */
-    public void setBouncerShowingOverDream(boolean bouncerShowingOverDream) {
-        mBouncerShowingOverDream = bouncerShowingOverDream;
-    }
-
-    /**
-     * Propagate the bouncer state to status bar components.
-     *
-     * Separate from {@link #setBouncerShowing} because we sometimes re-create the status bar and
-     * should update only the status bar components.
-     */
-    private void setBouncerShowingForStatusBarComponents(boolean bouncerShowing) {
-        int importance = bouncerShowing
-                ? IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
-                : IMPORTANT_FOR_ACCESSIBILITY_AUTO;
-        if (mPhoneStatusBarViewController != null) {
-            mPhoneStatusBarViewController.setImportantForAccessibility(importance);
-        }
-        mNotificationPanelViewController.setImportantForAccessibility(importance);
-        mNotificationPanelViewController.setBouncerShowing(bouncerShowing);
-    }
-
-    /**
-     * Collapses the notification shade if it is tracking or expanded.
-     */
-    public void collapseShade() {
-        if (mNotificationPanelViewController.isTracking()) {
-            mNotificationShadeWindowViewController.cancelCurrentTouch();
-        }
-        if (mPanelExpanded && mState == StatusBarState.SHADE) {
-            mShadeController.animateCollapsePanels();
-        }
-    }
-
-    @VisibleForTesting
-    final WakefulnessLifecycle.Observer mWakefulnessObserver = new WakefulnessLifecycle.Observer() {
-        @Override
-        public void onFinishedGoingToSleep() {
-            mNotificationPanelViewController.onAffordanceLaunchEnded();
-            releaseGestureWakeLock();
-            mLaunchCameraWhenFinishedWaking = false;
-            mDeviceInteractive = false;
-            mWakeUpComingFromTouch = false;
-            mWakeUpTouchLocation = null;
-            updateVisibleToUser();
-
-            updateNotificationPanelTouchState();
-            mNotificationShadeWindowViewController.cancelCurrentTouch();
-            if (mLaunchCameraOnFinishedGoingToSleep) {
-                mLaunchCameraOnFinishedGoingToSleep = false;
-
-                // This gets executed before we will show Keyguard, so post it in order that the state
-                // is correct.
-                mMainExecutor.execute(() -> mCommandQueueCallbacks.onCameraLaunchGestureDetected(
-                        mLastCameraLaunchSource));
-            }
-
-            if (mLaunchEmergencyActionOnFinishedGoingToSleep) {
-                mLaunchEmergencyActionOnFinishedGoingToSleep = false;
-
-                // This gets executed before we will show Keyguard, so post it in order that the
-                // state is correct.
-                mMainExecutor.execute(
-                        () -> mCommandQueueCallbacks.onEmergencyActionLaunchGestureDetected());
-            }
-            updateIsKeyguard();
-        }
-
-        @Override
-        public void onStartedGoingToSleep() {
-            String tag = "CentralSurfaces#onStartedGoingToSleep";
-            DejankUtils.startDetectingBlockingIpcs(tag);
-
-            //  cancel stale runnables that could put the device in the wrong state
-            cancelAfterLaunchTransitionRunnables();
-
-            updateRevealEffect(false /* wakingUp */);
-            updateNotificationPanelTouchState();
-            maybeEscalateHeadsUp();
-            dismissVolumeDialog();
-            mWakeUpCoordinator.setFullyAwake(false);
-            mKeyguardBypassController.onStartedGoingToSleep();
-
-            // The unlocked screen off and fold to aod animations might use our LightRevealScrim -
-            // we need to be expanded for it to be visible.
-            if (mDozeParameters.shouldShowLightRevealScrim()) {
-                makeExpandedVisible(true);
-            }
-
-            DejankUtils.stopDetectingBlockingIpcs(tag);
-        }
-
-        @Override
-        public void onStartedWakingUp() {
-            String tag = "CentralSurfaces#onStartedWakingUp";
-            DejankUtils.startDetectingBlockingIpcs(tag);
-            mNotificationShadeWindowController.batchApplyWindowLayoutParams(()-> {
-                mDeviceInteractive = true;
-                mWakeUpCoordinator.setWakingUp(true);
-                if (!mKeyguardBypassController.getBypassEnabled()) {
-                    mHeadsUpManager.releaseAllImmediately();
-                }
-                updateVisibleToUser();
-                updateIsKeyguard();
-                mDozeServiceHost.stopDozing();
-                // This is intentionally below the stopDozing call above, since it avoids that we're
-                // unnecessarily animating the wakeUp transition. Animations should only be enabled
-                // once we fully woke up.
-                updateRevealEffect(true /* wakingUp */);
-                updateNotificationPanelTouchState();
-
-                // If we are waking up during the screen off animation, we should undo making the
-                // expanded visible (we did that so the LightRevealScrim would be visible).
-                if (mScreenOffAnimationController.shouldHideLightRevealScrimOnWakeUp()) {
-                    makeExpandedInvisible();
-                }
-
-            });
-            DejankUtils.stopDetectingBlockingIpcs(tag);
-        }
-
-        @Override
-        public void onFinishedWakingUp() {
-            mWakeUpCoordinator.setFullyAwake(true);
-            mWakeUpCoordinator.setWakingUp(false);
-            if (mLaunchCameraWhenFinishedWaking) {
-                mNotificationPanelViewController.launchCamera(
-                        false /* animate */, mLastCameraLaunchSource);
-                mLaunchCameraWhenFinishedWaking = false;
-            }
-            if (mLaunchEmergencyActionWhenFinishedWaking) {
-                mLaunchEmergencyActionWhenFinishedWaking = false;
-                Intent emergencyIntent = getEmergencyActionIntent();
-                if (emergencyIntent != null) {
-                    mContext.startActivityAsUser(emergencyIntent,
-                            getActivityUserHandle(emergencyIntent));
-                }
-            }
-            updateScrimController();
-        }
-    };
-
-    /**
-     * We need to disable touch events because these might
-     * collapse the panel after we expanded it, and thus we would end up with a blank
-     * Keyguard.
-     */
-    void updateNotificationPanelTouchState() {
-        boolean goingToSleepWithoutAnimation = isGoingToSleep()
-                && !mDozeParameters.shouldControlScreenOff();
-        boolean disabled = (!mDeviceInteractive && !mDozeServiceHost.isPulsing())
-                || goingToSleepWithoutAnimation;
-        mNotificationPanelViewController.setTouchAndAnimationDisabled(disabled);
-        mNotificationIconAreaController.setAnimationsEnabled(!disabled);
-    }
-
-    final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() {
-        @Override
-        public void onScreenTurningOn(Runnable onDrawn) {
-            mFalsingCollector.onScreenTurningOn();
-            mNotificationPanelViewController.onScreenTurningOn();
-        }
-
-        @Override
-        public void onScreenTurnedOn() {
-            mScrimController.onScreenTurnedOn();
-        }
-
-        @Override
-        public void onScreenTurnedOff() {
-            Trace.beginSection("CentralSurfaces#onScreenTurnedOff");
-            mFalsingCollector.onScreenOff();
-            mScrimController.onScreenTurnedOff();
-            if (mCloseQsBeforeScreenOff) {
-                mNotificationPanelViewController.closeQs();
-                mCloseQsBeforeScreenOff = false;
-            }
-            updateIsKeyguard();
-            Trace.endSection();
-        }
-    };
-
-    public int getWakefulnessState() {
-        return mWakefulnessLifecycle.getWakefulness();
-    }
-
-    /**
-     * @return true if the screen is currently fully off, i.e. has finished turning off and has
-     * since not started turning on.
-     */
-    public boolean isScreenFullyOff() {
-        return mScreenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_OFF;
-    }
-
-    public void showScreenPinningRequest(int taskId, boolean allowCancel) {
-        mScreenPinningRequest.showPrompt(taskId, allowCancel);
-    }
-
-    @Nullable Intent getEmergencyActionIntent() {
-        Intent emergencyIntent = new Intent(EmergencyGesture.ACTION_LAUNCH_EMERGENCY);
-        PackageManager pm = mContext.getPackageManager();
-        List<ResolveInfo> emergencyActivities = pm.queryIntentActivities(emergencyIntent,
-                PackageManager.MATCH_SYSTEM_ONLY);
-        ResolveInfo resolveInfo = getTopEmergencySosInfo(emergencyActivities);
-        if (resolveInfo == null) {
-            Log.wtf(TAG, "Couldn't find an app to process the emergency intent.");
-            return null;
-        }
-        emergencyIntent.setComponent(new ComponentName(resolveInfo.activityInfo.packageName,
-                resolveInfo.activityInfo.name));
-        emergencyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        return emergencyIntent;
-    }
-
-    /**
-     * Select and return the "best" ResolveInfo for Emergency SOS Activity.
-     */
-    private @Nullable ResolveInfo getTopEmergencySosInfo(List<ResolveInfo> emergencyActivities) {
-        // No matched activity.
-        if (emergencyActivities == null || emergencyActivities.isEmpty()) {
-            return null;
-        }
-
-        // Of multiple matched Activities, give preference to the pre-set package name.
-        String preferredAppPackageName =
-                mContext.getString(R.string.config_preferredEmergencySosPackage);
-
-        // If there is no preferred app, then return first match.
-        if (TextUtils.isEmpty(preferredAppPackageName)) {
-            return emergencyActivities.get(0);
-        }
-
-        for (ResolveInfo emergencyInfo: emergencyActivities) {
-            // If activity is from the preferred app, use it.
-            if (TextUtils.equals(emergencyInfo.activityInfo.packageName, preferredAppPackageName)) {
-                return emergencyInfo;
-            }
-        }
-        // No matching activity: return first match
-        return emergencyActivities.get(0);
-    }
-
-    boolean isCameraAllowedByAdmin() {
-        if (mDevicePolicyManager.getCameraDisabled(null,
-                mLockscreenUserManager.getCurrentUserId())) {
-            return false;
-        } else if (mStatusBarKeyguardViewManager == null
-                || (isKeyguardShowing() && isKeyguardSecure())) {
-            // Check if the admin has disabled the camera specifically for the keyguard
-            return (mDevicePolicyManager.getKeyguardDisabledFeatures(null,
-                    mLockscreenUserManager.getCurrentUserId())
-                    & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) == 0;
-        }
-        return true;
-    }
-
-    boolean isGoingToSleep() {
-        return mWakefulnessLifecycle.getWakefulness()
-                == WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP;
-    }
-
-    boolean isWakingOrAwake() {
-        return mWakefulnessLifecycle.getWakefulness() == WakefulnessLifecycle.WAKEFULNESS_WAKING
-                || mWakefulnessLifecycle.getWakefulness() == WakefulnessLifecycle.WAKEFULNESS_AWAKE;
-    }
-
-    public void notifyBiometricAuthModeChanged() {
-        mDozeServiceHost.updateDozing();
-        updateScrimController();
-    }
-
-    /**
-     * Set the amount of progress we are currently in if we're transitioning to the full shade.
-     * 0.0f means we're not transitioning yet, while 1 means we're all the way in the full
-     * shade.
-     */
-    public void setTransitionToFullShadeProgress(float transitionToFullShadeProgress) {
-        mTransitionToFullShadeProgress = transitionToFullShadeProgress;
-    }
-
-    /**
-     * Sets the amount of progress to the bouncer being fully hidden/visible. 1 means the bouncer
-     * is fully hidden, while 0 means the bouncer is visible.
-     */
-    public void setBouncerHiddenFraction(float expansion) {
-        mScrimController.setBouncerHiddenFraction(expansion);
-    }
-
-    @VisibleForTesting
-    public void updateScrimController() {
-        Trace.beginSection("CentralSurfaces#updateScrimController");
-
-        boolean unlocking = mKeyguardStateController.isShowing() && (
-                mBiometricUnlockController.isWakeAndUnlock()
-                        || mKeyguardStateController.isKeyguardFadingAway()
-                        || mKeyguardStateController.isKeyguardGoingAway()
-                        || mKeyguardViewMediator.requestedShowSurfaceBehindKeyguard()
-                        || mKeyguardViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehind());
-
-        mScrimController.setExpansionAffectsAlpha(!unlocking);
-
-        boolean launchingAffordanceWithPreview =
-                mNotificationPanelViewController.isLaunchingAffordanceWithPreview();
-        mScrimController.setLaunchingAffordanceWithPreview(launchingAffordanceWithPreview);
-
-        if (mStatusBarKeyguardViewManager.isShowingAlternateAuth()) {
-            if (mState == StatusBarState.SHADE || mState == StatusBarState.SHADE_LOCKED
-                    || mTransitionToFullShadeProgress > 0f) {
-                mScrimController.transitionTo(ScrimState.AUTH_SCRIMMED_SHADE);
-            } else {
-                mScrimController.transitionTo(ScrimState.AUTH_SCRIMMED);
-            }
-        } else if (mBouncerShowing && !unlocking) {
-            // Bouncer needs the front scrim when it's on top of an activity,
-            // tapping on a notification, editing QS or being dismissed by
-            // FLAG_DISMISS_KEYGUARD_ACTIVITY.
-            ScrimState state = mStatusBarKeyguardViewManager.bouncerNeedsScrimming()
-                    ? ScrimState.BOUNCER_SCRIMMED : ScrimState.BOUNCER;
-            mScrimController.transitionTo(state);
-        } else if (launchingAffordanceWithPreview) {
-            // We want to avoid animating when launching with a preview.
-            mScrimController.transitionTo(ScrimState.UNLOCKED, mUnlockScrimCallback);
-        } else if (mBrightnessMirrorVisible) {
-            mScrimController.transitionTo(ScrimState.BRIGHTNESS_MIRROR);
-        } else if (mState == StatusBarState.SHADE_LOCKED) {
-            mScrimController.transitionTo(ScrimState.SHADE_LOCKED);
-        } else if (mDozeServiceHost.isPulsing()) {
-            mScrimController.transitionTo(ScrimState.PULSING,
-                    mDozeScrimController.getScrimCallback());
-        } else if (mDozeServiceHost.hasPendingScreenOffCallback()) {
-            mScrimController.transitionTo(ScrimState.OFF, new ScrimController.Callback() {
-                @Override
-                public void onFinished() {
-                    mDozeServiceHost.executePendingScreenOffCallback();
-                }
-            });
-        } else if (mDozing && !unlocking) {
-            mScrimController.transitionTo(ScrimState.AOD);
-        } else if (mKeyguardStateController.isShowing() && !isOccluded() && !unlocking) {
-            mScrimController.transitionTo(ScrimState.KEYGUARD);
-        } else if (mKeyguardStateController.isShowing() && mKeyguardUpdateMonitor.isDreaming()) {
-            mScrimController.transitionTo(ScrimState.DREAMING);
-        } else {
-            mScrimController.transitionTo(ScrimState.UNLOCKED, mUnlockScrimCallback);
-        }
-        updateLightRevealScrimVisibility();
-
-        Trace.endSection();
-    }
-
-    public boolean isKeyguardShowing() {
-        if (mStatusBarKeyguardViewManager == null) {
-            Slog.i(TAG, "isKeyguardShowing() called before startKeyguard(), returning true");
-            return true;
-        }
-        return mStatusBarKeyguardViewManager.isShowing();
-    }
-
-    public boolean shouldIgnoreTouch() {
-        return (mStatusBarStateController.isDozing()
-                && mDozeServiceHost.getIgnoreTouchWhilePulsing())
-                || mScreenOffAnimationController.shouldIgnoreKeyguardTouches();
-    }
-
-    // Begin Extra BaseStatusBar methods.
-
-    protected final CommandQueue mCommandQueue;
-    protected IStatusBarService mBarService;
-
-    // all notifications
-    protected NotificationStackScrollLayout mStackScroller;
-
-    // handling reordering
-    private final VisualStabilityManager mVisualStabilityManager;
-
-    protected AccessibilityManager mAccessibilityManager;
-
-    protected boolean mDeviceInteractive;
-
-    protected boolean mVisible;
-
-    // mScreenOnFromKeyguard && mVisible.
-    private boolean mVisibleToUser;
-
-    protected DevicePolicyManager mDevicePolicyManager;
-    private final PowerManager mPowerManager;
-    protected StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
-
-    protected KeyguardManager mKeyguardManager;
-    private final DeviceProvisionedController mDeviceProvisionedController;
-
-    private final NavigationBarController mNavigationBarController;
-    private final AccessibilityFloatingMenuController mAccessibilityFloatingMenuController;
-
-    // UI-specific methods
-
-    protected WindowManager mWindowManager;
-    protected IWindowManager mWindowManagerService;
-    private IDreamManager mDreamManager;
-
-    protected Display mDisplay;
-    private int mDisplayId;
-
-    protected NotificationShelfController mNotificationShelfController;
-
-    private final Lazy<AssistManager> mAssistManagerLazy;
-
-    public boolean isDeviceInteractive() {
-        return mDeviceInteractive;
-    }
-
-    private final BroadcastReceiver mBannerActionBroadcastReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (BANNER_ACTION_CANCEL.equals(action) || BANNER_ACTION_SETUP.equals(action)) {
-                NotificationManager noMan = (NotificationManager)
-                        mContext.getSystemService(Context.NOTIFICATION_SERVICE);
-                noMan.cancel(com.android.internal.messages.nano.SystemMessageProto.SystemMessage.
-                        NOTE_HIDDEN_NOTIFICATIONS);
-
-                Settings.Secure.putInt(mContext.getContentResolver(),
-                        Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING, 0);
-                if (BANNER_ACTION_SETUP.equals(action)) {
-                    mShadeController.animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
-                            true /* force */);
-                    mContext.startActivity(new Intent(Settings.ACTION_APP_NOTIFICATION_REDACTION)
-                            .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
-
-                    );
-                }
-            }
-        }
-    };
-
-    public void setNotificationSnoozed(StatusBarNotification sbn, SnoozeOption snoozeOption) {
-        mNotificationsController.setNotificationSnoozed(sbn, snoozeOption);
-    }
-
-
-    public void awakenDreams() {
-        mUiBgExecutor.execute(() -> {
-            try {
-                mDreamManager.awaken();
-            } catch (RemoteException e) {
-                e.printStackTrace();
-            }
-        });
-    }
-
-    protected void toggleKeyboardShortcuts(int deviceId) {
-        KeyboardShortcuts.toggle(mContext, deviceId);
-    }
-
-    protected void dismissKeyboardShortcuts() {
-        KeyboardShortcuts.dismiss();
-    }
-
-    /**
-     * Dismiss the keyguard then execute an action.
-     *
-     * @param action The action to execute after dismissing the keyguard.
-     * @param collapsePanel Whether we should collapse the panel after dismissing the keyguard.
-     * @param willAnimateOnKeyguard Whether {@param action} will run an animation on the keyguard if
-     *                              we are locked.
-     */
-    private void executeActionDismissingKeyguard(Runnable action, boolean afterKeyguardGone,
-            boolean collapsePanel, boolean willAnimateOnKeyguard) {
-        if (!mDeviceProvisionedController.isDeviceProvisioned()) return;
-
-        OnDismissAction onDismissAction = new OnDismissAction() {
-            @Override
-            public boolean onDismiss() {
-                new Thread(() -> {
-                    try {
-                        // The intent we are sending is for the application, which
-                        // won't have permission to immediately start an activity after
-                        // the user switches to home.  We know it is safe to do at this
-                        // point, so make sure new activity switches are now allowed.
-                        ActivityManager.getService().resumeAppSwitches();
-                    } catch (RemoteException e) {
-                    }
-                    action.run();
-                }).start();
-
-                return collapsePanel ? mShadeController.collapsePanel() : willAnimateOnKeyguard;
-            }
-
-            @Override
-            public boolean willRunAnimationOnKeyguard() {
-                return willAnimateOnKeyguard;
-            }
-        };
-        dismissKeyguardThenExecute(onDismissAction, afterKeyguardGone);
-    }
-
-    @Override
-    public void startPendingIntentDismissingKeyguard(final PendingIntent intent) {
-        startPendingIntentDismissingKeyguard(intent, null);
-    }
-
-    @Override
-    public void startPendingIntentDismissingKeyguard(
-            final PendingIntent intent, @Nullable final Runnable intentSentUiThreadCallback) {
-        startPendingIntentDismissingKeyguard(intent, intentSentUiThreadCallback,
-                (ActivityLaunchAnimator.Controller) null);
-    }
-
-    @Override
-    public void startPendingIntentDismissingKeyguard(PendingIntent intent,
-            Runnable intentSentUiThreadCallback, View associatedView) {
-        ActivityLaunchAnimator.Controller animationController = null;
-        if (associatedView instanceof ExpandableNotificationRow) {
-            animationController = mNotificationAnimationProvider.getAnimatorController(
-                    ((ExpandableNotificationRow) associatedView));
-        }
-
-        startPendingIntentDismissingKeyguard(intent, intentSentUiThreadCallback,
-                animationController);
-    }
-
-    @Override
-    public void startPendingIntentDismissingKeyguard(
-            final PendingIntent intent, @Nullable final Runnable intentSentUiThreadCallback,
-            @Nullable ActivityLaunchAnimator.Controller animationController) {
-        final boolean willLaunchResolverActivity = intent.isActivity()
-                && mActivityIntentHelper.wouldLaunchResolverActivity(intent.getIntent(),
-                mLockscreenUserManager.getCurrentUserId());
-
-        boolean animate = !willLaunchResolverActivity
-                && animationController != null
-                && shouldAnimateLaunch(intent.isActivity());
-
-        // If we animate, don't collapse the shade and defer the keyguard dismiss (in case we run
-        // the animation on the keyguard). The animation will take care of (instantly) collapsing
-        // the shade and hiding the keyguard once it is done.
-        boolean collapse = !animate;
-        executeActionDismissingKeyguard(() -> {
-            try {
-                // We wrap animationCallback with a StatusBarLaunchAnimatorController so that the
-                // shade is collapsed after the animation (or when it is cancelled, aborted, etc).
-                ActivityLaunchAnimator.Controller controller =
-                        animationController != null ? new StatusBarLaunchAnimatorController(
-                                animationController, this, intent.isActivity()) : null;
-
-                mActivityLaunchAnimator.startPendingIntentWithAnimation(
-                        controller, animate, intent.getCreatorPackage(),
-                        (animationAdapter) -> {
-                            ActivityOptions options = new ActivityOptions(
-                                    getActivityOptions(mDisplayId, animationAdapter));
-                            // TODO b/221255671: restrict this to only be set for notifications
-                            options.setEligibleForLegacyPermissionPrompt(true);
-                            return intent.sendAndReturnResult(null, 0, null, null, null,
-                                    null, options.toBundle());
-                        });
-            } catch (PendingIntent.CanceledException e) {
-                // the stack trace isn't very helpful here.
-                // Just log the exception message.
-                Log.w(TAG, "Sending intent failed: " + e);
-                if (!collapse) {
-                    // executeActionDismissingKeyguard did not collapse for us already.
-                    collapsePanelOnMainThread();
-                }
-                // TODO: Dismiss Keyguard.
-            }
-            if (intent.isActivity()) {
-                mAssistManagerLazy.get().hideAssist();
-            }
-            if (intentSentUiThreadCallback != null) {
-                postOnUiThread(intentSentUiThreadCallback);
-            }
-        }, willLaunchResolverActivity, collapse, animate);
-    }
-
-    private void postOnUiThread(Runnable runnable) {
-        mMainExecutor.execute(runnable);
-    }
-
     /**
      * Returns an ActivityOptions bundle created using the given parameters.
      *
-     * @param displayId The ID of the display to launch the activity in. Typically this would be the
-     *                  display the status bar is on.
+     * @param displayId The ID of the display to launch the activity in. Typically this would
+     *                  be the display the status bar is on.
      * @param animationAdapter The animation adapter used to start this activity, or {@code null}
      *                         for the default animation.
      */
-    public static Bundle getActivityOptions(int displayId,
+    static Bundle getActivityOptions(int displayId,
             @Nullable RemoteAnimationAdapter animationAdapter) {
         ActivityOptions options = getDefaultActivityOptions(animationAdapter);
         options.setLaunchDisplayId(displayId);
@@ -4063,15 +125,16 @@
     /**
      * Returns an ActivityOptions bundle created using the given parameters.
      *
-     * @param displayId The ID of the display to launch the activity in. Typically this would be the
-     *                  display the status bar is on.
-     * @param animationAdapter The animation adapter used to start this activity, or {@code null}
-     *                         for the default animation.
+     * @param displayId         The ID of the display to launch the activity in. Typically this
+     *                          would be the
+     *                          display the status bar is on.
+     * @param animationAdapter  The animation adapter used to start this activity, or {@code null}
+     *                          for the default animation.
      * @param isKeyguardShowing Whether keyguard is currently showing.
-     * @param eventTime The event time in milliseconds since boot, not including sleep. See
-     *                  {@link ActivityOptions#setSourceInfo}.
+     * @param eventTime         The event time in milliseconds since boot, not including sleep. See
+     *                          {@link ActivityOptions#setSourceInfo}.
      */
-    public static Bundle getActivityOptions(int displayId,
+    static Bundle getActivityOptions(int displayId,
             @Nullable RemoteAnimationAdapter animationAdapter, boolean isKeyguardShowing,
             long eventTime) {
         ActivityOptions options = getDefaultActivityOptions(animationAdapter);
@@ -4082,7 +145,7 @@
         return options.toBundle();
     }
 
-    public static ActivityOptions getDefaultActivityOptions(
+    static ActivityOptions getDefaultActivityOptions(
             @Nullable RemoteAnimationAdapter animationAdapter) {
         ActivityOptions options;
         if (animationAdapter != null) {
@@ -4095,71 +158,15 @@
         } else {
             options = ActivityOptions.makeBasic();
         }
+        options.setSplashScreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_SOLID_COLOR);
         return options;
     }
 
-    void visibilityChanged(boolean visible) {
-        if (mVisible != visible) {
-            mVisible = visible;
-            if (!visible) {
-                mGutsManager.closeAndSaveGuts(true /* removeLeavebehind */, true /* force */,
-                        true /* removeControls */, -1 /* x */, -1 /* y */, true /* resetMenu */);
-            }
-        }
-        updateVisibleToUser();
-    }
-
-    protected void updateVisibleToUser() {
-        boolean oldVisibleToUser = mVisibleToUser;
-        mVisibleToUser = mVisible && mDeviceInteractive;
-
-        if (oldVisibleToUser != mVisibleToUser) {
-            handleVisibleToUserChanged(mVisibleToUser);
-        }
-    }
-
     /**
-     * Clear Buzz/Beep/Blink.
+     * @return a PackageManager for userId or if userId is < 0 (USER_ALL etc) then
+     * return PackageManager for mContext
      */
-    public void clearNotificationEffects() {
-        try {
-            mBarService.clearNotificationEffects();
-        } catch (RemoteException e) {
-            // Won't fail unless the world has ended.
-        }
-    }
-
-    /**
-     * @return Whether the security bouncer from Keyguard is showing.
-     */
-    public boolean isBouncerShowing() {
-        return mBouncerShowing;
-    }
-
-    /**
-     * @return Whether the security bouncer from Keyguard is showing.
-     */
-    public boolean isBouncerShowingScrimmed() {
-        return isBouncerShowing() && mStatusBarKeyguardViewManager.bouncerNeedsScrimming();
-    }
-
-    public boolean isBouncerShowingOverDream() {
-        return mBouncerShowingOverDream;
-    }
-
-    /**
-     * When {@link KeyguardBouncer} starts to be dismissed, playing its animation.
-     */
-    public void onBouncerPreHideAnimation() {
-        mNotificationPanelViewController.onBouncerPreHideAnimation();
-
-    }
-
-    /**
-     * @return a PackageManger for userId or if userId is < 0 (USER_ALL etc) then
-     *         return PackageManager for mContext
-     */
-    public static PackageManager getPackageManagerForUser(Context context, int userId) {
+    static PackageManager getPackageManagerForUser(Context context, int userId) {
         Context contextForUser = context;
         // UserHandle defines special userId as negative values, e.g. USER_ALL
         if (userId >= 0) {
@@ -4168,350 +175,413 @@
                 // for user 0 we can still load information about the package.
                 contextForUser =
                         context.createPackageContextAsUser(context.getPackageName(),
-                        Context.CONTEXT_RESTRICTED,
-                        new UserHandle(userId));
-            } catch (NameNotFoundException e) {
+                                Context.CONTEXT_RESTRICTED,
+                                new UserHandle(userId));
+            } catch (PackageManager.NameNotFoundException e) {
                 // Shouldn't fail to find the package name for system ui.
             }
         }
         return contextForUser.getPackageManager();
     }
 
-    public boolean isKeyguardSecure() {
-        if (mStatusBarKeyguardViewManager == null) {
-            // startKeyguard() hasn't been called yet, so we don't know.
-            // Make sure anything that needs to know isKeyguardSecure() checks and re-checks this
-            // value onVisibilityChanged().
-            Slog.w(TAG, "isKeyguardSecure() called before startKeyguard(), returning false",
-                    new Throwable());
-            return false;
+    void animateExpandNotificationsPanel();
+
+    void animateExpandSettingsPanel(@Nullable String subpanel);
+
+    void animateCollapsePanels(int flags, boolean force);
+
+    void collapsePanelOnMainThread();
+
+    void collapsePanelWithDuration(int duration);
+
+    void togglePanel();
+
+    void start();
+
+    boolean updateIsKeyguard();
+
+    boolean updateIsKeyguard(boolean forceStateChange);
+
+    @NonNull
+    @Override
+    Lifecycle getLifecycle();
+
+    void wakeUpIfDozing(long time, View where, String why);
+
+    NotificationShadeWindowView getNotificationShadeWindowView();
+
+    NotificationShadeWindowViewController getNotificationShadeWindowViewController();
+
+    NotificationPanelViewController getNotificationPanelViewController();
+
+    ViewGroup getBouncerContainer();
+
+    int getStatusBarHeight();
+
+    void updateQsExpansionEnabled();
+
+    boolean isShadeDisabled();
+
+    void requestNotificationUpdate(String reason);
+
+    void requestFaceAuth(boolean userInitiatedRequest);
+
+    @Override
+    void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade,
+            int flags);
+
+    @Override
+    void startActivity(Intent intent, boolean dismissShade);
+
+    @Override
+    void startActivity(Intent intent, boolean dismissShade,
+            @Nullable ActivityLaunchAnimator.Controller animationController,
+            boolean showOverLockscreenWhenLocked);
+
+    @Override
+    void startActivity(Intent intent, boolean dismissShade,
+            @Nullable ActivityLaunchAnimator.Controller animationController,
+            boolean showOverLockscreenWhenLocked, UserHandle userHandle);
+
+    boolean isLaunchingActivityOverLockscreen();
+
+    @Override
+    void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade);
+
+    @Override
+    void startActivity(Intent intent, boolean dismissShade, Callback callback);
+
+    void setQsExpanded(boolean expanded);
+
+    boolean isWakeUpComingFromTouch();
+
+    boolean isFalsingThresholdNeeded();
+
+    void onKeyguardViewManagerStatesUpdated();
+
+    void setPanelExpanded(boolean isExpanded);
+
+    ViewGroup getNotificationScrollLayout();
+
+    boolean isPulsing();
+
+    @Nullable
+    View getAmbientIndicationContainer();
+
+    boolean isOccluded();
+
+    //TODO: These can / should probably be moved to NotificationPresenter or ShadeController
+    void onLaunchAnimationCancelled(boolean isLaunchForActivity);
+
+    void onLaunchAnimationEnd(boolean launchIsFullScreen);
+
+    boolean shouldAnimateLaunch(boolean isActivityIntent, boolean showOverLockscreen);
+
+    boolean shouldAnimateLaunch(boolean isActivityIntent);
+
+    boolean isDeviceInVrMode();
+
+    NotificationPresenter getPresenter();
+
+    void postAnimateCollapsePanels();
+
+    void postAnimateForceCollapsePanels();
+
+    void postAnimateOpenPanels();
+
+    boolean isExpandedVisible();
+
+    boolean isPanelExpanded();
+
+    void onInputFocusTransfer(boolean start, boolean cancel, float velocity);
+
+    void animateCollapseQuickSettings();
+
+    void onTouchEvent(MotionEvent event);
+
+    GestureRecorder getGestureRecorder();
+
+    BiometricUnlockController getBiometricUnlockController();
+
+    void showWirelessChargingAnimation(int batteryLevel);
+
+    void checkBarModes();
+
+    // Called by NavigationBarFragment
+    void setQsScrimEnabled(boolean scrimEnabled);
+
+    void updateBubblesVisibility();
+
+    void setInteracting(int barWindow, boolean interacting);
+
+    @Override
+    void dump(PrintWriter pwOriginal, String[] args);
+
+    void createAndAddWindows(@Nullable RegisterStatusBarResult result);
+
+    float getDisplayWidth();
+
+    float getDisplayHeight();
+
+    void startActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned,
+            boolean dismissShade, int flags);
+
+    void startActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned,
+            boolean dismissShade);
+
+    void startActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned,
+            boolean dismissShade, boolean disallowEnterPictureInPictureWhileLaunching,
+            Callback callback, int flags,
+            @Nullable ActivityLaunchAnimator.Controller animationController,
+            UserHandle userHandle);
+
+    void readyForKeyguardDone();
+
+    void executeRunnableDismissingKeyguard(Runnable runnable,
+            Runnable cancelAction,
+            boolean dismissShade,
+            boolean afterKeyguardGone,
+            boolean deferred);
+
+    void executeRunnableDismissingKeyguard(Runnable runnable,
+            Runnable cancelAction,
+            boolean dismissShade,
+            boolean afterKeyguardGone,
+            boolean deferred,
+            boolean willAnimateOnKeyguard);
+
+    void resetUserExpandedStates();
+
+    @Override
+    void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancelAction,
+            boolean afterKeyguardGone);
+
+    void setLockscreenUser(int newUserId);
+
+    @Override
+    void postQSRunnableDismissingKeyguard(Runnable runnable);
+
+    @Override
+    void postStartActivityDismissingKeyguard(PendingIntent intent);
+
+    @Override
+    void postStartActivityDismissingKeyguard(PendingIntent intent,
+            @Nullable ActivityLaunchAnimator.Controller animationController);
+
+    @Override
+    void postStartActivityDismissingKeyguard(Intent intent, int delay);
+
+    @Override
+    void postStartActivityDismissingKeyguard(Intent intent, int delay,
+            @Nullable ActivityLaunchAnimator.Controller animationController);
+
+    void showKeyguard();
+
+    boolean hideKeyguard();
+
+    void showKeyguardImpl();
+
+    boolean isInLaunchTransition();
+
+    void fadeKeyguardAfterLaunchTransition(Runnable beforeFading,
+            Runnable endRunnable, Runnable cancelRunnable);
+
+    void fadeKeyguardWhilePulsing();
+
+    void animateKeyguardUnoccluding();
+
+    void startLaunchTransitionTimeout();
+
+    boolean hideKeyguardImpl(boolean forceStateChange);
+
+    void keyguardGoingAway();
+
+    void setKeyguardFadingAway(long startTime, long delay, long fadeoutDuration,
+            boolean isBypassFading);
+
+    void finishKeyguardFadingAway();
+
+    void userActivity();
+
+    boolean interceptMediaKey(KeyEvent event);
+
+    boolean dispatchKeyEventPreIme(KeyEvent event);
+
+    boolean onMenuPressed();
+
+    void endAffordanceLaunch();
+
+    boolean onBackPressed();
+
+    boolean onSpacePressed();
+
+    void showBouncerWithDimissAndCancelIfKeyguard(OnDismissAction performAction,
+            Runnable cancelAction);
+
+    LightRevealScrim getLightRevealScrim();
+
+    void onTrackingStarted();
+
+    void onClosingFinished();
+
+    void onUnlockHintStarted();
+
+    void onHintFinished();
+
+    void onCameraHintStarted();
+
+    void onVoiceAssistHintStarted();
+
+    void onPhoneHintStarted();
+
+    void onTrackingStopped(boolean expand);
+
+    // TODO: Figure out way to remove these.
+    NavigationBarView getNavigationBarView();
+
+    boolean isOverviewEnabled();
+
+    void showPinningEnterExitToast(boolean entering);
+
+    void showPinningEscapeToast();
+
+    KeyguardBottomAreaView getKeyguardBottomAreaView();
+
+    void setBouncerShowing(boolean bouncerShowing);
+
+    void setBouncerShowingOverDream(boolean bouncerShowingOverDream);
+
+    void collapseShade();
+
+    int getWakefulnessState();
+
+    boolean isScreenFullyOff();
+
+    void showScreenPinningRequest(int taskId, boolean allowCancel);
+
+    @Nullable
+    Intent getEmergencyActionIntent();
+
+    boolean isCameraAllowedByAdmin();
+
+    boolean isGoingToSleep();
+
+    void notifyBiometricAuthModeChanged();
+
+    void setTransitionToFullShadeProgress(float transitionToFullShadeProgress);
+
+    void setBouncerHiddenFraction(float expansion);
+
+    @VisibleForTesting
+    void updateScrimController();
+
+    boolean isKeyguardShowing();
+
+    boolean shouldIgnoreTouch();
+
+    boolean isDeviceInteractive();
+
+    void setNotificationSnoozed(StatusBarNotification sbn,
+            NotificationSwipeActionHelper.SnoozeOption snoozeOption);
+
+    void awakenDreams();
+
+    @Override
+    void startPendingIntentDismissingKeyguard(PendingIntent intent);
+
+    @Override
+    void startPendingIntentDismissingKeyguard(
+            PendingIntent intent, @Nullable Runnable intentSentUiThreadCallback);
+
+    @Override
+    void startPendingIntentDismissingKeyguard(PendingIntent intent,
+            Runnable intentSentUiThreadCallback, View associatedView);
+
+    @Override
+    void startPendingIntentDismissingKeyguard(
+            PendingIntent intent, @Nullable Runnable intentSentUiThreadCallback,
+            @Nullable ActivityLaunchAnimator.Controller animationController);
+
+    void clearNotificationEffects();
+
+    boolean isBouncerShowing();
+
+    boolean isBouncerShowingScrimmed();
+
+    boolean isBouncerShowingOverDream();
+
+    void onBouncerPreHideAnimation();
+
+    boolean isKeyguardSecure();
+
+    NotificationPanelViewController getPanelController();
+
+    NotificationGutsManager getGutsManager();
+
+    void updateNotificationPanelTouchState();
+
+    void makeExpandedVisible(boolean force);
+
+    void instantCollapseNotificationPanel();
+
+    void visibilityChanged(boolean visible);
+
+    int getDisplayId();
+
+    int getRotation();
+
+    @VisibleForTesting
+    void setBarStateForTest(int state);
+
+    void wakeUpForFullScreenIntent();
+
+    void showTransientUnchecked();
+
+    void clearTransient();
+
+    void acquireGestureWakeLock(long time);
+
+    boolean setAppearance(int appearance);
+
+    int getBarMode();
+
+    void resendMessage(int msg);
+
+    void resendMessage(Object msg);
+
+    int getDisabled1();
+
+    void setDisabled1(int disabled);
+
+    int getDisabled2();
+
+    void setDisabled2(int disabled);
+
+    void setLastCameraLaunchSource(int source);
+
+    void setLaunchCameraOnFinishedGoingToSleep(boolean launch);
+
+    void setLaunchCameraOnFinishedWaking(boolean launch);
+
+    void setLaunchEmergencyActionOnFinishedGoingToSleep(boolean launch);
+
+    void setLaunchEmergencyActionOnFinishedWaking(boolean launch);
+
+    void setTopHidesStatusBar(boolean hides);
+
+    QSPanelController getQSPanelController();
+
+    boolean areNotificationAlertsDisabled();
+
+    float getDisplayDensity();
+
+    void extendDozePulse();
+
+    public static class KeyboardShortcutsMessage {
+        final int mDeviceId;
+
+        KeyboardShortcutsMessage(int deviceId) {
+            mDeviceId = deviceId;
         }
-        return mStatusBarKeyguardViewManager.isSecure();
-    }
-    public NotificationPanelViewController getPanelController() {
-        return mNotificationPanelViewController;
-    }
-    // End Extra BaseStatusBarMethods.
-
-    public NotificationGutsManager getGutsManager() {
-        return mGutsManager;
-    }
-
-    boolean isTransientShown() {
-        return mTransientShown;
-    }
-
-    private void updateLightRevealScrimVisibility() {
-        if (mLightRevealScrim == null) {
-            // status bar may not be inflated yet
-            return;
-        }
-
-        mLightRevealScrim.setAlpha(mScrimController.getState().getMaxLightRevealScrimAlpha());
-    }
-
-    private final KeyguardUpdateMonitorCallback mUpdateCallback =
-            new KeyguardUpdateMonitorCallback() {
-                @Override
-                public void onDreamingStateChanged(boolean dreaming) {
-                    updateScrimController();
-                    if (dreaming) {
-                        maybeEscalateHeadsUp();
-                    }
-                }
-
-                // TODO: (b/145659174) remove when moving to NewNotifPipeline. Replaced by
-                //  KeyguardCoordinator
-                @Override
-                public void onStrongAuthStateChanged(int userId) {
-                    super.onStrongAuthStateChanged(userId);
-                    mNotificationsController.requestNotificationUpdate("onStrongAuthStateChanged");
-                }
-            };
-
-
-    private final FalsingManager.FalsingBeliefListener mFalsingBeliefListener =
-            new FalsingManager.FalsingBeliefListener() {
-                @Override
-                public void onFalse() {
-                    // Hides quick settings, bouncer, and quick-quick settings.
-                    mStatusBarKeyguardViewManager.reset(true);
-                }
-            };
-
-    // Notifies StatusBarKeyguardViewManager every time the keyguard transition is over,
-    // this animation is tied to the scrim for historic reasons.
-    // TODO: notify when keyguard has faded away instead of the scrim.
-    private final ScrimController.Callback mUnlockScrimCallback = new ScrimController
-            .Callback() {
-        @Override
-        public void onFinished() {
-            if (mStatusBarKeyguardViewManager == null) {
-                Log.w(TAG, "Tried to notify keyguard visibility when "
-                        + "mStatusBarKeyguardViewManager was null");
-                return;
-            }
-            if (mKeyguardStateController.isKeyguardFadingAway()) {
-                mStatusBarKeyguardViewManager.onKeyguardFadedAway();
-            }
-        }
-
-        @Override
-        public void onCancelled() {
-            onFinished();
-        }
-    };
-
-    private final DeviceProvisionedListener mUserSetupObserver = new DeviceProvisionedListener() {
-        @Override
-        public void onUserSetupChanged() {
-            final boolean userSetup = mDeviceProvisionedController.isCurrentUserSetup();
-            Log.d(TAG, "mUserSetupObserver - DeviceProvisionedListener called for "
-                    + "current user");
-            if (MULTIUSER_DEBUG) {
-                Log.d(TAG, String.format("User setup changed: userSetup=%s mUserSetup=%s",
-                        userSetup, mUserSetup));
-            }
-
-            if (userSetup != mUserSetup) {
-                mUserSetup = userSetup;
-                if (!mUserSetup) {
-                    animateCollapseQuickSettings();
-                }
-                if (mNotificationPanelViewController != null) {
-                    mNotificationPanelViewController.setUserSetupComplete(mUserSetup);
-                }
-                updateQsExpansionEnabled();
-            }
-        }
-    };
-
-    private final BroadcastReceiver mWallpaperChangedReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (!mWallpaperSupported) {
-                // Receiver should not have been registered at all...
-                Log.wtf(TAG, "WallpaperManager not supported");
-                return;
-            }
-            WallpaperInfo info = mWallpaperManager.getWallpaperInfo(UserHandle.USER_CURRENT);
-            mWallpaperController.onWallpaperInfoUpdated(info);
-
-            final boolean deviceSupportsAodWallpaper = mContext.getResources().getBoolean(
-                    com.android.internal.R.bool.config_dozeSupportsAodWallpaper);
-            // If WallpaperInfo is null, it must be ImageWallpaper.
-            final boolean supportsAmbientMode = deviceSupportsAodWallpaper
-                    && (info != null && info.supportsAmbientMode());
-
-            mNotificationShadeWindowController.setWallpaperSupportsAmbientMode(supportsAmbientMode);
-            mScrimController.setWallpaperSupportsAmbientMode(supportsAmbientMode);
-            mKeyguardViewMediator.setWallpaperSupportsAmbientMode(supportsAmbientMode);
-        }
-    };
-
-    private final ConfigurationListener mConfigurationListener = new ConfigurationListener() {
-        @Override
-        public void onConfigChanged(Configuration newConfig) {
-            updateResources();
-            updateDisplaySize(); // populates mDisplayMetrics
-
-            if (DEBUG) {
-                Log.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
-            }
-
-            if (!mNotifPipelineFlags.isNewPipelineEnabled()) {
-                mViewHierarchyManager.updateRowStates();
-            }
-            mScreenPinningRequest.onConfigurationChanged();
-        }
-
-        @Override
-        public void onDensityOrFontScaleChanged() {
-            // TODO: Remove this.
-            if (mBrightnessMirrorController != null) {
-                mBrightnessMirrorController.onDensityOrFontScaleChanged();
-            }
-            // TODO: Bring these out of CentralSurfaces.
-            mUserInfoControllerImpl.onDensityOrFontScaleChanged();
-            mUserSwitcherController.onDensityOrFontScaleChanged();
-            mNotificationIconAreaController.onDensityOrFontScaleChanged(mContext);
-            mHeadsUpManager.onDensityOrFontScaleChanged();
-        }
-
-        @Override
-        public void onThemeChanged() {
-            if (mBrightnessMirrorController != null) {
-                mBrightnessMirrorController.onOverlayChanged();
-            }
-            // We need the new R.id.keyguard_indication_area before recreating
-            // mKeyguardIndicationController
-            mNotificationPanelViewController.onThemeChanged();
-
-            if (mStatusBarKeyguardViewManager != null) {
-                mStatusBarKeyguardViewManager.onThemeChanged();
-            }
-            if (mAmbientIndicationContainer instanceof AutoReinflateContainer) {
-                ((AutoReinflateContainer) mAmbientIndicationContainer).inflateLayout();
-            }
-            mNotificationIconAreaController.onThemeChanged();
-        }
-
-        @Override
-        public void onUiModeChanged() {
-            if (mBrightnessMirrorController != null) {
-                mBrightnessMirrorController.onUiModeChanged();
-            }
-        }
-    };
-
-    private StatusBarStateController.StateListener mStateListener =
-            new StatusBarStateController.StateListener() {
-                @Override
-                public void onStatePreChange(int oldState, int newState) {
-                    // If we're visible and switched to SHADE_LOCKED (the user dragged
-                    // down on the lockscreen), clear notification LED, vibration,
-                    // ringing.
-                    // Other transitions are covered in handleVisibleToUserChanged().
-                    if (mVisible && (newState == StatusBarState.SHADE_LOCKED
-                            || mStatusBarStateController.goingToFullShade())) {
-                        clearNotificationEffects();
-                    }
-                    if (newState == StatusBarState.KEYGUARD) {
-                        mRemoteInputManager.onPanelCollapsed();
-                        maybeEscalateHeadsUp();
-                    }
-                }
-
-                @Override
-                public void onStateChanged(int newState) {
-                    mState = newState;
-                    updateReportRejectedTouchVisibility();
-                    mDozeServiceHost.updateDozing();
-                    updateTheme();
-                    mNavigationBarController.touchAutoDim(mDisplayId);
-                    Trace.beginSection("CentralSurfaces#updateKeyguardState");
-                    if (mState == StatusBarState.KEYGUARD) {
-                        mNotificationPanelViewController.cancelPendingPanelCollapse();
-                    }
-                    updateDozingState();
-                    checkBarModes();
-                    updateScrimController();
-                    mPresenter.updateMediaMetaData(false, mState != StatusBarState.KEYGUARD);
-                    Trace.endSection();
-                }
-
-                @Override
-                public void onDozeAmountChanged(float linear, float eased) {
-                    if (mFeatureFlags.isEnabled(Flags.LOCKSCREEN_ANIMATIONS)
-                            && !(mLightRevealScrim.getRevealEffect() instanceof CircleReveal)) {
-                        mLightRevealScrim.setRevealAmount(1f - linear);
-                    }
-                }
-
-                @Override
-                public void onDozingChanged(boolean isDozing) {
-                    Trace.beginSection("CentralSurfaces#updateDozing");
-                    mDozing = isDozing;
-
-                    // Collapse the notification panel if open
-                    boolean dozingAnimated = mDozeServiceHost.getDozingRequested()
-                            && mDozeParameters.shouldControlScreenOff();
-                    mNotificationPanelViewController.resetViews(dozingAnimated);
-
-                    updateQsExpansionEnabled();
-                    mKeyguardViewMediator.setDozing(mDozing);
-
-                    mNotificationsController.requestNotificationUpdate("onDozingChanged");
-                    updateDozingState();
-                    mDozeServiceHost.updateDozing();
-                    updateScrimController();
-                    updateReportRejectedTouchVisibility();
-                    Trace.endSection();
-                }
-
-                @Override
-                public void onFullscreenStateChanged(boolean isFullscreen) {
-                    mIsFullscreen = isFullscreen;
-                    maybeUpdateBarMode();
-                }
-            };
-
-    private final BatteryController.BatteryStateChangeCallback mBatteryStateChangeCallback =
-            new BatteryController.BatteryStateChangeCallback() {
-                @Override
-                public void onPowerSaveChanged(boolean isPowerSave) {
-                    mMainExecutor.execute(mCheckBarModes);
-                    if (mDozeServiceHost != null) {
-                        mDozeServiceHost.firePowerSaveChanged(isPowerSave);
-                    }
-                }
-            };
-
-    private final ActivityLaunchAnimator.Callback mActivityLaunchAnimatorCallback =
-            new ActivityLaunchAnimator.Callback() {
-                @Override
-                public boolean isOnKeyguard() {
-                    return mKeyguardStateController.isShowing();
-                }
-
-                @Override
-                public void hideKeyguardWithAnimation(IRemoteAnimationRunner runner) {
-                    // We post to the main thread for 2 reasons:
-                    //   1. KeyguardViewMediator is not thread-safe.
-                    //   2. To ensure that ViewMediatorCallback#keyguardDonePending is called before
-                    //      ViewMediatorCallback#readyForKeyguardDone. The wrong order could occur
-                    //      when doing
-                    //      dismissKeyguardThenExecute { hideKeyguardWithAnimation(runner) }.
-                    mMainExecutor.execute(() -> mKeyguardViewMediator.hideWithAnimation(runner));
-                }
-
-                @Override
-                public int getBackgroundColor(TaskInfo task) {
-                    if (!mStartingSurfaceOptional.isPresent()) {
-                        Log.w(TAG, "No starting surface, defaulting to SystemBGColor");
-                        return SplashscreenContentDrawer.getSystemBGColor();
-                    }
-
-                    return mStartingSurfaceOptional.get().getBackgroundColor(task);
-                }
-            };
-
-    private final ActivityLaunchAnimator.Listener mActivityLaunchAnimatorListener =
-            new ActivityLaunchAnimator.Listener() {
-                @Override
-                public void onLaunchAnimationStart() {
-                    mKeyguardViewMediator.setBlursDisabledForAppLaunch(true);
-                }
-
-                @Override
-                public void onLaunchAnimationEnd() {
-                    mKeyguardViewMediator.setBlursDisabledForAppLaunch(false);
-                }
-            };
-
-    private final DemoMode mDemoModeCallback = new DemoMode() {
-        @Override
-        public void onDemoModeFinished() {
-            checkBarModes();
-        }
-
-        @Override
-        public void dispatchDemoCommand(String command, Bundle args) { }
-    };
-
-    /**
-     *  Determines what UserHandle to use when launching an activity.
-     *
-     *  We want to ensure that activities that are launched within the systemui process should be
-     *  launched as user of the current process.
-     * @param intent
-     * @return UserHandle
-     */
-    private UserHandle getActivityUserHandle(Intent intent) {
-        if (intent.getComponent() != null
-                && mContext.getPackageName().equals(intent.getComponent().getPackageName())) {
-            return new UserHandle(UserHandle.myUserId());
-        }
-        return UserHandle.CURRENT;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
new file mode 100644
index 0000000..ca4224f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -0,0 +1,4551 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
+import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
+import static android.app.StatusBarManager.WindowVisibleState;
+import static android.app.StatusBarManager.windowStateToString;
+import static android.view.InsetsState.ITYPE_STATUS_BAR;
+import static android.view.InsetsState.containsType;
+import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
+import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_STATUS_BARS;
+import static android.view.WindowInsetsController.APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS;
+
+import static androidx.core.view.ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_AUTO;
+import static androidx.core.view.ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS;
+import static androidx.lifecycle.Lifecycle.State.RESUMED;
+
+import static com.android.systemui.Dependency.TIME_TICK_HANDLER_NAME;
+import static com.android.systemui.charging.WirelessChargingLayout.UNKNOWN_BATTERY_LEVEL;
+import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP;
+import static com.android.systemui.statusbar.NotificationLockscreenUserManager.PERMISSION_SELF;
+import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
+import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
+import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
+import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
+import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
+import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
+
+import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.app.ActivityOptions;
+import android.app.ActivityTaskManager;
+import android.app.IWallpaperManager;
+import android.app.KeyguardManager;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.StatusBarManager;
+import android.app.TaskInfo;
+import android.app.TaskStackBuilder;
+import android.app.UiModeManager;
+import android.app.WallpaperInfo;
+import android.app.WallpaperManager;
+import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
+import android.content.ComponentCallbacks2;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Configuration;
+import android.graphics.Point;
+import android.graphics.PointF;
+import android.hardware.devicestate.DeviceStateManager;
+import android.metrics.LogMaker;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.PowerManager;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.os.Trace;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.service.dreams.DreamService;
+import android.service.dreams.IDreamManager;
+import android.service.notification.StatusBarNotification;
+import android.text.TextUtils;
+import android.util.ArraySet;
+import android.util.DisplayMetrics;
+import android.util.EventLog;
+import android.util.IndentingPrintWriter;
+import android.util.Log;
+import android.util.MathUtils;
+import android.util.Slog;
+import android.view.Display;
+import android.view.IRemoteAnimationRunner;
+import android.view.IWindowManager;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.ThreadedRenderer;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowInsetsController.Appearance;
+import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
+import android.view.accessibility.AccessibilityManager;
+import android.widget.DateTimeView;
+import android.window.SplashScreen;
+
+import androidx.annotation.NonNull;
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleRegistry;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.jank.InteractionJankMonitor;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEvent;
+import com.android.internal.logging.UiEventLogger;
+import com.android.internal.logging.UiEventLoggerImpl;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.statusbar.RegisterStatusBarResult;
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitorCallback;
+import com.android.keyguard.ViewMediatorCallback;
+import com.android.systemui.ActivityIntentHelper;
+import com.android.systemui.AutoReinflateContainer;
+import com.android.systemui.CoreStartable;
+import com.android.systemui.DejankUtils;
+import com.android.systemui.EventLogTags;
+import com.android.systemui.InitController;
+import com.android.systemui.Prefs;
+import com.android.systemui.R;
+import com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuController;
+import com.android.systemui.animation.ActivityLaunchAnimator;
+import com.android.systemui.animation.DelegateLaunchAnimatorController;
+import com.android.systemui.assist.AssistManager;
+import com.android.systemui.biometrics.AuthRippleController;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.camera.CameraIntents;
+import com.android.systemui.charging.WirelessChargingAnimation;
+import com.android.systemui.classifier.FalsingCollector;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.dagger.qualifiers.UiBackground;
+import com.android.systemui.demomode.DemoMode;
+import com.android.systemui.demomode.DemoModeController;
+import com.android.systemui.dreams.DreamOverlayStateController;
+import com.android.systemui.emergency.EmergencyGesture;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
+import com.android.systemui.fragments.ExtensionFragmentListener;
+import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.fragments.FragmentService;
+import com.android.systemui.keyguard.KeyguardService;
+import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
+import com.android.systemui.keyguard.KeyguardViewMediator;
+import com.android.systemui.keyguard.ScreenLifecycle;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.navigationbar.NavigationBarController;
+import com.android.systemui.navigationbar.NavigationBarView;
+import com.android.systemui.plugins.DarkIconDispatcher;
+import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.plugins.OverlayPlugin;
+import com.android.systemui.plugins.PluginDependencyProvider;
+import com.android.systemui.plugins.PluginListener;
+import com.android.systemui.plugins.qs.QS;
+import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.qs.QSFragment;
+import com.android.systemui.qs.QSPanelController;
+import com.android.systemui.recents.ScreenPinningRequest;
+import com.android.systemui.scrim.ScrimView;
+import com.android.systemui.settings.brightness.BrightnessSliderController;
+import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.statusbar.AutoHideUiElement;
+import com.android.systemui.statusbar.BackDropView;
+import com.android.systemui.statusbar.CircleReveal;
+import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.GestureRecorder;
+import com.android.systemui.statusbar.KeyboardShortcuts;
+import com.android.systemui.statusbar.KeyguardIndicationController;
+import com.android.systemui.statusbar.LiftReveal;
+import com.android.systemui.statusbar.LightRevealScrim;
+import com.android.systemui.statusbar.LockscreenShadeTransitionController;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.NotificationMediaManager;
+import com.android.systemui.statusbar.NotificationPresenter;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.NotificationShadeDepthController;
+import com.android.systemui.statusbar.NotificationShadeWindowController;
+import com.android.systemui.statusbar.NotificationShelfController;
+import com.android.systemui.statusbar.NotificationViewHierarchyManager;
+import com.android.systemui.statusbar.PowerButtonReveal;
+import com.android.systemui.statusbar.PulseExpansionHandler;
+import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.charging.WiredChargingRippleController;
+import com.android.systemui.statusbar.connectivity.NetworkController;
+import com.android.systemui.statusbar.core.StatusBarInitializer;
+import com.android.systemui.statusbar.notification.DynamicPrivacyController;
+import com.android.systemui.statusbar.notification.NotifPipelineFlags;
+import com.android.systemui.statusbar.notification.NotificationActivityStarter;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider;
+import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
+import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
+import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
+import com.android.systemui.statusbar.notification.init.NotificationsController;
+import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
+import com.android.systemui.statusbar.notification.logging.NotificationLogger;
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
+import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
+import com.android.systemui.statusbar.phone.dagger.StatusBarPhoneModule;
+import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
+import com.android.systemui.statusbar.phone.panelstate.PanelExpansionChangeEvent;
+import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
+import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.BrightnessMirrorController;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
+import com.android.systemui.statusbar.policy.ExtensionController;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
+import com.android.systemui.statusbar.policy.UserSwitcherController;
+import com.android.systemui.statusbar.window.StatusBarWindowController;
+import com.android.systemui.statusbar.window.StatusBarWindowStateController;
+import com.android.systemui.util.DumpUtilsKt;
+import com.android.systemui.util.WallpaperController;
+import com.android.systemui.util.concurrency.DelayableExecutor;
+import com.android.systemui.util.concurrency.MessageRouter;
+import com.android.systemui.volume.VolumeComponent;
+import com.android.systemui.wmshell.BubblesManager;
+import com.android.wm.shell.bubbles.Bubbles;
+import com.android.wm.shell.startingsurface.SplashscreenContentDrawer;
+import com.android.wm.shell.startingsurface.StartingSurface;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.Executor;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import dagger.Lazy;
+
+/**
+ * A class handling initialization and coordination between some of the key central surfaces in
+ * System UI: The notification shade, the keyguard (lockscreen), and the status bar.
+ *
+ * This class is not our ideal architecture because it doesn't enforce much isolation between these
+ * three mostly disparate surfaces. In an ideal world, this class would not exist. Instead, we would
+ * break it up into three modules -- one for each of those three surfaces -- and we would define any
+ * APIs that are needed for these surfaces to communicate with each other when necessary.
+ *
+ * <b>If at all possible, please avoid adding additional code to this monstrous class! Our goal is
+ * to break up this class into many small classes, and any code added here will slow down that goal.
+ * </b>
+ */
+@SysUISingleton
+public class CentralSurfacesImpl extends CoreStartable implements
+        CentralSurfaces {
+
+    private static final String BANNER_ACTION_CANCEL =
+            "com.android.systemui.statusbar.banner_action_cancel";
+    private static final String BANNER_ACTION_SETUP =
+            "com.android.systemui.statusbar.banner_action_setup";
+
+    private static final int MSG_OPEN_SETTINGS_PANEL = 1002;
+    private static final int MSG_LAUNCH_TRANSITION_TIMEOUT = 1003;
+    // 1020-1040 reserved for BaseStatusBar
+
+    /**
+     * The delay to reset the hint text when the hint animation is finished running.
+     */
+    private static final int HINT_RESET_DELAY_MS = 1200;
+
+    /** If true, the lockscreen will show a distinct wallpaper */
+    public static final boolean ENABLE_LOCKSCREEN_WALLPAPER = true;
+
+    private static final UiEventLogger sUiEventLogger = new UiEventLoggerImpl();
+
+    private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
+    private final DreamOverlayStateController mDreamOverlayStateController;
+    private CentralSurfacesCommandQueueCallbacks mCommandQueueCallbacks;
+    private float mTransitionToFullShadeProgress = 0f;
+    private NotificationListContainer mNotifListContainer;
+
+    private final KeyguardStateController.Callback mKeyguardStateControllerCallback =
+            new KeyguardStateController.Callback() {
+                @Override
+                public void onKeyguardShowingChanged() {
+                    boolean occluded = mKeyguardStateController.isOccluded();
+                    mStatusBarHideIconsForBouncerManager.setIsOccludedAndTriggerUpdate(occluded);
+                    mScrimController.setKeyguardOccluded(occluded);
+                }
+            };
+
+    void onStatusBarWindowStateChanged(@WindowVisibleState int state) {
+        updateBubblesVisibility();
+        mStatusBarWindowState = state;
+    }
+
+    @Override
+    public void acquireGestureWakeLock(long time) {
+        mGestureWakeLock.acquire(time);
+    }
+
+    @Override
+    public boolean setAppearance(int appearance) {
+        if (mAppearance != appearance) {
+            mAppearance = appearance;
+            return updateBarMode(barMode(isTransientShown(), appearance));
+        }
+
+        return false;
+    }
+
+    @Override
+    public int getBarMode() {
+        return mStatusBarMode;
+    }
+
+    @Override
+    public void resendMessage(int msg) {
+        mMessageRouter.cancelMessages(msg);
+        mMessageRouter.sendMessage(msg);
+    }
+
+    @Override
+    public void resendMessage(Object msg) {
+        mMessageRouter.cancelMessages(msg.getClass());
+        mMessageRouter.sendMessage(msg);
+    }
+
+    @Override
+    public int getDisabled1() {
+        return mDisabled1;
+    }
+
+    @Override
+    public void setDisabled1(int disabled) {
+        mDisabled1 = disabled;
+    }
+
+    @Override
+    public int getDisabled2() {
+        return mDisabled2;
+    }
+
+    @Override
+    public void setDisabled2(int disabled) {
+        mDisabled2 = disabled;
+    }
+
+    @Override
+    public void setLastCameraLaunchSource(int source) {
+        mLastCameraLaunchSource = source;
+    }
+
+    @Override
+    public void setLaunchCameraOnFinishedGoingToSleep(boolean launch) {
+        mLaunchCameraOnFinishedGoingToSleep = launch;
+    }
+
+    @Override
+    public void setLaunchCameraOnFinishedWaking(boolean launch) {
+        mLaunchCameraWhenFinishedWaking = launch;
+    }
+
+    @Override
+    public void setLaunchEmergencyActionOnFinishedGoingToSleep(boolean launch) {
+        mLaunchEmergencyActionOnFinishedGoingToSleep = launch;
+    }
+
+    @Override
+    public void setLaunchEmergencyActionOnFinishedWaking(boolean launch) {
+        mLaunchEmergencyActionWhenFinishedWaking = launch;
+    }
+
+    @Override
+    public void setTopHidesStatusBar(boolean hides) {
+        mTopHidesStatusBar = hides;
+    }
+
+    @Override
+    public QSPanelController getQSPanelController() {
+        return mQSPanelController;
+    }
+
+    /** */
+    @Override
+    public void animateExpandNotificationsPanel() {
+        mCommandQueueCallbacks.animateExpandNotificationsPanel();
+    }
+
+    /** */
+    @Override
+    public void animateExpandSettingsPanel(@Nullable String subpanel) {
+        mCommandQueueCallbacks.animateExpandSettingsPanel(subpanel);
+    }
+
+    /** */
+    @Override
+    public void animateCollapsePanels(int flags, boolean force) {
+        mCommandQueueCallbacks.animateCollapsePanels(flags, force);
+    }
+
+    /** */
+    @Override
+    public void togglePanel() {
+        mCommandQueueCallbacks.togglePanel();
+    }
+    /**
+     * The {@link StatusBarState} of the status bar.
+     */
+    protected int mState; // TODO: remove this. Just use StatusBarStateController
+    protected boolean mBouncerShowing;
+    private boolean mBouncerShowingOverDream;
+
+    private final PhoneStatusBarPolicy mIconPolicy;
+
+    private final VolumeComponent mVolumeComponent;
+    private BrightnessMirrorController mBrightnessMirrorController;
+    private boolean mBrightnessMirrorVisible;
+    private BiometricUnlockController mBiometricUnlockController;
+    private final LightBarController mLightBarController;
+    private final Lazy<LockscreenWallpaper> mLockscreenWallpaperLazy;
+    private final LockscreenGestureLogger mLockscreenGestureLogger;
+    @Nullable
+    protected LockscreenWallpaper mLockscreenWallpaper;
+    private final AutoHideController mAutoHideController;
+
+    private final Point mCurrentDisplaySize = new Point();
+
+    protected NotificationShadeWindowView mNotificationShadeWindowView;
+    protected PhoneStatusBarView mStatusBarView;
+    private PhoneStatusBarViewController mPhoneStatusBarViewController;
+    private PhoneStatusBarTransitions mStatusBarTransitions;
+    private AuthRippleController mAuthRippleController;
+    @WindowVisibleState private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
+    protected final NotificationShadeWindowController mNotificationShadeWindowController;
+    private final StatusBarWindowController mStatusBarWindowController;
+    private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+    @VisibleForTesting
+    DozeServiceHost mDozeServiceHost;
+    private boolean mWakeUpComingFromTouch;
+    private PointF mWakeUpTouchLocation;
+    private LightRevealScrim mLightRevealScrim;
+    private PowerButtonReveal mPowerButtonReveal;
+
+    private final Object mQueueLock = new Object();
+
+    private final PulseExpansionHandler mPulseExpansionHandler;
+    private final NotificationWakeUpCoordinator mWakeUpCoordinator;
+    private final KeyguardBypassController mKeyguardBypassController;
+    private final KeyguardStateController mKeyguardStateController;
+    private final HeadsUpManagerPhone mHeadsUpManager;
+    private final StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
+    private final DynamicPrivacyController mDynamicPrivacyController;
+    private final FalsingCollector mFalsingCollector;
+    private final FalsingManager mFalsingManager;
+    private final BroadcastDispatcher mBroadcastDispatcher;
+    private final ConfigurationController mConfigurationController;
+    protected NotificationShadeWindowViewController mNotificationShadeWindowViewController;
+    private final DozeParameters mDozeParameters;
+    private final Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy;
+    private final CentralSurfacesComponent.Factory mCentralSurfacesComponentFactory;
+    private final PluginManager mPluginManager;
+    private final ShadeController mShadeController;
+    private final InitController mInitController;
+
+    private final PluginDependencyProvider mPluginDependencyProvider;
+    private final KeyguardDismissUtil mKeyguardDismissUtil;
+    private final ExtensionController mExtensionController;
+    private final UserInfoControllerImpl mUserInfoControllerImpl;
+    private final DemoModeController mDemoModeController;
+    private final NotificationsController mNotificationsController;
+    private final OngoingCallController mOngoingCallController;
+    private final StatusBarSignalPolicy mStatusBarSignalPolicy;
+    private final StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
+
+    // expanded notifications
+    // the sliding/resizing panel within the notification window
+    protected NotificationPanelViewController mNotificationPanelViewController;
+
+    // settings
+    private QSPanelController mQSPanelController;
+
+    KeyguardIndicationController mKeyguardIndicationController;
+
+    private View mReportRejectedTouch;
+
+    private boolean mExpandedVisible;
+
+    private final int[] mAbsPos = new int[2];
+
+    private final NotifShadeEventSource mNotifShadeEventSource;
+    protected final NotificationEntryManager mEntryManager;
+    private final NotificationGutsManager mGutsManager;
+    private final NotificationLogger mNotificationLogger;
+    private final NotificationViewHierarchyManager mViewHierarchyManager;
+    private final PanelExpansionStateManager mPanelExpansionStateManager;
+    private final KeyguardViewMediator mKeyguardViewMediator;
+    protected final NotificationInterruptStateProvider mNotificationInterruptStateProvider;
+    private final BrightnessSliderController.Factory mBrightnessSliderFactory;
+    private final FeatureFlags mFeatureFlags;
+    private final FragmentService mFragmentService;
+    private final ScreenOffAnimationController mScreenOffAnimationController;
+    private final WallpaperController mWallpaperController;
+    private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
+    private final MessageRouter mMessageRouter;
+    private final WallpaperManager mWallpaperManager;
+
+    private CentralSurfacesComponent mCentralSurfacesComponent;
+
+    // Flags for disabling the status bar
+    // Two variables becaseu the first one evidently ran out of room for new flags.
+    private int mDisabled1 = 0;
+    private int mDisabled2 = 0;
+
+    /** @see android.view.WindowInsetsController#setSystemBarsAppearance(int, int) */
+    private @Appearance int mAppearance;
+
+    private boolean mTransientShown;
+
+    private final DisplayMetrics mDisplayMetrics;
+
+    // XXX: gesture research
+    private final GestureRecorder mGestureRec = DEBUG_GESTURES
+        ? new GestureRecorder("/sdcard/statusbar_gestures.dat")
+        : null;
+
+    private final ScreenPinningRequest mScreenPinningRequest;
+
+    private final MetricsLogger mMetricsLogger;
+
+    // ensure quick settings is disabled until the current user makes it through the setup wizard
+    @VisibleForTesting
+    protected boolean mUserSetup = false;
+
+    @VisibleForTesting
+    public enum StatusBarUiEvent implements UiEventLogger.UiEventEnum {
+        @UiEvent(doc = "Secured lockscreen is opened.")
+        LOCKSCREEN_OPEN_SECURE(405),
+
+        @UiEvent(doc = "Lockscreen without security is opened.")
+        LOCKSCREEN_OPEN_INSECURE(406),
+
+        @UiEvent(doc = "Secured lockscreen is closed.")
+        LOCKSCREEN_CLOSE_SECURE(407),
+
+        @UiEvent(doc = "Lockscreen without security is closed.")
+        LOCKSCREEN_CLOSE_INSECURE(408),
+
+        @UiEvent(doc = "Secured bouncer is opened.")
+        BOUNCER_OPEN_SECURE(409),
+
+        @UiEvent(doc = "Bouncer without security is opened.")
+        BOUNCER_OPEN_INSECURE(410),
+
+        @UiEvent(doc = "Secured bouncer is closed.")
+        BOUNCER_CLOSE_SECURE(411),
+
+        @UiEvent(doc = "Bouncer without security is closed.")
+        BOUNCER_CLOSE_INSECURE(412);
+
+        private final int mId;
+
+        StatusBarUiEvent(int id) {
+            mId = id;
+        }
+
+        @Override
+        public int getId() {
+            return mId;
+        }
+    }
+
+    private Handler mMainHandler;
+    private final DelayableExecutor mMainExecutor;
+
+    private int mInteractingWindows;
+    private @TransitionMode int mStatusBarMode;
+
+    private final ViewMediatorCallback mKeyguardViewMediatorCallback;
+    private final ScrimController mScrimController;
+    protected DozeScrimController mDozeScrimController;
+    private final Executor mUiBgExecutor;
+
+    protected boolean mDozing;
+    private boolean mIsFullscreen;
+
+    boolean mCloseQsBeforeScreenOff;
+
+    private final NotificationMediaManager mMediaManager;
+    private final NotificationLockscreenUserManager mLockscreenUserManager;
+    private final NotificationRemoteInputManager mRemoteInputManager;
+    private boolean mWallpaperSupported;
+
+    private Runnable mLaunchTransitionEndRunnable;
+    private Runnable mLaunchTransitionCancelRunnable;
+    private boolean mLaunchCameraWhenFinishedWaking;
+    private boolean mLaunchCameraOnFinishedGoingToSleep;
+    private boolean mLaunchEmergencyActionWhenFinishedWaking;
+    private boolean mLaunchEmergencyActionOnFinishedGoingToSleep;
+    private int mLastCameraLaunchSource;
+    protected PowerManager.WakeLock mGestureWakeLock;
+
+    private final int[] mTmpInt2 = new int[2];
+
+    // Fingerprint (as computed by getLoggingFingerprint() of the last logged state.
+    private int mLastLoggedStateFingerprint;
+    private boolean mTopHidesStatusBar;
+    private boolean mStatusBarWindowHidden;
+    private boolean mIsLaunchingActivityOverLockscreen;
+
+    private final UserSwitcherController mUserSwitcherController;
+    private final NetworkController mNetworkController;
+    private final LifecycleRegistry mLifecycle = new LifecycleRegistry(this);
+    protected final BatteryController mBatteryController;
+    protected boolean mPanelExpanded;
+    private UiModeManager mUiModeManager;
+    private LogMaker mStatusBarStateLog;
+    protected final NotificationIconAreaController mNotificationIconAreaController;
+    @Nullable private View mAmbientIndicationContainer;
+    private final SysuiColorExtractor mColorExtractor;
+    private final ScreenLifecycle mScreenLifecycle;
+    private final WakefulnessLifecycle mWakefulnessLifecycle;
+
+    private boolean mNoAnimationOnNextBarModeChange;
+    private final SysuiStatusBarStateController mStatusBarStateController;
+
+    private final ActivityLaunchAnimator mActivityLaunchAnimator;
+    private NotificationLaunchAnimatorControllerProvider mNotificationAnimationProvider;
+    protected NotificationPresenter mPresenter;
+    private NotificationActivityStarter mNotificationActivityStarter;
+    private final Lazy<NotificationShadeDepthController> mNotificationShadeDepthControllerLazy;
+    private final Optional<BubblesManager> mBubblesManagerOptional;
+    private final Optional<Bubbles> mBubblesOptional;
+    private final Bubbles.BubbleExpandListener mBubbleExpandListener;
+    private final Optional<StartingSurface> mStartingSurfaceOptional;
+    private final NotifPipelineFlags mNotifPipelineFlags;
+
+    private final ActivityIntentHelper mActivityIntentHelper;
+    private NotificationStackScrollLayoutController mStackScrollerController;
+
+    private final ColorExtractor.OnColorsChangedListener mOnColorsChangedListener =
+            (extractor, which) -> updateTheme();
+
+    private final InteractionJankMonitor mJankMonitor;
+
+
+    /**
+     * Public constructor for CentralSurfaces.
+     *
+     * CentralSurfaces is considered optional, and therefore can not be marked as @Inject directly.
+     * Instead, an @Provide method is included. See {@link StatusBarPhoneModule}.
+     */
+    @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
+    @Inject
+    public CentralSurfacesImpl(
+            Context context,
+            NotificationsController notificationsController,
+            FragmentService fragmentService,
+            LightBarController lightBarController,
+            AutoHideController autoHideController,
+            StatusBarWindowController statusBarWindowController,
+            StatusBarWindowStateController statusBarWindowStateController,
+            KeyguardUpdateMonitor keyguardUpdateMonitor,
+            StatusBarSignalPolicy statusBarSignalPolicy,
+            PulseExpansionHandler pulseExpansionHandler,
+            NotificationWakeUpCoordinator notificationWakeUpCoordinator,
+            KeyguardBypassController keyguardBypassController,
+            KeyguardStateController keyguardStateController,
+            HeadsUpManagerPhone headsUpManagerPhone,
+            DynamicPrivacyController dynamicPrivacyController,
+            FalsingManager falsingManager,
+            FalsingCollector falsingCollector,
+            BroadcastDispatcher broadcastDispatcher,
+            NotifShadeEventSource notifShadeEventSource,
+            NotificationEntryManager notificationEntryManager,
+            NotificationGutsManager notificationGutsManager,
+            NotificationLogger notificationLogger,
+            NotificationInterruptStateProvider notificationInterruptStateProvider,
+            NotificationViewHierarchyManager notificationViewHierarchyManager,
+            PanelExpansionStateManager panelExpansionStateManager,
+            KeyguardViewMediator keyguardViewMediator,
+            DisplayMetrics displayMetrics,
+            MetricsLogger metricsLogger,
+            @UiBackground Executor uiBgExecutor,
+            NotificationMediaManager notificationMediaManager,
+            NotificationLockscreenUserManager lockScreenUserManager,
+            NotificationRemoteInputManager remoteInputManager,
+            UserSwitcherController userSwitcherController,
+            NetworkController networkController,
+            BatteryController batteryController,
+            SysuiColorExtractor colorExtractor,
+            ScreenLifecycle screenLifecycle,
+            WakefulnessLifecycle wakefulnessLifecycle,
+            SysuiStatusBarStateController statusBarStateController,
+            Optional<BubblesManager> bubblesManagerOptional,
+            Optional<Bubbles> bubblesOptional,
+            VisualStabilityManager visualStabilityManager,
+            DeviceProvisionedController deviceProvisionedController,
+            NavigationBarController navigationBarController,
+            AccessibilityFloatingMenuController accessibilityFloatingMenuController,
+            Lazy<AssistManager> assistManagerLazy,
+            ConfigurationController configurationController,
+            NotificationShadeWindowController notificationShadeWindowController,
+            DozeParameters dozeParameters,
+            ScrimController scrimController,
+            Lazy<LockscreenWallpaper> lockscreenWallpaperLazy,
+            LockscreenGestureLogger lockscreenGestureLogger,
+            Lazy<BiometricUnlockController> biometricUnlockControllerLazy,
+            DozeServiceHost dozeServiceHost,
+            PowerManager powerManager,
+            ScreenPinningRequest screenPinningRequest,
+            DozeScrimController dozeScrimController,
+            VolumeComponent volumeComponent,
+            CommandQueue commandQueue,
+            CentralSurfacesComponent.Factory centralSurfacesComponentFactory,
+            PluginManager pluginManager,
+            ShadeController shadeController,
+            StatusBarKeyguardViewManager statusBarKeyguardViewManager,
+            ViewMediatorCallback viewMediatorCallback,
+            InitController initController,
+            @Named(TIME_TICK_HANDLER_NAME) Handler timeTickHandler,
+            PluginDependencyProvider pluginDependencyProvider,
+            KeyguardDismissUtil keyguardDismissUtil,
+            ExtensionController extensionController,
+            UserInfoControllerImpl userInfoControllerImpl,
+            PhoneStatusBarPolicy phoneStatusBarPolicy,
+            KeyguardIndicationController keyguardIndicationController,
+            DemoModeController demoModeController,
+            Lazy<NotificationShadeDepthController> notificationShadeDepthControllerLazy,
+            StatusBarTouchableRegionManager statusBarTouchableRegionManager,
+            NotificationIconAreaController notificationIconAreaController,
+            BrightnessSliderController.Factory brightnessSliderFactory,
+            ScreenOffAnimationController screenOffAnimationController,
+            WallpaperController wallpaperController,
+            OngoingCallController ongoingCallController,
+            StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager,
+            LockscreenShadeTransitionController lockscreenShadeTransitionController,
+            FeatureFlags featureFlags,
+            KeyguardUnlockAnimationController keyguardUnlockAnimationController,
+            @Main Handler mainHandler,
+            @Main DelayableExecutor delayableExecutor,
+            @Main MessageRouter messageRouter,
+            WallpaperManager wallpaperManager,
+            Optional<StartingSurface> startingSurfaceOptional,
+            ActivityLaunchAnimator activityLaunchAnimator,
+            NotifPipelineFlags notifPipelineFlags,
+            InteractionJankMonitor jankMonitor,
+            DeviceStateManager deviceStateManager,
+            DreamOverlayStateController dreamOverlayStateController,
+            WiredChargingRippleController wiredChargingRippleController) {
+        super(context);
+        mNotificationsController = notificationsController;
+        mFragmentService = fragmentService;
+        mLightBarController = lightBarController;
+        mAutoHideController = autoHideController;
+        mStatusBarWindowController = statusBarWindowController;
+        mKeyguardUpdateMonitor = keyguardUpdateMonitor;
+        mPulseExpansionHandler = pulseExpansionHandler;
+        mWakeUpCoordinator = notificationWakeUpCoordinator;
+        mKeyguardBypassController = keyguardBypassController;
+        mKeyguardStateController = keyguardStateController;
+        mHeadsUpManager = headsUpManagerPhone;
+        mKeyguardIndicationController = keyguardIndicationController;
+        mStatusBarTouchableRegionManager = statusBarTouchableRegionManager;
+        mDynamicPrivacyController = dynamicPrivacyController;
+        mFalsingCollector = falsingCollector;
+        mFalsingManager = falsingManager;
+        mBroadcastDispatcher = broadcastDispatcher;
+        mNotifShadeEventSource = notifShadeEventSource;
+        mEntryManager = notificationEntryManager;
+        mGutsManager = notificationGutsManager;
+        mNotificationLogger = notificationLogger;
+        mNotificationInterruptStateProvider = notificationInterruptStateProvider;
+        mViewHierarchyManager = notificationViewHierarchyManager;
+        mPanelExpansionStateManager = panelExpansionStateManager;
+        mKeyguardViewMediator = keyguardViewMediator;
+        mDisplayMetrics = displayMetrics;
+        mMetricsLogger = metricsLogger;
+        mUiBgExecutor = uiBgExecutor;
+        mMediaManager = notificationMediaManager;
+        mLockscreenUserManager = lockScreenUserManager;
+        mRemoteInputManager = remoteInputManager;
+        mUserSwitcherController = userSwitcherController;
+        mNetworkController = networkController;
+        mBatteryController = batteryController;
+        mColorExtractor = colorExtractor;
+        mScreenLifecycle = screenLifecycle;
+        mWakefulnessLifecycle = wakefulnessLifecycle;
+        mStatusBarStateController = statusBarStateController;
+        mBubblesManagerOptional = bubblesManagerOptional;
+        mBubblesOptional = bubblesOptional;
+        mVisualStabilityManager = visualStabilityManager;
+        mDeviceProvisionedController = deviceProvisionedController;
+        mNavigationBarController = navigationBarController;
+        mAccessibilityFloatingMenuController = accessibilityFloatingMenuController;
+        mAssistManagerLazy = assistManagerLazy;
+        mConfigurationController = configurationController;
+        mNotificationShadeWindowController = notificationShadeWindowController;
+        mDozeServiceHost = dozeServiceHost;
+        mPowerManager = powerManager;
+        mDozeParameters = dozeParameters;
+        mScrimController = scrimController;
+        mLockscreenWallpaperLazy = lockscreenWallpaperLazy;
+        mLockscreenGestureLogger = lockscreenGestureLogger;
+        mScreenPinningRequest = screenPinningRequest;
+        mDozeScrimController = dozeScrimController;
+        mBiometricUnlockControllerLazy = biometricUnlockControllerLazy;
+        mNotificationShadeDepthControllerLazy = notificationShadeDepthControllerLazy;
+        mVolumeComponent = volumeComponent;
+        mCommandQueue = commandQueue;
+        mCentralSurfacesComponentFactory = centralSurfacesComponentFactory;
+        mPluginManager = pluginManager;
+        mShadeController = shadeController;
+        mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
+        mKeyguardViewMediatorCallback = viewMediatorCallback;
+        mInitController = initController;
+        mPluginDependencyProvider = pluginDependencyProvider;
+        mKeyguardDismissUtil = keyguardDismissUtil;
+        mExtensionController = extensionController;
+        mUserInfoControllerImpl = userInfoControllerImpl;
+        mIconPolicy = phoneStatusBarPolicy;
+        mDemoModeController = demoModeController;
+        mNotificationIconAreaController = notificationIconAreaController;
+        mBrightnessSliderFactory = brightnessSliderFactory;
+        mWallpaperController = wallpaperController;
+        mOngoingCallController = ongoingCallController;
+        mStatusBarSignalPolicy = statusBarSignalPolicy;
+        mStatusBarHideIconsForBouncerManager = statusBarHideIconsForBouncerManager;
+        mFeatureFlags = featureFlags;
+        mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
+        mMainHandler = mainHandler;
+        mMainExecutor = delayableExecutor;
+        mMessageRouter = messageRouter;
+        mWallpaperManager = wallpaperManager;
+        mJankMonitor = jankMonitor;
+        mDreamOverlayStateController = dreamOverlayStateController;
+
+        mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
+        mStartingSurfaceOptional = startingSurfaceOptional;
+        mNotifPipelineFlags = notifPipelineFlags;
+        lockscreenShadeTransitionController.setCentralSurfaces(this);
+        statusBarWindowStateController.addListener(this::onStatusBarWindowStateChanged);
+
+        mScreenOffAnimationController = screenOffAnimationController;
+
+        mPanelExpansionStateManager.addExpansionListener(this::onPanelExpansionChanged);
+
+        mBubbleExpandListener =
+                (isExpanding, key) -> mContext.getMainExecutor().execute(() -> {
+                    mNotificationsController.requestNotificationUpdate("onBubbleExpandChanged");
+                    updateScrimController();
+                });
+
+        mActivityIntentHelper = new ActivityIntentHelper(mContext);
+        mActivityLaunchAnimator = activityLaunchAnimator;
+
+        // The status bar background may need updating when the ongoing call status changes.
+        mOngoingCallController.addCallback((animate) -> maybeUpdateBarMode());
+
+        // TODO(b/190746471): Find a better home for this.
+        DateTimeView.setReceiverHandler(timeTickHandler);
+
+        mMessageRouter.subscribeTo(KeyboardShortcutsMessage.class,
+                data -> toggleKeyboardShortcuts(data.mDeviceId));
+        mMessageRouter.subscribeTo(MSG_DISMISS_KEYBOARD_SHORTCUTS_MENU,
+                id -> dismissKeyboardShortcuts());
+        mMessageRouter.subscribeTo(AnimateExpandSettingsPanelMessage.class,
+                data -> mCommandQueueCallbacks.animateExpandSettingsPanel(data.mSubpanel));
+        mMessageRouter.subscribeTo(MSG_LAUNCH_TRANSITION_TIMEOUT,
+                id -> onLaunchTransitionTimeout());
+
+        deviceStateManager.registerCallback(mMainExecutor,
+                new FoldStateListener(mContext, this::onFoldedStateChanged));
+        wiredChargingRippleController.registerCallbacks();
+    }
+
+    @Override
+    public void start() {
+        mScreenLifecycle.addObserver(mScreenObserver);
+        mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
+        mUiModeManager = mContext.getSystemService(UiModeManager.class);
+        if (mBubblesOptional.isPresent()) {
+            mBubblesOptional.get().setExpandListener(mBubbleExpandListener);
+        }
+
+        mStatusBarSignalPolicy.init();
+        mKeyguardIndicationController.init();
+
+        mColorExtractor.addOnColorsChangedListener(mOnColorsChangedListener);
+        mStatusBarStateController.addCallback(mStateListener,
+                SysuiStatusBarStateController.RANK_STATUS_BAR);
+
+        mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+        mDreamManager = IDreamManager.Stub.asInterface(
+                ServiceManager.checkService(DreamService.DREAM_SERVICE));
+
+        mDisplay = mContext.getDisplay();
+        mDisplayId = mDisplay.getDisplayId();
+        updateDisplaySize();
+        mStatusBarHideIconsForBouncerManager.setDisplayId(mDisplayId);
+
+        // start old BaseStatusBar.start().
+        mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
+        mDevicePolicyManager = (DevicePolicyManager) mContext.getSystemService(
+                Context.DEVICE_POLICY_SERVICE);
+
+        mAccessibilityManager = (AccessibilityManager)
+                mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
+
+        mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController);
+        mBarService = IStatusBarService.Stub.asInterface(
+                ServiceManager.getService(Context.STATUS_BAR_SERVICE));
+
+        mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
+        mWallpaperSupported = mWallpaperManager.isWallpaperSupported();
+
+        RegisterStatusBarResult result = null;
+        try {
+            result = mBarService.registerStatusBar(mCommandQueue);
+        } catch (RemoteException ex) {
+            ex.rethrowFromSystemServer();
+        }
+
+        createAndAddWindows(result);
+
+        if (mWallpaperSupported) {
+            // Make sure we always have the most current wallpaper info.
+            IntentFilter wallpaperChangedFilter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
+            mBroadcastDispatcher.registerReceiver(mWallpaperChangedReceiver, wallpaperChangedFilter,
+                    null /* handler */, UserHandle.ALL);
+            mWallpaperChangedReceiver.onReceive(mContext, null);
+        } else if (DEBUG) {
+            Log.v(TAG, "start(): no wallpaper service ");
+        }
+
+        // Set up the initial notification state. This needs to happen before CommandQueue.disable()
+        setUpPresenter();
+
+        if (containsType(result.mTransientBarTypes, ITYPE_STATUS_BAR)) {
+            showTransientUnchecked();
+        }
+        mCommandQueueCallbacks.onSystemBarAttributesChanged(mDisplayId, result.mAppearance,
+                result.mAppearanceRegions, result.mNavbarColorManagedByIme, result.mBehavior,
+                result.mRequestedVisibilities, result.mPackageName);
+
+        // StatusBarManagerService has a back up of IME token and it's restored here.
+        mCommandQueueCallbacks.setImeWindowStatus(mDisplayId, result.mImeToken,
+                result.mImeWindowVis, result.mImeBackDisposition, result.mShowImeSwitcher);
+
+        // Set up the initial icon state
+        int numIcons = result.mIcons.size();
+        for (int i = 0; i < numIcons; i++) {
+            mCommandQueue.setIcon(result.mIcons.keyAt(i), result.mIcons.valueAt(i));
+        }
+
+        if (DEBUG) {
+            Log.d(TAG, String.format(
+                    "init: icons=%d disabled=0x%08x lights=0x%08x imeButton=0x%08x",
+                    numIcons,
+                    result.mDisabledFlags1,
+                    result.mAppearance,
+                    result.mImeWindowVis));
+        }
+
+        IntentFilter internalFilter = new IntentFilter();
+        internalFilter.addAction(BANNER_ACTION_CANCEL);
+        internalFilter.addAction(BANNER_ACTION_SETUP);
+        mContext.registerReceiver(mBannerActionBroadcastReceiver, internalFilter, PERMISSION_SELF,
+                null, Context.RECEIVER_EXPORTED_UNAUDITED);
+
+        if (mWallpaperSupported) {
+            IWallpaperManager wallpaperManager = IWallpaperManager.Stub.asInterface(
+                    ServiceManager.getService(Context.WALLPAPER_SERVICE));
+            try {
+                wallpaperManager.setInAmbientMode(false /* ambientMode */, 0L /* duration */);
+            } catch (RemoteException e) {
+                // Just pass, nothing critical.
+            }
+        }
+
+        // end old BaseStatusBar.start().
+
+        // Lastly, call to the icon policy to install/update all the icons.
+        mIconPolicy.init();
+
+        mKeyguardStateController.addCallback(new KeyguardStateController.Callback() {
+            @Override
+            public void onUnlockedChanged() {
+                logStateToEventlog();
+            }
+        });
+        startKeyguard();
+
+        mKeyguardUpdateMonitor.registerCallback(mUpdateCallback);
+        mDozeServiceHost.initialize(
+                this,
+                mStatusBarKeyguardViewManager,
+                mNotificationShadeWindowViewController,
+                mNotificationPanelViewController,
+                mAmbientIndicationContainer);
+        updateLightRevealScrimVisibility();
+
+        mConfigurationController.addCallback(mConfigurationListener);
+
+        mBatteryController.observe(mLifecycle, mBatteryStateChangeCallback);
+        mLifecycle.setCurrentState(RESUMED);
+
+        mAccessibilityFloatingMenuController.init();
+
+        // set the initial view visibility
+        int disabledFlags1 = result.mDisabledFlags1;
+        int disabledFlags2 = result.mDisabledFlags2;
+        mInitController.addPostInitTask(
+                () -> setUpDisableFlags(disabledFlags1, disabledFlags2));
+
+        mFalsingManager.addFalsingBeliefListener(mFalsingBeliefListener);
+
+        mPluginManager.addPluginListener(
+                new PluginListener<OverlayPlugin>() {
+                    private final ArraySet<OverlayPlugin> mOverlays = new ArraySet<>();
+
+                    @Override
+                    public void onPluginConnected(OverlayPlugin plugin, Context pluginContext) {
+                        mMainExecutor.execute(
+                                () -> plugin.setup(getNotificationShadeWindowView(),
+                                        getNavigationBarView(),
+                                        new Callback(plugin), mDozeParameters));
+                    }
+
+                    @Override
+                    public void onPluginDisconnected(OverlayPlugin plugin) {
+                        mMainExecutor.execute(() -> {
+                            mOverlays.remove(plugin);
+                            mNotificationShadeWindowController
+                                    .setForcePluginOpen(mOverlays.size() != 0, this);
+                        });
+                    }
+
+                    class Callback implements OverlayPlugin.Callback {
+                        private final OverlayPlugin mPlugin;
+
+                        Callback(OverlayPlugin plugin) {
+                            mPlugin = plugin;
+                        }
+
+                        @Override
+                        public void onHoldStatusBarOpenChange() {
+                            if (mPlugin.holdStatusBarOpen()) {
+                                mOverlays.add(mPlugin);
+                            } else {
+                                mOverlays.remove(mPlugin);
+                            }
+                            mMainExecutor.execute(() -> {
+                                mNotificationShadeWindowController
+                                        .setStateListener(b -> mOverlays.forEach(
+                                                o -> o.setCollapseDesired(b)));
+                                mNotificationShadeWindowController
+                                        .setForcePluginOpen(mOverlays.size() != 0, this);
+                            });
+                        }
+                    }
+                }, OverlayPlugin.class, true /* Allow multiple plugins */);
+
+        mStartingSurfaceOptional.ifPresent(startingSurface -> startingSurface.setSysuiProxy(
+                (requestTopUi, componentTag) -> mMainExecutor.execute(() ->
+                        mNotificationShadeWindowController.setRequestTopUi(
+                                requestTopUi, componentTag))));
+    }
+
+    private void onFoldedStateChanged(boolean isFolded, boolean willGoToSleep) {
+        Trace.beginSection("CentralSurfaces#onFoldedStateChanged");
+        onFoldedStateChangedInternal(isFolded, willGoToSleep);
+        Trace.endSection();
+    }
+
+    private void onFoldedStateChangedInternal(boolean isFolded, boolean willGoToSleep) {
+        // Folded state changes are followed by a screen off event.
+        // By default turning off the screen also closes the shade.
+        // We want to make sure that the shade status is kept after
+        // folding/unfolding.
+        boolean isShadeOpen = mShadeController.isShadeOpen();
+        boolean leaveOpen = isShadeOpen && !willGoToSleep;
+        if (DEBUG) {
+            Log.d(TAG, String.format(
+                    "#onFoldedStateChanged(): "
+                            + "isFolded=%s, "
+                            + "willGoToSleep=%s, "
+                            + "isShadeOpen=%s, "
+                            + "leaveOpen=%s",
+                    isFolded, willGoToSleep, isShadeOpen, leaveOpen));
+        }
+        if (leaveOpen) {
+            mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
+            if (mKeyguardStateController.isShowing()) {
+                // When device state changes on keyguard we don't want to keep the state of
+                // the shade and instead we open clean state of keyguard with shade closed.
+                // Normally some parts of QS state (like expanded/collapsed) are persisted and
+                // that causes incorrect UI rendering, especially when changing state with QS
+                // expanded. To prevent that we can close QS which resets QS and some parts of
+                // the shade to its default state. Read more in b/201537421
+                mCloseQsBeforeScreenOff = true;
+            }
+        }
+    }
+
+    // ================================================================================
+    // Constructing the view
+    // ================================================================================
+    protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {
+        updateDisplaySize(); // populates mDisplayMetrics
+        updateResources();
+        updateTheme();
+
+        inflateStatusBarWindow();
+        mNotificationShadeWindowView.setOnTouchListener(getStatusBarWindowTouchListener());
+        mWallpaperController.setRootView(mNotificationShadeWindowView);
+
+        // TODO: Deal with the ugliness that comes from having some of the status bar broken out
+        // into fragments, but the rest here, it leaves some awkward lifecycle and whatnot.
+        mNotificationLogger.setUpWithContainer(mNotifListContainer);
+        mNotificationIconAreaController.setupShelf(mNotificationShelfController);
+        mPanelExpansionStateManager.addExpansionListener(mWakeUpCoordinator);
+        mUserSwitcherController.init(mNotificationShadeWindowView);
+
+        // Allow plugins to reference DarkIconDispatcher and StatusBarStateController
+        mPluginDependencyProvider.allowPluginDependency(DarkIconDispatcher.class);
+        mPluginDependencyProvider.allowPluginDependency(StatusBarStateController.class);
+
+        // Set up CollapsedStatusBarFragment and PhoneStatusBarView
+        StatusBarInitializer initializer = mCentralSurfacesComponent.getStatusBarInitializer();
+        initializer.setStatusBarViewUpdatedListener(
+                (statusBarView, statusBarViewController, statusBarTransitions) -> {
+                    mStatusBarView = statusBarView;
+                    mPhoneStatusBarViewController = statusBarViewController;
+                    mStatusBarTransitions = statusBarTransitions;
+                    mNotificationShadeWindowViewController
+                            .setStatusBarViewController(mPhoneStatusBarViewController);
+                    // Ensure we re-propagate panel expansion values to the panel controller and
+                    // any listeners it may have, such as PanelBar. This will also ensure we
+                    // re-display the notification panel if necessary (for example, if
+                    // a heads-up notification was being displayed and should continue being
+                    // displayed).
+                    mNotificationPanelViewController.updatePanelExpansionAndVisibility();
+                    setBouncerShowingForStatusBarComponents(mBouncerShowing);
+                    checkBarModes();
+                });
+        initializer.initializeStatusBar(mCentralSurfacesComponent);
+
+        mStatusBarTouchableRegionManager.setup(this, mNotificationShadeWindowView);
+        mHeadsUpManager.addListener(mNotificationPanelViewController.getOnHeadsUpChangedListener());
+        if (!mNotifPipelineFlags.isNewPipelineEnabled()) {
+            mHeadsUpManager.addListener(mVisualStabilityManager);
+        }
+        mNotificationPanelViewController.setHeadsUpManager(mHeadsUpManager);
+
+        createNavigationBar(result);
+
+        if (ENABLE_LOCKSCREEN_WALLPAPER && mWallpaperSupported) {
+            mLockscreenWallpaper = mLockscreenWallpaperLazy.get();
+        }
+
+        mNotificationPanelViewController.setKeyguardIndicationController(
+                mKeyguardIndicationController);
+
+        mAmbientIndicationContainer = mNotificationShadeWindowView.findViewById(
+                R.id.ambient_indication_container);
+
+        mAutoHideController.setStatusBar(new AutoHideUiElement() {
+            @Override
+            public void synchronizeState() {
+                checkBarModes();
+            }
+
+            @Override
+            public boolean shouldHideOnTouch() {
+                return !mRemoteInputManager.isRemoteInputActive();
+            }
+
+            @Override
+            public boolean isVisible() {
+                return isTransientShown();
+            }
+
+            @Override
+            public void hide() {
+                clearTransient();
+            }
+        });
+
+        ScrimView scrimBehind = mNotificationShadeWindowView.findViewById(R.id.scrim_behind);
+        ScrimView notificationsScrim = mNotificationShadeWindowView
+                .findViewById(R.id.scrim_notifications);
+        ScrimView scrimInFront = mNotificationShadeWindowView.findViewById(R.id.scrim_in_front);
+
+        mScrimController.setScrimVisibleListener(scrimsVisible -> {
+            mNotificationShadeWindowController.setScrimsVisibility(scrimsVisible);
+        });
+        mScrimController.attachViews(scrimBehind, notificationsScrim, scrimInFront);
+
+        mLightRevealScrim = mNotificationShadeWindowView.findViewById(R.id.light_reveal_scrim);
+        mLightRevealScrim.setScrimOpaqueChangedListener((opaque) -> {
+            Runnable updateOpaqueness = () -> {
+                mNotificationShadeWindowController.setLightRevealScrimOpaque(
+                        mLightRevealScrim.isScrimOpaque());
+                mScreenOffAnimationController
+                        .onScrimOpaqueChanged(mLightRevealScrim.isScrimOpaque());
+            };
+            if (opaque) {
+                // Delay making the view opaque for a frame, because it needs some time to render
+                // otherwise this can lead to a flicker where the scrim doesn't cover the screen
+                mLightRevealScrim.post(updateOpaqueness);
+            } else {
+                updateOpaqueness.run();
+            }
+        });
+
+        mScreenOffAnimationController.initialize(this, mLightRevealScrim);
+        updateLightRevealScrimVisibility();
+
+        mNotificationPanelViewController.initDependencies(
+                this,
+                this::makeExpandedInvisible,
+                mNotificationShelfController);
+
+        BackDropView backdrop = mNotificationShadeWindowView.findViewById(R.id.backdrop);
+        mMediaManager.setup(backdrop, backdrop.findViewById(R.id.backdrop_front),
+                backdrop.findViewById(R.id.backdrop_back), mScrimController, mLockscreenWallpaper);
+        float maxWallpaperZoom = mContext.getResources().getFloat(
+                com.android.internal.R.dimen.config_wallpaperMaxScale);
+        mNotificationShadeDepthControllerLazy.get().addListener(depth -> {
+            float scale = MathUtils.lerp(maxWallpaperZoom, 1f, depth);
+            backdrop.setPivotX(backdrop.getWidth() / 2f);
+            backdrop.setPivotY(backdrop.getHeight() / 2f);
+            backdrop.setScaleX(scale);
+            backdrop.setScaleY(scale);
+        });
+
+        mNotificationPanelViewController.setUserSetupComplete(mUserSetup);
+
+        // Set up the quick settings tile panel
+        final View container = mNotificationShadeWindowView.findViewById(R.id.qs_frame);
+        if (container != null) {
+            FragmentHostManager fragmentHostManager = FragmentHostManager.get(container);
+            ExtensionFragmentListener.attachExtensonToFragment(container, QS.TAG, R.id.qs_frame,
+                    mExtensionController
+                            .newExtension(QS.class)
+                            .withPlugin(QS.class)
+                            .withDefault(this::createDefaultQSFragment)
+                            .build());
+            mBrightnessMirrorController = new BrightnessMirrorController(
+                    mNotificationShadeWindowView,
+                    mNotificationPanelViewController,
+                    mNotificationShadeDepthControllerLazy.get(),
+                    mBrightnessSliderFactory,
+                    (visible) -> {
+                        mBrightnessMirrorVisible = visible;
+                        updateScrimController();
+                    });
+            fragmentHostManager.addTagListener(QS.TAG, (tag, f) -> {
+                QS qs = (QS) f;
+                if (qs instanceof QSFragment) {
+                    mQSPanelController = ((QSFragment) qs).getQSPanelController();
+                    ((QSFragment) qs).setBrightnessMirrorController(mBrightnessMirrorController);
+                }
+            });
+        }
+
+        mReportRejectedTouch = mNotificationShadeWindowView
+                .findViewById(R.id.report_rejected_touch);
+        if (mReportRejectedTouch != null) {
+            updateReportRejectedTouchVisibility();
+            mReportRejectedTouch.setOnClickListener(v -> {
+                Uri session = mFalsingManager.reportRejectedTouch();
+                if (session == null) { return; }
+
+                StringWriter message = new StringWriter();
+                message.write("Build info: ");
+                message.write(SystemProperties.get("ro.build.description"));
+                message.write("\nSerial number: ");
+                message.write(SystemProperties.get("ro.serialno"));
+                message.write("\n");
+
+                startActivityDismissingKeyguard(Intent.createChooser(new Intent(Intent.ACTION_SEND)
+                                .setType("*/*")
+                                .putExtra(Intent.EXTRA_SUBJECT, "Rejected touch report")
+                                .putExtra(Intent.EXTRA_STREAM, session)
+                                .putExtra(Intent.EXTRA_TEXT, message.toString()),
+                        "Share rejected touch report")
+                                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
+                        true /* onlyProvisioned */, true /* dismissShade */);
+            });
+        }
+
+        if (!mPowerManager.isInteractive()) {
+            mBroadcastReceiver.onReceive(mContext, new Intent(Intent.ACTION_SCREEN_OFF));
+        }
+        mGestureWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
+                "sysui:GestureWakeLock");
+
+        // receive broadcasts
+        registerBroadcastReceiver();
+
+        IntentFilter demoFilter = new IntentFilter();
+        if (DEBUG_MEDIA_FAKE_ARTWORK) {
+            demoFilter.addAction(ACTION_FAKE_ARTWORK);
+        }
+        mContext.registerReceiverAsUser(mDemoReceiver, UserHandle.ALL, demoFilter,
+                android.Manifest.permission.DUMP, null,
+                Context.RECEIVER_EXPORTED_UNAUDITED);
+
+        // listen for USER_SETUP_COMPLETE setting (per-user)
+        mDeviceProvisionedController.addCallback(mUserSetupObserver);
+        mUserSetupObserver.onUserSetupChanged();
+
+        // disable profiling bars, since they overlap and clutter the output on app windows
+        ThreadedRenderer.overrideProperty("disableProfileBars", "true");
+
+        // Private API call to make the shadows look better for Recents
+        ThreadedRenderer.overrideProperty("ambientRatio", String.valueOf(1.5f));
+    }
+
+
+    /**
+     * When swiping up to dismiss the lock screen, the panel expansion fraction goes from 1f to 0f.
+     * This results in the clock/notifications/other content disappearing off the top of the screen.
+     *
+     * We also use the expansion fraction to animate in the app/launcher surface from the bottom of
+     * the screen, 'pushing' off the notifications and other content. To do this, we dispatch the
+     * expansion fraction to the KeyguardViewMediator if we're in the process of dismissing the
+     * keyguard.
+     */
+    private void dispatchPanelExpansionForKeyguardDismiss(float fraction, boolean trackingTouch) {
+        // Things that mean we're not swiping to dismiss the keyguard, and should ignore this
+        // expansion:
+        // - Keyguard isn't even visible.
+        // - Keyguard is occluded. Expansion changes here are the shade being expanded over the
+        //   occluding activity.
+        // - Keyguard is visible, but can't be dismissed (swiping up will show PIN/password prompt).
+        // - The SIM is locked, you can't swipe to unlock. If the SIM is locked but there is no
+        //   device lock set, canDismissLockScreen returns true even though you should not be able
+        //   to dismiss the lock screen until entering the SIM PIN.
+        // - QS is expanded and we're swiping - swiping up now will hide QS, not dismiss the
+        //   keyguard.
+        if (!isKeyguardShowing()
+                || isOccluded()
+                || !mKeyguardStateController.canDismissLockScreen()
+                || mKeyguardViewMediator.isAnySimPinSecure()
+                || (mNotificationPanelViewController.isQsExpanded() && trackingTouch)) {
+            return;
+        }
+
+        // Otherwise, we should let the keyguard know about this if we're tracking touch, or if we
+        // are already animating the keyguard dismiss (since we will need to either finish or cancel
+        // the animation).
+        if (trackingTouch
+                || mKeyguardViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehindOrWillBe()
+                || mKeyguardUnlockAnimationController.isUnlockingWithSmartSpaceTransition()) {
+            mKeyguardStateController.notifyKeyguardDismissAmountChanged(
+                    1f - fraction, trackingTouch);
+        }
+    }
+
+    private void onPanelExpansionChanged(PanelExpansionChangeEvent event) {
+        float fraction = event.getFraction();
+        boolean tracking = event.getTracking();
+        dispatchPanelExpansionForKeyguardDismiss(fraction, tracking);
+
+        if (fraction == 0 || fraction == 1) {
+            if (getNavigationBarView() != null) {
+                getNavigationBarView().onStatusBarPanelStateChanged();
+            }
+            if (getNotificationPanelViewController() != null) {
+                getNotificationPanelViewController().updateSystemUiStateFlags();
+            }
+        }
+    }
+
+    @NonNull
+    @Override
+    public Lifecycle getLifecycle() {
+        return mLifecycle;
+    }
+
+    @VisibleForTesting
+    protected void registerBroadcastReceiver() {
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+        filter.addAction(Intent.ACTION_SCREEN_OFF);
+        mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, null, UserHandle.ALL);
+    }
+
+    protected QS createDefaultQSFragment() {
+        return FragmentHostManager.get(mNotificationShadeWindowView).create(QSFragment.class);
+    }
+
+    private void setUpPresenter() {
+        // Set up the initial notification state.
+        mActivityLaunchAnimator.setCallback(mActivityLaunchAnimatorCallback);
+        mActivityLaunchAnimator.addListener(mActivityLaunchAnimatorListener);
+        mNotificationAnimationProvider = new NotificationLaunchAnimatorControllerProvider(
+                mNotificationShadeWindowViewController,
+                mNotifListContainer,
+                mHeadsUpManager,
+                mJankMonitor);
+        mNotificationShelfController.setOnActivatedListener(mPresenter);
+        mRemoteInputManager.addControllerCallback(mNotificationShadeWindowController);
+        mStackScrollerController.setNotificationActivityStarter(mNotificationActivityStarter);
+        mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);
+        mNotificationsController.initialize(
+                mPresenter,
+                mNotifListContainer,
+                mStackScrollerController.getNotifStackController(),
+                mNotificationActivityStarter,
+                mCentralSurfacesComponent.getBindRowCallback());
+    }
+
+    /**
+     * Post-init task of {@link #start()}
+     * @param state1 disable1 flags
+     * @param state2 disable2 flags
+     */
+    protected void setUpDisableFlags(int state1, int state2) {
+        mCommandQueue.disable(mDisplayId, state1, state2, false /* animate */);
+    }
+
+    /**
+     * Ask the display to wake up if currently dozing, else do nothing
+     *
+     * @param time when to wake up
+     * @param where the view requesting the wakeup
+     * @param why the reason for the wake up
+     */
+    @Override
+    public void wakeUpIfDozing(long time, View where, String why) {
+        if (mDozing && mScreenOffAnimationController.allowWakeUpIfDozing()) {
+            mPowerManager.wakeUp(
+                    time, PowerManager.WAKE_REASON_GESTURE, "com.android.systemui:" + why);
+            mWakeUpComingFromTouch = true;
+            where.getLocationInWindow(mTmpInt2);
+
+            // NOTE, the incoming view can sometimes be the entire container... unsure if
+            // this location is valuable enough
+            mWakeUpTouchLocation = new PointF(mTmpInt2[0] + where.getWidth() / 2,
+                    mTmpInt2[1] + where.getHeight() / 2);
+            mFalsingCollector.onScreenOnFromTouch();
+        }
+    }
+
+    // TODO(b/117478341): This was left such that CarStatusBar can override this method.
+    // Try to remove this.
+    protected void createNavigationBar(@Nullable RegisterStatusBarResult result) {
+        mNavigationBarController.createNavigationBars(true /* includeDefaultDisplay */, result);
+    }
+
+    /**
+     * Returns the {@link android.view.View.OnTouchListener} that will be invoked when the
+     * background window of the status bar is clicked.
+     */
+    protected View.OnTouchListener getStatusBarWindowTouchListener() {
+        return (v, event) -> {
+            mAutoHideController.checkUserAutoHide(event);
+            mRemoteInputManager.checkRemoteInputOutside(event);
+            if (event.getAction() == MotionEvent.ACTION_UP) {
+                if (mExpandedVisible) {
+                    mShadeController.animateCollapsePanels();
+                }
+            }
+            return mNotificationShadeWindowView.onTouchEvent(event);
+        };
+    }
+
+    private void inflateStatusBarWindow() {
+        if (mCentralSurfacesComponent != null) {
+            // Tear down
+            for (CentralSurfacesComponent.Startable s : mCentralSurfacesComponent.getStartables()) {
+                s.stop();
+            }
+        }
+        mCentralSurfacesComponent = mCentralSurfacesComponentFactory.create();
+        mFragmentService.addFragmentInstantiationProvider(mCentralSurfacesComponent);
+
+        mNotificationShadeWindowView = mCentralSurfacesComponent.getNotificationShadeWindowView();
+        mNotificationShadeWindowViewController = mCentralSurfacesComponent
+                .getNotificationShadeWindowViewController();
+        mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView);
+        mNotificationShadeWindowViewController.setupExpandedStatusBar();
+        mNotificationPanelViewController =
+                mCentralSurfacesComponent.getNotificationPanelViewController();
+        mCentralSurfacesComponent.getLockIconViewController().init();
+        mStackScrollerController =
+                mCentralSurfacesComponent.getNotificationStackScrollLayoutController();
+        mStackScroller = mStackScrollerController.getView();
+        mNotifListContainer = mCentralSurfacesComponent.getNotificationListContainer();
+        mPresenter = mCentralSurfacesComponent.getNotificationPresenter();
+        mNotificationActivityStarter = mCentralSurfacesComponent.getNotificationActivityStarter();
+        mNotificationShelfController = mCentralSurfacesComponent.getNotificationShelfController();
+        mAuthRippleController = mCentralSurfacesComponent.getAuthRippleController();
+        mAuthRippleController.init();
+
+        mHeadsUpManager.addListener(mCentralSurfacesComponent.getStatusBarHeadsUpChangeListener());
+
+        // Listen for demo mode changes
+        mDemoModeController.addCallback(mDemoModeCallback);
+
+        if (mCommandQueueCallbacks != null) {
+            mCommandQueue.removeCallback(mCommandQueueCallbacks);
+        }
+        mCommandQueueCallbacks =
+                mCentralSurfacesComponent.getCentralSurfacesCommandQueueCallbacks();
+        // Connect in to the status bar manager service
+        mCommandQueue.addCallback(mCommandQueueCallbacks);
+
+        // Perform all other initialization for CentralSurfacesScope
+        for (CentralSurfacesComponent.Startable s : mCentralSurfacesComponent.getStartables()) {
+            s.start();
+        }
+    }
+
+    protected void startKeyguard() {
+        Trace.beginSection("CentralSurfaces#startKeyguard");
+        mBiometricUnlockController = mBiometricUnlockControllerLazy.get();
+        mBiometricUnlockController.setBiometricModeListener(
+                new BiometricUnlockController.BiometricModeListener() {
+                    @Override
+                    public void onResetMode() {
+                        setWakeAndUnlocking(false);
+                    }
+
+                    @Override
+                    public void onModeChanged(int mode) {
+                        switch (mode) {
+                            case BiometricUnlockController.MODE_WAKE_AND_UNLOCK_FROM_DREAM:
+                            case BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING:
+                            case BiometricUnlockController.MODE_WAKE_AND_UNLOCK:
+                                setWakeAndUnlocking(true);
+                        }
+                    }
+
+                    @Override
+                    public void notifyBiometricAuthModeChanged() {
+                        CentralSurfacesImpl.this.notifyBiometricAuthModeChanged();
+                    }
+
+                    private void setWakeAndUnlocking(boolean wakeAndUnlocking) {
+                        if (getNavigationBarView() != null) {
+                            getNavigationBarView().setWakeAndUnlocking(wakeAndUnlocking);
+                        }
+                    }
+                });
+        mStatusBarKeyguardViewManager.registerCentralSurfaces(
+                /* statusBar= */ this,
+                mNotificationPanelViewController,
+                mPanelExpansionStateManager,
+                mBiometricUnlockController,
+                mStackScroller,
+                mKeyguardBypassController);
+        mKeyguardStateController.addCallback(mKeyguardStateControllerCallback);
+        mKeyguardIndicationController
+                .setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
+        mBiometricUnlockController.setKeyguardViewController(mStatusBarKeyguardViewManager);
+        mRemoteInputManager.addControllerCallback(mStatusBarKeyguardViewManager);
+        mDynamicPrivacyController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
+
+        mLightBarController.setBiometricUnlockController(mBiometricUnlockController);
+        mMediaManager.setBiometricUnlockController(mBiometricUnlockController);
+        mKeyguardDismissUtil.setDismissHandler(this::executeWhenUnlocked);
+        Trace.endSection();
+    }
+
+    @Override
+    public NotificationShadeWindowView getNotificationShadeWindowView() {
+        return mNotificationShadeWindowView;
+    }
+
+    @Override
+    public NotificationShadeWindowViewController getNotificationShadeWindowViewController() {
+        return mNotificationShadeWindowViewController;
+    }
+
+    @Override
+    public NotificationPanelViewController getNotificationPanelViewController() {
+        return mNotificationPanelViewController;
+    }
+
+    @Override
+    public ViewGroup getBouncerContainer() {
+        return mNotificationShadeWindowViewController.getBouncerContainer();
+    }
+
+    @Override
+    public int getStatusBarHeight() {
+        return mStatusBarWindowController.getStatusBarHeight();
+    }
+
+    /**
+     * Disable QS if device not provisioned.
+     * If the user switcher is simple then disable QS during setup because
+     * the user intends to use the lock screen user switcher, QS in not needed.
+     */
+    @Override
+    public void updateQsExpansionEnabled() {
+        final boolean expandEnabled = mDeviceProvisionedController.isDeviceProvisioned()
+                && (mUserSetup || mUserSwitcherController == null
+                        || !mUserSwitcherController.isSimpleUserSwitcher())
+                && !isShadeDisabled()
+                && ((mDisabled2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) == 0)
+                && !mDozing;
+        mNotificationPanelViewController.setQsExpansionEnabledPolicy(expandEnabled);
+        Log.d(TAG, "updateQsExpansionEnabled - QS Expand enabled: " + expandEnabled);
+    }
+
+    @Override
+    public boolean isShadeDisabled() {
+        return (mDisabled2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) != 0;
+    }
+
+    /**
+     * Request a notification update
+     * @param reason why we're requesting a notification update
+     */
+    @Override
+    public void requestNotificationUpdate(String reason) {
+        mNotificationsController.requestNotificationUpdate(reason);
+    }
+
+    /**
+     * Asks {@link KeyguardUpdateMonitor} to run face auth.
+     */
+    @Override
+    public void requestFaceAuth(boolean userInitiatedRequest) {
+        if (!mKeyguardStateController.canDismissLockScreen()) {
+            mKeyguardUpdateMonitor.requestFaceAuth(userInitiatedRequest);
+        }
+    }
+
+    private void updateReportRejectedTouchVisibility() {
+        if (mReportRejectedTouch == null) {
+            return;
+        }
+        mReportRejectedTouch.setVisibility(mState == StatusBarState.KEYGUARD && !mDozing
+                && mFalsingCollector.isReportingEnabled() ? View.VISIBLE : View.INVISIBLE);
+    }
+
+    @Override
+    public boolean areNotificationAlertsDisabled() {
+        return (mDisabled1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
+    }
+
+    @Override
+    public void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade,
+            int flags) {
+        startActivityDismissingKeyguard(intent, onlyProvisioned, dismissShade, flags);
+    }
+
+    @Override
+    public void startActivity(Intent intent, boolean dismissShade) {
+        startActivityDismissingKeyguard(intent, false /* onlyProvisioned */, dismissShade);
+    }
+
+    @Override
+    public void startActivity(Intent intent, boolean dismissShade,
+            @Nullable ActivityLaunchAnimator.Controller animationController,
+            boolean showOverLockscreenWhenLocked) {
+        startActivity(intent, dismissShade, animationController, showOverLockscreenWhenLocked,
+                getActivityUserHandle(intent));
+    }
+
+    @Override
+    public void startActivity(Intent intent, boolean dismissShade,
+            @Nullable ActivityLaunchAnimator.Controller animationController,
+            boolean showOverLockscreenWhenLocked, UserHandle userHandle) {
+        // Make sure that we dismiss the keyguard if it is directly dismissable or when we don't
+        // want to show the activity above it.
+        if (mKeyguardStateController.isUnlocked() || !showOverLockscreenWhenLocked) {
+            startActivityDismissingKeyguard(intent, false, dismissShade,
+                    false /* disallowEnterPictureInPictureWhileLaunching */, null /* callback */,
+                    0 /* flags */, animationController, userHandle);
+            return;
+        }
+
+        boolean animate =
+                animationController != null && shouldAnimateLaunch(true /* isActivityIntent */,
+                        showOverLockscreenWhenLocked);
+
+        ActivityLaunchAnimator.Controller controller = null;
+        if (animate) {
+            // Wrap the animation controller to dismiss the shade and set
+            // mIsLaunchingActivityOverLockscreen during the animation.
+            ActivityLaunchAnimator.Controller delegate = wrapAnimationController(
+                    animationController, dismissShade);
+            controller = new DelegateLaunchAnimatorController(delegate) {
+                @Override
+                public void onIntentStarted(boolean willAnimate) {
+                    getDelegate().onIntentStarted(willAnimate);
+
+                    if (willAnimate) {
+                        CentralSurfacesImpl.this.mIsLaunchingActivityOverLockscreen = true;
+                    }
+                }
+
+                @Override
+                public void onLaunchAnimationStart(boolean isExpandingFullyAbove) {
+                    super.onLaunchAnimationStart(isExpandingFullyAbove);
+
+                    // Double check that the keyguard is still showing and not going away, but if so
+                    // set the keyguard occluded. Typically, WM will let KeyguardViewMediator know
+                    // directly, but we're overriding that to play the custom launch animation, so
+                    // we need to take care of that here. The unocclude animation is not overridden,
+                    // so WM will call KeyguardViewMediator's unocclude animation runner when the
+                    // activity is exited.
+                    if (mKeyguardStateController.isShowing()
+                            && !mKeyguardStateController.isKeyguardGoingAway()) {
+                        mKeyguardViewMediator.setOccluded(true /* isOccluded */,
+                                true /* animate */);
+                    }
+                }
+
+                @Override
+                public void onLaunchAnimationEnd(boolean isExpandingFullyAbove) {
+                    // Set mIsLaunchingActivityOverLockscreen to false before actually finishing the
+                    // animation so that we can assume that mIsLaunchingActivityOverLockscreen
+                    // being true means that we will collapse the shade (or at least run the
+                    // post collapse runnables) later on.
+                    CentralSurfacesImpl.this.mIsLaunchingActivityOverLockscreen = false;
+                    getDelegate().onLaunchAnimationEnd(isExpandingFullyAbove);
+                }
+
+                @Override
+                public void onLaunchAnimationCancelled() {
+                    // Set mIsLaunchingActivityOverLockscreen to false before actually finishing the
+                    // animation so that we can assume that mIsLaunchingActivityOverLockscreen
+                    // being true means that we will collapse the shade (or at least run the
+                    // post collapse runnables) later on.
+                    CentralSurfacesImpl.this.mIsLaunchingActivityOverLockscreen = false;
+                    getDelegate().onLaunchAnimationCancelled();
+                }
+            };
+        } else if (dismissShade) {
+            // The animation will take care of dismissing the shade at the end of the animation. If
+            // we don't animate, collapse it directly.
+            collapseShade();
+        }
+
+        mActivityLaunchAnimator.startIntentWithAnimation(controller, animate,
+                intent.getPackage(), showOverLockscreenWhenLocked, (adapter) -> TaskStackBuilder
+                        .create(mContext)
+                        .addNextIntent(intent)
+                        .startActivities(
+                                CentralSurfaces.getActivityOptions(getDisplayId(), adapter),
+                                userHandle));
+    }
+
+    /**
+     * Whether we are currently animating an activity launch above the lockscreen (occluding
+     * activity).
+     */
+    @Override
+    public boolean isLaunchingActivityOverLockscreen() {
+        return mIsLaunchingActivityOverLockscreen;
+    }
+
+    @Override
+    public void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade) {
+        startActivityDismissingKeyguard(intent, onlyProvisioned, dismissShade);
+    }
+
+    @Override
+    public void startActivity(Intent intent, boolean dismissShade, Callback callback) {
+        startActivityDismissingKeyguard(intent, false, dismissShade,
+                false /* disallowEnterPictureInPictureWhileLaunching */, callback, 0,
+                null /* animationController */, getActivityUserHandle(intent));
+    }
+
+    @Override
+    public void setQsExpanded(boolean expanded) {
+        mNotificationShadeWindowController.setQsExpanded(expanded);
+        mNotificationPanelViewController.setStatusAccessibilityImportance(expanded
+                ? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
+                : View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
+        mNotificationPanelViewController.updateSystemUiStateFlags();
+        if (getNavigationBarView() != null) {
+            getNavigationBarView().onStatusBarPanelStateChanged();
+        }
+    }
+
+    @Override
+    public boolean isWakeUpComingFromTouch() {
+        return mWakeUpComingFromTouch;
+    }
+
+    @Override
+    public boolean isFalsingThresholdNeeded() {
+        return true;
+    }
+
+    /**
+     * To be called when there's a state change in StatusBarKeyguardViewManager.
+     */
+    @Override
+    public void onKeyguardViewManagerStatesUpdated() {
+        logStateToEventlog();
+    }
+
+    @Override
+    public void setPanelExpanded(boolean isExpanded) {
+        if (mPanelExpanded != isExpanded) {
+            mNotificationLogger.onPanelExpandedChanged(isExpanded);
+        }
+        mPanelExpanded = isExpanded;
+        mStatusBarHideIconsForBouncerManager.setPanelExpandedAndTriggerUpdate(isExpanded);
+        mNotificationShadeWindowController.setPanelExpanded(isExpanded);
+        mStatusBarStateController.setPanelExpanded(isExpanded);
+        if (isExpanded && mStatusBarStateController.getState() != StatusBarState.KEYGUARD) {
+            if (DEBUG) {
+                Log.v(TAG, "clearing notification effects from Height");
+            }
+            clearNotificationEffects();
+        }
+
+        if (!isExpanded) {
+            mRemoteInputManager.onPanelCollapsed();
+        }
+    }
+
+    @Override
+    public ViewGroup getNotificationScrollLayout() {
+        return mStackScroller;
+    }
+
+    @Override
+    public boolean isPulsing() {
+        return mDozeServiceHost.isPulsing();
+    }
+
+    @androidx.annotation.Nullable
+    @Override
+    public View getAmbientIndicationContainer() {
+        return mAmbientIndicationContainer;
+    }
+
+    /**
+     * When the keyguard is showing and covered by a "showWhenLocked" activity it
+     * is occluded. This is controlled by {@link com.android.server.policy.PhoneWindowManager}
+     *
+     * @return whether the keyguard is currently occluded
+     */
+    @Override
+    public boolean isOccluded() {
+        return mKeyguardStateController.isOccluded();
+    }
+
+    /** A launch animation was cancelled. */
+    //TODO: These can / should probably be moved to NotificationPresenter or ShadeController
+    @Override
+    public void onLaunchAnimationCancelled(boolean isLaunchForActivity) {
+        if (mPresenter.isPresenterFullyCollapsed() && !mPresenter.isCollapsing()
+                && isLaunchForActivity) {
+            onClosingFinished();
+        } else {
+            mShadeController.collapsePanel(true /* animate */);
+        }
+    }
+
+    /** A launch animation ended. */
+    @Override
+    public void onLaunchAnimationEnd(boolean launchIsFullScreen) {
+        if (!mPresenter.isCollapsing()) {
+            onClosingFinished();
+        }
+        if (launchIsFullScreen) {
+            instantCollapseNotificationPanel();
+        }
+    }
+
+    /**
+     * Whether we should animate an activity launch.
+     *
+     * Note: This method must be called *before* dismissing the keyguard.
+     */
+    @Override
+    public boolean shouldAnimateLaunch(boolean isActivityIntent, boolean showOverLockscreen) {
+        // TODO(b/184121838): Support launch animations when occluded.
+        if (isOccluded()) {
+            return false;
+        }
+
+        // Always animate if we are not showing the keyguard or if we animate over the lockscreen
+        // (without unlocking it).
+        if (showOverLockscreen || !mKeyguardStateController.isShowing()) {
+            return true;
+        }
+
+        // If we are locked and have to dismiss the keyguard, only animate if remote unlock
+        // animations are enabled. We also don't animate non-activity launches as they can break the
+        // animation.
+        // TODO(b/184121838): Support non activity launches on the lockscreen.
+        return isActivityIntent && KeyguardService.sEnableRemoteKeyguardGoingAwayAnimation;
+    }
+
+    /** Whether we should animate an activity launch. */
+    @Override
+    public boolean shouldAnimateLaunch(boolean isActivityIntent) {
+        return shouldAnimateLaunch(isActivityIntent, false /* showOverLockscreen */);
+    }
+
+    @Override
+    public boolean isDeviceInVrMode() {
+        return mPresenter.isDeviceInVrMode();
+    }
+
+    @Override
+    public NotificationPresenter getPresenter() {
+        return mPresenter;
+    }
+
+    @VisibleForTesting
+    @Override
+    public void setBarStateForTest(int state) {
+        mState = state;
+    }
+
+    static class AnimateExpandSettingsPanelMessage {
+        final String mSubpanel;
+
+        AnimateExpandSettingsPanelMessage(String subpanel) {
+            mSubpanel = subpanel;
+        }
+    }
+
+    private void maybeEscalateHeadsUp() {
+        mHeadsUpManager.getAllEntries().forEach(entry -> {
+            final StatusBarNotification sbn = entry.getSbn();
+            final Notification notification = sbn.getNotification();
+            if (notification.fullScreenIntent != null) {
+                if (DEBUG) {
+                    Log.d(TAG, "converting a heads up to fullScreen");
+                }
+                try {
+                    EventLog.writeEvent(EventLogTags.SYSUI_HEADS_UP_ESCALATION,
+                            sbn.getKey());
+                    wakeUpForFullScreenIntent();
+                    notification.fullScreenIntent.send();
+                    entry.notifyFullScreenIntentLaunched();
+                } catch (PendingIntent.CanceledException e) {
+                }
+            }
+        });
+        mHeadsUpManager.releaseAllImmediately();
+    }
+
+    @Override
+    public void wakeUpForFullScreenIntent() {
+        if (isGoingToSleep() || mDozing) {
+            mPowerManager.wakeUp(
+                    SystemClock.uptimeMillis(),
+                    PowerManager.WAKE_REASON_APPLICATION,
+                    "com.android.systemui:full_screen_intent");
+            mWakeUpComingFromTouch = false;
+            mWakeUpTouchLocation = null;
+        }
+    }
+
+    @Override
+    public void makeExpandedVisible(boolean force) {
+        if (SPEW) Log.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
+        if (!force && (mExpandedVisible || !mCommandQueue.panelsEnabled())) {
+            return;
+        }
+
+        mExpandedVisible = true;
+
+        // Expand the window to encompass the full screen in anticipation of the drag.
+        // This is only possible to do atomically because the status bar is at the top of the screen!
+        mNotificationShadeWindowController.setPanelVisible(true);
+
+        visibilityChanged(true);
+        mCommandQueue.recomputeDisableFlags(mDisplayId, !force /* animate */);
+        setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
+    }
+
+    @Override
+    public void postAnimateCollapsePanels() {
+        mMainExecutor.execute(mShadeController::animateCollapsePanels);
+    }
+
+    @Override
+    public void postAnimateForceCollapsePanels() {
+        mMainExecutor.execute(
+                () -> mShadeController.animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE,
+                true /* force */));
+    }
+
+    @Override
+    public void postAnimateOpenPanels() {
+        mMessageRouter.sendMessage(MSG_OPEN_SETTINGS_PANEL);
+    }
+
+    @Override
+    public boolean isExpandedVisible() {
+        return mExpandedVisible;
+    }
+
+    @Override
+    public boolean isPanelExpanded() {
+        return mPanelExpanded;
+    }
+
+    /**
+     * Called when another window is about to transfer it's input focus.
+     */
+    @Override
+    public void onInputFocusTransfer(boolean start, boolean cancel, float velocity) {
+        if (!mCommandQueue.panelsEnabled()) {
+            return;
+        }
+
+        if (start) {
+            mNotificationPanelViewController.startWaitingForOpenPanelGesture();
+        } else {
+            mNotificationPanelViewController.stopWaitingForOpenPanelGesture(cancel, velocity);
+        }
+    }
+
+    @Override
+    public void animateCollapseQuickSettings() {
+        if (mState == StatusBarState.SHADE) {
+            mNotificationPanelViewController.collapsePanel(
+                    true, false /* delayed */, 1.0f /* speedUpFactor */);
+        }
+    }
+
+    void makeExpandedInvisible() {
+        if (SPEW) Log.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible
+                + " mExpandedVisible=" + mExpandedVisible);
+
+        if (!mExpandedVisible || mNotificationShadeWindowView == null) {
+            return;
+        }
+
+        // Ensure the panel is fully collapsed (just in case; bug 6765842, 7260868)
+        mNotificationPanelViewController.collapsePanel(/*animate=*/ false, false /* delayed*/,
+                1.0f /* speedUpFactor */);
+
+        mNotificationPanelViewController.closeQs();
+
+        mExpandedVisible = false;
+        visibilityChanged(false);
+
+        // Update the visibility of notification shade and status bar window.
+        mNotificationShadeWindowController.setPanelVisible(false);
+        mStatusBarWindowController.setForceStatusBarVisible(false);
+
+        // Close any guts that might be visible
+        mGutsManager.closeAndSaveGuts(true /* removeLeavebehind */, true /* force */,
+                true /* removeControls */, -1 /* x */, -1 /* y */, true /* resetMenu */);
+
+        mShadeController.runPostCollapseRunnables();
+        setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
+        if (!mNotificationActivityStarter.isCollapsingToShowActivityOverLockscreen()) {
+            showBouncerOrLockScreenIfKeyguard();
+        } else if (DEBUG) {
+            Log.d(TAG, "Not showing bouncer due to activity showing over lockscreen");
+        }
+        mCommandQueue.recomputeDisableFlags(
+                mDisplayId,
+                mNotificationPanelViewController.hideStatusBarIconsWhenExpanded() /* animate */);
+
+        // Trimming will happen later if Keyguard is showing - doing it here might cause a jank in
+        // the bouncer appear animation.
+        if (!mStatusBarKeyguardViewManager.isShowing()) {
+            WindowManagerGlobal.getInstance().trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
+        }
+    }
+
+    /** Called when a touch event occurred on {@link PhoneStatusBarView}. */
+    @Override
+    public void onTouchEvent(MotionEvent event) {
+        // TODO(b/202981994): Move this touch debugging to a central location. (Right now, it's
+        //   split between NotificationPanelViewController and here.)
+        if (DEBUG_GESTURES) {
+            if (event.getActionMasked() != MotionEvent.ACTION_MOVE) {
+                EventLog.writeEvent(EventLogTags.SYSUI_STATUSBAR_TOUCH,
+                        event.getActionMasked(), (int) event.getX(), (int) event.getY(),
+                        mDisabled1, mDisabled2);
+            }
+
+        }
+
+        if (SPEW) {
+            Log.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled1="
+                    + mDisabled1 + " mDisabled2=" + mDisabled2);
+        } else if (CHATTY) {
+            if (event.getAction() != MotionEvent.ACTION_MOVE) {
+                Log.d(TAG, String.format(
+                            "panel: %s at (%f, %f) mDisabled1=0x%08x mDisabled2=0x%08x",
+                            MotionEvent.actionToString(event.getAction()),
+                            event.getRawX(), event.getRawY(), mDisabled1, mDisabled2));
+            }
+        }
+
+        if (DEBUG_GESTURES) {
+            mGestureRec.add(event);
+        }
+
+        if (mStatusBarWindowState == WINDOW_STATE_SHOWING) {
+            final boolean upOrCancel =
+                    event.getAction() == MotionEvent.ACTION_UP ||
+                    event.getAction() == MotionEvent.ACTION_CANCEL;
+            setInteracting(StatusBarManager.WINDOW_STATUS_BAR, !upOrCancel || mExpandedVisible);
+        }
+    }
+
+    @Override
+    public GestureRecorder getGestureRecorder() {
+        return mGestureRec;
+    }
+
+    @Override
+    public BiometricUnlockController getBiometricUnlockController() {
+        return mBiometricUnlockController;
+    }
+
+    @Override
+    public void showTransientUnchecked() {
+        if (!mTransientShown) {
+            mTransientShown = true;
+            mNoAnimationOnNextBarModeChange = true;
+            maybeUpdateBarMode();
+        }
+    }
+
+    @Override
+    public void clearTransient() {
+        if (mTransientShown) {
+            mTransientShown = false;
+            maybeUpdateBarMode();
+        }
+    }
+
+    private void maybeUpdateBarMode() {
+        final int barMode = barMode(mTransientShown, mAppearance);
+        if (updateBarMode(barMode)) {
+            mLightBarController.onStatusBarModeChanged(barMode);
+            updateBubblesVisibility();
+        }
+    }
+
+    private boolean updateBarMode(int barMode) {
+        if (mStatusBarMode != barMode) {
+            mStatusBarMode = barMode;
+            checkBarModes();
+            mAutoHideController.touchAutoHide();
+            return true;
+        }
+        return false;
+    }
+
+    private @TransitionMode int barMode(boolean isTransient, int appearance) {
+        final int lightsOutOpaque = APPEARANCE_LOW_PROFILE_BARS | APPEARANCE_OPAQUE_STATUS_BARS;
+        if (mOngoingCallController.hasOngoingCall() && mIsFullscreen) {
+            return MODE_SEMI_TRANSPARENT;
+        } else if (isTransient) {
+            return MODE_SEMI_TRANSPARENT;
+        } else if ((appearance & lightsOutOpaque) == lightsOutOpaque) {
+            return MODE_LIGHTS_OUT;
+        } else if ((appearance & APPEARANCE_LOW_PROFILE_BARS) != 0) {
+            return MODE_LIGHTS_OUT_TRANSPARENT;
+        } else if ((appearance & APPEARANCE_OPAQUE_STATUS_BARS) != 0) {
+            return MODE_OPAQUE;
+        } else if ((appearance & APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS) != 0) {
+            return MODE_SEMI_TRANSPARENT;
+        } else {
+            return MODE_TRANSPARENT;
+        }
+    }
+
+    @Override
+    public void showWirelessChargingAnimation(int batteryLevel) {
+        showChargingAnimation(batteryLevel, UNKNOWN_BATTERY_LEVEL, 0);
+    }
+
+    protected void showChargingAnimation(int batteryLevel, int transmittingBatteryLevel,
+            long animationDelay) {
+        WirelessChargingAnimation.makeWirelessChargingAnimation(mContext, null,
+                transmittingBatteryLevel, batteryLevel,
+                new WirelessChargingAnimation.Callback() {
+                    @Override
+                    public void onAnimationStarting() {
+                        mNotificationShadeWindowController.setRequestTopUi(true, TAG);
+                    }
+
+                    @Override
+                    public void onAnimationEnded() {
+                        mNotificationShadeWindowController.setRequestTopUi(false, TAG);
+                    }
+                }, false, sUiEventLogger).show(animationDelay);
+    }
+
+    @Override
+    public void checkBarModes() {
+        if (mDemoModeController.isInDemoMode()) return;
+        if (mStatusBarTransitions != null) {
+            checkBarMode(mStatusBarMode, mStatusBarWindowState, mStatusBarTransitions);
+        }
+        mNavigationBarController.checkNavBarModes(mDisplayId);
+        mNoAnimationOnNextBarModeChange = false;
+    }
+
+    // Called by NavigationBarFragment
+    @Override
+    public void setQsScrimEnabled(boolean scrimEnabled) {
+        mNotificationPanelViewController.setQsScrimEnabled(scrimEnabled);
+    }
+
+    /** Temporarily hides Bubbles if the status bar is hidden. */
+    @Override
+    public void updateBubblesVisibility() {
+        mBubblesOptional.ifPresent(bubbles -> bubbles.onStatusBarVisibilityChanged(
+                mStatusBarMode != MODE_LIGHTS_OUT
+                        && mStatusBarMode != MODE_LIGHTS_OUT_TRANSPARENT
+                        && !mStatusBarWindowHidden));
+    }
+
+    void checkBarMode(@TransitionMode int mode, @WindowVisibleState int windowState,
+            BarTransitions transitions) {
+        final boolean anim = !mNoAnimationOnNextBarModeChange && mDeviceInteractive
+                && windowState != WINDOW_STATE_HIDDEN;
+        transitions.transitionTo(mode, anim);
+    }
+
+    private void finishBarAnimations() {
+        if (mStatusBarTransitions != null) {
+            mStatusBarTransitions.finishAnimations();
+        }
+        mNavigationBarController.finishBarAnimations(mDisplayId);
+    }
+
+    private final Runnable mCheckBarModes = this::checkBarModes;
+
+    @Override
+    public void setInteracting(int barWindow, boolean interacting) {
+        mInteractingWindows = interacting
+                ? (mInteractingWindows | barWindow)
+                : (mInteractingWindows & ~barWindow);
+        if (mInteractingWindows != 0) {
+            mAutoHideController.suspendAutoHide();
+        } else {
+            mAutoHideController.resumeSuspendedAutoHide();
+        }
+        checkBarModes();
+    }
+
+    private void dismissVolumeDialog() {
+        if (mVolumeComponent != null) {
+            mVolumeComponent.dismissNow();
+        }
+    }
+
+    @Override
+    public void dump(PrintWriter pwOriginal, String[] args) {
+        IndentingPrintWriter pw = DumpUtilsKt.asIndenting(pwOriginal);
+        synchronized (mQueueLock) {
+            pw.println("Current Status Bar state:");
+            pw.println("  mExpandedVisible=" + mExpandedVisible);
+            pw.println("  mDisplayMetrics=" + mDisplayMetrics);
+            pw.println("  mStackScroller: " + CentralSurfaces.viewInfo(mStackScroller));
+            pw.println("  mStackScroller: " + CentralSurfaces.viewInfo(mStackScroller)
+                    + " scroll " + mStackScroller.getScrollX()
+                    + "," + mStackScroller.getScrollY());
+        }
+
+        pw.print("  mInteractingWindows="); pw.println(mInteractingWindows);
+        pw.print("  mStatusBarWindowState=");
+        pw.println(windowStateToString(mStatusBarWindowState));
+        pw.print("  mStatusBarMode=");
+        pw.println(BarTransitions.modeToString(mStatusBarMode));
+        pw.print("  mDozing="); pw.println(mDozing);
+        pw.print("  mWallpaperSupported= "); pw.println(mWallpaperSupported);
+
+        pw.println("  ShadeWindowView: ");
+        if (mNotificationShadeWindowViewController != null) {
+            mNotificationShadeWindowViewController.dump(pw, args);
+            CentralSurfaces.dumpBarTransitions(
+                    pw, "PhoneStatusBarTransitions", mStatusBarTransitions);
+        }
+
+        pw.println("  mMediaManager: ");
+        if (mMediaManager != null) {
+            mMediaManager.dump(pw, args);
+        }
+
+        pw.println("  Panels: ");
+        if (mNotificationPanelViewController != null) {
+            pw.println("    mNotificationPanel="
+                    + mNotificationPanelViewController.getView() + " params="
+                    + mNotificationPanelViewController.getView().getLayoutParams().debug(""));
+            pw.print  ("      ");
+            mNotificationPanelViewController.dump(pw, args);
+        }
+        pw.println("  mStackScroller: ");
+        if (mStackScroller != null) {
+            // Double indent until we rewrite the rest of this dump()
+            pw.increaseIndent();
+            pw.increaseIndent();
+            mStackScroller.dump(pw, args);
+            pw.decreaseIndent();
+            pw.decreaseIndent();
+        }
+        pw.println("  Theme:");
+        String nightMode = mUiModeManager == null ? "null" : mUiModeManager.getNightMode() + "";
+        pw.println("    dark theme: " + nightMode +
+                " (auto: " + UiModeManager.MODE_NIGHT_AUTO +
+                ", yes: " + UiModeManager.MODE_NIGHT_YES +
+                ", no: " + UiModeManager.MODE_NIGHT_NO + ")");
+        final boolean lightWpTheme = mContext.getThemeResId()
+                == R.style.Theme_SystemUI_LightWallpaper;
+        pw.println("    light wallpaper theme: " + lightWpTheme);
+
+        if (mKeyguardIndicationController != null) {
+            mKeyguardIndicationController.dump(pw, args);
+        }
+
+        if (mScrimController != null) {
+            mScrimController.dump(pw, args);
+        }
+
+        if (mLightRevealScrim != null) {
+            pw.println(
+                    "mLightRevealScrim.getRevealEffect(): " + mLightRevealScrim.getRevealEffect());
+            pw.println(
+                    "mLightRevealScrim.getRevealAmount(): " + mLightRevealScrim.getRevealAmount());
+        }
+
+        if (mStatusBarKeyguardViewManager != null) {
+            mStatusBarKeyguardViewManager.dump(pw);
+        }
+
+        mNotificationsController.dump(pw, args, DUMPTRUCK);
+
+        if (DEBUG_GESTURES) {
+            pw.print("  status bar gestures: ");
+            mGestureRec.dump(pw, args);
+        }
+
+        if (mHeadsUpManager != null) {
+            mHeadsUpManager.dump(pw, args);
+        } else {
+            pw.println("  mHeadsUpManager: null");
+        }
+
+        if (mStatusBarTouchableRegionManager != null) {
+            mStatusBarTouchableRegionManager.dump(pw, args);
+        } else {
+            pw.println("  mStatusBarTouchableRegionManager: null");
+        }
+
+        if (mLightBarController != null) {
+            mLightBarController.dump(pw, args);
+        }
+
+        pw.println("SharedPreferences:");
+        for (Map.Entry<String, ?> entry : Prefs.getAll(mContext).entrySet()) {
+            pw.print("  "); pw.print(entry.getKey()); pw.print("="); pw.println(entry.getValue());
+        }
+
+        pw.println("Camera gesture intents:");
+        pw.println("   Insecure camera: " + CameraIntents.getInsecureCameraIntent(mContext));
+        pw.println("   Secure camera: " + CameraIntents.getSecureCameraIntent(mContext));
+        pw.println("   Override package: "
+                + CameraIntents.getOverrideCameraPackage(mContext));
+    }
+
+    @Override
+    public void createAndAddWindows(@Nullable RegisterStatusBarResult result) {
+        makeStatusBarView(result);
+        mNotificationShadeWindowController.attach();
+        mStatusBarWindowController.attach();
+    }
+
+    // called by makeStatusbar and also by PhoneStatusBarView
+    void updateDisplaySize() {
+        mDisplay.getMetrics(mDisplayMetrics);
+        mDisplay.getSize(mCurrentDisplaySize);
+        if (DEBUG_GESTURES) {
+            mGestureRec.tag("display",
+                    String.format("%dx%d", mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels));
+        }
+    }
+
+    @Override
+    public float getDisplayDensity() {
+        return mDisplayMetrics.density;
+    }
+
+    @Override
+    public float getDisplayWidth() {
+        return mDisplayMetrics.widthPixels;
+    }
+
+    @Override
+    public float getDisplayHeight() {
+        return mDisplayMetrics.heightPixels;
+    }
+
+    @Override
+    public int getRotation() {
+        return mDisplay.getRotation();
+    }
+
+    @Override
+    public int getDisplayId() {
+        return mDisplayId;
+    }
+
+    @Override
+    public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
+            boolean dismissShade, int flags) {
+        startActivityDismissingKeyguard(intent, onlyProvisioned, dismissShade,
+                false /* disallowEnterPictureInPictureWhileLaunching */, null /* callback */,
+                flags, null /* animationController */, getActivityUserHandle(intent));
+    }
+
+    @Override
+    public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
+            boolean dismissShade) {
+        startActivityDismissingKeyguard(intent, onlyProvisioned, dismissShade, 0);
+    }
+
+    @Override
+    public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
+            final boolean dismissShade, final boolean disallowEnterPictureInPictureWhileLaunching,
+            final Callback callback, int flags,
+            @Nullable ActivityLaunchAnimator.Controller animationController,
+            final UserHandle userHandle) {
+        if (onlyProvisioned && !mDeviceProvisionedController.isDeviceProvisioned()) return;
+
+        final boolean willLaunchResolverActivity =
+                mActivityIntentHelper.wouldLaunchResolverActivity(intent,
+                        mLockscreenUserManager.getCurrentUserId());
+
+        boolean animate =
+                animationController != null && !willLaunchResolverActivity && shouldAnimateLaunch(
+                        true /* isActivityIntent */);
+        ActivityLaunchAnimator.Controller animController =
+                animationController != null ? wrapAnimationController(animationController,
+                        dismissShade) : null;
+
+        // If we animate, we will dismiss the shade only once the animation is done. This is taken
+        // care of by the StatusBarLaunchAnimationController.
+        boolean dismissShadeDirectly = dismissShade && animController == null;
+
+        Runnable runnable = () -> {
+            mAssistManagerLazy.get().hideAssist();
+            intent.setFlags(
+                    Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+            intent.addFlags(flags);
+            int[] result = new int[]{ActivityManager.START_CANCELED};
+
+            mActivityLaunchAnimator.startIntentWithAnimation(animController,
+                    animate, intent.getPackage(), (adapter) -> {
+                        ActivityOptions options = new ActivityOptions(
+                                CentralSurfaces.getActivityOptions(mDisplayId, adapter));
+                        options.setDisallowEnterPictureInPictureWhileLaunching(
+                                disallowEnterPictureInPictureWhileLaunching);
+                        if (CameraIntents.isInsecureCameraIntent(intent)) {
+                            // Normally an activity will set it's requested rotation
+                            // animation on its window. However when launching an activity
+                            // causes the orientation to change this is too late. In these cases
+                            // the default animation is used. This doesn't look good for
+                            // the camera (as it rotates the camera contents out of sync
+                            // with physical reality). So, we ask the WindowManager to
+                            // force the crossfade animation if an orientation change
+                            // happens to occur during the launch.
+                            options.setRotationAnimationHint(
+                                    WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS);
+                        }
+                        if (Settings.Panel.ACTION_VOLUME.equals(intent.getAction())) {
+                            // Settings Panel is implemented as activity(not a dialog), so
+                            // underlying app is paused and may enter picture-in-picture mode
+                            // as a result.
+                            // So we need to disable picture-in-picture mode here
+                            // if it is volume panel.
+                            options.setDisallowEnterPictureInPictureWhileLaunching(true);
+                        }
+
+                        try {
+                            result[0] = ActivityTaskManager.getService().startActivityAsUser(
+                                    null, mContext.getBasePackageName(),
+                                    mContext.getAttributionTag(),
+                                    intent,
+                                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
+                                    null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null,
+                                    options.toBundle(), userHandle.getIdentifier());
+                        } catch (RemoteException e) {
+                            Log.w(TAG, "Unable to start activity", e);
+                        }
+                        return result[0];
+                    });
+
+            if (callback != null) {
+                callback.onActivityStarted(result[0]);
+            }
+        };
+        Runnable cancelRunnable = () -> {
+            if (callback != null) {
+                callback.onActivityStarted(ActivityManager.START_CANCELED);
+            }
+        };
+        executeRunnableDismissingKeyguard(runnable, cancelRunnable, dismissShadeDirectly,
+                willLaunchResolverActivity, true /* deferred */, animate);
+    }
+
+    @Nullable
+    private ActivityLaunchAnimator.Controller wrapAnimationController(
+            ActivityLaunchAnimator.Controller animationController, boolean dismissShade) {
+        View rootView = animationController.getLaunchContainer().getRootView();
+
+        Optional<ActivityLaunchAnimator.Controller> controllerFromStatusBar =
+                mStatusBarWindowController.wrapAnimationControllerIfInStatusBar(
+                        rootView, animationController);
+        if (controllerFromStatusBar.isPresent()) {
+            return controllerFromStatusBar.get();
+        }
+
+        if (dismissShade) {
+            // If the view is not in the status bar, then we are animating a view in the shade.
+            // We have to make sure that we collapse it when the animation ends or is cancelled.
+            return new StatusBarLaunchAnimatorController(animationController, this,
+                    true /* isLaunchForActivity */);
+        }
+
+        return animationController;
+    }
+
+    @Override
+    public void readyForKeyguardDone() {
+        mStatusBarKeyguardViewManager.readyForKeyguardDone();
+    }
+
+    @Override
+    public void executeRunnableDismissingKeyguard(final Runnable runnable,
+            final Runnable cancelAction,
+            final boolean dismissShade,
+            final boolean afterKeyguardGone,
+            final boolean deferred) {
+        executeRunnableDismissingKeyguard(runnable, cancelAction, dismissShade, afterKeyguardGone,
+                deferred, false /* willAnimateOnKeyguard */);
+    }
+
+    @Override
+    public void executeRunnableDismissingKeyguard(final Runnable runnable,
+            final Runnable cancelAction,
+            final boolean dismissShade,
+            final boolean afterKeyguardGone,
+            final boolean deferred,
+            final boolean willAnimateOnKeyguard) {
+        OnDismissAction onDismissAction = new OnDismissAction() {
+            @Override
+            public boolean onDismiss() {
+                if (runnable != null) {
+                    if (mStatusBarKeyguardViewManager.isShowing()
+                            && mStatusBarKeyguardViewManager.isOccluded()) {
+                        mStatusBarKeyguardViewManager.addAfterKeyguardGoneRunnable(runnable);
+                    } else {
+                        mMainExecutor.execute(runnable);
+                    }
+                }
+                if (dismissShade) {
+                    if (mExpandedVisible && !mBouncerShowing) {
+                        mShadeController.animateCollapsePanels(
+                                CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
+                                true /* force */, true /* delayed*/);
+                    } else {
+
+                        // Do it after DismissAction has been processed to conserve the needed
+                        // ordering.
+                        mMainExecutor.execute(mShadeController::runPostCollapseRunnables);
+                    }
+                } else if (CentralSurfacesImpl.this.isInLaunchTransition()
+                        && mNotificationPanelViewController.isLaunchTransitionFinished()) {
+
+                    // We are not dismissing the shade, but the launch transition is already
+                    // finished,
+                    // so nobody will call readyForKeyguardDone anymore. Post it such that
+                    // keyguardDonePending gets called first.
+                    mMainExecutor.execute(mStatusBarKeyguardViewManager::readyForKeyguardDone);
+                }
+                return deferred;
+            }
+
+            @Override
+            public boolean willRunAnimationOnKeyguard() {
+                return willAnimateOnKeyguard;
+            }
+        };
+        dismissKeyguardThenExecute(onDismissAction, cancelAction, afterKeyguardGone);
+    }
+
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            Trace.beginSection("CentralSurfaces#onReceive");
+            if (DEBUG) Log.v(TAG, "onReceive: " + intent);
+            String action = intent.getAction();
+            String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
+            if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
+                KeyboardShortcuts.dismiss();
+                mRemoteInputManager.closeRemoteInputs();
+                if (mLockscreenUserManager.isCurrentProfile(getSendingUserId())) {
+                    int flags = CommandQueue.FLAG_EXCLUDE_NONE;
+                    if (reason != null) {
+                        if (reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
+                            flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
+                        }
+                        // Do not collapse notifications when starting dreaming if the notifications
+                        // shade is used for the screen off animation. It might require expanded
+                        // state for the scrims to be visible
+                        if (reason.equals(SYSTEM_DIALOG_REASON_DREAM)
+                                && mScreenOffAnimationController.shouldExpandNotifications()) {
+                            flags |= CommandQueue.FLAG_EXCLUDE_NOTIFICATION_PANEL;
+                        }
+                    }
+                    mShadeController.animateCollapsePanels(flags);
+                }
+            } else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
+                if (mNotificationShadeWindowController != null) {
+                    mNotificationShadeWindowController.setNotTouchable(false);
+                }
+                finishBarAnimations();
+                resetUserExpandedStates();
+            }
+            Trace.endSection();
+        }
+    };
+
+    private final BroadcastReceiver mDemoReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (DEBUG) Log.v(TAG, "onReceive: " + intent);
+            String action = intent.getAction();
+            if (ACTION_FAKE_ARTWORK.equals(action)) {
+                if (DEBUG_MEDIA_FAKE_ARTWORK) {
+                    mPresenter.updateMediaMetaData(true, true);
+                }
+            }
+        }
+    };
+
+    @Override
+    public void resetUserExpandedStates() {
+        mNotificationsController.resetUserExpandedStates();
+    }
+
+    private void executeWhenUnlocked(OnDismissAction action, boolean requiresShadeOpen,
+            boolean afterKeyguardGone) {
+        if (mStatusBarKeyguardViewManager.isShowing() && requiresShadeOpen) {
+            mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
+        }
+        dismissKeyguardThenExecute(action, null /* cancelAction */,
+                afterKeyguardGone /* afterKeyguardGone */);
+    }
+
+    protected void dismissKeyguardThenExecute(OnDismissAction action, boolean afterKeyguardGone) {
+        dismissKeyguardThenExecute(action, null /* cancelRunnable */, afterKeyguardGone);
+    }
+
+    @Override
+    public void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancelAction,
+            boolean afterKeyguardGone) {
+        if (mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_ASLEEP
+                && mKeyguardStateController.canDismissLockScreen()
+                && !mStatusBarStateController.leaveOpenOnKeyguardHide()
+                && mDozeServiceHost.isPulsing()) {
+            // Reuse the biometric wake-and-unlock transition if we dismiss keyguard from a pulse.
+            // TODO: Factor this transition out of BiometricUnlockController.
+            mBiometricUnlockController.startWakeAndUnlock(
+                    BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING);
+        }
+        if (mStatusBarKeyguardViewManager.isShowing()) {
+            mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction,
+                    afterKeyguardGone);
+        } else {
+            action.onDismiss();
+        }
+    }
+    /**
+     * Notify the shade controller that the current user changed
+     *
+     * @param newUserId userId of the new user
+     */
+    @Override
+    public void setLockscreenUser(int newUserId) {
+        if (mLockscreenWallpaper != null) {
+            mLockscreenWallpaper.setCurrentUser(newUserId);
+        }
+        mScrimController.setCurrentUser(newUserId);
+        if (mWallpaperSupported) {
+            mWallpaperChangedReceiver.onReceive(mContext, null);
+        }
+    }
+
+    /**
+     * Reload some of our resources when the configuration changes.
+     *
+     * We don't reload everything when the configuration changes -- we probably
+     * should, but getting that smooth is tough.  Someday we'll fix that.  In the
+     * meantime, just update the things that we know change.
+     */
+    void updateResources() {
+        // Update the quick setting tiles
+        if (mQSPanelController != null) {
+            mQSPanelController.updateResources();
+        }
+
+        if (mStatusBarWindowController != null) {
+            mStatusBarWindowController.refreshStatusBarHeight();
+        }
+
+        if (mNotificationPanelViewController != null) {
+            mNotificationPanelViewController.updateResources();
+        }
+        if (mBrightnessMirrorController != null) {
+            mBrightnessMirrorController.updateResources();
+        }
+        if (mStatusBarKeyguardViewManager != null) {
+            mStatusBarKeyguardViewManager.updateResources();
+        }
+
+        mPowerButtonReveal = new PowerButtonReveal(mContext.getResources().getDimensionPixelSize(
+                com.android.systemui.R.dimen.physical_power_button_center_screen_location_y));
+    }
+
+    // Visibility reporting
+    protected void handleVisibleToUserChanged(boolean visibleToUser) {
+        if (visibleToUser) {
+            handleVisibleToUserChangedImpl(visibleToUser);
+            mNotificationLogger.startNotificationLogging();
+        } else {
+            mNotificationLogger.stopNotificationLogging();
+            handleVisibleToUserChangedImpl(visibleToUser);
+        }
+    }
+
+    // Visibility reporting
+    void handleVisibleToUserChangedImpl(boolean visibleToUser) {
+        if (visibleToUser) {
+            /* The LEDs are turned off when the notification panel is shown, even just a little bit.
+             * See also CentralSurfaces.setPanelExpanded for another place where we attempt to do
+             * this.
+             */
+            boolean pinnedHeadsUp = mHeadsUpManager.hasPinnedHeadsUp();
+            boolean clearNotificationEffects =
+                    !mPresenter.isPresenterFullyCollapsed() &&
+                            (mState == StatusBarState.SHADE
+                                    || mState == StatusBarState.SHADE_LOCKED);
+            int notificationLoad = mNotificationsController.getActiveNotificationsCount();
+            if (pinnedHeadsUp && mPresenter.isPresenterFullyCollapsed()) {
+                notificationLoad = 1;
+            }
+            final int finalNotificationLoad = notificationLoad;
+            mUiBgExecutor.execute(() -> {
+                try {
+                    mBarService.onPanelRevealed(clearNotificationEffects,
+                            finalNotificationLoad);
+                } catch (RemoteException ex) {
+                    // Won't fail unless the world has ended.
+                }
+            });
+        } else {
+            mUiBgExecutor.execute(() -> {
+                try {
+                    mBarService.onPanelHidden();
+                } catch (RemoteException ex) {
+                    // Won't fail unless the world has ended.
+                }
+            });
+        }
+
+    }
+
+    private void logStateToEventlog() {
+        boolean isShowing = mStatusBarKeyguardViewManager.isShowing();
+        boolean isOccluded = mStatusBarKeyguardViewManager.isOccluded();
+        boolean isBouncerShowing = mStatusBarKeyguardViewManager.isBouncerShowing();
+        boolean isSecure = mKeyguardStateController.isMethodSecure();
+        boolean unlocked = mKeyguardStateController.canDismissLockScreen();
+        int stateFingerprint = getLoggingFingerprint(mState,
+                isShowing,
+                isOccluded,
+                isBouncerShowing,
+                isSecure,
+                unlocked);
+        if (stateFingerprint != mLastLoggedStateFingerprint) {
+            if (mStatusBarStateLog == null) {
+                mStatusBarStateLog = new LogMaker(MetricsEvent.VIEW_UNKNOWN);
+            }
+            mMetricsLogger.write(mStatusBarStateLog
+                    .setCategory(isBouncerShowing ? MetricsEvent.BOUNCER : MetricsEvent.LOCKSCREEN)
+                    .setType(isShowing ? MetricsEvent.TYPE_OPEN : MetricsEvent.TYPE_CLOSE)
+                    .setSubtype(isSecure ? 1 : 0));
+            EventLogTags.writeSysuiStatusBarState(mState,
+                    isShowing ? 1 : 0,
+                    isOccluded ? 1 : 0,
+                    isBouncerShowing ? 1 : 0,
+                    isSecure ? 1 : 0,
+                    unlocked ? 1 : 0);
+            mLastLoggedStateFingerprint = stateFingerprint;
+
+            StringBuilder uiEventValueBuilder = new StringBuilder();
+            uiEventValueBuilder.append(isBouncerShowing ? "BOUNCER" : "LOCKSCREEN");
+            uiEventValueBuilder.append(isShowing ? "_OPEN" : "_CLOSE");
+            uiEventValueBuilder.append(isSecure ? "_SECURE" : "_INSECURE");
+            sUiEventLogger.log(StatusBarUiEvent.valueOf(uiEventValueBuilder.toString()));
+        }
+    }
+
+    /**
+     * Returns a fingerprint of fields logged to eventlog
+     */
+    private static int getLoggingFingerprint(int statusBarState, boolean keyguardShowing,
+            boolean keyguardOccluded, boolean bouncerShowing, boolean secure,
+            boolean currentlyInsecure) {
+        // Reserve 8 bits for statusBarState. We'll never go higher than
+        // that, right? Riiiight.
+        return (statusBarState & 0xFF)
+                | ((keyguardShowing   ? 1 : 0) <<  8)
+                | ((keyguardOccluded  ? 1 : 0) <<  9)
+                | ((bouncerShowing    ? 1 : 0) << 10)
+                | ((secure            ? 1 : 0) << 11)
+                | ((currentlyInsecure ? 1 : 0) << 12);
+    }
+
+    @Override
+    public void postQSRunnableDismissingKeyguard(final Runnable runnable) {
+        mMainExecutor.execute(() -> {
+            mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
+            executeRunnableDismissingKeyguard(
+                    () -> mMainExecutor.execute(runnable), null, false, false, false);
+        });
+    }
+
+    @Override
+    public void postStartActivityDismissingKeyguard(PendingIntent intent) {
+        postStartActivityDismissingKeyguard(intent, null /* animationController */);
+    }
+
+    @Override
+    public void postStartActivityDismissingKeyguard(final PendingIntent intent,
+            @Nullable ActivityLaunchAnimator.Controller animationController) {
+        mMainExecutor.execute(() -> startPendingIntentDismissingKeyguard(intent,
+                null /* intentSentUiThreadCallback */, animationController));
+    }
+
+    @Override
+    public void postStartActivityDismissingKeyguard(final Intent intent, int delay) {
+        postStartActivityDismissingKeyguard(intent, delay, null /* animationController */);
+    }
+
+    @Override
+    public void postStartActivityDismissingKeyguard(Intent intent, int delay,
+            @Nullable ActivityLaunchAnimator.Controller animationController) {
+        mMainExecutor.executeDelayed(
+                () ->
+                        startActivityDismissingKeyguard(intent, true /* onlyProvisioned */,
+                                true /* dismissShade */,
+                                false /* disallowEnterPictureInPictureWhileLaunching */,
+                                null /* callback */,
+                                0 /* flags */,
+                                animationController,
+                                getActivityUserHandle(intent)),
+                delay);
+    }
+
+    @Override
+    public void showKeyguard() {
+        mStatusBarStateController.setKeyguardRequested(true);
+        mStatusBarStateController.setLeaveOpenOnKeyguardHide(false);
+        updateIsKeyguard();
+        mAssistManagerLazy.get().onLockscreenShown();
+    }
+
+    @Override
+    public boolean hideKeyguard() {
+        mStatusBarStateController.setKeyguardRequested(false);
+        return updateIsKeyguard();
+    }
+
+    @Override
+    public boolean updateIsKeyguard() {
+        return updateIsKeyguard(false /* forceStateChange */);
+    }
+
+    @Override
+    public boolean updateIsKeyguard(boolean forceStateChange) {
+        boolean wakeAndUnlocking = mBiometricUnlockController.isWakeAndUnlock();
+
+        // For dozing, keyguard needs to be shown whenever the device is non-interactive. Otherwise
+        // there's no surface we can show to the user. Note that the device goes fully interactive
+        // late in the transition, so we also allow the device to start dozing once the screen has
+        // turned off fully.
+        boolean keyguardForDozing = mDozeServiceHost.getDozingRequested()
+                && (!mDeviceInteractive || (isGoingToSleep()
+                    && (isScreenFullyOff()
+                        || (mKeyguardStateController.isShowing() && !isOccluded()))));
+        boolean isWakingAndOccluded = isOccluded() && isWakingOrAwake();
+        boolean shouldBeKeyguard = (mStatusBarStateController.isKeyguardRequested()
+                || keyguardForDozing) && !wakeAndUnlocking && !isWakingAndOccluded;
+        if (keyguardForDozing) {
+            updatePanelExpansionForKeyguard();
+        }
+        if (shouldBeKeyguard) {
+            if (mScreenOffAnimationController.isKeyguardShowDelayed()
+                    || (isGoingToSleep()
+                    && mScreenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_TURNING_OFF)) {
+                // Delay showing the keyguard until screen turned off.
+            } else {
+                showKeyguardImpl();
+            }
+        } else {
+            // During folding a foldable device this might be called as a result of
+            // 'onScreenTurnedOff' call for the inner display.
+            // In this case:
+            //  * When phone is locked on folding: it doesn't make sense to hide keyguard as it
+            //    will be immediately locked again
+            //  * When phone is unlocked: we still don't want to execute hiding of the keyguard
+            //    as the animation could prepare 'fake AOD' interface (without actually
+            //    transitioning to keyguard state) and this might reset the view states
+            if (!mScreenOffAnimationController.isKeyguardHideDelayed()) {
+                return hideKeyguardImpl(forceStateChange);
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public void showKeyguardImpl() {
+        Trace.beginSection("CentralSurfaces#showKeyguard");
+        if (mKeyguardStateController.isLaunchTransitionFadingAway()) {
+            mNotificationPanelViewController.cancelAnimation();
+            onLaunchTransitionFadingEnded();
+        }
+        mMessageRouter.cancelMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
+        if (!mLockscreenShadeTransitionController.isWakingToShadeLocked()) {
+            mStatusBarStateController.setState(StatusBarState.KEYGUARD);
+        }
+        updatePanelExpansionForKeyguard();
+        Trace.endSection();
+    }
+
+    private void updatePanelExpansionForKeyguard() {
+        if (mState == StatusBarState.KEYGUARD && mBiometricUnlockController.getMode()
+                != BiometricUnlockController.MODE_WAKE_AND_UNLOCK && !mBouncerShowing) {
+            mShadeController.instantExpandNotificationsPanel();
+        }
+    }
+
+    private void onLaunchTransitionFadingEnded() {
+        mNotificationPanelViewController.resetAlpha();
+        mNotificationPanelViewController.onAffordanceLaunchEnded();
+        releaseGestureWakeLock();
+        runLaunchTransitionEndRunnable();
+        mKeyguardStateController.setLaunchTransitionFadingAway(false);
+        mPresenter.updateMediaMetaData(true /* metaDataChanged */, true);
+    }
+
+    @Override
+    public boolean isInLaunchTransition() {
+        return mNotificationPanelViewController.isLaunchTransitionRunning()
+                || mNotificationPanelViewController.isLaunchTransitionFinished();
+    }
+
+    /**
+     * Fades the content of the keyguard away after the launch transition is done.
+     *
+     * @param beforeFading the runnable to be run when the circle is fully expanded and the fading
+     *                     starts
+     * @param endRunnable the runnable to be run when the transition is done. Will not run
+     *                    if the transition is cancelled, instead cancelRunnable will run
+     * @param cancelRunnable the runnable to be run if the transition is cancelled
+     */
+    @Override
+    public void fadeKeyguardAfterLaunchTransition(final Runnable beforeFading,
+            Runnable endRunnable, Runnable cancelRunnable) {
+        mMessageRouter.cancelMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
+        mLaunchTransitionEndRunnable = endRunnable;
+        mLaunchTransitionCancelRunnable = cancelRunnable;
+        Runnable hideRunnable = () -> {
+            mKeyguardStateController.setLaunchTransitionFadingAway(true);
+            if (beforeFading != null) {
+                beforeFading.run();
+            }
+            updateScrimController();
+            mPresenter.updateMediaMetaData(false, true);
+            mNotificationPanelViewController.resetAlpha();
+            mNotificationPanelViewController.fadeOut(
+                    FADE_KEYGUARD_START_DELAY, FADE_KEYGUARD_DURATION,
+                    this::onLaunchTransitionFadingEnded);
+            mCommandQueue.appTransitionStarting(mDisplayId, SystemClock.uptimeMillis(),
+                    LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION, true);
+        };
+        if (mNotificationPanelViewController.isLaunchTransitionRunning()) {
+            mNotificationPanelViewController.setLaunchTransitionEndRunnable(hideRunnable);
+        } else {
+            hideRunnable.run();
+        }
+    }
+
+    private void cancelAfterLaunchTransitionRunnables() {
+        if (mLaunchTransitionCancelRunnable != null) {
+            mLaunchTransitionCancelRunnable.run();
+        }
+        mLaunchTransitionEndRunnable = null;
+        mLaunchTransitionCancelRunnable = null;
+        mNotificationPanelViewController.setLaunchTransitionEndRunnable(null);
+    }
+
+    /**
+     * Fades the content of the Keyguard while we are dozing and makes it invisible when finished
+     * fading.
+     */
+    @Override
+    public void fadeKeyguardWhilePulsing() {
+        mNotificationPanelViewController.fadeOut(0, FADE_KEYGUARD_DURATION_PULSING,
+                ()-> {
+                hideKeyguard();
+                mStatusBarKeyguardViewManager.onKeyguardFadedAway();
+            }).start();
+    }
+
+    /**
+     * Plays the animation when an activity that was occluding Keyguard goes away.
+     */
+    @Override
+    public void animateKeyguardUnoccluding() {
+        mNotificationPanelViewController.setExpandedFraction(0f);
+        mCommandQueueCallbacks.animateExpandNotificationsPanel();
+        mScrimController.setUnocclusionAnimationRunning(true);
+    }
+
+    /**
+     * Starts the timeout when we try to start the affordances on Keyguard. We usually rely that
+     * Keyguard goes away via fadeKeyguardAfterLaunchTransition, however, that might not happen
+     * because the launched app crashed or something else went wrong.
+     */
+    @Override
+    public void startLaunchTransitionTimeout() {
+        mMessageRouter.sendMessageDelayed(
+                MSG_LAUNCH_TRANSITION_TIMEOUT, LAUNCH_TRANSITION_TIMEOUT_MS);
+    }
+
+    private void onLaunchTransitionTimeout() {
+        Log.w(TAG, "Launch transition: Timeout!");
+        mNotificationPanelViewController.onAffordanceLaunchEnded();
+        releaseGestureWakeLock();
+        mNotificationPanelViewController.resetViews(false /* animate */);
+    }
+
+    private void runLaunchTransitionEndRunnable() {
+        mLaunchTransitionCancelRunnable = null;
+        if (mLaunchTransitionEndRunnable != null) {
+            Runnable r = mLaunchTransitionEndRunnable;
+
+            // mLaunchTransitionEndRunnable might call showKeyguard, which would execute it again,
+            // which would lead to infinite recursion. Protect against it.
+            mLaunchTransitionEndRunnable = null;
+            r.run();
+        }
+    }
+
+    /**
+     * @return true if we would like to stay in the shade, false if it should go away entirely
+     */
+    @Override
+    public boolean hideKeyguardImpl(boolean forceStateChange) {
+        Trace.beginSection("CentralSurfaces#hideKeyguard");
+        boolean staying = mStatusBarStateController.leaveOpenOnKeyguardHide();
+        int previousState = mStatusBarStateController.getState();
+        if (!(mStatusBarStateController.setState(StatusBarState.SHADE, forceStateChange))) {
+            //TODO: StatusBarStateController should probably know about hiding the keyguard and
+            // notify listeners.
+
+            // If the state didn't change, we may still need to update public mode
+            mLockscreenUserManager.updatePublicMode();
+        }
+        if (mStatusBarStateController.leaveOpenOnKeyguardHide()) {
+            if (!mStatusBarStateController.isKeyguardRequested()) {
+                mStatusBarStateController.setLeaveOpenOnKeyguardHide(false);
+            }
+            long delay = mKeyguardStateController.calculateGoingToFullShadeDelay();
+            mLockscreenShadeTransitionController.onHideKeyguard(delay, previousState);
+
+            // Disable layout transitions in navbar for this transition because the load is just
+            // too heavy for the CPU and GPU on any device.
+            mNavigationBarController.disableAnimationsDuringHide(mDisplayId, delay);
+        } else if (!mNotificationPanelViewController.isCollapsing()) {
+            instantCollapseNotificationPanel();
+        }
+
+        // Keyguard state has changed, but QS is not listening anymore. Make sure to update the tile
+        // visibilities so next time we open the panel we know the correct height already.
+        if (mQSPanelController != null) {
+            mQSPanelController.refreshAllTiles();
+        }
+        mMessageRouter.cancelMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
+        releaseGestureWakeLock();
+        mNotificationPanelViewController.onAffordanceLaunchEnded();
+        mNotificationPanelViewController.resetAlpha();
+        mNotificationPanelViewController.resetTranslation();
+        mNotificationPanelViewController.resetViewGroupFade();
+        updateDozingState();
+        updateScrimController();
+        Trace.endSection();
+        return staying;
+    }
+
+    private void releaseGestureWakeLock() {
+        if (mGestureWakeLock.isHeld()) {
+            mGestureWakeLock.release();
+        }
+    }
+
+    /**
+     * Notifies the status bar that Keyguard is going away very soon.
+     */
+    @Override
+    public void keyguardGoingAway() {
+        // Treat Keyguard exit animation as an app transition to achieve nice transition for status
+        // bar.
+        mKeyguardStateController.notifyKeyguardGoingAway(true);
+        mCommandQueue.appTransitionPending(mDisplayId, true /* forced */);
+        updateScrimController();
+    }
+
+    /**
+     * Notifies the status bar the Keyguard is fading away with the specified timings.
+     *  @param startTime the start time of the animations in uptime millis
+     * @param delay the precalculated animation delay in milliseconds
+     * @param fadeoutDuration the duration of the exit animation, in milliseconds
+     * @param isBypassFading is this a fading away animation while bypassing
+     */
+    @Override
+    public void setKeyguardFadingAway(long startTime, long delay, long fadeoutDuration,
+            boolean isBypassFading) {
+        mCommandQueue.appTransitionStarting(mDisplayId, startTime + fadeoutDuration
+                        - LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION,
+                LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION, true);
+        mCommandQueue.recomputeDisableFlags(mDisplayId, fadeoutDuration > 0 /* animate */);
+        mCommandQueue.appTransitionStarting(mDisplayId,
+                    startTime - LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION,
+                    LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION, true);
+        mKeyguardStateController.notifyKeyguardFadingAway(delay, fadeoutDuration, isBypassFading);
+    }
+
+    /**
+     * Notifies that the Keyguard fading away animation is done.
+     */
+    @Override
+    public void finishKeyguardFadingAway() {
+        mKeyguardStateController.notifyKeyguardDoneFading();
+        mScrimController.setExpansionAffectsAlpha(true);
+
+        // If the device was re-locked while unlocking, we might have a pending lock that was
+        // delayed because the keyguard was in the middle of going away.
+        mKeyguardViewMediator.maybeHandlePendingLock();
+    }
+
+    /**
+     * Switches theme from light to dark and vice-versa.
+     */
+    protected void updateTheme() {
+        // Set additional scrim only if the lock and system wallpaper are different to prevent
+        // applying the dimming effect twice.
+        mUiBgExecutor.execute(() -> {
+            float dimAmount = 0f;
+            if (mWallpaperManager.lockScreenWallpaperExists()) {
+                dimAmount = mWallpaperManager.getWallpaperDimAmount();
+            }
+            final float scrimDimAmount = dimAmount;
+            mMainExecutor.execute(() -> {
+                mScrimController.setAdditionalScrimBehindAlphaKeyguard(scrimDimAmount);
+                mScrimController.applyCompositeAlphaOnScrimBehindKeyguard();
+            });
+        });
+
+        // Lock wallpaper defines the color of the majority of the views, hence we'll use it
+        // to set our default theme.
+        final boolean lockDarkText = mColorExtractor.getNeutralColors().supportsDarkText();
+        final int themeResId = lockDarkText ? R.style.Theme_SystemUI_LightWallpaper
+                : R.style.Theme_SystemUI;
+        if (mContext.getThemeResId() != themeResId) {
+            mContext.setTheme(themeResId);
+            mConfigurationController.notifyThemeChanged();
+        }
+    }
+
+    private void updateDozingState() {
+        Trace.traceCounter(Trace.TRACE_TAG_APP, "dozing", mDozing ? 1 : 0);
+        Trace.beginSection("CentralSurfaces#updateDozingState");
+
+        boolean visibleNotOccluded = mStatusBarKeyguardViewManager.isShowing()
+                && !mStatusBarKeyguardViewManager.isOccluded();
+        // If we're dozing and we'll be animating the screen off, the keyguard isn't currently
+        // visible but will be shortly for the animation, so we should proceed as if it's visible.
+        boolean visibleNotOccludedOrWillBe =
+                visibleNotOccluded || (mDozing && mDozeParameters.shouldDelayKeyguardShow());
+
+        boolean wakeAndUnlock = mBiometricUnlockController.getMode()
+                == BiometricUnlockController.MODE_WAKE_AND_UNLOCK;
+        boolean animate = (!mDozing && mDozeServiceHost.shouldAnimateWakeup() && !wakeAndUnlock)
+                || (mDozing && mDozeParameters.shouldControlScreenOff()
+                && visibleNotOccludedOrWillBe);
+
+        mNotificationPanelViewController.setDozing(mDozing, animate, mWakeUpTouchLocation);
+        updateQsExpansionEnabled();
+        Trace.endSection();
+    }
+
+    @Override
+    public void userActivity() {
+        if (mState == StatusBarState.KEYGUARD) {
+            mKeyguardViewMediatorCallback.userActivity();
+        }
+    }
+
+    @Override
+    public boolean interceptMediaKey(KeyEvent event) {
+        return mState == StatusBarState.KEYGUARD
+                && mStatusBarKeyguardViewManager.interceptMediaKey(event);
+    }
+
+    /**
+     * While IME is active and a BACK event is detected, check with
+     * {@link StatusBarKeyguardViewManager#dispatchBackKeyEventPreIme()} to see if the event
+     * should be handled before routing to IME, in order to prevent the user having to hit back
+     * twice to exit bouncer.
+     */
+    @Override
+    public boolean dispatchKeyEventPreIme(KeyEvent event) {
+        switch (event.getKeyCode()) {
+            case KeyEvent.KEYCODE_BACK:
+                if (mState == StatusBarState.KEYGUARD
+                        && mStatusBarKeyguardViewManager.dispatchBackKeyEventPreIme()) {
+                    return onBackPressed();
+                }
+        }
+        return false;
+    }
+
+    protected boolean shouldUnlockOnMenuPressed() {
+        return mDeviceInteractive && mState != StatusBarState.SHADE
+            && mStatusBarKeyguardViewManager.shouldDismissOnMenuPressed();
+    }
+
+    @Override
+    public boolean onMenuPressed() {
+        if (shouldUnlockOnMenuPressed()) {
+            mShadeController.animateCollapsePanels(
+                    CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL /* flags */, true /* force */);
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void endAffordanceLaunch() {
+        releaseGestureWakeLock();
+        mNotificationPanelViewController.onAffordanceLaunchEnded();
+    }
+
+    @Override
+    public boolean onBackPressed() {
+        final boolean isScrimmedBouncer =
+                mScrimController.getState() == ScrimState.BOUNCER_SCRIMMED;
+        final boolean isBouncerOverDream = isBouncerShowingOverDream();
+
+        if (mStatusBarKeyguardViewManager.onBackPressed(
+                isScrimmedBouncer || isBouncerOverDream /* hideImmediately */)) {
+            if (isScrimmedBouncer || isBouncerOverDream) {
+                mStatusBarStateController.setLeaveOpenOnKeyguardHide(false);
+            } else {
+                mNotificationPanelViewController.expandWithoutQs();
+            }
+            return true;
+        }
+        if (mNotificationPanelViewController.isQsCustomizing()) {
+            mNotificationPanelViewController.closeQsCustomizer();
+            return true;
+        }
+        if (mNotificationPanelViewController.isQsExpanded()) {
+            if (mNotificationPanelViewController.isQsDetailShowing()) {
+                mNotificationPanelViewController.closeQsDetail();
+            } else {
+                mNotificationPanelViewController.animateCloseQs(false /* animateAway */);
+            }
+            return true;
+        }
+        if (mNotificationPanelViewController.closeUserSwitcherIfOpen()) {
+            return true;
+        }
+        if (mState != StatusBarState.KEYGUARD && mState != StatusBarState.SHADE_LOCKED
+                && !isBouncerOverDream) {
+            if (mNotificationPanelViewController.canPanelBeCollapsed()) {
+                mShadeController.animateCollapsePanels();
+            }
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean onSpacePressed() {
+        if (mDeviceInteractive && mState != StatusBarState.SHADE) {
+            mShadeController.animateCollapsePanels(
+                    CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL /* flags */, true /* force */);
+            return true;
+        }
+        return false;
+    }
+
+    private void showBouncerOrLockScreenIfKeyguard() {
+        // If the keyguard is animating away, we aren't really the keyguard anymore and should not
+        // show the bouncer/lockscreen.
+        if (!mKeyguardViewMediator.isHiding()
+                && !mKeyguardUnlockAnimationController.isPlayingCannedUnlockAnimation()) {
+            if (mState == StatusBarState.SHADE_LOCKED
+                    && mKeyguardUpdateMonitor.isUdfpsEnrolled()) {
+                // shade is showing while locked on the keyguard, so go back to showing the
+                // lock screen where users can use the UDFPS affordance to enter the device
+                mStatusBarKeyguardViewManager.reset(true);
+            } else if ((mState == StatusBarState.KEYGUARD
+                    && !mStatusBarKeyguardViewManager.bouncerIsOrWillBeShowing())
+                    || mState == StatusBarState.SHADE_LOCKED) {
+                mStatusBarKeyguardViewManager.showGenericBouncer(true /* scrimmed */);
+            }
+        }
+    }
+
+    /**
+     * Show the bouncer if we're currently on the keyguard or shade locked and aren't hiding.
+     * @param performAction the action to perform when the bouncer is dismissed.
+     * @param cancelAction the action to perform when unlock is aborted.
+     */
+    @Override
+    public void showBouncerWithDimissAndCancelIfKeyguard(OnDismissAction performAction,
+            Runnable cancelAction) {
+        if ((mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)
+                && !mKeyguardViewMediator.isHiding()) {
+            mStatusBarKeyguardViewManager.dismissWithAction(performAction, cancelAction,
+                    false /* afterKeyguardGone */);
+        } else if (cancelAction != null) {
+            cancelAction.run();
+        }
+    }
+
+    @Override
+    public void instantCollapseNotificationPanel() {
+        mNotificationPanelViewController.instantCollapse();
+        mShadeController.runPostCollapseRunnables();
+    }
+
+    /**
+     * Collapse the panel directly if we are on the main thread, post the collapsing on the main
+     * thread if we are not.
+     */
+    @Override
+    public void collapsePanelOnMainThread() {
+        if (Looper.getMainLooper().isCurrentThread()) {
+            mShadeController.collapsePanel();
+        } else {
+            mContext.getMainExecutor().execute(mShadeController::collapsePanel);
+        }
+    }
+
+    /** Collapse the panel. The collapsing will be animated for the given {@code duration}. */
+    @Override
+    public void collapsePanelWithDuration(int duration) {
+        mNotificationPanelViewController.collapseWithDuration(duration);
+    }
+
+    /**
+     * Updates the light reveal effect to reflect the reason we're waking or sleeping (for example,
+     * from the power button).
+     * @param wakingUp Whether we're updating because we're waking up (true) or going to sleep
+     *                 (false).
+     */
+    private void updateRevealEffect(boolean wakingUp) {
+        if (mLightRevealScrim == null) {
+            return;
+        }
+
+        final boolean wakingUpFromPowerButton = wakingUp
+                && !(mLightRevealScrim.getRevealEffect() instanceof CircleReveal)
+                && mWakefulnessLifecycle.getLastWakeReason()
+                == PowerManager.WAKE_REASON_POWER_BUTTON;
+        final boolean sleepingFromPowerButton = !wakingUp
+                && mWakefulnessLifecycle.getLastSleepReason()
+                == PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON;
+
+        if (wakingUpFromPowerButton || sleepingFromPowerButton) {
+            mLightRevealScrim.setRevealEffect(mPowerButtonReveal);
+            mLightRevealScrim.setRevealAmount(1f - mStatusBarStateController.getDozeAmount());
+        } else if (!wakingUp || !(mLightRevealScrim.getRevealEffect() instanceof CircleReveal)) {
+            // If we're going to sleep, but it's not from the power button, use the default reveal.
+            // If we're waking up, only use the default reveal if the biometric controller didn't
+            // already set it to the circular reveal because we're waking up from a fingerprint/face
+            // auth.
+            mLightRevealScrim.setRevealEffect(LiftReveal.INSTANCE);
+            mLightRevealScrim.setRevealAmount(1f - mStatusBarStateController.getDozeAmount());
+        }
+    }
+
+    @Override
+    public LightRevealScrim getLightRevealScrim() {
+        return mLightRevealScrim;
+    }
+
+    @Override
+    public void onTrackingStarted() {
+        mShadeController.runPostCollapseRunnables();
+    }
+
+    @Override
+    public void onClosingFinished() {
+        mShadeController.runPostCollapseRunnables();
+        if (!mPresenter.isPresenterFullyCollapsed()) {
+            // if we set it not to be focusable when collapsing, we have to undo it when we aborted
+            // the closing
+            mNotificationShadeWindowController.setNotificationShadeFocusable(true);
+        }
+    }
+
+    @Override
+    public void onUnlockHintStarted() {
+        mFalsingCollector.onUnlockHintStarted();
+        mKeyguardIndicationController.showActionToUnlock();
+    }
+
+    @Override
+    public void onHintFinished() {
+        // Delay the reset a bit so the user can read the text.
+        mKeyguardIndicationController.hideTransientIndicationDelayed(HINT_RESET_DELAY_MS);
+    }
+
+    @Override
+    public void onCameraHintStarted() {
+        mFalsingCollector.onCameraHintStarted();
+        mKeyguardIndicationController.showTransientIndication(R.string.camera_hint);
+    }
+
+    @Override
+    public void onVoiceAssistHintStarted() {
+        mFalsingCollector.onLeftAffordanceHintStarted();
+        mKeyguardIndicationController.showTransientIndication(R.string.voice_hint);
+    }
+
+    @Override
+    public void onPhoneHintStarted() {
+        mFalsingCollector.onLeftAffordanceHintStarted();
+        mKeyguardIndicationController.showTransientIndication(R.string.phone_hint);
+    }
+
+    @Override
+    public void onTrackingStopped(boolean expand) {
+        if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
+            if (!expand && !mKeyguardStateController.canDismissLockScreen()) {
+                mStatusBarKeyguardViewManager.showBouncer(false /* scrimmed */);
+            }
+        }
+    }
+
+    // TODO: Figure out way to remove these.
+    @Override
+    public NavigationBarView getNavigationBarView() {
+        return mNavigationBarController.getNavigationBarView(mDisplayId);
+    }
+
+    @Override
+    public boolean isOverviewEnabled() {
+        return mNavigationBarController.isOverviewEnabled(mDisplayId);
+    }
+
+    @Override
+    public void showPinningEnterExitToast(boolean entering) {
+        mNavigationBarController.showPinningEnterExitToast(mDisplayId, entering);
+    }
+
+    @Override
+    public void showPinningEscapeToast() {
+        mNavigationBarController.showPinningEscapeToast(mDisplayId);
+    }
+
+    /**
+     * TODO: Remove this method. Views should not be passed forward. Will cause theme issues.
+     * @return bottom area view
+     */
+    @Override
+    public KeyguardBottomAreaView getKeyguardBottomAreaView() {
+        return mNotificationPanelViewController.getKeyguardBottomAreaView();
+    }
+
+    /**
+     * Propagation of the bouncer state, indicating that it's fully visible.
+     */
+    @Override
+    public void setBouncerShowing(boolean bouncerShowing) {
+        mBouncerShowing = bouncerShowing;
+        mKeyguardBypassController.setBouncerShowing(bouncerShowing);
+        mPulseExpansionHandler.setBouncerShowing(bouncerShowing);
+        setBouncerShowingForStatusBarComponents(bouncerShowing);
+        mStatusBarHideIconsForBouncerManager.setBouncerShowingAndTriggerUpdate(bouncerShowing);
+        mCommandQueue.recomputeDisableFlags(mDisplayId, true /* animate */);
+        updateScrimController();
+        if (!mBouncerShowing) {
+            updatePanelExpansionForKeyguard();
+        }
+    }
+
+    /**
+     * Sets whether the bouncer over dream is showing. Note that the bouncer over dream is handled
+     * independently of the rest of the notification panel. As a result, setting this state via
+     * {@link #setBouncerShowing(boolean)} leads to unintended side effects from states modified
+     * behind the dream.
+     */
+    @Override
+    public void setBouncerShowingOverDream(boolean bouncerShowingOverDream) {
+        mBouncerShowingOverDream = bouncerShowingOverDream;
+    }
+
+    /**
+     * Propagate the bouncer state to status bar components.
+     *
+     * Separate from {@link #setBouncerShowing} because we sometimes re-create the status bar and
+     * should update only the status bar components.
+     */
+    private void setBouncerShowingForStatusBarComponents(boolean bouncerShowing) {
+        int importance = bouncerShowing
+                ? IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
+                : IMPORTANT_FOR_ACCESSIBILITY_AUTO;
+        if (mPhoneStatusBarViewController != null) {
+            mPhoneStatusBarViewController.setImportantForAccessibility(importance);
+        }
+        mNotificationPanelViewController.setImportantForAccessibility(importance);
+        mNotificationPanelViewController.setBouncerShowing(bouncerShowing);
+    }
+
+    /**
+     * Collapses the notification shade if it is tracking or expanded.
+     */
+    @Override
+    public void collapseShade() {
+        if (mNotificationPanelViewController.isTracking()) {
+            mNotificationShadeWindowViewController.cancelCurrentTouch();
+        }
+        if (mPanelExpanded && mState == StatusBarState.SHADE) {
+            mShadeController.animateCollapsePanels();
+        }
+    }
+
+    @VisibleForTesting
+    final WakefulnessLifecycle.Observer mWakefulnessObserver = new WakefulnessLifecycle.Observer() {
+        @Override
+        public void onFinishedGoingToSleep() {
+            mNotificationPanelViewController.onAffordanceLaunchEnded();
+            releaseGestureWakeLock();
+            mLaunchCameraWhenFinishedWaking = false;
+            mDeviceInteractive = false;
+            mWakeUpComingFromTouch = false;
+            mWakeUpTouchLocation = null;
+            updateVisibleToUser();
+
+            updateNotificationPanelTouchState();
+            mNotificationShadeWindowViewController.cancelCurrentTouch();
+            if (mLaunchCameraOnFinishedGoingToSleep) {
+                mLaunchCameraOnFinishedGoingToSleep = false;
+
+                // This gets executed before we will show Keyguard, so post it in order that the state
+                // is correct.
+                mMainExecutor.execute(() -> mCommandQueueCallbacks.onCameraLaunchGestureDetected(
+                        mLastCameraLaunchSource));
+            }
+
+            if (mLaunchEmergencyActionOnFinishedGoingToSleep) {
+                mLaunchEmergencyActionOnFinishedGoingToSleep = false;
+
+                // This gets executed before we will show Keyguard, so post it in order that the
+                // state is correct.
+                mMainExecutor.execute(
+                        () -> mCommandQueueCallbacks.onEmergencyActionLaunchGestureDetected());
+            }
+            updateIsKeyguard();
+        }
+
+        @Override
+        public void onStartedGoingToSleep() {
+            String tag = "CentralSurfaces#onStartedGoingToSleep";
+            DejankUtils.startDetectingBlockingIpcs(tag);
+
+            //  cancel stale runnables that could put the device in the wrong state
+            cancelAfterLaunchTransitionRunnables();
+
+            updateRevealEffect(false /* wakingUp */);
+            updateNotificationPanelTouchState();
+            maybeEscalateHeadsUp();
+            dismissVolumeDialog();
+            mWakeUpCoordinator.setFullyAwake(false);
+            mKeyguardBypassController.onStartedGoingToSleep();
+
+            // The unlocked screen off and fold to aod animations might use our LightRevealScrim -
+            // we need to be expanded for it to be visible.
+            if (mDozeParameters.shouldShowLightRevealScrim()) {
+                makeExpandedVisible(true);
+            }
+
+            DejankUtils.stopDetectingBlockingIpcs(tag);
+        }
+
+        @Override
+        public void onStartedWakingUp() {
+            String tag = "CentralSurfaces#onStartedWakingUp";
+            DejankUtils.startDetectingBlockingIpcs(tag);
+            mNotificationShadeWindowController.batchApplyWindowLayoutParams(()-> {
+                mDeviceInteractive = true;
+                mWakeUpCoordinator.setWakingUp(true);
+                if (!mKeyguardBypassController.getBypassEnabled()) {
+                    mHeadsUpManager.releaseAllImmediately();
+                }
+                updateVisibleToUser();
+                updateIsKeyguard();
+                mDozeServiceHost.stopDozing();
+                // This is intentionally below the stopDozing call above, since it avoids that we're
+                // unnecessarily animating the wakeUp transition. Animations should only be enabled
+                // once we fully woke up.
+                updateRevealEffect(true /* wakingUp */);
+                updateNotificationPanelTouchState();
+
+                // If we are waking up during the screen off animation, we should undo making the
+                // expanded visible (we did that so the LightRevealScrim would be visible).
+                if (mScreenOffAnimationController.shouldHideLightRevealScrimOnWakeUp()) {
+                    makeExpandedInvisible();
+                }
+
+            });
+            DejankUtils.stopDetectingBlockingIpcs(tag);
+        }
+
+        @Override
+        public void onFinishedWakingUp() {
+            mWakeUpCoordinator.setFullyAwake(true);
+            mWakeUpCoordinator.setWakingUp(false);
+            if (mLaunchCameraWhenFinishedWaking) {
+                mNotificationPanelViewController.launchCamera(
+                        false /* animate */, mLastCameraLaunchSource);
+                mLaunchCameraWhenFinishedWaking = false;
+            }
+            if (mLaunchEmergencyActionWhenFinishedWaking) {
+                mLaunchEmergencyActionWhenFinishedWaking = false;
+                Intent emergencyIntent = getEmergencyActionIntent();
+                if (emergencyIntent != null) {
+                    mContext.startActivityAsUser(emergencyIntent,
+                            getActivityUserHandle(emergencyIntent));
+                }
+            }
+            updateScrimController();
+        }
+    };
+
+    /**
+     * We need to disable touch events because these might
+     * collapse the panel after we expanded it, and thus we would end up with a blank
+     * Keyguard.
+     */
+    @Override
+    public void updateNotificationPanelTouchState() {
+        boolean goingToSleepWithoutAnimation = isGoingToSleep()
+                && !mDozeParameters.shouldControlScreenOff();
+        boolean disabled = (!mDeviceInteractive && !mDozeServiceHost.isPulsing())
+                || goingToSleepWithoutAnimation;
+        mNotificationPanelViewController.setTouchAndAnimationDisabled(disabled);
+        mNotificationIconAreaController.setAnimationsEnabled(!disabled);
+    }
+
+    final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() {
+        @Override
+        public void onScreenTurningOn(Runnable onDrawn) {
+            mFalsingCollector.onScreenTurningOn();
+            mNotificationPanelViewController.onScreenTurningOn();
+        }
+
+        @Override
+        public void onScreenTurnedOn() {
+            mScrimController.onScreenTurnedOn();
+        }
+
+        @Override
+        public void onScreenTurnedOff() {
+            Trace.beginSection("CentralSurfaces#onScreenTurnedOff");
+            mFalsingCollector.onScreenOff();
+            mScrimController.onScreenTurnedOff();
+            if (mCloseQsBeforeScreenOff) {
+                mNotificationPanelViewController.closeQs();
+                mCloseQsBeforeScreenOff = false;
+            }
+            updateIsKeyguard();
+            Trace.endSection();
+        }
+    };
+
+    @Override
+    public int getWakefulnessState() {
+        return mWakefulnessLifecycle.getWakefulness();
+    }
+
+    /**
+     * @return true if the screen is currently fully off, i.e. has finished turning off and has
+     * since not started turning on.
+     */
+    @Override
+    public boolean isScreenFullyOff() {
+        return mScreenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_OFF;
+    }
+
+    @Override
+    public void showScreenPinningRequest(int taskId, boolean allowCancel) {
+        mScreenPinningRequest.showPrompt(taskId, allowCancel);
+    }
+
+    @Nullable
+    @Override
+    public Intent getEmergencyActionIntent() {
+        Intent emergencyIntent = new Intent(EmergencyGesture.ACTION_LAUNCH_EMERGENCY);
+        PackageManager pm = mContext.getPackageManager();
+        List<ResolveInfo> emergencyActivities = pm.queryIntentActivities(emergencyIntent,
+                PackageManager.MATCH_SYSTEM_ONLY);
+        ResolveInfo resolveInfo = getTopEmergencySosInfo(emergencyActivities);
+        if (resolveInfo == null) {
+            Log.wtf(TAG, "Couldn't find an app to process the emergency intent.");
+            return null;
+        }
+        emergencyIntent.setComponent(new ComponentName(resolveInfo.activityInfo.packageName,
+                resolveInfo.activityInfo.name));
+        emergencyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        return emergencyIntent;
+    }
+
+    /**
+     * Select and return the "best" ResolveInfo for Emergency SOS Activity.
+     */
+    private @Nullable ResolveInfo getTopEmergencySosInfo(List<ResolveInfo> emergencyActivities) {
+        // No matched activity.
+        if (emergencyActivities == null || emergencyActivities.isEmpty()) {
+            return null;
+        }
+
+        // Of multiple matched Activities, give preference to the pre-set package name.
+        String preferredAppPackageName =
+                mContext.getString(R.string.config_preferredEmergencySosPackage);
+
+        // If there is no preferred app, then return first match.
+        if (TextUtils.isEmpty(preferredAppPackageName)) {
+            return emergencyActivities.get(0);
+        }
+
+        for (ResolveInfo emergencyInfo: emergencyActivities) {
+            // If activity is from the preferred app, use it.
+            if (TextUtils.equals(emergencyInfo.activityInfo.packageName, preferredAppPackageName)) {
+                return emergencyInfo;
+            }
+        }
+        // No matching activity: return first match
+        return emergencyActivities.get(0);
+    }
+
+    @Override
+    public boolean isCameraAllowedByAdmin() {
+        if (mDevicePolicyManager.getCameraDisabled(null,
+                mLockscreenUserManager.getCurrentUserId())) {
+            return false;
+        } else if (mStatusBarKeyguardViewManager == null
+                || (isKeyguardShowing() && isKeyguardSecure())) {
+            // Check if the admin has disabled the camera specifically for the keyguard
+            return (mDevicePolicyManager.getKeyguardDisabledFeatures(null,
+                    mLockscreenUserManager.getCurrentUserId())
+                    & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) == 0;
+        }
+        return true;
+    }
+
+    @Override
+    public boolean isGoingToSleep() {
+        return mWakefulnessLifecycle.getWakefulness()
+                == WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP;
+    }
+
+    boolean isWakingOrAwake() {
+        return mWakefulnessLifecycle.getWakefulness() == WakefulnessLifecycle.WAKEFULNESS_WAKING
+                || mWakefulnessLifecycle.getWakefulness() == WakefulnessLifecycle.WAKEFULNESS_AWAKE;
+    }
+
+    @Override
+    public void notifyBiometricAuthModeChanged() {
+        mDozeServiceHost.updateDozing();
+        updateScrimController();
+    }
+
+    /**
+     * Set the amount of progress we are currently in if we're transitioning to the full shade.
+     * 0.0f means we're not transitioning yet, while 1 means we're all the way in the full
+     * shade.
+     */
+    @Override
+    public void setTransitionToFullShadeProgress(float transitionToFullShadeProgress) {
+        mTransitionToFullShadeProgress = transitionToFullShadeProgress;
+    }
+
+    /**
+     * Sets the amount of progress to the bouncer being fully hidden/visible. 1 means the bouncer
+     * is fully hidden, while 0 means the bouncer is visible.
+     */
+    @Override
+    public void setBouncerHiddenFraction(float expansion) {
+        mScrimController.setBouncerHiddenFraction(expansion);
+    }
+
+    @Override
+    @VisibleForTesting
+    public void updateScrimController() {
+        Trace.beginSection("CentralSurfaces#updateScrimController");
+
+        boolean unlocking = mKeyguardStateController.isShowing() && (
+                mBiometricUnlockController.isWakeAndUnlock()
+                        || mKeyguardStateController.isKeyguardFadingAway()
+                        || mKeyguardStateController.isKeyguardGoingAway()
+                        || mKeyguardViewMediator.requestedShowSurfaceBehindKeyguard()
+                        || mKeyguardViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehind());
+
+        mScrimController.setExpansionAffectsAlpha(!unlocking);
+
+        boolean launchingAffordanceWithPreview =
+                mNotificationPanelViewController.isLaunchingAffordanceWithPreview();
+        mScrimController.setLaunchingAffordanceWithPreview(launchingAffordanceWithPreview);
+
+        if (mStatusBarKeyguardViewManager.isShowingAlternateAuth()) {
+            if (mState == StatusBarState.SHADE || mState == StatusBarState.SHADE_LOCKED
+                    || mTransitionToFullShadeProgress > 0f) {
+                mScrimController.transitionTo(ScrimState.AUTH_SCRIMMED_SHADE);
+            } else {
+                mScrimController.transitionTo(ScrimState.AUTH_SCRIMMED);
+            }
+        } else if (mBouncerShowing && !unlocking) {
+            // Bouncer needs the front scrim when it's on top of an activity,
+            // tapping on a notification, editing QS or being dismissed by
+            // FLAG_DISMISS_KEYGUARD_ACTIVITY.
+            ScrimState state = mStatusBarKeyguardViewManager.bouncerNeedsScrimming()
+                    ? ScrimState.BOUNCER_SCRIMMED : ScrimState.BOUNCER;
+            mScrimController.transitionTo(state);
+        } else if (launchingAffordanceWithPreview) {
+            // We want to avoid animating when launching with a preview.
+            mScrimController.transitionTo(ScrimState.UNLOCKED, mUnlockScrimCallback);
+        } else if (mBrightnessMirrorVisible) {
+            mScrimController.transitionTo(ScrimState.BRIGHTNESS_MIRROR);
+        } else if (mState == StatusBarState.SHADE_LOCKED) {
+            mScrimController.transitionTo(ScrimState.SHADE_LOCKED);
+        } else if (mDozeServiceHost.isPulsing()) {
+            mScrimController.transitionTo(ScrimState.PULSING,
+                    mDozeScrimController.getScrimCallback());
+        } else if (mDozeServiceHost.hasPendingScreenOffCallback()) {
+            mScrimController.transitionTo(ScrimState.OFF, new ScrimController.Callback() {
+                @Override
+                public void onFinished() {
+                    mDozeServiceHost.executePendingScreenOffCallback();
+                }
+            });
+        } else if (mDozing && !unlocking) {
+            mScrimController.transitionTo(ScrimState.AOD);
+        } else if (mKeyguardStateController.isShowing() && !isOccluded() && !unlocking) {
+            mScrimController.transitionTo(ScrimState.KEYGUARD);
+        } else if (mKeyguardStateController.isShowing() && mKeyguardUpdateMonitor.isDreaming()) {
+            mScrimController.transitionTo(ScrimState.DREAMING);
+        } else {
+            mScrimController.transitionTo(ScrimState.UNLOCKED, mUnlockScrimCallback);
+        }
+        updateLightRevealScrimVisibility();
+
+        Trace.endSection();
+    }
+
+    @Override
+    public boolean isKeyguardShowing() {
+        if (mStatusBarKeyguardViewManager == null) {
+            Slog.i(TAG, "isKeyguardShowing() called before startKeyguard(), returning true");
+            return true;
+        }
+        return mStatusBarKeyguardViewManager.isShowing();
+    }
+
+    @Override
+    public boolean shouldIgnoreTouch() {
+        return (mStatusBarStateController.isDozing()
+                && mDozeServiceHost.getIgnoreTouchWhilePulsing())
+                || mScreenOffAnimationController.shouldIgnoreKeyguardTouches();
+    }
+
+    // Begin Extra BaseStatusBar methods.
+
+    protected final CommandQueue mCommandQueue;
+    protected IStatusBarService mBarService;
+
+    // all notifications
+    protected NotificationStackScrollLayout mStackScroller;
+
+    // handling reordering
+    private final VisualStabilityManager mVisualStabilityManager;
+
+    protected AccessibilityManager mAccessibilityManager;
+
+    protected boolean mDeviceInteractive;
+
+    protected boolean mVisible;
+
+    // mScreenOnFromKeyguard && mVisible.
+    private boolean mVisibleToUser;
+
+    protected DevicePolicyManager mDevicePolicyManager;
+    private final PowerManager mPowerManager;
+    protected StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+
+    protected KeyguardManager mKeyguardManager;
+    private final DeviceProvisionedController mDeviceProvisionedController;
+
+    private final NavigationBarController mNavigationBarController;
+    private final AccessibilityFloatingMenuController mAccessibilityFloatingMenuController;
+
+    // UI-specific methods
+
+    protected WindowManager mWindowManager;
+    protected IWindowManager mWindowManagerService;
+    private IDreamManager mDreamManager;
+
+    protected Display mDisplay;
+    private int mDisplayId;
+
+    protected NotificationShelfController mNotificationShelfController;
+
+    private final Lazy<AssistManager> mAssistManagerLazy;
+
+    @Override
+    public boolean isDeviceInteractive() {
+        return mDeviceInteractive;
+    }
+
+    private final BroadcastReceiver mBannerActionBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (BANNER_ACTION_CANCEL.equals(action) || BANNER_ACTION_SETUP.equals(action)) {
+                NotificationManager noMan = (NotificationManager)
+                        mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+                noMan.cancel(com.android.internal.messages.nano.SystemMessageProto.SystemMessage.
+                        NOTE_HIDDEN_NOTIFICATIONS);
+
+                Settings.Secure.putInt(mContext.getContentResolver(),
+                        Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING, 0);
+                if (BANNER_ACTION_SETUP.equals(action)) {
+                    mShadeController.animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
+                            true /* force */);
+                    mContext.startActivity(new Intent(Settings.ACTION_APP_NOTIFICATION_REDACTION)
+                            .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+
+                    );
+                }
+            }
+        }
+    };
+
+    @Override
+    public void setNotificationSnoozed(StatusBarNotification sbn, SnoozeOption snoozeOption) {
+        mNotificationsController.setNotificationSnoozed(sbn, snoozeOption);
+    }
+
+
+    @Override
+    public void awakenDreams() {
+        mUiBgExecutor.execute(() -> {
+            try {
+                mDreamManager.awaken();
+            } catch (RemoteException e) {
+                e.printStackTrace();
+            }
+        });
+    }
+
+    protected void toggleKeyboardShortcuts(int deviceId) {
+        KeyboardShortcuts.toggle(mContext, deviceId);
+    }
+
+    protected void dismissKeyboardShortcuts() {
+        KeyboardShortcuts.dismiss();
+    }
+
+    /**
+     * Dismiss the keyguard then execute an action.
+     *
+     * @param action The action to execute after dismissing the keyguard.
+     * @param collapsePanel Whether we should collapse the panel after dismissing the keyguard.
+     * @param willAnimateOnKeyguard Whether {@param action} will run an animation on the keyguard if
+     *                              we are locked.
+     */
+    private void executeActionDismissingKeyguard(Runnable action, boolean afterKeyguardGone,
+            boolean collapsePanel, boolean willAnimateOnKeyguard) {
+        if (!mDeviceProvisionedController.isDeviceProvisioned()) return;
+
+        OnDismissAction onDismissAction = new OnDismissAction() {
+            @Override
+            public boolean onDismiss() {
+                new Thread(() -> {
+                    try {
+                        // The intent we are sending is for the application, which
+                        // won't have permission to immediately start an activity after
+                        // the user switches to home.  We know it is safe to do at this
+                        // point, so make sure new activity switches are now allowed.
+                        ActivityManager.getService().resumeAppSwitches();
+                    } catch (RemoteException e) {
+                    }
+                    action.run();
+                }).start();
+
+                return collapsePanel ? mShadeController.collapsePanel() : willAnimateOnKeyguard;
+            }
+
+            @Override
+            public boolean willRunAnimationOnKeyguard() {
+                return willAnimateOnKeyguard;
+            }
+        };
+        dismissKeyguardThenExecute(onDismissAction, afterKeyguardGone);
+    }
+
+    @Override
+    public void startPendingIntentDismissingKeyguard(final PendingIntent intent) {
+        startPendingIntentDismissingKeyguard(intent, null);
+    }
+
+    @Override
+    public void startPendingIntentDismissingKeyguard(
+            final PendingIntent intent, @Nullable final Runnable intentSentUiThreadCallback) {
+        startPendingIntentDismissingKeyguard(intent, intentSentUiThreadCallback,
+                (ActivityLaunchAnimator.Controller) null);
+    }
+
+    @Override
+    public void startPendingIntentDismissingKeyguard(PendingIntent intent,
+            Runnable intentSentUiThreadCallback, View associatedView) {
+        ActivityLaunchAnimator.Controller animationController = null;
+        if (associatedView instanceof ExpandableNotificationRow) {
+            animationController = mNotificationAnimationProvider.getAnimatorController(
+                    ((ExpandableNotificationRow) associatedView));
+        }
+
+        startPendingIntentDismissingKeyguard(intent, intentSentUiThreadCallback,
+                animationController);
+    }
+
+    @Override
+    public void startPendingIntentDismissingKeyguard(
+            final PendingIntent intent, @Nullable final Runnable intentSentUiThreadCallback,
+            @Nullable ActivityLaunchAnimator.Controller animationController) {
+        final boolean willLaunchResolverActivity = intent.isActivity()
+                && mActivityIntentHelper.wouldLaunchResolverActivity(intent.getIntent(),
+                mLockscreenUserManager.getCurrentUserId());
+
+        boolean animate = !willLaunchResolverActivity
+                && animationController != null
+                && shouldAnimateLaunch(intent.isActivity());
+
+        // If we animate, don't collapse the shade and defer the keyguard dismiss (in case we run
+        // the animation on the keyguard). The animation will take care of (instantly) collapsing
+        // the shade and hiding the keyguard once it is done.
+        boolean collapse = !animate;
+        executeActionDismissingKeyguard(() -> {
+            try {
+                // We wrap animationCallback with a StatusBarLaunchAnimatorController so that the
+                // shade is collapsed after the animation (or when it is cancelled, aborted, etc).
+                ActivityLaunchAnimator.Controller controller =
+                        animationController != null ? new StatusBarLaunchAnimatorController(
+                                animationController, this, intent.isActivity()) : null;
+
+                mActivityLaunchAnimator.startPendingIntentWithAnimation(
+                        controller, animate, intent.getCreatorPackage(),
+                        (animationAdapter) -> {
+                            ActivityOptions options = new ActivityOptions(
+                                    CentralSurfaces.getActivityOptions(
+                                            mDisplayId, animationAdapter));
+                            // TODO b/221255671: restrict this to only be set for notifications
+                            options.setEligibleForLegacyPermissionPrompt(true);
+                            return intent.sendAndReturnResult(null, 0, null, null, null,
+                                    null, options.toBundle());
+                        });
+            } catch (PendingIntent.CanceledException e) {
+                // the stack trace isn't very helpful here.
+                // Just log the exception message.
+                Log.w(TAG, "Sending intent failed: " + e);
+                if (!collapse) {
+                    // executeActionDismissingKeyguard did not collapse for us already.
+                    collapsePanelOnMainThread();
+                }
+                // TODO: Dismiss Keyguard.
+            }
+            if (intent.isActivity()) {
+                mAssistManagerLazy.get().hideAssist();
+            }
+            if (intentSentUiThreadCallback != null) {
+                postOnUiThread(intentSentUiThreadCallback);
+            }
+        }, willLaunchResolverActivity, collapse, animate);
+    }
+
+    private void postOnUiThread(Runnable runnable) {
+        mMainExecutor.execute(runnable);
+    }
+
+    @Override
+    public void visibilityChanged(boolean visible) {
+        if (mVisible != visible) {
+            mVisible = visible;
+            if (!visible) {
+                mGutsManager.closeAndSaveGuts(true /* removeLeavebehind */, true /* force */,
+                        true /* removeControls */, -1 /* x */, -1 /* y */, true /* resetMenu */);
+            }
+        }
+        updateVisibleToUser();
+    }
+
+    protected void updateVisibleToUser() {
+        boolean oldVisibleToUser = mVisibleToUser;
+        mVisibleToUser = mVisible && mDeviceInteractive;
+
+        if (oldVisibleToUser != mVisibleToUser) {
+            handleVisibleToUserChanged(mVisibleToUser);
+        }
+    }
+
+    /**
+     * Clear Buzz/Beep/Blink.
+     */
+    @Override
+    public void clearNotificationEffects() {
+        try {
+            mBarService.clearNotificationEffects();
+        } catch (RemoteException e) {
+            // Won't fail unless the world has ended.
+        }
+    }
+
+    /**
+     * @return Whether the security bouncer from Keyguard is showing.
+     */
+    @Override
+    public boolean isBouncerShowing() {
+        return mBouncerShowing;
+    }
+
+    /**
+     * @return Whether the security bouncer from Keyguard is showing.
+     */
+    @Override
+    public boolean isBouncerShowingScrimmed() {
+        return isBouncerShowing() && mStatusBarKeyguardViewManager.bouncerNeedsScrimming();
+    }
+
+    @Override
+    public boolean isBouncerShowingOverDream() {
+        return mBouncerShowingOverDream;
+    }
+
+    /**
+     * When {@link KeyguardBouncer} starts to be dismissed, playing its animation.
+     */
+    @Override
+    public void onBouncerPreHideAnimation() {
+        mNotificationPanelViewController.onBouncerPreHideAnimation();
+
+    }
+
+    @Override
+    public boolean isKeyguardSecure() {
+        if (mStatusBarKeyguardViewManager == null) {
+            // startKeyguard() hasn't been called yet, so we don't know.
+            // Make sure anything that needs to know isKeyguardSecure() checks and re-checks this
+            // value onVisibilityChanged().
+            Slog.w(TAG, "isKeyguardSecure() called before startKeyguard(), returning false",
+                    new Throwable());
+            return false;
+        }
+        return mStatusBarKeyguardViewManager.isSecure();
+    }
+    @Override
+    public NotificationPanelViewController getPanelController() {
+        return mNotificationPanelViewController;
+    }
+    // End Extra BaseStatusBarMethods.
+
+    @Override
+    public NotificationGutsManager getGutsManager() {
+        return mGutsManager;
+    }
+
+    boolean isTransientShown() {
+        return mTransientShown;
+    }
+
+    private void updateLightRevealScrimVisibility() {
+        if (mLightRevealScrim == null) {
+            // status bar may not be inflated yet
+            return;
+        }
+
+        mLightRevealScrim.setAlpha(mScrimController.getState().getMaxLightRevealScrimAlpha());
+    }
+
+    @Override
+    public void extendDozePulse(){
+        mDozeScrimController.extendPulse();
+    }
+
+    private final KeyguardUpdateMonitorCallback mUpdateCallback =
+            new KeyguardUpdateMonitorCallback() {
+                @Override
+                public void onDreamingStateChanged(boolean dreaming) {
+                    updateScrimController();
+                    if (dreaming) {
+                        maybeEscalateHeadsUp();
+                    }
+                }
+
+                // TODO: (b/145659174) remove when moving to NewNotifPipeline. Replaced by
+                //  KeyguardCoordinator
+                @Override
+                public void onStrongAuthStateChanged(int userId) {
+                    super.onStrongAuthStateChanged(userId);
+                    mNotificationsController.requestNotificationUpdate("onStrongAuthStateChanged");
+                }
+            };
+
+
+    private final FalsingManager.FalsingBeliefListener mFalsingBeliefListener =
+            new FalsingManager.FalsingBeliefListener() {
+                @Override
+                public void onFalse() {
+                    // Hides quick settings, bouncer, and quick-quick settings.
+                    mStatusBarKeyguardViewManager.reset(true);
+                }
+            };
+
+    // Notifies StatusBarKeyguardViewManager every time the keyguard transition is over,
+    // this animation is tied to the scrim for historic reasons.
+    // TODO: notify when keyguard has faded away instead of the scrim.
+    private final ScrimController.Callback mUnlockScrimCallback = new ScrimController
+            .Callback() {
+        @Override
+        public void onFinished() {
+            if (mStatusBarKeyguardViewManager == null) {
+                Log.w(TAG, "Tried to notify keyguard visibility when "
+                        + "mStatusBarKeyguardViewManager was null");
+                return;
+            }
+            if (mKeyguardStateController.isKeyguardFadingAway()) {
+                mStatusBarKeyguardViewManager.onKeyguardFadedAway();
+            }
+        }
+
+        @Override
+        public void onCancelled() {
+            onFinished();
+        }
+    };
+
+    private final DeviceProvisionedListener mUserSetupObserver = new DeviceProvisionedListener() {
+        @Override
+        public void onUserSetupChanged() {
+            final boolean userSetup = mDeviceProvisionedController.isCurrentUserSetup();
+            Log.d(TAG, "mUserSetupObserver - DeviceProvisionedListener called for "
+                    + "current user");
+            if (MULTIUSER_DEBUG) {
+                Log.d(TAG, String.format("User setup changed: userSetup=%s mUserSetup=%s",
+                        userSetup, mUserSetup));
+            }
+
+            if (userSetup != mUserSetup) {
+                mUserSetup = userSetup;
+                if (!mUserSetup) {
+                    animateCollapseQuickSettings();
+                }
+                if (mNotificationPanelViewController != null) {
+                    mNotificationPanelViewController.setUserSetupComplete(mUserSetup);
+                }
+                updateQsExpansionEnabled();
+            }
+        }
+    };
+
+    private final BroadcastReceiver mWallpaperChangedReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (!mWallpaperSupported) {
+                // Receiver should not have been registered at all...
+                Log.wtf(TAG, "WallpaperManager not supported");
+                return;
+            }
+            WallpaperInfo info = mWallpaperManager.getWallpaperInfo(UserHandle.USER_CURRENT);
+            mWallpaperController.onWallpaperInfoUpdated(info);
+
+            final boolean deviceSupportsAodWallpaper = mContext.getResources().getBoolean(
+                    com.android.internal.R.bool.config_dozeSupportsAodWallpaper);
+            // If WallpaperInfo is null, it must be ImageWallpaper.
+            final boolean supportsAmbientMode = deviceSupportsAodWallpaper
+                    && (info != null && info.supportsAmbientMode());
+
+            mNotificationShadeWindowController.setWallpaperSupportsAmbientMode(supportsAmbientMode);
+            mScrimController.setWallpaperSupportsAmbientMode(supportsAmbientMode);
+            mKeyguardViewMediator.setWallpaperSupportsAmbientMode(supportsAmbientMode);
+        }
+    };
+
+    private final ConfigurationListener mConfigurationListener = new ConfigurationListener() {
+        @Override
+        public void onConfigChanged(Configuration newConfig) {
+            updateResources();
+            updateDisplaySize(); // populates mDisplayMetrics
+
+            if (DEBUG) {
+                Log.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
+            }
+
+            if (!mNotifPipelineFlags.isNewPipelineEnabled()) {
+                mViewHierarchyManager.updateRowStates();
+            }
+            mScreenPinningRequest.onConfigurationChanged();
+        }
+
+        @Override
+        public void onDensityOrFontScaleChanged() {
+            // TODO: Remove this.
+            if (mBrightnessMirrorController != null) {
+                mBrightnessMirrorController.onDensityOrFontScaleChanged();
+            }
+            // TODO: Bring these out of CentralSurfaces.
+            mUserInfoControllerImpl.onDensityOrFontScaleChanged();
+            mUserSwitcherController.onDensityOrFontScaleChanged();
+            mNotificationIconAreaController.onDensityOrFontScaleChanged(mContext);
+            mHeadsUpManager.onDensityOrFontScaleChanged();
+        }
+
+        @Override
+        public void onThemeChanged() {
+            if (mBrightnessMirrorController != null) {
+                mBrightnessMirrorController.onOverlayChanged();
+            }
+            // We need the new R.id.keyguard_indication_area before recreating
+            // mKeyguardIndicationController
+            mNotificationPanelViewController.onThemeChanged();
+
+            if (mStatusBarKeyguardViewManager != null) {
+                mStatusBarKeyguardViewManager.onThemeChanged();
+            }
+            if (mAmbientIndicationContainer instanceof AutoReinflateContainer) {
+                ((AutoReinflateContainer) mAmbientIndicationContainer).inflateLayout();
+            }
+            mNotificationIconAreaController.onThemeChanged();
+        }
+
+        @Override
+        public void onUiModeChanged() {
+            if (mBrightnessMirrorController != null) {
+                mBrightnessMirrorController.onUiModeChanged();
+            }
+        }
+    };
+
+    private StatusBarStateController.StateListener mStateListener =
+            new StatusBarStateController.StateListener() {
+                @Override
+                public void onStatePreChange(int oldState, int newState) {
+                    // If we're visible and switched to SHADE_LOCKED (the user dragged
+                    // down on the lockscreen), clear notification LED, vibration,
+                    // ringing.
+                    // Other transitions are covered in handleVisibleToUserChanged().
+                    if (mVisible && (newState == StatusBarState.SHADE_LOCKED
+                            || mStatusBarStateController.goingToFullShade())) {
+                        clearNotificationEffects();
+                    }
+                    if (newState == StatusBarState.KEYGUARD) {
+                        mRemoteInputManager.onPanelCollapsed();
+                        maybeEscalateHeadsUp();
+                    }
+                }
+
+                @Override
+                public void onStateChanged(int newState) {
+                    mState = newState;
+                    updateReportRejectedTouchVisibility();
+                    mDozeServiceHost.updateDozing();
+                    updateTheme();
+                    mNavigationBarController.touchAutoDim(mDisplayId);
+                    Trace.beginSection("CentralSurfaces#updateKeyguardState");
+                    if (mState == StatusBarState.KEYGUARD) {
+                        mNotificationPanelViewController.cancelPendingPanelCollapse();
+                    }
+                    updateDozingState();
+                    checkBarModes();
+                    updateScrimController();
+                    mPresenter.updateMediaMetaData(false, mState != StatusBarState.KEYGUARD);
+                    Trace.endSection();
+                }
+
+                @Override
+                public void onDozeAmountChanged(float linear, float eased) {
+                    if (mFeatureFlags.isEnabled(Flags.LOCKSCREEN_ANIMATIONS)
+                            && !(mLightRevealScrim.getRevealEffect() instanceof CircleReveal)) {
+                        mLightRevealScrim.setRevealAmount(1f - linear);
+                    }
+                }
+
+                @Override
+                public void onDozingChanged(boolean isDozing) {
+                    Trace.beginSection("CentralSurfaces#updateDozing");
+                    mDozing = isDozing;
+
+                    // Collapse the notification panel if open
+                    boolean dozingAnimated = mDozeServiceHost.getDozingRequested()
+                            && mDozeParameters.shouldControlScreenOff();
+                    mNotificationPanelViewController.resetViews(dozingAnimated);
+
+                    updateQsExpansionEnabled();
+                    mKeyguardViewMediator.setDozing(mDozing);
+
+                    mNotificationsController.requestNotificationUpdate("onDozingChanged");
+                    updateDozingState();
+                    mDozeServiceHost.updateDozing();
+                    updateScrimController();
+                    updateReportRejectedTouchVisibility();
+                    Trace.endSection();
+                }
+
+                @Override
+                public void onFullscreenStateChanged(boolean isFullscreen) {
+                    mIsFullscreen = isFullscreen;
+                    maybeUpdateBarMode();
+                }
+            };
+
+    private final BatteryController.BatteryStateChangeCallback mBatteryStateChangeCallback =
+            new BatteryController.BatteryStateChangeCallback() {
+                @Override
+                public void onPowerSaveChanged(boolean isPowerSave) {
+                    mMainExecutor.execute(mCheckBarModes);
+                    if (mDozeServiceHost != null) {
+                        mDozeServiceHost.firePowerSaveChanged(isPowerSave);
+                    }
+                }
+            };
+
+    private final ActivityLaunchAnimator.Callback mActivityLaunchAnimatorCallback =
+            new ActivityLaunchAnimator.Callback() {
+                @Override
+                public boolean isOnKeyguard() {
+                    return mKeyguardStateController.isShowing();
+                }
+
+                @Override
+                public void hideKeyguardWithAnimation(IRemoteAnimationRunner runner) {
+                    // We post to the main thread for 2 reasons:
+                    //   1. KeyguardViewMediator is not thread-safe.
+                    //   2. To ensure that ViewMediatorCallback#keyguardDonePending is called before
+                    //      ViewMediatorCallback#readyForKeyguardDone. The wrong order could occur
+                    //      when doing
+                    //      dismissKeyguardThenExecute { hideKeyguardWithAnimation(runner) }.
+                    mMainExecutor.execute(() -> mKeyguardViewMediator.hideWithAnimation(runner));
+                }
+
+                @Override
+                public int getBackgroundColor(TaskInfo task) {
+                    if (!mStartingSurfaceOptional.isPresent()) {
+                        Log.w(TAG, "No starting surface, defaulting to SystemBGColor");
+                        return SplashscreenContentDrawer.getSystemBGColor();
+                    }
+
+                    return mStartingSurfaceOptional.get().getBackgroundColor(task);
+                }
+            };
+
+    private final ActivityLaunchAnimator.Listener mActivityLaunchAnimatorListener =
+            new ActivityLaunchAnimator.Listener() {
+                @Override
+                public void onLaunchAnimationStart() {
+                    mKeyguardViewMediator.setBlursDisabledForAppLaunch(true);
+                }
+
+                @Override
+                public void onLaunchAnimationEnd() {
+                    mKeyguardViewMediator.setBlursDisabledForAppLaunch(false);
+                }
+            };
+
+    private final DemoMode mDemoModeCallback = new DemoMode() {
+        @Override
+        public void onDemoModeFinished() {
+            checkBarModes();
+        }
+
+        @Override
+        public void dispatchDemoCommand(String command, Bundle args) { }
+    };
+
+    /**
+     *  Determines what UserHandle to use when launching an activity.
+     *
+     *  We want to ensure that activities that are launched within the systemui process should be
+     *  launched as user of the current process.
+     * @param intent
+     * @return UserHandle
+     */
+    private UserHandle getActivityUserHandle(Intent intent) {
+        String[] packages = mContext.getResources().getStringArray(R.array.system_ui_packages);
+        for (String pkg : packages) {
+            if (intent.getComponent() == null) break;
+            if (pkg.equals(intent.getComponent().getPackageName())) {
+                return new UserHandle(UserHandle.myUserId());
+            }
+        }
+        return UserHandle.CURRENT;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
index b6ad9f7..16fddb42 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
@@ -93,7 +93,8 @@
         mDisplayId = mContext.getDisplayId();
     }
 
-    public void destroy(Context context) {
+    /** Call to cleanup the LightBarTransitionsController when done with it. */
+    public void destroy() {
         mCommandQueue.removeCallback(this);
         mStatusBarStateController.removeCallback(this);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 29fdfdb..ae3e09d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -885,7 +885,10 @@
 
                     @Override
                     public void onUnlockAnimationStarted(
-                            boolean playingCannedAnimation, boolean isWakeAndUnlock) {
+                            boolean playingCannedAnimation,
+                            boolean isWakeAndUnlock,
+                            long unlockAnimationStartDelay,
+                            long unlockAnimationDuration) {
                         // Disable blurs while we're unlocking so that panel expansion does not
                         // cause blurring. This will eventually be re-enabled by the panel view on
                         // ACTION_UP, since the user's finger might still be down after a swipe to
@@ -902,7 +905,22 @@
                                 onTrackingStopped(false);
                                 instantCollapse();
                             } else {
-                                fling(0f, false, 1f, false);
+                                mView.animate()
+                                        .alpha(0f)
+                                        .setStartDelay(0)
+                                        // Translate up by 4%.
+                                        .translationY(mView.getHeight() * -0.04f)
+                                        // This start delay is to give us time to animate out before
+                                        // the launcher icons animation starts, so use that as our
+                                        // duration.
+                                        .setDuration(unlockAnimationStartDelay)
+                                        .setInterpolator(EMPHASIZED_DECELERATE)
+                                        .withEndAction(() -> {
+                                            instantCollapse();
+                                            mView.setAlpha(1f);
+                                            mView.setTranslationY(0f);
+                                        })
+                                        .start();
                             }
                         }
                     }
@@ -1233,6 +1251,11 @@
         mKeyguardBottomArea.initQRCodeScanner(mQRCodeScannerController);
     }
 
+    @VisibleForTesting
+    void setMaxDisplayedNotifications(int maxAllowed) {
+        mMaxAllowedKeyguardNotifications = maxAllowed;
+    }
+
     private void updateMaxDisplayedNotifications(boolean recompute) {
         if (recompute) {
             mMaxAllowedKeyguardNotifications = Math.max(computeMaxKeyguardNotifications(), 1);
@@ -1463,7 +1486,11 @@
     /**
      * @return the maximum keyguard notifications that can fit on the screen
      */
-    private int computeMaxKeyguardNotifications() {
+    @VisibleForTesting
+    int computeMaxKeyguardNotifications() {
+        if (mAmbientState.getFractionToShade() > 0 || mAmbientState.getDozeAmount() > 0) {
+            return mMaxAllowedKeyguardNotifications;
+        }
         float topPadding = mNotificationStackScrollLayoutController.getTopPadding();
         float shelfIntrinsicHeight =
                 mNotificationShelfController.getVisibility() == View.GONE
@@ -1735,6 +1762,11 @@
         return false;
     }
 
+    @VisibleForTesting
+    boolean isQsTracking() {
+        return mQsTracking;
+    }
+
     @Override
     protected boolean isInContentBounds(float x, float y) {
         float stackScrollerX = mNotificationStackScrollLayoutController.getX();
@@ -2812,16 +2844,16 @@
     private boolean shouldQuickSettingsIntercept(float x, float y, float yDiff) {
         if (!isQsExpansionEnabled() || mCollapsedOnDown
                 || (mKeyguardShowing && mKeyguardBypassController.getBypassEnabled())
-                || (mKeyguardShowing && mShouldUseSplitNotificationShade)) {
+                || mShouldUseSplitNotificationShade) {
             return false;
         }
         View header = mKeyguardShowing || mQs == null ? mKeyguardStatusBar : mQs.getHeader();
-
+        int frameTop = mKeyguardShowing || mQs == null ? 0 : mQsFrame.getTop();
         mQsInterceptRegion.set(
                 /* left= */ (int) mQsFrame.getX(),
-                /* top= */ header.getTop(),
+                /* top= */ header.getTop() + frameTop,
                 /* right= */ (int) mQsFrame.getX() + mQsFrame.getWidth(),
-                /* bottom= */ header.getBottom());
+                /* bottom= */ header.getBottom() + frameTop);
         // Also allow QS to intercept if the touch is near the notch.
         mStatusBarTouchableRegionManager.updateRegionForNotch(mQsInterceptRegion);
         final boolean onHeader = mQsInterceptRegion.contains((int) x, (int) y);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
index 2f11b16..be5b33e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
@@ -252,7 +252,7 @@
                 }
 
                 if (mStatusBarStateController.isDozing()) {
-                    mService.mDozeScrimController.extendPulse();
+                    mService.extendDozePulse();
                 }
                 mLockIconViewController.onTouchEvent(
                         ev,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 052a4f7..7f5cef0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -164,6 +164,10 @@
 
         @Override
         public void onVisibilityChanged(boolean isVisible) {
+            mCentralSurfaces
+                    .setBouncerShowingOverDream(
+                            isVisible && mDreamOverlayStateController.isOverlayActive());
+
             if (!isVisible) {
                 mCentralSurfaces.setBouncerHiddenFraction(KeyguardBouncer.EXPANSION_HIDDEN);
             }
@@ -390,6 +394,11 @@
                     && !mBouncer.isShowing() && !mBouncer.isAnimatingAway()) {
                 mBouncer.show(false /* resetSecuritySelection */, false /* scrimmed */);
             }
+        } else if (!mShowing && mBouncer.inTransit()) {
+            // Keyguard is not visible anymore, but expansion animation was still running.
+            // We need to keep propagating the expansion state to the bouncer, otherwise it will be
+            // stuck in transit.
+            mBouncer.setExpansion(fraction);
         } else if (mPulsing && fraction == KeyguardBouncer.EXPANSION_VISIBLE) {
             // Panel expanded while pulsing but didn't translate the bouncer (because we are
             // unlocked.) Let's simply wake-up to dismiss the lock screen.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
index 5d38eea..c5e5297 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
@@ -31,6 +31,7 @@
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutListContainerModule;
 import com.android.systemui.statusbar.phone.CentralSurfacesCommandQueueCallbacks;
+import com.android.systemui.statusbar.phone.CentralSurfacesImpl;
 import com.android.systemui.statusbar.phone.LargeScreenShadeHeaderController;
 import com.android.systemui.statusbar.phone.NotificationPanelViewController;
 import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
@@ -51,7 +52,7 @@
 
 /**
  * Dagger subcomponent for classes (semi-)related to the status bar. The component is created once
- * inside {@link com.android.systemui.statusbar.phone.CentralSurfaces} and never re-created.
+ * inside {@link CentralSurfacesImpl} and never re-created.
  *
  * TODO(b/197137564): This should likely be re-factored a bit. It includes classes that aren't
  * directly related to status bar functionality, like multiple notification classes. And, the fact
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
index c024c72..942d186 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
@@ -16,317 +16,22 @@
 
 package com.android.systemui.statusbar.phone.dagger;
 
-import static com.android.systemui.Dependency.TIME_TICK_HANDLER_NAME;
-
-import android.app.WallpaperManager;
-import android.content.Context;
-import android.hardware.devicestate.DeviceStateManager;
-import android.os.Handler;
-import android.os.PowerManager;
-import android.util.DisplayMetrics;
-
-import com.android.internal.jank.InteractionJankMonitor;
-import com.android.internal.logging.MetricsLogger;
-import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.ViewMediatorCallback;
-import com.android.systemui.InitController;
-import com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuController;
-import com.android.systemui.animation.ActivityLaunchAnimator;
-import com.android.systemui.assist.AssistManager;
-import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.classifier.FalsingCollector;
-import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.dagger.qualifiers.UiBackground;
-import com.android.systemui.demomode.DemoModeController;
-import com.android.systemui.dreams.DreamOverlayStateController;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.fragments.FragmentService;
-import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
-import com.android.systemui.keyguard.KeyguardViewMediator;
-import com.android.systemui.keyguard.ScreenLifecycle;
-import com.android.systemui.keyguard.WakefulnessLifecycle;
-import com.android.systemui.navigationbar.NavigationBarController;
-import com.android.systemui.plugins.FalsingManager;
-import com.android.systemui.plugins.PluginDependencyProvider;
-import com.android.systemui.recents.ScreenPinningRequest;
-import com.android.systemui.settings.brightness.BrightnessSliderController;
-import com.android.systemui.shared.plugins.PluginManager;
-import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.KeyguardIndicationController;
-import com.android.systemui.statusbar.LockscreenShadeTransitionController;
-import com.android.systemui.statusbar.NotificationLockscreenUserManager;
-import com.android.systemui.statusbar.NotificationMediaManager;
-import com.android.systemui.statusbar.NotificationRemoteInputManager;
-import com.android.systemui.statusbar.NotificationShadeDepthController;
-import com.android.systemui.statusbar.NotificationShadeWindowController;
-import com.android.systemui.statusbar.NotificationViewHierarchyManager;
-import com.android.systemui.statusbar.PulseExpansionHandler;
-import com.android.systemui.statusbar.SysuiStatusBarStateController;
-import com.android.systemui.statusbar.charging.WiredChargingRippleController;
-import com.android.systemui.statusbar.connectivity.NetworkController;
-import com.android.systemui.statusbar.notification.DynamicPrivacyController;
-import com.android.systemui.statusbar.notification.NotifPipelineFlags;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
-import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
-import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
-import com.android.systemui.statusbar.notification.init.NotificationsController;
-import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
-import com.android.systemui.statusbar.notification.logging.NotificationLogger;
-import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
-import com.android.systemui.statusbar.phone.AutoHideController;
-import com.android.systemui.statusbar.phone.BiometricUnlockController;
-import com.android.systemui.statusbar.phone.DozeParameters;
-import com.android.systemui.statusbar.phone.DozeScrimController;
-import com.android.systemui.statusbar.phone.DozeServiceHost;
-import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
-import com.android.systemui.statusbar.phone.KeyguardBypassController;
-import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
-import com.android.systemui.statusbar.phone.LightBarController;
-import com.android.systemui.statusbar.phone.LockscreenGestureLogger;
-import com.android.systemui.statusbar.phone.LockscreenWallpaper;
-import com.android.systemui.statusbar.phone.NotificationIconAreaController;
-import com.android.systemui.statusbar.phone.PhoneStatusBarPolicy;
-import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
-import com.android.systemui.statusbar.phone.ScrimController;
-import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
-import com.android.systemui.statusbar.phone.StatusBarHideIconsForBouncerManager;
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
-import com.android.systemui.statusbar.phone.StatusBarSignalPolicy;
-import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager;
-import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
-import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
-import com.android.systemui.statusbar.policy.BatteryController;
-import com.android.systemui.statusbar.policy.ConfigurationController;
-import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.statusbar.policy.ExtensionController;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
-import com.android.systemui.statusbar.policy.UserSwitcherController;
-import com.android.systemui.statusbar.window.StatusBarWindowController;
-import com.android.systemui.statusbar.window.StatusBarWindowStateController;
-import com.android.systemui.util.WallpaperController;
-import com.android.systemui.util.concurrency.DelayableExecutor;
-import com.android.systemui.util.concurrency.MessageRouter;
-import com.android.systemui.volume.VolumeComponent;
-import com.android.systemui.wmshell.BubblesManager;
-import com.android.wm.shell.bubbles.Bubbles;
-import com.android.wm.shell.startingsurface.StartingSurface;
+import com.android.systemui.statusbar.phone.CentralSurfacesImpl;
 
-import java.util.Optional;
-import java.util.concurrent.Executor;
-
-import javax.inject.Named;
-
-import dagger.Lazy;
+import dagger.Binds;
 import dagger.Module;
-import dagger.Provides;
 
 /**
- * Dagger Module providing {@link CentralSurfaces}.
+ * Dagger Module providing {@link CentralSurfacesImpl}.
  */
 @Module
 public interface StatusBarPhoneModule {
     /**
      * Provides our instance of CentralSurfaces which is considered optional.
      */
-    @Provides
+    @Binds
     @SysUISingleton
-    static CentralSurfaces provideCentralSurfaces(
-            Context context,
-            NotificationsController notificationsController,
-            FragmentService fragmentService,
-            LightBarController lightBarController,
-            AutoHideController autoHideController,
-            StatusBarWindowController statusBarWindowController,
-            StatusBarWindowStateController statusBarWindowStateController,
-            KeyguardUpdateMonitor keyguardUpdateMonitor,
-            StatusBarSignalPolicy statusBarSignalPolicy,
-            PulseExpansionHandler pulseExpansionHandler,
-            NotificationWakeUpCoordinator notificationWakeUpCoordinator,
-            KeyguardBypassController keyguardBypassController,
-            KeyguardStateController keyguardStateController,
-            HeadsUpManagerPhone headsUpManagerPhone,
-            DynamicPrivacyController dynamicPrivacyController,
-            FalsingManager falsingManager,
-            FalsingCollector falsingCollector,
-            BroadcastDispatcher broadcastDispatcher,
-            NotifShadeEventSource notifShadeEventSource,
-            NotificationEntryManager notificationEntryManager,
-            NotificationGutsManager notificationGutsManager,
-            NotificationLogger notificationLogger,
-            NotificationInterruptStateProvider notificationInterruptStateProvider,
-            NotificationViewHierarchyManager notificationViewHierarchyManager,
-            PanelExpansionStateManager panelExpansionStateManager,
-            KeyguardViewMediator keyguardViewMediator,
-            DisplayMetrics displayMetrics,
-            MetricsLogger metricsLogger,
-            @UiBackground Executor uiBgExecutor,
-            NotificationMediaManager notificationMediaManager,
-            NotificationLockscreenUserManager lockScreenUserManager,
-            NotificationRemoteInputManager remoteInputManager,
-            UserSwitcherController userSwitcherController,
-            NetworkController networkController,
-            BatteryController batteryController,
-            SysuiColorExtractor colorExtractor,
-            ScreenLifecycle screenLifecycle,
-            WakefulnessLifecycle wakefulnessLifecycle,
-            SysuiStatusBarStateController statusBarStateController,
-            Optional<BubblesManager> bubblesManagerOptional,
-            Optional<Bubbles> bubblesOptional,
-            VisualStabilityManager visualStabilityManager,
-            DeviceProvisionedController deviceProvisionedController,
-            NavigationBarController navigationBarController,
-            AccessibilityFloatingMenuController accessibilityFloatingMenuController,
-            Lazy<AssistManager> assistManagerLazy,
-            ConfigurationController configurationController,
-            NotificationShadeWindowController notificationShadeWindowController,
-            DozeParameters dozeParameters,
-            ScrimController scrimController,
-            Lazy<LockscreenWallpaper> lockscreenWallpaperLazy,
-            LockscreenGestureLogger lockscreenGestureLogger,
-            Lazy<BiometricUnlockController> biometricUnlockControllerLazy,
-            DozeServiceHost dozeServiceHost,
-            PowerManager powerManager,
-            ScreenPinningRequest screenPinningRequest,
-            DozeScrimController dozeScrimController,
-            VolumeComponent volumeComponent,
-            CommandQueue commandQueue,
-            CentralSurfacesComponent.Factory statusBarComponentFactory,
-            PluginManager pluginManager,
-            ShadeController shadeController,
-            StatusBarKeyguardViewManager statusBarKeyguardViewManager,
-            ViewMediatorCallback viewMediatorCallback,
-            InitController initController,
-            @Named(TIME_TICK_HANDLER_NAME) Handler timeTickHandler,
-            PluginDependencyProvider pluginDependencyProvider,
-            KeyguardDismissUtil keyguardDismissUtil,
-            ExtensionController extensionController,
-            UserInfoControllerImpl userInfoControllerImpl,
-            PhoneStatusBarPolicy phoneStatusBarPolicy,
-            KeyguardIndicationController keyguardIndicationController,
-            DemoModeController demoModeController,
-            Lazy<NotificationShadeDepthController> notificationShadeDepthController,
-            StatusBarTouchableRegionManager statusBarTouchableRegionManager,
-            NotificationIconAreaController notificationIconAreaController,
-            BrightnessSliderController.Factory brightnessSliderFactory,
-            ScreenOffAnimationController screenOffAnimationController,
-            WallpaperController wallpaperController,
-            OngoingCallController ongoingCallController,
-            StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager,
-            LockscreenShadeTransitionController transitionController,
-            FeatureFlags featureFlags,
-            KeyguardUnlockAnimationController keyguardUnlockAnimationController,
-            @Main Handler mainHandler,
-            @Main DelayableExecutor delayableExecutor,
-            @Main MessageRouter messageRouter,
-            WallpaperManager wallpaperManager,
-            Optional<StartingSurface> startingSurfaceOptional,
-            ActivityLaunchAnimator activityLaunchAnimator,
-            NotifPipelineFlags notifPipelineFlags,
-            InteractionJankMonitor jankMonitor,
-            DeviceStateManager deviceStateManager,
-            DreamOverlayStateController dreamOverlayStateController,
-            WiredChargingRippleController wiredChargingRippleController) {
-        return new CentralSurfaces(
-                context,
-                notificationsController,
-                fragmentService,
-                lightBarController,
-                autoHideController,
-                statusBarWindowController,
-                statusBarWindowStateController,
-                keyguardUpdateMonitor,
-                statusBarSignalPolicy,
-                pulseExpansionHandler,
-                notificationWakeUpCoordinator,
-                keyguardBypassController,
-                keyguardStateController,
-                headsUpManagerPhone,
-                dynamicPrivacyController,
-                falsingManager,
-                falsingCollector,
-                broadcastDispatcher,
-                notifShadeEventSource,
-                notificationEntryManager,
-                notificationGutsManager,
-                notificationLogger,
-                notificationInterruptStateProvider,
-                notificationViewHierarchyManager,
-                panelExpansionStateManager,
-                keyguardViewMediator,
-                displayMetrics,
-                metricsLogger,
-                uiBgExecutor,
-                notificationMediaManager,
-                lockScreenUserManager,
-                remoteInputManager,
-                userSwitcherController,
-                networkController,
-                batteryController,
-                colorExtractor,
-                screenLifecycle,
-                wakefulnessLifecycle,
-                statusBarStateController,
-                bubblesManagerOptional,
-                bubblesOptional,
-                visualStabilityManager,
-                deviceProvisionedController,
-                navigationBarController,
-                accessibilityFloatingMenuController,
-                assistManagerLazy,
-                configurationController,
-                notificationShadeWindowController,
-                dozeParameters,
-                scrimController,
-                lockscreenWallpaperLazy,
-                lockscreenGestureLogger,
-                biometricUnlockControllerLazy,
-                dozeServiceHost,
-                powerManager,
-                screenPinningRequest,
-                dozeScrimController,
-                volumeComponent,
-                commandQueue,
-                statusBarComponentFactory,
-                pluginManager,
-                shadeController,
-                statusBarKeyguardViewManager,
-                viewMediatorCallback,
-                initController,
-                timeTickHandler,
-                pluginDependencyProvider,
-                keyguardDismissUtil,
-                extensionController,
-                userInfoControllerImpl,
-                phoneStatusBarPolicy,
-                keyguardIndicationController,
-                demoModeController,
-                notificationShadeDepthController,
-                statusBarTouchableRegionManager,
-                notificationIconAreaController,
-                brightnessSliderFactory,
-                screenOffAnimationController,
-                wallpaperController,
-                ongoingCallController,
-                statusBarHideIconsForBouncerManager,
-                transitionController,
-                featureFlags,
-                keyguardUnlockAnimationController,
-                mainHandler,
-                delayableExecutor,
-                messageRouter,
-                wallpaperManager,
-                startingSurfaceOptional,
-                activityLaunchAnimator,
-                notifPipelineFlags,
-                jankMonitor,
-                deviceStateManager,
-                dreamOverlayStateController,
-                wiredChargingRippleController
-        );
-    }
+    CentralSurfaces bindsCentralSurfaces(CentralSurfacesImpl impl);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentComponent.java
index 2eba325..6717bc7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentComponent.java
@@ -18,14 +18,12 @@
 
 import com.android.systemui.battery.BatteryMeterViewController;
 import com.android.systemui.dagger.qualifiers.RootView;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
 import com.android.systemui.statusbar.phone.LightsOutNotifController;
 import com.android.systemui.statusbar.phone.PhoneStatusBarTransitions;
 import com.android.systemui.statusbar.phone.PhoneStatusBarView;
 import com.android.systemui.statusbar.phone.PhoneStatusBarViewController;
 import com.android.systemui.statusbar.phone.StatusBarDemoMode;
-import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
 import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;
 
 import dagger.BindsInstance;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
index 1753157..650a5d0 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
@@ -22,7 +22,6 @@
 import android.testing.AndroidTestingRunner;
 
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -55,8 +54,6 @@
     @Mock
     DozeParameters mDozeParameters;
     @Mock
-    KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
-    @Mock
     ScreenOffAnimationController mScreenOffAnimationController;
     @Captor
     private ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardUpdateMonitorCallbackCaptor;
@@ -75,7 +72,6 @@
                 mKeyguardUpdateMonitor,
                 mConfigurationController,
                 mDozeParameters,
-                mKeyguardUnlockAnimationController,
                 mScreenOffAnimationController);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index 80df1e3..b733c5e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -564,6 +564,7 @@
         // Configure UdfpsView to accept the ACTION_DOWN event
         when(mUdfpsView.isIlluminationRequested()).thenReturn(false);
         when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
+        when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
 
         // GIVEN that the overlay is showing
         mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, TEST_UDFPS_SENSOR_ID,
@@ -579,6 +580,7 @@
         // FIX THIS TEST
         mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
         moveEvent.recycle();
+        mFgExecutor.runAllReady();
         // THEN FingerprintManager is notified about onPointerDown
         verify(mAlternateTouchProvider).onPointerDown(eq(TEST_REQUEST_ID), eq(0), eq(0), eq(0f),
                 eq(0f));
@@ -588,6 +590,7 @@
         // AND illumination begins
         verify(mUdfpsView).startIllumination(mOnIlluminatedRunnableCaptor.capture());
         verify(mLatencyTracker, never()).onActionEnd(eq(LatencyTracker.ACTION_UDFPS_ILLUMINATE));
+        verify(mKeyguardUpdateMonitor).onUdfpsPointerDown(eq((int) TEST_REQUEST_ID));
         // AND onIlluminatedRunnable notifies FingerprintManager about onUiReady
         mOnIlluminatedRunnableCaptor.getValue().run();
         InOrder inOrder = inOrder(mFingerprintManager, mLatencyTracker);
@@ -606,6 +609,7 @@
         when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
         // WHEN fingerprint is requested because of AOD interrupt
         mUdfpsController.onAodInterrupt(0, 0, 2f, 3f);
+        mFgExecutor.runAllReady();
         // THEN illumination begins
         // AND onIlluminatedRunnable that notifies FingerprintManager is set
         verify(mUdfpsView).startIllumination(mOnIlluminatedRunnableCaptor.capture());
@@ -614,6 +618,7 @@
                 eq(0), eq(0), eq(3f) /* minor */, eq(2f) /* major */);
         verify(mFingerprintManager, never()).onPointerDown(anyLong(), anyInt(), anyInt(), anyInt(),
                 anyFloat(), anyFloat());
+        verify(mKeyguardUpdateMonitor).onUdfpsPointerDown(eq((int) TEST_REQUEST_ID));
     }
 
     @Test
@@ -641,6 +646,7 @@
         mFgExecutor.runAllReady();
         when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
         mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
+        mFgExecutor.runAllReady();
         when(mUdfpsView.isIlluminationRequested()).thenReturn(true);
         // WHEN it times out
         mFgExecutor.advanceClockToNext();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
index 442e41c..c3fca29 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
@@ -428,7 +428,6 @@
     @Test
     public void testInformBouncerShowingOnExpand() {
         swipeToPosition(1f, Direction.UP, 0);
-        verify(mCentralSurfaces).setBouncerShowingOverDream(true);
     }
 
     /**
@@ -441,7 +440,6 @@
         Mockito.clearInvocations(mCentralSurfaces);
 
         swipeToPosition(0f, Direction.DOWN, 0);
-        verify(mCentralSurfaces).setBouncerShowingOverDream(false);
     }
 
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
index 6a9c3e3..b8c85bb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
@@ -25,8 +25,12 @@
 import android.content.Intent
 import android.content.pm.ApplicationInfo
 import android.content.pm.PackageManager
+import android.graphics.Bitmap
+import android.graphics.Canvas
+import android.graphics.Color
 import android.graphics.drawable.Animatable2
 import android.graphics.drawable.AnimatedVectorDrawable
+import android.graphics.drawable.Drawable
 import android.graphics.drawable.GradientDrawable
 import android.graphics.drawable.Icon
 import android.graphics.drawable.RippleDrawable
@@ -124,7 +128,7 @@
     @Mock private lateinit var falsingManager: FalsingManager
     @Mock private lateinit var transitionParent: ViewGroup
     private lateinit var appIcon: ImageView
-    private lateinit var albumView: ImageView
+    @Mock private lateinit var albumView: ImageView
     private lateinit var titleText: TextView
     private lateinit var artistText: TextView
     private lateinit var seamless: ViewGroup
@@ -296,7 +300,6 @@
 
         // Set up mock views for the players
         appIcon = ImageView(context)
-        albumView = ImageView(context)
         titleText = TextView(context)
         artistText = TextView(context)
         seamless = FrameLayout(context)
@@ -416,7 +419,6 @@
         whenever(coverContainer1.context).thenReturn(mockContext)
         whenever(coverContainer2.context).thenReturn(mockContext)
         whenever(coverContainer3.context).thenReturn(mockContext)
-
     }
 
     @After
@@ -537,6 +539,60 @@
     }
 
     @Test
+    fun bindAlbumView_setAfterExecutors() {
+        val bmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
+        val canvas = Canvas(bmp)
+        canvas.drawColor(Color.RED)
+        val albumArt = Icon.createWithBitmap(bmp)
+        val state = mediaData.copy(artwork = albumArt)
+
+        player.attachPlayer(viewHolder)
+        player.bindPlayer(state, PACKAGE)
+        bgExecutor.runAllReady()
+        mainExecutor.runAllReady()
+
+        verify(albumView).setImageDrawable(any(Drawable::class.java))
+    }
+
+    @Test
+    fun bindAlbumView_bitmapInLaterStates_setAfterExecutors() {
+        val bmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
+        val canvas = Canvas(bmp)
+        canvas.drawColor(Color.RED)
+        val albumArt = Icon.createWithBitmap(bmp)
+
+        val state0 = mediaData.copy(artwork = null)
+        val state1 = mediaData.copy(artwork = albumArt)
+        val state2 = mediaData.copy(artwork = albumArt)
+        player.attachPlayer(viewHolder)
+
+        // First binding sets (empty) drawable
+        player.bindPlayer(state0, PACKAGE)
+        bgExecutor.runAllReady()
+        mainExecutor.runAllReady()
+        verify(albumView).setImageDrawable(any(Drawable::class.java))
+
+        // Run Metadata update so that later states don't update
+        val captor = argumentCaptor<Animator.AnimatorListener>()
+        verify(mockAnimator, times(2)).addListener(captor.capture())
+        captor.value.onAnimationEnd(mockAnimator)
+        assertThat(titleText.getText()).isEqualTo(TITLE)
+        assertThat(artistText.getText()).isEqualTo(ARTIST)
+
+        // Second binding sets transition drawable
+        player.bindPlayer(state1, PACKAGE)
+        bgExecutor.runAllReady()
+        mainExecutor.runAllReady()
+        verify(albumView, times(2)).setImageDrawable(any(Drawable::class.java))
+
+        // Third binding does run transition or update background
+        player.bindPlayer(state2, PACKAGE)
+        bgExecutor.runAllReady()
+        mainExecutor.runAllReady()
+        verify(albumView, times(2)).setImageDrawable(any(Drawable::class.java))
+    }
+
+    @Test
     fun bind_seekBarDisabled_hasActions_seekBarVisibilityIsSetToInvisible() {
         useRealConstraintSets()
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
index f5b006d..4a740f6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
@@ -205,10 +205,9 @@
         when(mNavigationBarView.getAccessibilityButton()).thenReturn(mAccessibilityButton);
         when(mNavigationBarView.getImeSwitchButton()).thenReturn(mImeSwitchButton);
         when(mNavigationBarView.getBackButton()).thenReturn(mBackButton);
-        when(mNavigationBarView.getBarTransitions()).thenReturn(mNavigationBarTransitions);
         when(mNavigationBarView.getRotationButtonController())
                 .thenReturn(mRotationButtonController);
-        when(mNavigationBarView.getLightTransitionsController())
+        when(mNavigationBarTransitions.getLightTransitionsController())
                 .thenReturn(mLightBarTransitionsController);
         when(mStatusBarKeyguardViewManager.isNavBarVisible()).thenReturn(true);
         setupSysuiDependency();
@@ -459,6 +458,7 @@
                 mInputMethodManager,
                 mDeadZone,
                 mDeviceConfigProxyFake,
+                mNavigationBarTransitions,
                 Optional.of(mock(BackAnimation.class))));
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java
index 6a2a78b..cafd2cf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java
@@ -21,7 +21,6 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
@@ -37,8 +36,8 @@
 import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.recents.OverviewProxyService;
-import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.BarTransitions;
+import com.android.systemui.statusbar.phone.LightBarTransitionsController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import org.junit.Before;
@@ -53,9 +52,16 @@
 public class NavigationBarTransitionsTest extends SysuiTestCase {
 
     @Mock
+    LightBarTransitionsController.Factory mLightBarTransitionsFactory;
+    @Mock
+    LightBarTransitionsController mLightBarTransitions;
+    @Mock
     EdgeBackGestureHandler.Factory mEdgeBackGestureHandlerFactory;
     @Mock
     EdgeBackGestureHandler mEdgeBackGestureHandler;
+    @Mock
+    IWindowManager mIWindowManager;
+
     private NavigationBarTransitions mTransitions;
 
     @Before
@@ -64,7 +70,6 @@
 
         when(mEdgeBackGestureHandlerFactory.create(any(Context.class)))
                 .thenReturn(mEdgeBackGestureHandler);
-        mDependency.injectMockDependency(IWindowManager.class);
         mDependency.injectMockDependency(AssistManager.class);
         mDependency.injectMockDependency(OverviewProxyService.class);
         mDependency.injectMockDependency(StatusBarStateController.class);
@@ -76,10 +81,12 @@
                 .when(mDependency.injectMockDependency(NavigationModeController.class))
                 .getCurrentUserContext();
 
+        when(mLightBarTransitionsFactory.create(any())).thenReturn(mLightBarTransitions);
         NavigationBarView navBar = spy(new NavigationBarView(mContext, null));
         when(navBar.getCurrentView()).thenReturn(navBar);
         when(navBar.findViewById(anyInt())).thenReturn(navBar);
-        mTransitions = new NavigationBarTransitions(navBar, mock(CommandQueue.class));
+        mTransitions = new NavigationBarTransitions(
+                navBar, mIWindowManager, mLightBarTransitionsFactory);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 077f6bf..e8608fa7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -34,15 +34,20 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.graphics.Rect;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.util.MathUtils;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
 
 import androidx.test.annotation.UiThreadTest;
 import androidx.test.filters.SmallTest;
@@ -572,9 +577,70 @@
         assertEquals(0, mStackScroller.getSpeedBumpIndex());
     }
 
+    @Test
+    public void testInsideQSHeader_noOffset() {
+        ViewGroup qsHeader = mock(ViewGroup.class);
+        Rect boundsOnScreen = new Rect(0, 0, 1000, 1000);
+        mockBoundsOnScreen(qsHeader, boundsOnScreen);
+
+        mStackScroller.setQsHeader(qsHeader);
+        mStackScroller.setLeftTopRightBottom(0, 0, 2000, 2000);
+
+        MotionEvent event1 = transformEventForView(createMotionEvent(100f, 100f), mStackScroller);
+        assertTrue(mStackScroller.isInsideQsHeader(event1));
+
+        MotionEvent event2 = transformEventForView(createMotionEvent(1100f, 100f), mStackScroller);
+        assertFalse(mStackScroller.isInsideQsHeader(event2));
+    }
+
+    @Test
+    public void testInsideQSHeader_Offset() {
+        ViewGroup qsHeader = mock(ViewGroup.class);
+        Rect boundsOnScreen = new Rect(100, 100, 1000, 1000);
+        mockBoundsOnScreen(qsHeader, boundsOnScreen);
+
+        mStackScroller.setQsHeader(qsHeader);
+        mStackScroller.setLeftTopRightBottom(200, 200, 2000, 2000);
+
+        MotionEvent event1 = transformEventForView(createMotionEvent(50f, 50f), mStackScroller);
+        assertFalse(mStackScroller.isInsideQsHeader(event1));
+
+        MotionEvent event2 = transformEventForView(createMotionEvent(150f, 150f), mStackScroller);
+        assertTrue(mStackScroller.isInsideQsHeader(event2));
+
+        MotionEvent event3 = transformEventForView(createMotionEvent(250f, 250f), mStackScroller);
+        assertTrue(mStackScroller.isInsideQsHeader(event2));
+    }
+
     private void setBarStateForTest(int state) {
         // Can't inject this through the listener or we end up on the actual implementation
         // rather than the mock because the spy just coppied the anonymous inner /shruggie.
         mStackScroller.setStatusBarState(state);
     }
+
+    private static void mockBoundsOnScreen(View view, Rect bounds) {
+        doAnswer(invocation -> {
+            Rect out = invocation.getArgument(0);
+            out.set(bounds);
+            return null;
+        }).when(view).getBoundsOnScreen(any());
+    }
+
+    private static MotionEvent transformEventForView(MotionEvent event, View view) {
+        // From `ViewGroup#dispatchTransformedTouchEvent`
+        MotionEvent transformed = event.copy();
+        transformed.offsetLocation(-view.getTop(), -view.getLeft());
+        return transformed;
+    }
+
+    private static MotionEvent createMotionEvent(float x, float y) {
+        return MotionEvent.obtain(
+                /* downTime= */0,
+                /* eventTime= */0,
+                MotionEvent.ACTION_DOWN,
+                x,
+                y,
+                /* metaState= */0
+        );
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
similarity index 99%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index 84edabd..d364505 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -178,12 +178,12 @@
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper(setAsMainLooper = true)
-public class CentralSurfacesTest extends SysuiTestCase {
+public class CentralSurfacesImplTest extends SysuiTestCase {
 
     private static final int FOLD_STATE_FOLDED = 0;
     private static final int FOLD_STATE_UNFOLDED = 1;
 
-    private CentralSurfaces mCentralSurfaces;
+    private CentralSurfacesImpl mCentralSurfaces;
     private FakeMetricsLogger mMetricsLogger;
     private PowerManager mPowerManager;
     private TestableNotificationInterruptStateProviderImpl mNotificationInterruptStateProvider;
@@ -383,7 +383,7 @@
         when(mOperatorNameViewControllerFactory.create(any()))
                 .thenReturn(mOperatorNameViewController);
 
-        mCentralSurfaces = new CentralSurfaces(
+        mCentralSurfaces = new CentralSurfacesImpl(
                 mContext,
                 mNotificationsController,
                 mock(FragmentService.class),
@@ -479,7 +479,7 @@
                 mDreamOverlayStateController,
                 mWiredChargingRippleController);
         when(mKeyguardViewMediator.registerCentralSurfaces(
-                any(CentralSurfaces.class),
+                any(CentralSurfacesImpl.class),
                 any(NotificationPanelViewController.class),
                 any(PanelExpansionStateManager.class),
                 any(BiometricUnlockController.class),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
index 05fb1f59..cad603c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
@@ -56,6 +56,7 @@
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewParent;
 import android.view.ViewPropertyAnimator;
 import android.view.ViewStub;
 import android.view.accessibility.AccessibilityManager;
@@ -99,6 +100,7 @@
 import com.android.systemui.model.SysUiState;
 import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.qrcodescanner.controller.QRCodeScannerController;
 import com.android.systemui.screenrecord.RecordingController;
 import com.android.systemui.statusbar.CommandQueue;
@@ -334,6 +336,12 @@
     private NotificationStackSizeCalculator mNotificationStackSizeCalculator;
     @Mock
     private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
+    @Mock
+    private QS mQs;
+    @Mock
+    private View mQsHeader;
+    @Mock
+    private ViewParent mViewParent;
     private NotificationPanelViewController.PanelEventsEmitter mPanelEventsEmitter;
     private Optional<SysUIUnfoldComponent> mSysUIUnfoldComponent = Optional.empty();
     private SysuiStatusBarStateController mStatusBarStateController;
@@ -455,6 +463,9 @@
             return null;
         }).when(mNotificationShadeWindowController).batchApplyWindowLayoutParams(any());
 
+        when(mView.getParent()).thenReturn(mViewParent);
+        when(mQs.getHeader()).thenReturn(mQsHeader);
+
         mMainHandler = new Handler(Looper.getMainLooper());
         mPanelEventsEmitter = new NotificationPanelViewController.PanelEventsEmitter();
 
@@ -547,6 +558,37 @@
     }
 
     @Test
+    public void computeMaxKeyguardNotifications_lockscreenToShade_returnsExistingMax() {
+        when(mAmbientState.getFractionToShade()).thenReturn(0.5f);
+        mNotificationPanelViewController.setMaxDisplayedNotifications(-1);
+
+        // computeMaxKeyguardNotifications sets maxAllowed to 0 at minimum if it updates the value
+        assertThat(mNotificationPanelViewController.computeMaxKeyguardNotifications())
+                .isEqualTo(-1);
+    }
+
+    @Test
+    public void computeMaxKeyguardNotifications_dozeAmountNotZero_returnsExistingMax() {
+        when(mAmbientState.getDozeAmount()).thenReturn(0.5f);
+        mNotificationPanelViewController.setMaxDisplayedNotifications(-1);
+
+        // computeMaxKeyguardNotifications sets maxAllowed to 0 at minimum if it updates the value
+        assertThat(mNotificationPanelViewController.computeMaxKeyguardNotifications())
+                .isEqualTo(-1);
+    }
+
+    @Test
+    public void computeMaxKeyguardNotifications_noTransition_updatesMax() {
+        when(mAmbientState.getFractionToShade()).thenReturn(0f);
+        when(mAmbientState.getDozeAmount()).thenReturn(0f);
+        mNotificationPanelViewController.setMaxDisplayedNotifications(-1);
+
+        // computeMaxKeyguardNotifications sets maxAllowed to 0 at minimum if it updates the value
+        assertThat(mNotificationPanelViewController.computeMaxKeyguardNotifications())
+                .isNotEqualTo(-1);
+    }
+
+    @Test
     public void testSetPanelScrimMinFraction() {
         mNotificationPanelViewController.setPanelScrimMinFraction(0.5f);
         verify(mNotificationShadeDepthController).setPanelPullDownMinFraction(eq(0.5f));
@@ -984,6 +1026,50 @@
         assertThat(mNotificationPanelViewController.mQsExpandImmediate).isTrue();
     }
 
+    @Test
+    public void interceptTouchEvent_withinQs_shadeExpanded_startsQsTracking() {
+        mNotificationPanelViewController.mQs = mQs;
+        when(mQsFrame.getX()).thenReturn(0f);
+        when(mQsFrame.getWidth()).thenReturn(1000);
+        when(mQsHeader.getTop()).thenReturn(0);
+        when(mQsHeader.getBottom()).thenReturn(1000);
+        PanelViewController.TouchHandler touchHandler =
+                mNotificationPanelViewController.createTouchHandler();
+
+        mNotificationPanelViewController.setExpandedFraction(1f);
+        touchHandler.onInterceptTouchEvent(
+                createMotionEvent(/* x= */ 0, /* y= */ 0, MotionEvent.ACTION_DOWN));
+        touchHandler.onInterceptTouchEvent(
+                createMotionEvent(/* x= */ 0, /* y= */ 500, MotionEvent.ACTION_MOVE));
+
+        assertThat(mNotificationPanelViewController.isQsTracking()).isTrue();
+    }
+
+    @Test
+    public void interceptTouchEvent_withinQs_shadeExpanded_inSplitShade_doesNotStartQsTracking() {
+        enableSplitShade(true);
+        mNotificationPanelViewController.mQs = mQs;
+        when(mQsFrame.getX()).thenReturn(0f);
+        when(mQsFrame.getWidth()).thenReturn(1000);
+        when(mQsHeader.getTop()).thenReturn(0);
+        when(mQsHeader.getBottom()).thenReturn(1000);
+        PanelViewController.TouchHandler touchHandler =
+                mNotificationPanelViewController.createTouchHandler();
+
+        mNotificationPanelViewController.setExpandedFraction(1f);
+        touchHandler.onInterceptTouchEvent(
+                createMotionEvent(/* x= */ 0, /* y= */ 0, MotionEvent.ACTION_DOWN));
+        touchHandler.onInterceptTouchEvent(
+                createMotionEvent(/* x= */ 0, /* y= */ 500, MotionEvent.ACTION_MOVE));
+
+        assertThat(mNotificationPanelViewController.isQsTracking()).isFalse();
+    }
+
+    private static MotionEvent createMotionEvent(int x, int y, int action) {
+        return MotionEvent.obtain(
+                /* downTime= */ 0, /* eventTime= */ 0, action, x, y, /* metaState= */ 0);
+    }
+
     private void triggerPositionClockAndNotifications() {
         mNotificationPanelViewController.closeQs();
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index a94ad0b..aaa5a6b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -61,7 +61,9 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
 import java.util.Optional;
@@ -97,6 +99,7 @@
     @Mock private LatencyTracker mLatencyTracker;
 
     private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+    private KeyguardBouncer.BouncerExpansionCallback mBouncerExpansionCallback;
 
     @Before
     public void setUp() {
@@ -136,6 +139,11 @@
                 mBypassController);
         when(mKeyguardStateController.isOccluded()).thenReturn(false);
         mStatusBarKeyguardViewManager.show(null);
+        ArgumentCaptor<KeyguardBouncer.BouncerExpansionCallback> callbackArgumentCaptor =
+                ArgumentCaptor.forClass(KeyguardBouncer.BouncerExpansionCallback.class);
+        verify(mKeyguardBouncerFactory).create(any(ViewGroup.class),
+                callbackArgumentCaptor.capture());
+        mBouncerExpansionCallback = callbackArgumentCaptor.getValue();
     }
 
     @Test
@@ -192,6 +200,15 @@
     }
 
     @Test
+    public void onPanelExpansionChanged_propagatesToBouncer_evenAfterHidden() {
+        mStatusBarKeyguardViewManager.hide(0, 0);
+        when(mBouncer.inTransit()).thenReturn(true);
+
+        mStatusBarKeyguardViewManager.onPanelExpansionChanged(EXPANSION_EVENT);
+        verify(mBouncer).setExpansion(eq(EXPANSION_EVENT.getFraction()));
+    }
+
+    @Test
     public void onPanelExpansionChanged_showsBouncerWhenSwiping() {
         when(mKeyguardStateController.canDismissLockScreen()).thenReturn(false);
         mStatusBarKeyguardViewManager.onPanelExpansionChanged(EXPANSION_EVENT);
@@ -417,4 +434,24 @@
         return new PanelExpansionChangeEvent(
                 fraction, expanded, tracking, /* dragDownPxAmount= */ 0f);
     }
+
+    @Test
+    public void testReportBouncerOnDreamWhenVisible() {
+        mBouncerExpansionCallback.onVisibilityChanged(true);
+        verify(mCentralSurfaces).setBouncerShowingOverDream(false);
+        Mockito.clearInvocations(mCentralSurfaces);
+        when(mDreamOverlayStateController.isOverlayActive()).thenReturn(true);
+        mBouncerExpansionCallback.onVisibilityChanged(true);
+        verify(mCentralSurfaces).setBouncerShowingOverDream(true);
+    }
+
+    @Test
+    public void testReportBouncerOnDreamWhenNotVisible() {
+        mBouncerExpansionCallback.onVisibilityChanged(false);
+        verify(mCentralSurfaces).setBouncerShowingOverDream(false);
+        Mockito.clearInvocations(mCentralSurfaces);
+        when(mDreamOverlayStateController.isOverlayActive()).thenReturn(true);
+        mBouncerExpansionCallback.onVisibilityChanged(false);
+        verify(mCentralSurfaces).setBouncerShowingOverDream(false);
+    }
 }
diff --git a/packages/VpnDialogs/res/values-iw/strings.xml b/packages/VpnDialogs/res/values-iw/strings.xml
index 81903d2..56d8105 100644
--- a/packages/VpnDialogs/res/values-iw/strings.xml
+++ b/packages/VpnDialogs/res/values-iw/strings.xml
@@ -32,6 +32,6 @@
     <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"‏לשינוי של הגדרות ה-VPN"</string>
     <string name="configure" msgid="4905518375574791375">"הגדרה"</string>
     <string name="disconnect" msgid="971412338304200056">"נתק"</string>
-    <string name="open_app" msgid="3717639178595958667">"לאפליקציה"</string>
+    <string name="open_app" msgid="3717639178595958667">"פתיחת האפליקציה"</string>
     <string name="dismiss" msgid="6192859333764711227">"סגירה"</string>
 </resources>
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 8c4db70..aa5c501 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -805,12 +805,13 @@
      * Updates the last fill response when a dataset was selected.
      */
     void logDatasetSelected(@Nullable String selectedDataset, int sessionId,
-            @Nullable Bundle clientState) {
+            @Nullable Bundle clientState,  int presentationType) {
         synchronized (mLock) {
             if (isValidEventLocked("logDatasetSelected()", sessionId)) {
                 mEventHistory.addEvent(
                         new Event(Event.TYPE_DATASET_SELECTED, selectedDataset, clientState, null,
-                                null, null, null, null, null, null, null));
+                                null, null, null, null, null, null, null, NO_SAVE_UI_REASON_NONE,
+                                presentationType));
             }
         }
     }
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index b0445ae..73d45be 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -21,6 +21,7 @@
 import static android.service.autofill.FillEventHistory.Event.UI_TYPE_DIALOG;
 import static android.service.autofill.FillEventHistory.Event.UI_TYPE_INLINE;
 import static android.service.autofill.FillEventHistory.Event.UI_TYPE_MENU;
+import static android.service.autofill.FillEventHistory.Event.UI_TYPE_UNKNOWN;
 import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;
 import static android.service.autofill.FillRequest.FLAG_PASSWORD_INPUT_TYPE;
 import static android.service.autofill.FillRequest.FLAG_SUPPORTS_FILL_DIALOG;
@@ -1479,7 +1480,7 @@
 
     // AutoFillUiCallback
     @Override
-    public void fill(int requestId, int datasetIndex, Dataset dataset) {
+    public void fill(int requestId, int datasetIndex, Dataset dataset, int uiType) {
         synchronized (mLock) {
             if (mDestroyed) {
                 Slog.w(TAG, "Call to Session#fill() rejected - session: "
@@ -1489,7 +1490,7 @@
         }
         mHandler.sendMessage(obtainMessage(
                 Session::autoFill,
-                this, requestId, datasetIndex, dataset, true));
+                this, requestId, datasetIndex, dataset, true, uiType));
     }
 
     // AutoFillUiCallback
@@ -1730,7 +1731,7 @@
                 if (!isAuthResultDatasetEphemeral(oldDataset, data)) {
                     authenticatedResponse.getDatasets().set(datasetIdx, dataset);
                 }
-                autoFill(requestId, datasetIdx, dataset, false);
+                autoFill(requestId, datasetIdx, dataset, false, UI_TYPE_UNKNOWN);
             } else {
                 Slog.w(TAG, "invalid index (" + datasetIdx + ") for authentication id "
                         + authenticationId);
@@ -3469,7 +3470,7 @@
                 new InlineFillUi.InlineSuggestionUiCallback() {
                     @Override
                     public void autofill(@NonNull Dataset dataset, int datasetIndex) {
-                        fill(response.getRequestId(), datasetIndex, dataset);
+                        fill(response.getRequestId(), datasetIndex, dataset, UI_TYPE_INLINE);
                     }
 
                     @Override
@@ -3988,7 +3989,8 @@
         return viewState;
     }
 
-    void autoFill(int requestId, int datasetIndex, Dataset dataset, boolean generateEvent) {
+    void autoFill(int requestId, int datasetIndex, Dataset dataset, boolean generateEvent,
+            int uiType) {
         if (sDebug) {
             Slog.d(TAG, "autoFill(): requestId=" + requestId  + "; datasetIdx=" + datasetIndex
                     + "; dataset=" + dataset);
@@ -4002,7 +4004,7 @@
             // Autofill it directly...
             if (dataset.getAuthentication() == null) {
                 if (generateEvent) {
-                    mService.logDatasetSelected(dataset.getId(), id, mClientState);
+                    mService.logDatasetSelected(dataset.getId(), id, mClientState, uiType);
                 }
                 if (mCurrentViewId != null) {
                     mInlineSessionController.hideInlineSuggestionsUiLocked(mCurrentViewId);
diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
index 056ab92..57768ef 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -15,6 +15,9 @@
  */
 package com.android.server.autofill.ui;
 
+import static android.service.autofill.FillEventHistory.Event.UI_TYPE_DIALOG;
+import static android.service.autofill.FillEventHistory.Event.UI_TYPE_MENU;
+
 import static com.android.server.autofill.Helper.sDebug;
 import static com.android.server.autofill.Helper.sVerbose;
 
@@ -31,6 +34,7 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.service.autofill.Dataset;
+import android.service.autofill.FillEventHistory;
 import android.service.autofill.FillResponse;
 import android.service.autofill.SaveInfo;
 import android.service.autofill.ValueFinder;
@@ -81,7 +85,8 @@
     public interface AutoFillUiCallback {
         void authenticate(int requestId, int datasetIndex, @NonNull IntentSender intent,
                 @Nullable Bundle extras, boolean authenticateInline);
-        void fill(int requestId, int datasetIndex, @NonNull Dataset dataset);
+        void fill(int requestId, int datasetIndex, @NonNull Dataset dataset,
+                @FillEventHistory.Event.UiType int uiType);
         void save();
         void cancelSave();
         void requestShowFillUi(AutofillId id, int width, int height,
@@ -236,7 +241,8 @@
                     hideFillUiUiThread(callback, true);
                     if (mCallback != null) {
                         final int datasetIndex = response.getDatasets().indexOf(dataset);
-                        mCallback.fill(response.getRequestId(), datasetIndex, dataset);
+                        mCallback.fill(response.getRequestId(), datasetIndex,
+                                dataset, UI_TYPE_MENU);
                     }
                 }
 
@@ -414,7 +420,8 @@
                             hideFillDialogUiThread(callback);
                             if (mCallback != null) {
                                 final int datasetIndex = response.getDatasets().indexOf(dataset);
-                                mCallback.fill(response.getRequestId(), datasetIndex, dataset);
+                                mCallback.fill(response.getRequestId(), datasetIndex, dataset,
+                                        UI_TYPE_DIALOG);
                             }
                         }
 
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index a67b858d..5167500 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -873,6 +873,13 @@
         mContext.registerReceiver(mBroadcastReceiver, filter);
     }
 
+    //helper function to determine if limit on num listeners applies to callingUid
+    private boolean doesLimitApplyForListeners(int callingUid, int exemptUid) {
+        return (callingUid != Process.SYSTEM_UID
+                && callingUid != Process.PHONE_UID
+                && callingUid != exemptUid);
+    }
+
     @Override
     public void addOnSubscriptionsChangedListener(String callingPackage, String callingFeatureId,
             IOnSubscriptionsChangedListener callback) {
@@ -887,7 +894,9 @@
         synchronized (mRecords) {
             // register
             IBinder b = callback.asBinder();
-            Record r = add(b, Binder.getCallingUid(), Binder.getCallingPid(), false);
+            boolean doesLimitApply = doesLimitApplyForListeners(Binder.getCallingUid(),
+                    Process.myUid());
+            Record r = add(b, Binder.getCallingUid(), Binder.getCallingPid(), doesLimitApply); //
 
             if (r == null) {
                 return;
@@ -941,7 +950,9 @@
         synchronized (mRecords) {
             // register
             IBinder b = callback.asBinder();
-            Record r = add(b, Binder.getCallingUid(), Binder.getCallingPid(), false);
+            boolean doesLimitApply = doesLimitApplyForListeners(Binder.getCallingUid(),
+                    Process.myUid());
+            Record r = add(b, Binder.getCallingUid(), Binder.getCallingPid(), doesLimitApply); //
 
             if (r == null) {
                 return;
@@ -1070,10 +1081,8 @@
         synchronized (mRecords) {
             // register
             IBinder b = callback.asBinder();
-            boolean doesLimitApply =
-                    Binder.getCallingUid() != Process.SYSTEM_UID
-                            && Binder.getCallingUid() != Process.PHONE_UID
-                            && Binder.getCallingUid() != Process.myUid();
+            boolean doesLimitApply = doesLimitApplyForListeners(Binder.getCallingUid(),
+                    Process.myUid());
             Record r = add(b, Binder.getCallingUid(), Binder.getCallingPid(), doesLimitApply);
 
             if (r == null) {
@@ -1417,7 +1426,7 @@
                         .isRegistrationLimitEnabledInPlatformCompat(callingUid)) {
                     throw new IllegalStateException(errorMsg);
                 }
-            } else if (doesLimitApply && numRecordsForPid
+            } else if (numRecordsForPid
                     >= TelephonyCallback.DEFAULT_PER_PID_REGISTRATION_LIMIT / 2) {
                 // Log the warning independently of the dynamically set limit -- apps shouldn't be
                 // doing this regardless of whether we're throwing them an exception for it.
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index a900f6f..6092f16 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -143,10 +143,12 @@
             "android.hardware.media.omx@1.0::IOmx",
             "android.hardware.media.omx@1.0::IOmxStore",
             "android.hardware.neuralnetworks@1.0::IDevice",
+            "android.hardware.power@1.0::IPower",
             "android.hardware.power.stats@1.0::IPowerStats",
             "android.hardware.sensors@1.0::ISensors",
             "android.hardware.sensors@2.0::ISensors",
             "android.hardware.sensors@2.1::ISensors",
+            "android.hardware.vibrator@1.0::IVibrator",
             "android.hardware.vr@1.0::IVr",
             "android.system.suspend@1.0::ISystemSuspend"
     );
@@ -155,7 +157,10 @@
             "android.hardware.biometrics.face.IFace/",
             "android.hardware.biometrics.fingerprint.IFingerprint/",
             "android.hardware.light.ILights/",
+            "android.hardware.power.IPower/",
             "android.hardware.power.stats.IPowerStats/",
+            "android.hardware.vibrator.IVibrator/",
+            "android.hardware.vibrator.IVibratorManager/"
     };
 
     private static Watchdog sWatchdog;
@@ -863,6 +868,7 @@
         if (halfWatchdog) {
             dropboxTag = "pre_watchdog";
             CriticalEventLog.getInstance().logHalfWatchdog(subject);
+            FrameworkStatsLog.write(FrameworkStatsLog.SYSTEM_SERVER_PRE_WATCHDOG_OCCURRED);
         } else {
             dropboxTag = "watchdog";
             CriticalEventLog.getInstance().logWatchdog(subject, errorId);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 201b6c3..af171b5 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -49,6 +49,7 @@
 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.content.pm.PackageManager.SIGNATURE_NO_MATCH;
 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;
@@ -8705,7 +8706,9 @@
         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
 
         // Check if we should rate limit and abort early if needed.
-        if (mDropboxRateLimiter.shouldRateLimit(eventType, processName)) return;
+        final DropboxRateLimiter.RateLimitResult rateLimitResult =
+                mDropboxRateLimiter.shouldRateLimit(eventType, processName);
+        if (rateLimitResult.shouldRateLimit()) return;
 
         final StringBuilder sb = new StringBuilder(1024);
         appendDropBoxProcessHeaders(process, processName, sb);
@@ -8754,6 +8757,8 @@
                         millisSinceOldestPendingRead).append("\n");
             }
         }
+        sb.append("Dropped-Count: ").append(
+                rateLimitResult.droppedCountSinceRateLimitActivated()).append("\n");
         sb.append("\n");
 
         // Do the rest in a worker thread to avoid blocking the caller on I/O
@@ -14506,8 +14511,12 @@
                 return false;
             }
 
-            int match = mContext.getPackageManager().checkSignatures(
-                    ii.targetPackage, ii.packageName);
+            int match = SIGNATURE_NO_MATCH;
+            try {
+                match = AppGlobals.getPackageManager().checkSignatures(
+                        ii.targetPackage, ii.packageName, userId);
+            } catch (RemoteException e) {
+            }
             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
                 if (Build.IS_DEBUGGABLE && (callingUid == Process.ROOT_UID)
                         && (flags & INSTR_FLAG_ALWAYS_CHECK_SIGNATURE) == 0) {
diff --git a/services/core/java/com/android/server/am/AppBatteryTracker.java b/services/core/java/com/android/server/am/AppBatteryTracker.java
index 9ce2751..9894a52 100644
--- a/services/core/java/com/android/server/am/AppBatteryTracker.java
+++ b/services/core/java/com/android/server/am/AppBatteryTracker.java
@@ -287,7 +287,10 @@
      */
     @Override
     byte[] getTrackerInfoForStatsd(int uid) {
-        final ImmutableBatteryUsage temp = mUidBatteryUsageInWindow.get(uid);
+        final ImmutableBatteryUsage temp;
+        synchronized (mLock) {
+            temp = mUidBatteryUsageInWindow.get(uid);
+        }
         if (temp == null) {
             return null;
         }
diff --git a/services/core/java/com/android/server/am/AppBindServiceEventsTracker.java b/services/core/java/com/android/server/am/AppBindServiceEventsTracker.java
index 9bed077..f944322 100644
--- a/services/core/java/com/android/server/am/AppBindServiceEventsTracker.java
+++ b/services/core/java/com/android/server/am/AppBindServiceEventsTracker.java
@@ -24,6 +24,9 @@
 import android.annotation.NonNull;
 import android.app.ActivityManagerInternal.BindServiceEventListener;
 import android.content.Context;
+import android.os.AppBackgroundRestrictionsInfo;
+import android.os.SystemClock;
+import android.util.proto.ProtoOutputStream;
 
 import com.android.server.am.AppBindServiceEventsTracker.AppBindServiceEventsPolicy;
 import com.android.server.am.AppRestrictionController.TrackerType;
@@ -82,6 +85,22 @@
     }
 
     @Override
+    byte[] getTrackerInfoForStatsd(int uid) {
+        final long now = SystemClock.elapsedRealtime();
+        final int numOfBindRequests = getTotalEventsLocked(uid, now);
+        if (numOfBindRequests == 0) {
+            // Not interested.
+            return null;
+        }
+        final ProtoOutputStream proto = new ProtoOutputStream();
+        proto.write(
+                AppBackgroundRestrictionsInfo.BindServiceEventsTrackerInfo.BIND_SERVICE_REQUESTS,
+                numOfBindRequests);
+        proto.flush();
+        return proto.getBytes();
+    }
+
+    @Override
     void dump(PrintWriter pw, String prefix) {
         pw.print(prefix);
         pw.println("APP BIND SERVICE EVENT TRACKER:");
diff --git a/services/core/java/com/android/server/am/AppBroadcastEventsTracker.java b/services/core/java/com/android/server/am/AppBroadcastEventsTracker.java
index a9155a1..b509008f 100644
--- a/services/core/java/com/android/server/am/AppBroadcastEventsTracker.java
+++ b/services/core/java/com/android/server/am/AppBroadcastEventsTracker.java
@@ -24,6 +24,9 @@
 import android.annotation.NonNull;
 import android.app.ActivityManagerInternal.BroadcastEventListener;
 import android.content.Context;
+import android.os.AppBackgroundRestrictionsInfo;
+import android.os.SystemClock;
+import android.util.proto.ProtoOutputStream;
 
 import com.android.server.am.AppBroadcastEventsTracker.AppBroadcastEventsPolicy;
 import com.android.server.am.AppRestrictionController.TrackerType;
@@ -81,6 +84,21 @@
     }
 
     @Override
+    byte[] getTrackerInfoForStatsd(int uid) {
+        final long now = SystemClock.elapsedRealtime();
+        final int numOfBroadcasts = getTotalEventsLocked(uid, now);
+        if (numOfBroadcasts == 0) {
+            // Not interested.
+            return null;
+        }
+        final ProtoOutputStream proto = new ProtoOutputStream();
+        proto.write(AppBackgroundRestrictionsInfo.BroadcastEventsTrackerInfo.BROADCASTS_SENT,
+                numOfBroadcasts);
+        proto.flush();
+        return proto.getBytes();
+    }
+
+    @Override
     void dump(PrintWriter pw, String prefix) {
         pw.print(prefix);
         pw.println("APP BROADCAST EVENT TRACKER:");
diff --git a/services/core/java/com/android/server/am/AppFGSTracker.java b/services/core/java/com/android/server/am/AppFGSTracker.java
index ddd2764..50515cd 100644
--- a/services/core/java/com/android/server/am/AppFGSTracker.java
+++ b/services/core/java/com/android/server/am/AppFGSTracker.java
@@ -35,6 +35,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.ServiceInfo.ForegroundServiceType;
+import android.os.AppBackgroundRestrictionsInfo;
 import android.os.Handler;
 import android.os.Message;
 import android.os.PowerExemptionManager.ReasonCode;
@@ -49,6 +50,7 @@
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 import android.util.TimeUtils;
+import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
@@ -516,6 +518,12 @@
                 foregroundServiceTypeToIndex(FOREGROUND_SERVICE_TYPE_NONE));
     }
 
+    @Override
+    long getTotalDurations(int uid, long now) {
+        return getTotalDurations(uid, now,
+                foregroundServiceTypeToIndex(FOREGROUND_SERVICE_TYPE_NONE));
+    }
+
     boolean hasForegroundServices(String packageName, int uid) {
         synchronized (mLock) {
             final PackageDurations pkg = mPkgEvents.get(uid, packageName);
@@ -562,6 +570,21 @@
     }
 
     @Override
+    byte[] getTrackerInfoForStatsd(int uid) {
+        final long fgsDurations = getTotalDurations(uid, SystemClock.elapsedRealtime());
+        if (fgsDurations == 0L) {
+            // Not interested
+            return null;
+        }
+        final ProtoOutputStream proto = new ProtoOutputStream();
+        proto.write(AppBackgroundRestrictionsInfo.FgsTrackerInfo.FGS_NOTIFICATION_VISIBLE,
+                hasForegroundServiceNotifications(uid));
+        proto.write(AppBackgroundRestrictionsInfo.FgsTrackerInfo.FGS_DURATION, fgsDurations);
+        proto.flush();
+        return proto.getBytes();
+    }
+
+    @Override
     void dump(PrintWriter pw, String prefix) {
         pw.print(prefix);
         pw.println("APP FOREGROUND SERVICE TRACKER:");
diff --git a/services/core/java/com/android/server/am/AppRestrictionController.java b/services/core/java/com/android/server/am/AppRestrictionController.java
index 7b763b7..0c1ab81 100644
--- a/services/core/java/com/android/server/am/AppRestrictionController.java
+++ b/services/core/java/com/android/server/am/AppRestrictionController.java
@@ -2435,6 +2435,21 @@
         }
 
         void postLongRunningFgsIfNecessary(String packageName, int uid) {
+            // Log the event in statsd.
+            FrameworkStatsLog.write(FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO,
+                    uid,
+                    mBgController.getRestrictionLevel(uid),
+                    AppBackgroundRestrictionsInfo.THRESHOLD_UNKNOWN,
+                    AppBackgroundRestrictionsInfo.FGS_TRACKER,
+                    mInjector.getAppFGSTracker().getTrackerInfoForStatsd(uid),
+                    null, // BatteryTrackerInfo
+                    null, // BroadcastEventsTrackerInfo
+                    null, // BindServiceEventsTrackerInfo
+                    getExemptionReasonForStatsd(
+                            mBgController.getBackgroundRestrictionExemptionReason(uid)),
+                    AppBackgroundRestrictionsInfo.UNKNOWN, // OptimizationLevel
+                    AppBackgroundRestrictionsInfo.SDK_UNKNOWN, // TargetSdk
+                    ActivityManager.isLowRamDeviceStatic());
             PendingIntent pendingIntent;
             if (!mBgController.mConstantsObserver.mBgPromptFgsWithNotiOnLongRunning
                     && mBgController.hasForegroundServiceNotifications(packageName, uid)) {
diff --git a/services/core/java/com/android/server/am/BaseAppStateTimeSlotEventsTracker.java b/services/core/java/com/android/server/am/BaseAppStateTimeSlotEventsTracker.java
index a12d7de..ff78355 100644
--- a/services/core/java/com/android/server/am/BaseAppStateTimeSlotEventsTracker.java
+++ b/services/core/java/com/android/server/am/BaseAppStateTimeSlotEventsTracker.java
@@ -133,6 +133,15 @@
         mTmpPkgs.clear();
     }
 
+    @GuardedBy("mLock")
+    int getTotalEventsLocked(int uid, long now) {
+        final U events = getUidEventsLocked(uid);
+        if (events == null) {
+            return 0;
+        }
+        return events.getTotalEvents(now, SimpleAppStateTimeslotEvents.DEFAULT_INDEX);
+    }
+
     private void trimEvents() {
         final long now = SystemClock.elapsedRealtime();
         trim(Math.max(0, now - mInjector.getPolicy().getMaxTrackingDuration()));
diff --git a/services/core/java/com/android/server/am/DropboxRateLimiter.java b/services/core/java/com/android/server/am/DropboxRateLimiter.java
index c517023..672736d 100644
--- a/services/core/java/com/android/server/am/DropboxRateLimiter.java
+++ b/services/core/java/com/android/server/am/DropboxRateLimiter.java
@@ -49,7 +49,7 @@
     }
 
     /** Determines whether dropbox entries of a specific tag and process should be rate limited. */
-    public boolean shouldRateLimit(String eventType, String processName) {
+    public RateLimitResult shouldRateLimit(String eventType, String processName) {
         // Rate-limit how often we're willing to do the heavy lifting to collect and record logs.
         final long now = mClock.uptimeMillis();
         synchronized (mErrorClusterRecords) {
@@ -60,17 +60,33 @@
             if (errRecord == null) {
                 errRecord = new ErrorRecord(now, 1);
                 mErrorClusterRecords.put(errorKey(eventType, processName), errRecord);
-            } else if (now - errRecord.getStartTime() > RATE_LIMIT_BUFFER_DURATION) {
+                return new RateLimitResult(false, 0);
+            }
+
+            if (now - errRecord.getStartTime() > RATE_LIMIT_BUFFER_DURATION) {
                 errRecord.setStartTime(now);
                 errRecord.setCount(1);
-            } else {
-                errRecord.incrementCount();
-                if (errRecord.getCount() > RATE_LIMIT_ALLOWED_ENTRIES) return true;
+                return new RateLimitResult(false, recentlyDroppedCount(errRecord));
+            }
+
+            errRecord.incrementCount();
+            if (errRecord.getCount() > RATE_LIMIT_ALLOWED_ENTRIES) {
+                return new RateLimitResult(true, recentlyDroppedCount(errRecord));
             }
         }
-        return false;
+        return new RateLimitResult(false, 0);
     }
 
+    /**
+     * Returns the number of entries of a certain type and process that have recenlty been
+     * dropped. Resets every RATE_LIMIT_BUFFER_DURATION if events are still actively created or
+     * RATE_LIMIT_BUFFER_EXPIRY if not. */
+    private int recentlyDroppedCount(ErrorRecord errRecord) {
+        if (errRecord == null || errRecord.getCount() < RATE_LIMIT_ALLOWED_ENTRIES) return 0;
+        return errRecord.getCount() - RATE_LIMIT_ALLOWED_ENTRIES;
+    }
+
+
     private void maybeRemoveExpiredRecords(long now) {
         if (now - mLastMapCleanUp <= RATE_LIMIT_BUFFER_EXPIRY) return;
 
@@ -87,6 +103,27 @@
         return eventType + processName;
     }
 
+    /** Holds information on whether we should rate limit and how many events have been dropped. */
+    public class RateLimitResult {
+        boolean mShouldRateLimit;
+        int mDroppedCountSinceRateLimitActivated;
+
+        public RateLimitResult(boolean shouldRateLimit, int droppedCountSinceRateLimitActivated) {
+            mShouldRateLimit = shouldRateLimit;
+            mDroppedCountSinceRateLimitActivated = droppedCountSinceRateLimitActivated;
+        }
+
+        /** Whether to rate limit. */
+        public boolean shouldRateLimit() {
+            return mShouldRateLimit;
+        }
+
+        /** The number of dropped events since rate limit was activated. */
+        public int droppedCountSinceRateLimitActivated() {
+            return mDroppedCountSinceRateLimitActivated;
+        }
+    }
+
     private class ErrorRecord {
         long mStartTime;
         int mCount;
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index fc73a59..c09e928 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -2307,8 +2307,8 @@
             if (!regularZygote) {
                 // webview and app zygote don't have the permission to create the nodes
                 if (Process.createProcessGroup(uid, startResult.pid) < 0) {
-                    Slog.e(ActivityManagerService.TAG, "Unable to create process group for "
-                            + app.processName + " (" + startResult.pid + ")");
+                    throw new AssertionError("Unable to create process group for " + app.processName
+                            + " (" + startResult.pid + ")");
                 }
             }
 
diff --git a/services/core/java/com/android/server/ambientcontext/AmbientContextManagerPerUserService.java b/services/core/java/com/android/server/ambientcontext/AmbientContextManagerPerUserService.java
index 766283b..028288f 100644
--- a/services/core/java/com/android/server/ambientcontext/AmbientContextManagerPerUserService.java
+++ b/services/core/java/com/android/server/ambientcontext/AmbientContextManagerPerUserService.java
@@ -43,7 +43,6 @@
 import android.service.ambientcontext.AmbientContextDetectionResult;
 import android.service.ambientcontext.AmbientContextDetectionServiceStatus;
 import android.text.TextUtils;
-import android.util.ArraySet;
 import android.util.IndentingPrintWriter;
 import android.util.Slog;
 
@@ -54,7 +53,6 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Set;
 
 /**
  * Per-user manager service for {@link AmbientContextEvent}s.
@@ -69,19 +67,13 @@
     RemoteAmbientContextDetectionService mRemoteService;
 
     private ComponentName mComponentName;
-    private Set<PendingIntent> mExistingPendingIntents;
 
     AmbientContextManagerPerUserService(
             @NonNull AmbientContextManagerService master, Object lock, @UserIdInt int userId) {
         super(master, lock, userId);
-        mExistingPendingIntents = new ArraySet<>();
     }
 
     void destroyLocked() {
-        if (isVerbose()) {
-            Slog.v(TAG, "destroyLocked()");
-        }
-
         Slog.d(TAG, "Trying to cancel the remote request. Reason: Service destroyed.");
         if (mRemoteService != null) {
             synchronized (mLock) {
@@ -118,7 +110,19 @@
         if (mComponentName == null) {
             mComponentName = updateServiceInfoLocked();
         }
-        return mComponentName != null;
+        if (mComponentName == null) {
+            return false;
+        }
+
+        ServiceInfo serviceInfo;
+        try {
+            serviceInfo = AppGlobals.getPackageManager().getServiceInfo(
+                    mComponentName, 0, mUserId);
+        } catch (RemoteException e) {
+            Slog.w(TAG, "RemoteException while setting up service");
+            return false;
+        }
+        return serviceInfo != null;
     }
 
     @Override
@@ -171,18 +175,10 @@
                 return;
             }
 
-            // Remove any existing PendingIntent for this package.
-            String callingPackage = pendingIntent.getCreatorPackage();
-            PendingIntent duplicatePendingIntent = findExistingRequestByPackage(callingPackage);
-            if (duplicatePendingIntent != null) {
-                Slog.d(TAG, "Replace duplicate request from " + callingPackage);
-                mExistingPendingIntents.remove(duplicatePendingIntent);
-            }
-
-            // Register package and add pendingIntent to mExistingPendingIntents
-            startDetection(request, callingPackage, createDetectionResultRemoteCallback(),
-                    getServerStatusCallback(clientStatusCallback));
-            mExistingPendingIntents.add(pendingIntent);
+            // Register package and add to existing ClientRequests cache
+            startDetection(request, pendingIntent.getCreatorPackage(),
+                    createDetectionResultRemoteCallback(), clientStatusCallback);
+            mMaster.newClientAdded(mUserId, request, pendingIntent, clientStatusCallback);
         }
     }
 
@@ -214,15 +210,17 @@
 
     @VisibleForTesting
     void startDetection(AmbientContextEventRequest request, String callingPackage,
-            RemoteCallback detectionResultCallback, RemoteCallback statusCallback) {
+            RemoteCallback detectionResultCallback, RemoteCallback clientStatusCallback) {
         Slog.d(TAG, "Requested detection of " + request.getEventTypes());
         synchronized (mLock) {
             if (setUpServiceIfNeeded()) {
                 ensureRemoteServiceInitiated();
                 mRemoteService.startDetection(request, callingPackage, detectionResultCallback,
-                        statusCallback);
+                        getServerStatusCallback(clientStatusCallback));
             } else {
                 Slog.w(TAG, "No valid component found for AmbientContextDetectionService");
+                sendStatusToCallback(clientStatusCallback,
+                        AmbientContextManager.STATUS_NOT_SUPPORTED);
             }
         }
     }
@@ -245,15 +243,8 @@
      */
     public void onUnregisterObserver(String callingPackage) {
         synchronized (mLock) {
-            PendingIntent pendingIntent = findExistingRequestByPackage(callingPackage);
-            if (pendingIntent == null) {
-                Slog.d(TAG, "No registration found for " + callingPackage);
-                return;
-            }
-
-            // Remove from existing requests
-            mExistingPendingIntents.remove(pendingIntent);
-            stopDetection(pendingIntent.getCreatorPackage());
+            stopDetection(callingPackage);
+            mMaster.clientRemoved(mUserId, callingPackage);
         }
     }
 
@@ -265,7 +256,7 @@
             if (!setUpServiceIfNeeded()) {
                 Slog.w(TAG, "Detection service is not available at this moment.");
                 sendStatusToCallback(statusCallback,
-                        AmbientContextManager.STATUS_SERVICE_UNAVAILABLE);
+                        AmbientContextManager.STATUS_NOT_SUPPORTED);
                 return;
             }
             ensureRemoteServiceInitiated();
@@ -382,16 +373,6 @@
         }
     }
 
-    @Nullable
-    private PendingIntent findExistingRequestByPackage(String callingPackage) {
-        for (PendingIntent pendingIntent : mExistingPendingIntents) {
-            if (pendingIntent.getCreatorPackage().equals(callingPackage)) {
-                return pendingIntent;
-            }
-        }
-        return null;
-    }
-
     /**
      * Sends out the Intent to the client after the event is detected.
      *
@@ -418,22 +399,22 @@
     }
 
     @NonNull
-    private RemoteCallback createDetectionResultRemoteCallback() {
+    RemoteCallback createDetectionResultRemoteCallback() {
         return new RemoteCallback(result -> {
             AmbientContextDetectionResult detectionResult =
                     (AmbientContextDetectionResult) result.get(
                             AmbientContextDetectionResult.RESULT_RESPONSE_BUNDLE_KEY);
+            String packageName = detectionResult.getPackageName();
+            PendingIntent pendingIntent = mMaster.getPendingIntent(mUserId, packageName);
+            if (pendingIntent == null) {
+                return;
+            }
+
             final long token = Binder.clearCallingIdentity();
             try {
-                for (PendingIntent pendingIntent : mExistingPendingIntents) {
-                    // Send PendingIntent to requesting packages
-                    String creatorPackage = pendingIntent.getCreatorPackage();
-                    if (detectionResult.getPackageName().equals(creatorPackage)) {
-                        sendDetectionResultIntent(pendingIntent, detectionResult);
-                        Slog.i(TAG, "Got detection result of " + detectionResult.getEvents()
-                                + " for " + creatorPackage);
-                    }
-                }
+                sendDetectionResultIntent(pendingIntent, detectionResult);
+                Slog.i(TAG, "Got detection result of " + detectionResult.getEvents()
+                        + " for " + packageName);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
diff --git a/services/core/java/com/android/server/ambientcontext/AmbientContextManagerService.java b/services/core/java/com/android/server/ambientcontext/AmbientContextManagerService.java
index cfca7ec..4206262 100644
--- a/services/core/java/com/android/server/ambientcontext/AmbientContextManagerService.java
+++ b/services/core/java/com/android/server/ambientcontext/AmbientContextManagerService.java
@@ -20,6 +20,7 @@
 
 import android.Manifest;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.app.PendingIntent;
 import android.app.ambientcontext.AmbientContextEvent;
@@ -34,6 +35,7 @@
 import android.os.ShellCallback;
 import android.os.UserHandle;
 import android.provider.DeviceConfig;
+import android.util.ArraySet;
 import android.util.Slog;
 
 import com.android.internal.R;
@@ -60,9 +62,50 @@
 
     /** Default value in absence of {@link DeviceConfig} override. */
     private static final boolean DEFAULT_SERVICE_ENABLED = true;
+    public static final int MAX_TEMPORARY_SERVICE_DURATION_MS = 30000;
+
+    static class ClientRequest {
+        private final int mUserId;
+        private final AmbientContextEventRequest mRequest;
+        private final PendingIntent mPendingIntent;
+        private final RemoteCallback mClientStatusCallback;
+
+        ClientRequest(int userId, AmbientContextEventRequest request,
+                PendingIntent pendingIntent, RemoteCallback clientStatusCallback) {
+            this.mUserId = userId;
+            this.mRequest = request;
+            this.mPendingIntent = pendingIntent;
+            this.mClientStatusCallback = clientStatusCallback;
+        }
+
+        String getPackageName() {
+            return mPendingIntent.getCreatorPackage();
+        }
+
+        AmbientContextEventRequest getRequest() {
+            return mRequest;
+        }
+
+        PendingIntent getPendingIntent() {
+            return mPendingIntent;
+        }
+
+        RemoteCallback getClientStatusCallback() {
+            return mClientStatusCallback;
+        }
+
+        boolean hasUserId(int userId) {
+            return mUserId == userId;
+        }
+
+        boolean hasUserIdAndPackageName(int userId, String packageName) {
+            return (userId == mUserId) && packageName.equals(getPackageName());
+        }
+    }
 
     private final Context mContext;
     boolean mIsServiceEnabled;
+    private Set<ClientRequest> mExistingClientRequests;
 
     public AmbientContextManagerService(Context context) {
         super(context,
@@ -73,6 +116,7 @@
                 PACKAGE_UPDATE_POLICY_REFRESH_EAGER
                         | /*To avoid high latency*/ PACKAGE_RESTART_POLICY_REFRESH_EAGER);
         mContext = context;
+        mExistingClientRequests = new ArraySet<>();
     }
 
     @Override
@@ -94,6 +138,44 @@
         }
     }
 
+    void newClientAdded(int userId, AmbientContextEventRequest request,
+            PendingIntent pendingIntent, RemoteCallback clientStatusCallback) {
+        Slog.d(TAG, "New client added: " + pendingIntent.getCreatorPackage());
+
+        // Remove any existing ClientRequest for this user and package.
+        mExistingClientRequests.removeAll(
+                findExistingRequests(userId, pendingIntent.getCreatorPackage()));
+
+        // Add to existing ClientRequests
+        mExistingClientRequests.add(
+                new ClientRequest(userId, request, pendingIntent, clientStatusCallback));
+    }
+
+    void clientRemoved(int userId, String packageName) {
+        Slog.d(TAG, "Remove client: " + packageName);
+        mExistingClientRequests.removeAll(findExistingRequests(userId, packageName));
+    }
+
+    private Set<ClientRequest> findExistingRequests(int userId, String packageName) {
+        Set<ClientRequest> existingRequests = new ArraySet<>();
+        for (ClientRequest clientRequest : mExistingClientRequests) {
+            if (clientRequest.hasUserIdAndPackageName(userId, packageName)) {
+                existingRequests.add(clientRequest);
+            }
+        }
+        return existingRequests;
+    }
+
+    @Nullable
+    PendingIntent getPendingIntent(int userId, String packageName) {
+        for (ClientRequest clientRequest : mExistingClientRequests) {
+            if (clientRequest.hasUserIdAndPackageName(userId, packageName)) {
+                return clientRequest.getPendingIntent();
+            }
+        }
+        return null;
+    }
+
     private void onDeviceConfigChange(@NonNull Set<String> keys) {
         if (keys.contains(KEY_SERVICE_ENABLED)) {
             mIsServiceEnabled = DeviceConfig.getBoolean(
@@ -111,9 +193,33 @@
     @Override
     protected void onServiceRemoved(
             AmbientContextManagerPerUserService service, @UserIdInt int userId) {
+        Slog.d(TAG, "onServiceRemoved");
         service.destroyLocked();
     }
 
+    @Override
+    protected void onServicePackageRestartedLocked(@UserIdInt int userId) {
+        Slog.d(TAG, "Restoring remote request. Reason: Service package restarted.");
+        restorePreviouslyEnabledClients(userId);
+    }
+
+    @Override
+    protected void onServicePackageUpdatedLocked(@UserIdInt int userId) {
+        Slog.d(TAG, "Restoring remote request. Reason: Service package updated.");
+        restorePreviouslyEnabledClients(userId);
+    }
+
+    @Override
+    protected void enforceCallingPermissionForManagement() {
+        getContext().enforceCallingPermission(
+                Manifest.permission.ACCESS_AMBIENT_CONTEXT_EVENT, TAG);
+    }
+
+    @Override
+    protected int getMaximumTemporaryServiceDurationMs() {
+        return MAX_TEMPORARY_SERVICE_DURATION_MS;
+    }
+
     /** Returns {@code true} if the detection service is configured on this device. */
     public static boolean isDetectionServiceConfigured() {
         final PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
@@ -182,6 +288,22 @@
         }
     }
 
+    private void restorePreviouslyEnabledClients(int userId) {
+        synchronized (mLock) {
+            final AmbientContextManagerPerUserService service = getServiceForUserLocked(userId);
+            for (ClientRequest clientRequest : mExistingClientRequests) {
+                // Start detection for previously enabled clients
+                if (clientRequest.hasUserId(userId)) {
+                    Slog.d(TAG, "Restoring detection for " + clientRequest.getPackageName());
+                    service.startDetection(clientRequest.getRequest(),
+                            clientRequest.getPackageName(),
+                            service.createDetectionResultRemoteCallback(),
+                            clientRequest.getClientStatusCallback());
+                }
+            }
+        }
+    }
+
     /**
      * Returns the AmbientContextManagerPerUserService component for this user.
      */
diff --git a/services/core/java/com/android/server/ambientcontext/AmbientContextShellCommand.java b/services/core/java/com/android/server/ambientcontext/AmbientContextShellCommand.java
index e2b22dc..ec6c2f0 100644
--- a/services/core/java/com/android/server/ambientcontext/AmbientContextShellCommand.java
+++ b/services/core/java/com/android/server/ambientcontext/AmbientContextShellCommand.java
@@ -21,12 +21,12 @@
 import android.annotation.NonNull;
 import android.app.ambientcontext.AmbientContextEvent;
 import android.app.ambientcontext.AmbientContextEventRequest;
+import android.app.ambientcontext.AmbientContextManager;
 import android.content.ComponentName;
 import android.os.Binder;
 import android.os.RemoteCallback;
 import android.os.ShellCommand;
 import android.service.ambientcontext.AmbientContextDetectionResult;
-import android.service.ambientcontext.AmbientContextDetectionServiceStatus;
 
 import java.io.PrintWriter;
 
@@ -51,13 +51,13 @@
     /** Callbacks for AmbientContextEventService results used internally for testing. */
     static class TestableCallbackInternal {
         private AmbientContextDetectionResult mLastResult;
-        private AmbientContextDetectionServiceStatus mLastStatus;
+        private int mLastStatus;
 
         public AmbientContextDetectionResult getLastResult() {
             return mLastResult;
         }
 
-        public AmbientContextDetectionServiceStatus getLastStatus() {
+        public int getLastStatus() {
             return mLastStatus;
         }
 
@@ -80,13 +80,10 @@
         @NonNull
         private RemoteCallback createRemoteStatusCallback() {
             return new RemoteCallback(result -> {
-                AmbientContextDetectionServiceStatus status =
-                        (AmbientContextDetectionServiceStatus) result.get(
-                                AmbientContextDetectionServiceStatus.STATUS_RESPONSE_BUNDLE_KEY);
+                int status = result.getInt(AmbientContextManager.STATUS_RESPONSE_BUNDLE_KEY);
                 final long token = Binder.clearCallingIdentity();
                 try {
                     mLastStatus = status;
-                    out.println("Status available: " + status);
                 } finally {
                     Binder.restoreCallingIdentity(token);
                 }
@@ -110,8 +107,6 @@
                 return runStopDetection();
             case "get-last-status-code":
                 return getLastStatusCode();
-            case "get-last-package-name":
-                return getLastPackageName();
             case "query-service-status":
                 return runQueryServiceStatus();
             case "get-bound-package":
@@ -126,7 +121,8 @@
     private int runStartDetection() {
         final int userId = Integer.parseInt(getNextArgRequired());
         final String packageName = getNextArgRequired();
-        mService.startDetection(userId, REQUEST, packageName,
+        mService.startDetection(
+                userId, REQUEST, packageName,
                 sTestableCallbackInternal.createRemoteDetectionResultCallback(),
                 sTestableCallbackInternal.createRemoteStatusCallback());
         return 0;
@@ -151,18 +147,9 @@
     }
 
     private int getLastStatusCode() {
-        AmbientContextDetectionServiceStatus lastResponse =
-                sTestableCallbackInternal.getLastStatus();
-        if (lastResponse == null) {
-            return -1;
-        }
-        return lastResponse.getStatusCode();
-    }
-
-    private int getLastPackageName() {
-        AmbientContextDetectionServiceStatus lastResponse =
-                sTestableCallbackInternal.getLastStatus();
-        out.println(lastResponse == null ? "" : lastResponse.getPackageName());
+        final PrintWriter resultPrinter = getOutPrintWriter();
+        int lastStatus = sTestableCallbackInternal.getLastStatus();
+        resultPrinter.println(lastStatus);
         return 0;
     }
 
@@ -174,22 +161,21 @@
         pw.println("    Print this help text.");
         pw.println();
         pw.println("  start-detection USER_ID PACKAGE_NAME: Starts AmbientContextEvent detection.");
-        pw.println("  stop-detection USER_ID: Stops AmbientContextEvent detection.");
+        pw.println("  stop-detection USER_ID PACKAGE_NAME: Stops AmbientContextEvent detection.");
         pw.println("  get-last-status-code: Prints the latest request status code.");
-        pw.println("  get-last-package-name: Prints the latest request package name.");
-        pw.println("  query-event-status USER_ID PACKAGE_NAME: Prints the event status code.");
+        pw.println("  query-service-status USER_ID PACKAGE_NAME: Prints the service status code.");
         pw.println("  get-bound-package USER_ID:"
                 + "     Print the bound package that implements the service.");
-        pw.println("  set-temporary-service USER_ID [COMPONENT_NAME DURATION]");
+        pw.println("  set-temporary-service USER_ID [PACKAGE_NAME] [COMPONENT_NAME DURATION]");
         pw.println("    Temporarily (for DURATION ms) changes the service implementation.");
         pw.println("    To reset, call with just the USER_ID argument.");
     }
 
     private int getBoundPackageName() {
-        final PrintWriter out = getOutPrintWriter();
+        final PrintWriter resultPrinter = getOutPrintWriter();
         final int userId = Integer.parseInt(getNextArgRequired());
         final ComponentName componentName = mService.getComponentName(userId);
-        out.println(componentName == null ? "" : componentName.getPackageName());
+        resultPrinter.println(componentName == null ? "" : componentName.getPackageName());
         return 0;
     }
 
diff --git a/services/core/java/com/android/server/biometrics/Utils.java b/services/core/java/com/android/server/biometrics/Utils.java
index e1ef277..e0bd6189 100644
--- a/services/core/java/com/android/server/biometrics/Utils.java
+++ b/services/core/java/com/android/server/biometrics/Utils.java
@@ -65,6 +65,7 @@
 import com.android.internal.widget.LockPatternUtils;
 import com.android.server.biometrics.sensors.BaseClientMonitor;
 
+import java.util.ArrayList;
 import java.util.List;
 
 public class Utils {
@@ -89,13 +90,40 @@
     }
 
     /** If virtualized biometrics are supported (requires debug build). */
-    public static boolean isVirtualEnabled(Context context) {
+    public static boolean isVirtualEnabled(@NonNull Context context) {
         return Build.isDebuggable()
                 && Settings.Secure.getIntForUser(context.getContentResolver(),
                 Settings.Secure.BIOMETRIC_VIRTUAL_ENABLED, 0, UserHandle.USER_CURRENT) == 1;
     }
 
     /**
+     * Get the enabled HAL instances. If virtual is enabled and available it will be returned as
+     * the only instance, otherwise all other instances will be returned.
+     *
+     * @param context system context
+     * @param declaredInstances known instances
+     * @return filtered list of enabled instances
+     */
+    @NonNull
+    public static List<String> filterAvailableHalInstances(@NonNull Context context,
+            @NonNull List<String> declaredInstances) {
+        if (declaredInstances.size() <= 1) {
+            return declaredInstances;
+        }
+
+        final int virtualAt = declaredInstances.indexOf("virtual");
+        if (isVirtualEnabled(context) && virtualAt != -1) {
+            return List.of(declaredInstances.get(virtualAt));
+        }
+
+        declaredInstances = new ArrayList<>(declaredInstances);
+        if (virtualAt != -1) {
+            declaredInstances.remove(virtualAt);
+        }
+        return declaredInstances;
+    }
+
+    /**
      * Combines {@link PromptInfo#setDeviceCredentialAllowed(boolean)} with
      * {@link PromptInfo#setAuthenticators(int)}, as the former is not flexible enough.
      */
diff --git a/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java b/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java
index 5aa9b79..c8a90e7 100644
--- a/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java
@@ -92,7 +92,7 @@
         void sendHapticFeedback();
     }
 
-    private static CoexCoordinator sInstance;
+    private static final CoexCoordinator sInstance = new CoexCoordinator();
 
     @VisibleForTesting
     public static class SuccessfulAuth {
@@ -147,14 +147,9 @@
         }
     }
 
-    /**
-     * @return a singleton instance.
-     */
+    /** The singleton instance. */
     @NonNull
     public static CoexCoordinator getInstance() {
-        if (sInstance == null) {
-            sInstance = new CoexCoordinator();
-        }
         return sInstance;
     }
 
@@ -339,18 +334,8 @@
                         auth.mCallback.sendHapticFeedback();
                         auth.mCallback.sendAuthenticationResult(true /* addAuthTokenIfStrong */);
                         auth.mCallback.handleLifecycleAfterAuth();
-                    } else if (isFaceScanning()) {
-                        // UDFPS rejected but face is still scanning
-                        Slog.d(TAG, "UDFPS rejected in multi-sensor auth, face: " + face);
-                        callback.handleLifecycleAfterAuth();
-
-                        // TODO(b/193089985): Enforce/ensure that face auth finishes (whether
-                        //  accept/reject) within X amount of time. Otherwise users will be stuck
-                        //  waiting with their finger down for a long time.
                     } else {
-                        // Face not scanning, and was not found in the queue. Most likely, face
-                        // auth was too long ago.
-                        Slog.d(TAG, "UDFPS rejected in multi-sensor auth, face not scanning");
+                        Slog.d(TAG, "UDFPS rejected in multi-sensor auth");
                         callback.sendHapticFeedback();
                         callback.handleLifecycleAfterAuth();
                     }
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index 9b098ca..3d8e466 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -48,7 +48,6 @@
 import android.hardware.biometrics.ITestSession;
 import android.hardware.biometrics.ITestSessionCallback;
 import android.hardware.biometrics.fingerprint.IFingerprint;
-import android.hardware.biometrics.fingerprint.SensorProps;
 import android.hardware.fingerprint.Fingerprint;
 import android.hardware.fingerprint.FingerprintManager;
 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
@@ -81,6 +80,7 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.server.ServiceThread;
@@ -95,12 +95,16 @@
 import com.android.server.biometrics.sensors.fingerprint.hidl.Fingerprint21;
 import com.android.server.biometrics.sensors.fingerprint.hidl.Fingerprint21UdfpsMock;
 
+import com.google.android.collect.Lists;
+
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.Executor;
+import java.util.function.Function;
+import java.util.function.Supplier;
 
 /**
  * A service to manage multiple clients that want to access the fingerprint HAL API.
@@ -116,10 +120,12 @@
     private final LockoutResetDispatcher mLockoutResetDispatcher;
     private final GestureAvailabilityDispatcher mGestureAvailabilityDispatcher;
     private final LockPatternUtils mLockPatternUtils;
-    private final FingerprintServiceWrapper mServiceWrapper;
     @NonNull private final List<ServiceProvider> mServiceProviders;
     @NonNull private final BiometricStateCallback mBiometricStateCallback;
     @NonNull private final Handler mHandler;
+    @NonNull private final BiometricContext mBiometricContext;
+    @NonNull private final Supplier<IBiometricService> mBiometricServiceSupplier;
+    @NonNull private final Function<String, IFingerprint> mIFingerprintProvider;
 
     @GuardedBy("mLock")
     @NonNull private final RemoteCallbackList<IFingerprintAuthenticatorsRegisteredCallback>
@@ -170,7 +176,7 @@
     /**
      * Receives the incoming binder calls from FingerprintManager.
      */
-    private final class FingerprintServiceWrapper extends IFingerprintService.Stub {
+    private final IFingerprintService.Stub mServiceWrapper = new IFingerprintService.Stub() {
         @Override
         public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
                 @NonNull String opPackageName) {
@@ -853,54 +859,6 @@
             mGestureAvailabilityDispatcher.removeCallback(callback);
         }
 
-        private void addHidlProviders(List<FingerprintSensorPropertiesInternal> hidlSensors) {
-            for (FingerprintSensorPropertiesInternal hidlSensor : hidlSensors) {
-                final Fingerprint21 fingerprint21;
-                if ((Build.IS_USERDEBUG || Build.IS_ENG)
-                        && getContext().getResources().getBoolean(R.bool.allow_test_udfps)
-                        && Settings.Secure.getIntForUser(getContext().getContentResolver(),
-                        Fingerprint21UdfpsMock.CONFIG_ENABLE_TEST_UDFPS, 0 /* default */,
-                        UserHandle.USER_CURRENT) != 0) {
-                    fingerprint21 = Fingerprint21UdfpsMock.newInstance(getContext(),
-                            mBiometricStateCallback, hidlSensor,
-                            mLockoutResetDispatcher, mGestureAvailabilityDispatcher,
-                            BiometricContext.getInstance(getContext()));
-                } else {
-                    fingerprint21 = Fingerprint21.newInstance(getContext(),
-                            mBiometricStateCallback, hidlSensor, mHandler,
-                            mLockoutResetDispatcher, mGestureAvailabilityDispatcher);
-                }
-                mServiceProviders.add(fingerprint21);
-            }
-        }
-
-        private void addAidlProviders() {
-            final String[] instances = ServiceManager.getDeclaredInstances(IFingerprint.DESCRIPTOR);
-            if (instances == null || instances.length == 0) {
-                return;
-            }
-            for (String instance : instances) {
-                final String fqName = IFingerprint.DESCRIPTOR + "/" + instance;
-                final IFingerprint fp = IFingerprint.Stub.asInterface(
-                        Binder.allowBlocking(ServiceManager.waitForDeclaredService(fqName)));
-                if (fp == null) {
-                    Slog.e(TAG, "Unable to get declared service: " + fqName);
-                    continue;
-                }
-                try {
-                    final SensorProps[] props = fp.getSensorProps();
-                    final FingerprintProvider provider =
-                            new FingerprintProvider(getContext(), mBiometricStateCallback, props,
-                                    instance, mLockoutResetDispatcher,
-                                    mGestureAvailabilityDispatcher,
-                                    BiometricContext.getInstance(getContext()));
-                    mServiceProviders.add(provider);
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Remote exception in getSensorProps: " + fqName);
-                }
-            }
-        }
-
         @Override // Binder call
         public void registerAuthenticators(
                 @NonNull List<FingerprintSensorPropertiesInternal> hidlSensors) {
@@ -914,42 +872,16 @@
                     true /* allowIo */);
             thread.start();
             final Handler handler = new Handler(thread.getLooper());
-
             handler.post(() -> {
-                addHidlProviders(hidlSensors);
-                addAidlProviders();
-
-                final IBiometricService biometricService = IBiometricService.Stub.asInterface(
-                        ServiceManager.getService(Context.BIOMETRIC_SERVICE));
-
-                // Register each sensor individually with BiometricService
-                for (ServiceProvider provider : mServiceProviders) {
-                    final List<FingerprintSensorPropertiesInternal> props =
-                            provider.getSensorProperties();
-                    for (FingerprintSensorPropertiesInternal prop : props) {
-                        final int sensorId = prop.sensorId;
-                        final @BiometricManager.Authenticators.Types int strength =
-                                Utils.propertyStrengthToAuthenticatorStrength(prop.sensorStrength);
-                        final FingerprintAuthenticator authenticator = new FingerprintAuthenticator(
-                                mServiceWrapper, sensorId);
-                        try {
-                            biometricService.registerAuthenticator(sensorId, TYPE_FINGERPRINT,
-                                    strength, authenticator);
-                        } catch (RemoteException e) {
-                            Slog.e(TAG, "Remote exception when registering sensorId: " + sensorId);
-                        }
-                    }
+                List<String> aidlSensors = new ArrayList<>();
+                final String[] instances =
+                        ServiceManager.getDeclaredInstances(IFingerprint.DESCRIPTOR);
+                if (instances != null) {
+                    aidlSensors.addAll(Lists.newArrayList(instances));
                 }
-
-                synchronized (mLock) {
-                    for (ServiceProvider provider : mServiceProviders) {
-                        mSensorProps.addAll(provider.getSensorProperties());
-                    }
-                }
-
-                broadcastCurrentEnrollmentState(null); // broadcasts to all listeners
-                broadcastAllAuthenticatorsRegistered();
+                registerAuthenticatorsForService(aidlSensors, hidlSensors);
             });
+            thread.quitSafely();
         }
 
         @Override
@@ -1033,11 +965,25 @@
         public void registerBiometricStateListener(@NonNull IBiometricStateListener listener) {
             FingerprintService.this.registerBiometricStateListener(listener);
         }
-    }
+    };
 
     public FingerprintService(Context context) {
+        this(context, BiometricContext.getInstance(context),
+                () -> IBiometricService.Stub.asInterface(
+                        ServiceManager.getService(Context.BIOMETRIC_SERVICE)),
+                (fqName) -> IFingerprint.Stub.asInterface(
+                        Binder.allowBlocking(ServiceManager.waitForDeclaredService(fqName))));
+    }
+
+    @VisibleForTesting
+    FingerprintService(Context context,
+            BiometricContext biometricContext,
+            Supplier<IBiometricService> biometricServiceProvider,
+            Function<String, IFingerprint> fingerprintProvider) {
         super(context);
-        mServiceWrapper = new FingerprintServiceWrapper();
+        mBiometricContext = biometricContext;
+        mBiometricServiceSupplier = biometricServiceProvider;
+        mIFingerprintProvider = fingerprintProvider;
         mAppOps = context.getSystemService(AppOpsManager.class);
         mGestureAvailabilityDispatcher = new GestureAvailabilityDispatcher();
         mLockoutResetDispatcher = new LockoutResetDispatcher(context);
@@ -1049,6 +995,86 @@
         mHandler = new Handler(Looper.getMainLooper());
     }
 
+    @VisibleForTesting
+    void registerAuthenticatorsForService(@NonNull List<String> aidlInstanceNames,
+            @NonNull List<FingerprintSensorPropertiesInternal> hidlSensors) {
+        addHidlProviders(hidlSensors);
+        addAidlProviders(Utils.filterAvailableHalInstances(getContext(), aidlInstanceNames));
+
+        final IBiometricService biometricService = mBiometricServiceSupplier.get();
+
+        // Register each sensor individually with BiometricService
+        for (ServiceProvider provider : mServiceProviders) {
+            final List<FingerprintSensorPropertiesInternal> props =
+                    provider.getSensorProperties();
+            for (FingerprintSensorPropertiesInternal prop : props) {
+                final int sensorId = prop.sensorId;
+                @BiometricManager.Authenticators.Types final int strength =
+                        Utils.propertyStrengthToAuthenticatorStrength(prop.sensorStrength);
+                final FingerprintAuthenticator authenticator = new FingerprintAuthenticator(
+                        mServiceWrapper, sensorId);
+                try {
+                    biometricService.registerAuthenticator(sensorId, TYPE_FINGERPRINT,
+                            strength, authenticator);
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "Remote exception when registering sensorId: " + sensorId);
+                }
+            }
+        }
+
+        synchronized (mLock) {
+            for (ServiceProvider provider : mServiceProviders) {
+                mSensorProps.addAll(provider.getSensorProperties());
+            }
+        }
+
+        broadcastCurrentEnrollmentState(null); // broadcasts to all listeners
+        broadcastAllAuthenticatorsRegistered();
+    }
+
+    private void addHidlProviders(List<FingerprintSensorPropertiesInternal> hidlSensors) {
+        for (FingerprintSensorPropertiesInternal hidlSensor : hidlSensors) {
+            final Fingerprint21 fingerprint21;
+            if ((Build.IS_USERDEBUG || Build.IS_ENG)
+                    && getContext().getResources().getBoolean(R.bool.allow_test_udfps)
+                    && Settings.Secure.getIntForUser(getContext().getContentResolver(),
+                    Fingerprint21UdfpsMock.CONFIG_ENABLE_TEST_UDFPS, 0 /* default */,
+                    UserHandle.USER_CURRENT) != 0) {
+                fingerprint21 = Fingerprint21UdfpsMock.newInstance(getContext(),
+                        mBiometricStateCallback, hidlSensor,
+                        mLockoutResetDispatcher, mGestureAvailabilityDispatcher,
+                        BiometricContext.getInstance(getContext()));
+            } else {
+                fingerprint21 = Fingerprint21.newInstance(getContext(),
+                        mBiometricStateCallback, hidlSensor, mHandler,
+                        mLockoutResetDispatcher, mGestureAvailabilityDispatcher);
+            }
+            mServiceProviders.add(fingerprint21);
+        }
+    }
+
+    private void addAidlProviders(List<String> instances) {
+        for (String instance : instances) {
+            final String fqName = IFingerprint.DESCRIPTOR + "/" + instance;
+            final IFingerprint fp = mIFingerprintProvider.apply(fqName);
+
+            if (fp != null) {
+                try {
+                    final FingerprintProvider provider = new FingerprintProvider(getContext(),
+                            mBiometricStateCallback, fp.getSensorProps(), instance,
+                            mLockoutResetDispatcher, mGestureAvailabilityDispatcher,
+                            mBiometricContext);
+                    Slog.i(TAG, "Adding AIDL provider: " + fqName);
+                    mServiceProviders.add(provider);
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "Remote exception in getSensorProps: " + fqName);
+                }
+            } else {
+                Slog.e(TAG, "Unable to get declared service: " + fqName);
+            }
+        }
+    }
+
     // Notifies the callbacks that all of the authenticators have been registered and removes the
     // invoked callbacks from the callback list.
     private void broadcastAllAuthenticatorsRegistered() {
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index e713e17..1fdc860 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -2534,7 +2534,9 @@
             super(TAG);
             mProfile = profile;
             mIpSecManager = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE);
-            mNetworkCallback = new VpnIkev2Utils.Ikev2VpnNetworkCallback(TAG, this);
+            // Pass mExecutor into Ikev2VpnNetworkCallback and make sure that IkeV2VpnRunnerCallback
+            // will be called by the mExecutor thread.
+            mNetworkCallback = new VpnIkev2Utils.Ikev2VpnNetworkCallback(TAG, this, mExecutor);
             mSessionKey = UUID.randomUUID().toString();
         }
 
@@ -2689,73 +2691,68 @@
          * <p>The Ikev2VpnRunner will unconditionally switch to the new network, killing the old IKE
          * state in the process, and starting a new IkeSession instance.
          *
-         * <p>This method is called multiple times over the lifetime of the Ikev2VpnRunner, and is
-         * called on the ConnectivityService thread. Thus, the actual work MUST be proxied to the
-         * mExecutor thread in order to ensure consistency of the Ikev2VpnRunner fields.
+         * <p>This method MUST always be called on the mExecutor thread in order to ensure
+         * consistency of the Ikev2VpnRunner fields.
          */
         public void onDefaultNetworkChanged(@NonNull Network network) {
             Log.d(TAG, "Starting IKEv2/IPsec session on new network: " + network);
 
-            // Proxy to the Ikev2VpnRunner (single-thread) executor to ensure consistency in lieu
-            // of locking.
-            mExecutor.execute(() -> {
-                try {
-                    if (!mIsRunning) {
-                        Log.d(TAG, "onDefaultNetworkChanged after exit");
-                        return; // VPN has been shut down.
-                    }
-
-                    // Clear mInterface to prevent Ikev2VpnRunner being cleared when
-                    // interfaceRemoved() is called.
-                    mInterface = null;
-                    // Without MOBIKE, we have no way to seamlessly migrate. Close on old
-                    // (non-default) network, and start the new one.
-                    resetIkeState();
-                    mActiveNetwork = network;
-
-                    // Get Ike options from IkeTunnelConnectionParams if it's available in the
-                    // profile.
-                    final IkeTunnelConnectionParams ikeTunConnParams =
-                            mProfile.getIkeTunnelConnectionParams();
-                    final IkeSessionParams ikeSessionParams;
-                    final ChildSessionParams childSessionParams;
-                    if (ikeTunConnParams != null) {
-                        final IkeSessionParams.Builder builder = new IkeSessionParams.Builder(
-                                ikeTunConnParams.getIkeSessionParams()).setNetwork(network);
-                        ikeSessionParams = builder.build();
-                        childSessionParams = ikeTunConnParams.getTunnelModeChildSessionParams();
-                    } else {
-                        ikeSessionParams = VpnIkev2Utils.buildIkeSessionParams(
-                                mContext, mProfile, network);
-                        childSessionParams = VpnIkev2Utils.buildChildSessionParams(
-                                mProfile.getAllowedAlgorithms());
-                    }
-
-                    // TODO: Remove the need for adding two unused addresses with
-                    // IPsec tunnels.
-                    final InetAddress address = InetAddress.getLocalHost();
-                    mTunnelIface =
-                            mIpSecManager.createIpSecTunnelInterface(
-                                    address /* unused */,
-                                    address /* unused */,
-                                    network);
-                    NetdUtils.setInterfaceUp(mNetd, mTunnelIface.getInterfaceName());
-
-                    mSession = mIkev2SessionCreator.createIkeSession(
-                            mContext,
-                            ikeSessionParams,
-                            childSessionParams,
-                            mExecutor,
-                            new VpnIkev2Utils.IkeSessionCallbackImpl(
-                                    TAG, IkeV2VpnRunner.this, network),
-                            new VpnIkev2Utils.ChildSessionCallbackImpl(
-                                    TAG, IkeV2VpnRunner.this, network));
-                    Log.d(TAG, "Ike Session started for network " + network);
-                } catch (Exception e) {
-                    Log.i(TAG, "Setup failed for network " + network + ". Aborting", e);
-                    onSessionLost(network, e);
+            try {
+                if (!mIsRunning) {
+                    Log.d(TAG, "onDefaultNetworkChanged after exit");
+                    return; // VPN has been shut down.
                 }
-            });
+
+                // Clear mInterface to prevent Ikev2VpnRunner being cleared when
+                // interfaceRemoved() is called.
+                mInterface = null;
+                // Without MOBIKE, we have no way to seamlessly migrate. Close on old
+                // (non-default) network, and start the new one.
+                resetIkeState();
+                mActiveNetwork = network;
+
+                // Get Ike options from IkeTunnelConnectionParams if it's available in the
+                // profile.
+                final IkeTunnelConnectionParams ikeTunConnParams =
+                        mProfile.getIkeTunnelConnectionParams();
+                final IkeSessionParams ikeSessionParams;
+                final ChildSessionParams childSessionParams;
+                if (ikeTunConnParams != null) {
+                    final IkeSessionParams.Builder builder = new IkeSessionParams.Builder(
+                            ikeTunConnParams.getIkeSessionParams()).setNetwork(network);
+                    ikeSessionParams = builder.build();
+                    childSessionParams = ikeTunConnParams.getTunnelModeChildSessionParams();
+                } else {
+                    ikeSessionParams = VpnIkev2Utils.buildIkeSessionParams(
+                            mContext, mProfile, network);
+                    childSessionParams = VpnIkev2Utils.buildChildSessionParams(
+                            mProfile.getAllowedAlgorithms());
+                }
+
+                // TODO: Remove the need for adding two unused addresses with
+                // IPsec tunnels.
+                final InetAddress address = InetAddress.getLocalHost();
+                mTunnelIface =
+                        mIpSecManager.createIpSecTunnelInterface(
+                                address /* unused */,
+                                address /* unused */,
+                                network);
+                NetdUtils.setInterfaceUp(mNetd, mTunnelIface.getInterfaceName());
+
+                mSession = mIkev2SessionCreator.createIkeSession(
+                        mContext,
+                        ikeSessionParams,
+                        childSessionParams,
+                        mExecutor,
+                        new VpnIkev2Utils.IkeSessionCallbackImpl(
+                                TAG, IkeV2VpnRunner.this, network),
+                        new VpnIkev2Utils.ChildSessionCallbackImpl(
+                                TAG, IkeV2VpnRunner.this, network));
+                Log.d(TAG, "Ike Session started for network " + network);
+            } catch (Exception e) {
+                Log.i(TAG, "Setup failed for network " + network + ". Aborting", e);
+                onSessionLost(network, e);
+            }
         }
 
         /** Marks the state as FAILED, and disconnects. */
diff --git a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
index a0a596d..6982d60 100644
--- a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
+++ b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
@@ -86,6 +86,7 @@
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
+import java.util.concurrent.ExecutorService;
 
 /**
  * Utility class to build and convert IKEv2/IPsec parameters.
@@ -376,22 +377,25 @@
     static class Ikev2VpnNetworkCallback extends NetworkCallback {
         private final String mTag;
         private final Vpn.IkeV2VpnRunnerCallback mCallback;
+        private final ExecutorService mExecutor;
 
-        Ikev2VpnNetworkCallback(String tag, Vpn.IkeV2VpnRunnerCallback callback) {
+        Ikev2VpnNetworkCallback(String tag, Vpn.IkeV2VpnRunnerCallback callback,
+                ExecutorService executor) {
             mTag = tag;
             mCallback = callback;
+            mExecutor = executor;
         }
 
         @Override
         public void onAvailable(@NonNull Network network) {
             Log.d(mTag, "Starting IKEv2/IPsec session on new network: " + network);
-            mCallback.onDefaultNetworkChanged(network);
+            mExecutor.execute(() -> mCallback.onDefaultNetworkChanged(network));
         }
 
         @Override
         public void onLost(@NonNull Network network) {
             Log.d(mTag, "Tearing down; lost network: " + network);
-            mCallback.onSessionLost(network, null);
+            mExecutor.execute(() -> mCallback.onSessionLost(network, null));
         }
     }
 
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 698f41f..80ff834 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -1389,12 +1389,10 @@
                 // Brightness throttling is needed, so do so quickly.
                 // Later, when throttling is removed, we let other mechanisms decide on speed.
                 slowChange = false;
-                updateScreenBrightnessSetting = true;
             }
             mAppliedThrottling = true;
         } else if (mAppliedThrottling) {
             mAppliedThrottling = false;
-            updateScreenBrightnessSetting = true;
         }
 
         if (updateScreenBrightnessSetting) {
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 3af46e3..d04006a 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -115,7 +115,6 @@
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.os.SomeArgs;
-import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.XmlUtils;
@@ -171,19 +170,6 @@
 
     private static final int DEFAULT_VIBRATION_MAGNITUDE = 192;
 
-    /**
-     * We know the issue and are working to fix it, so suppressing the toast to not annoy
-     * dogfooders.
-     *
-     * TODO(b/169067926): Remove this
-     */
-    private static final String[] PACKAGE_BLOCKLIST_FOR_UNTRUSTED_TOUCHES_TOAST = {
-            "com.snapchat.android" // b/173297887
-    };
-
-    /** TODO(b/169067926): Remove this. */
-    private static final boolean UNTRUSTED_TOUCHES_TOAST = false;
-
     private final NativeInputManagerService mNative;
 
     private final Context mContext;
@@ -462,7 +448,6 @@
         registerAccessibilityLargePointerSettingObserver();
         registerLongPressTimeoutObserver();
         registerMaximumObscuringOpacityForTouchSettingObserver();
-        registerBlockUntrustedTouchesModeSettingObserver();
 
         mContext.registerReceiver(new BroadcastReceiver() {
             @Override
@@ -479,7 +464,6 @@
         updateAccessibilityLargePointerFromSettings();
         updateDeepPressStatusFromSettings("just booted");
         updateMaximumObscuringOpacityForTouchFromSettings();
-        updateBlockUntrustedTouchesModeFromSettings();
     }
 
     // TODO(BT) Pass in parameter for bluetooth system
@@ -1709,6 +1693,13 @@
             mPointerIconDisplayContext = null;
         }
 
+        synchronized (mAdditionalDisplayInputPropertiesLock) {
+            setPointerIconVisible(AdditionalDisplayInputProperties.DEFAULT_POINTER_ICON_VISIBLE,
+                    displayId);
+            setPointerAcceleration(AdditionalDisplayInputProperties.DEFAULT_POINTER_ACCELERATION,
+                    displayId);
+        }
+
         mNative.displayRemoved(displayId);
     }
 
@@ -1931,23 +1922,6 @@
                 }, UserHandle.USER_ALL);
     }
 
-    private void registerBlockUntrustedTouchesModeSettingObserver() {
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Global.getUriFor(Settings.Global.BLOCK_UNTRUSTED_TOUCHES_MODE),
-                /* notifyForDescendants */ true,
-                new ContentObserver(mHandler) {
-                    @Override
-                    public void onChange(boolean selfChange) {
-                        updateBlockUntrustedTouchesModeFromSettings();
-                    }
-                }, UserHandle.USER_ALL);
-    }
-
-    private void updateBlockUntrustedTouchesModeFromSettings() {
-        final int mode = InputManager.getInstance().getBlockUntrustedTouchesMode(mContext);
-        mNative.setBlockUntrustedTouchesMode(mode);
-    }
-
     private void registerMaximumObscuringOpacityForTouchSettingObserver() {
         mContext.getContentResolver().registerContentObserver(
                 Settings.Global.getUriFor(Settings.Global.MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH),
@@ -2847,22 +2821,6 @@
         mWindowManagerCallbacks.notifyDropWindow(token, x, y);
     }
 
-    // Native callback
-    @SuppressWarnings("unused")
-    private void notifyUntrustedTouch(String packageName) {
-        // TODO(b/169067926): Remove toast after gathering feedback on dogfood.
-        if (!UNTRUSTED_TOUCHES_TOAST || ArrayUtils.contains(
-                PACKAGE_BLOCKLIST_FOR_UNTRUSTED_TOUCHES_TOAST, packageName)) {
-            Log.i(TAG, "Suppressing untrusted touch toast for " + packageName);
-            return;
-        }
-        DisplayThread.getHandler().post(() ->
-                Toast.makeText(mContext,
-                        "Touch obscured by " + packageName
-                                + " will be blocked. Check go/untrusted-touches",
-                        Toast.LENGTH_SHORT).show());
-    }
-
     // Native callback.
     @SuppressWarnings("unused")
     private void notifyNoFocusedWindowAnr(InputApplicationHandle inputApplicationHandle) {
diff --git a/services/core/java/com/android/server/input/NativeInputManagerService.java b/services/core/java/com/android/server/input/NativeInputManagerService.java
index 2169155..b29619e 100644
--- a/services/core/java/com/android/server/input/NativeInputManagerService.java
+++ b/services/core/java/com/android/server/input/NativeInputManagerService.java
@@ -68,8 +68,6 @@
 
     void setMaximumObscuringOpacityForTouch(float opacity);
 
-    void setBlockUntrustedTouchesMode(int mode);
-
     int injectInputEvent(InputEvent event, int pid, int uid, int syncMode,
             int timeoutMillis, int policyFlags);
 
@@ -234,9 +232,6 @@
         public native void setMaximumObscuringOpacityForTouch(float opacity);
 
         @Override
-        public native void setBlockUntrustedTouchesMode(int mode);
-
-        @Override
         public native int injectInputEvent(InputEvent event, int pid, int uid, int syncMode,
                 int timeoutMillis, int policyFlags);
 
diff --git a/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java b/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java
index 7bb0d48..e4e9d01 100644
--- a/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java
+++ b/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java
@@ -158,6 +158,7 @@
             Collection<GnssListenerRegistration> registrations) {
         boolean fullTracking = false;
         boolean enableCorrVecOutputs = false;
+        int intervalMillis = Integer.MAX_VALUE;
 
         if (mSettingsHelper.isGnssMeasurementsFullTrackingEnabled()) {
             fullTracking = true;
@@ -171,11 +172,13 @@
             if (request.isCorrelationVectorOutputsEnabled()) {
                 enableCorrVecOutputs = true;
             }
+            intervalMillis = Math.min(intervalMillis, request.getIntervalMillis());
         }
 
         return new GnssMeasurementRequest.Builder()
                     .setFullTracking(fullTracking)
                     .setCorrelationVectorOutputsEnabled(enableCorrVecOutputs)
+                    .setIntervalMillis(intervalMillis)
                     .build();
     }
 
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
index 0e4bbbb..d5a759d 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
@@ -212,7 +212,10 @@
             if ("--old".equals(opt)) {
                 mOld = getNextArgRequired();
             } else if ("--user".equals(opt)) {
-                mCurrentUserId = Integer.parseInt(getNextArgRequired());
+                mCurrentUserId = UserHandle.parseUserArg(getNextArgRequired());
+                if (mCurrentUserId == UserHandle.USER_CURRENT) {
+                    mCurrentUserId = ActivityManager.getCurrentUser();
+                }
             } else {
                 getErrPrintWriter().println("Unknown option: " + opt);
                 throw new IllegalArgumentException();
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 4e09831..0ba8d2c 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -1255,7 +1255,7 @@
             // to be installed for different users: ignore userId for now.
             try {
                 return mPackageManager.checkSignatures(
-                        packageName1, packageName2) == SIGNATURE_MATCH;
+                        packageName1, packageName2, userId) == SIGNATURE_MATCH;
             } catch (RemoteException e) {
                 // Intentionally left blank
             }
diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java
index 54b6cab..3d75bef 100644
--- a/services/core/java/com/android/server/pm/ApexManager.java
+++ b/services/core/java/com/android/server/pm/ApexManager.java
@@ -62,6 +62,7 @@
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -122,17 +123,19 @@
         public final File apexDirectory;
         public final File preInstalledApexPath;
         public final boolean isFactory;
+        public final File apexFile;
 
-        private ActiveApexInfo(File apexDirectory, File preInstalledApexPath) {
-            this(null, apexDirectory, preInstalledApexPath, true);
+        private ActiveApexInfo(File apexDirectory, File preInstalledApexPath, File apexFile) {
+            this(null, apexDirectory, preInstalledApexPath, true, apexFile);
         }
 
         private ActiveApexInfo(@Nullable String apexModuleName, File apexDirectory,
-                File preInstalledApexPath, boolean isFactory) {
+                File preInstalledApexPath, boolean isFactory, File apexFile) {
             this.apexModuleName = apexModuleName;
             this.apexDirectory = apexDirectory;
             this.preInstalledApexPath = preInstalledApexPath;
             this.isFactory = isFactory;
+            this.apexFile = apexFile;
         }
 
         private ActiveApexInfo(ApexInfo apexInfo) {
@@ -141,7 +144,8 @@
                     new File(Environment.getApexDirectory() + File.separator
                             + apexInfo.moduleName),
                     new File(apexInfo.preinstalledModulePath),
-                    apexInfo.isFactory);
+                    apexInfo.isFactory,
+                    new File(apexInfo.modulePath));
         }
     }
 
@@ -371,6 +375,15 @@
     public abstract List<ApexSystemServiceInfo> getApexSystemServices();
 
     /**
+     * Returns an APEX file backing the mount point {@code file} is located on, or {@code null} if
+     * {@code file} doesn't belong to a {@code /apex} mount point.
+     *
+     * <p>Also returns {@code null} if device doesn't support updatable APEX packages.
+     */
+    @Nullable
+    public abstract File getBackingApexFile(@NonNull File file);
+
+    /**
      * Dumps various state information to the provided {@link PrintWriter} object.
      *
      * @param pw the {@link PrintWriter} object to send information to.
@@ -392,6 +405,7 @@
     protected static class ApexManagerImpl extends ApexManager {
         private final Object mLock = new Object();
 
+        // TODO(ioffe): this should be either List or ArrayMap.
         @GuardedBy("mLock")
         private Set<ActiveApexInfo> mActiveApexInfosCache;
 
@@ -944,6 +958,25 @@
         }
 
         @Override
+        public File getBackingApexFile(File file) {
+            Path path = file.toPath();
+            if (!path.startsWith(Environment.getApexDirectory().toPath())) {
+                return null;
+            }
+            if (path.getNameCount() < 2) {
+                return null;
+            }
+            String moduleName = file.toPath().getName(1).toString();
+            final List<ActiveApexInfo> apexes = getActiveApexInfos();
+            for (int i = 0; i < apexes.size(); i++) {
+                if (apexes.get(i).apexModuleName.equals(moduleName)) {
+                    return apexes.get(i).apexFile;
+                }
+            }
+            return null;
+        }
+
+        @Override
         void dump(PrintWriter pw) {
             final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
             try {
@@ -987,7 +1020,8 @@
      * An implementation of {@link ApexManager} that should be used in case device does not support
      * updating APEX packages.
      */
-    private static final class ApexManagerFlattenedApex extends ApexManager {
+    @VisibleForTesting
+    static final class ApexManagerFlattenedApex extends ApexManager {
         @Override
         ApexInfo[] getAllApexInfos() {
             return null;
@@ -1016,7 +1050,8 @@
                                 // In flattened configuration, init special-cases the art directory
                                 // and bind-mounts com.android.art.debug to com.android.art.
                                 && !file.getName().equals("com.android.art.debug")) {
-                            result.add(new ActiveApexInfo(file, Environment.getRootDirectory()));
+                            result.add(
+                                    new ActiveApexInfo(file, Environment.getRootDirectory(), file));
                         }
                     }
                 }
@@ -1173,7 +1208,11 @@
 
         @Override
         void dump(PrintWriter pw) {
-            // No-op
+        }
+
+        @Override
+        public File getBackingApexFile(File file) {
+            return null;
         }
     }
 }
diff --git a/services/core/java/com/android/server/pm/AppsFilterImpl.java b/services/core/java/com/android/server/pm/AppsFilterImpl.java
index c447880..f757405 100644
--- a/services/core/java/com/android/server/pm/AppsFilterImpl.java
+++ b/services/core/java/com/android/server/pm/AppsFilterImpl.java
@@ -189,6 +189,8 @@
 
     private final Object mCacheLock = new Object();
 
+    private final boolean mIsSnapshot;
+
     /**
      * This structure maps uid -> uid and indicates whether access from the first should be
      * filtered to the second. It's essentially a cache of the
@@ -322,6 +324,7 @@
                 mProtectedBroadcasts, mProtectedBroadcasts, "AppsFilter.mProtectedBroadcasts");
 
         mSnapshot = makeCache();
+        mIsSnapshot = false;
     }
 
     /**
@@ -360,6 +363,7 @@
         mBackgroundExecutor = null;
         mSnapshot = new SnapshotCache.Sealed<>();
         mSystemReady = orig.mSystemReady;
+        mIsSnapshot = true;
     }
 
     /**
@@ -1136,6 +1140,7 @@
             }
         }
         mQueriesViaComponentRequireRecompute = false;
+        onChanged();
     }
 
     /**
@@ -1405,6 +1410,7 @@
         }
     }
 
+    @SuppressWarnings("GuardedBy")
     private boolean shouldFilterApplicationInternal(PackageDataSnapshot snapshot, int callingUid,
             Object callingSetting, PackageStateInternal targetPkgSetting, int targetUserId) {
         if (DEBUG_TRACING) {
@@ -1563,16 +1569,53 @@
                 if (DEBUG_TRACING) {
                     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueriesViaComponent");
                 }
-                if (mQueriesViaComponentRequireRecompute) {
-                    recomputeComponentVisibility(snapshot.getPackageStates());
-                    onChanged();
-                }
-                synchronized (mLock) {
-                    if (mQueriesViaComponent.contains(callingAppId, targetAppId)) {
-                        if (DEBUG_LOGGING) {
-                            log(callingSetting, targetPkgSetting, "queries component");
+                if (!mQueriesViaComponentRequireRecompute) {
+                    synchronized (mLock) {
+                        if (mQueriesViaComponent.contains(callingAppId, targetAppId)) {
+                            if (DEBUG_LOGGING) {
+                                log(callingSetting, targetPkgSetting, "queries component");
+                            }
+                            return false;
                         }
-                        return false;
+                    }
+                } else { // mQueriesViaComponent is stale
+                    if (!mIsSnapshot) {
+                        // Only recompute mQueriesViaComponent if not in snapshot
+                        recomputeComponentVisibility(snapshot.getPackageStates());
+                        synchronized (mLock) {
+                            if (mQueriesViaComponent.contains(callingAppId, targetAppId)) {
+                                if (DEBUG_LOGGING) {
+                                    log(callingSetting, targetPkgSetting, "queries component");
+                                }
+                                return false;
+                            }
+                        }
+                    } else {
+                        // Do no recompute or use mQueriesViaComponent if it's stale in snapshot
+                        // Since we know we are in the snapshot, no need to acquire mLock because
+                        // mProtectedBroadcasts will not change
+                        if (callingPkgSetting != null) {
+                            if (callingPkgSetting.getPkg() != null
+                                    && canQueryViaComponents(callingPkgSetting.getPkg(), targetPkg,
+                                    mProtectedBroadcasts)) {
+                                if (DEBUG_LOGGING) {
+                                    log(callingSetting, targetPkgSetting, "queries component");
+                                }
+                                return false;
+                            }
+                        } else {
+                            for (int i = callingSharedPkgSettings.size() - 1; i >= 0; i--) {
+                                final AndroidPackage pkg =
+                                        callingSharedPkgSettings.valueAt(i).getPkg();
+                                if (pkg != null && canQueryViaComponents(pkg, targetPkg,
+                                        mProtectedBroadcasts)) {
+                                    if (DEBUG_LOGGING) {
+                                        log(callingSetting, targetPkgSetting, "queries component");
+                                    }
+                                    return false;
+                                }
+                            }
+                        }
                     }
                 }
             } finally {
diff --git a/services/core/java/com/android/server/pm/Computer.java b/services/core/java/com/android/server/pm/Computer.java
index 43a532cf..8e8ca86 100644
--- a/services/core/java/com/android/server/pm/Computer.java
+++ b/services/core/java/com/android/server/pm/Computer.java
@@ -373,7 +373,7 @@
     PackageStateInternal getPackageStateFiltered(@NonNull String packageName, int callingUid,
             @UserIdInt int userId);
 
-    int checkSignatures(@NonNull String pkg1, @NonNull String pkg2);
+    int checkSignatures(@NonNull String pkg1, @NonNull String pkg2, int userId);
 
     int checkUidSignatures(int uid1, int uid2);
 
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index b089529..24004bc 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -4219,7 +4219,11 @@
     }
 
     @Override
-    public int checkSignatures(@NonNull String pkg1, @NonNull String pkg2) {
+    public int checkSignatures(@NonNull String pkg1, @NonNull String pkg2, int userId) {
+        final int callingUid = Binder.getCallingUid();
+        enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
+                false /* checkShell */, "checkSignatures");
+
         final AndroidPackage p1 = mPackages.get(pkg1);
         final AndroidPackage p2 = mPackages.get(pkg2);
         final PackageStateInternal ps1 =
@@ -4229,10 +4233,8 @@
         if (p1 == null || ps1 == null || p2 == null || ps2 == null) {
             return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
         }
-        final int callingUid = Binder.getCallingUid();
-        final int callingUserId = UserHandle.getUserId(callingUid);
-        if (shouldFilterApplicationIncludingUninstalled(ps1, callingUid, callingUserId)
-                || shouldFilterApplicationIncludingUninstalled(ps2, callingUid, callingUserId)) {
+        if (shouldFilterApplicationIncludingUninstalled(ps1, callingUid, userId)
+                || shouldFilterApplicationIncludingUninstalled(ps2, callingUid, userId)) {
             return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
         }
         return checkSignaturesInternal(p1.getSigningDetails(), p2.getSigningDetails());
diff --git a/services/core/java/com/android/server/pm/IPackageManagerBase.java b/services/core/java/com/android/server/pm/IPackageManagerBase.java
index 7f0fcea..9c396b6 100644
--- a/services/core/java/com/android/server/pm/IPackageManagerBase.java
+++ b/services/core/java/com/android/server/pm/IPackageManagerBase.java
@@ -230,8 +230,8 @@
 
     @Override
     @Deprecated
-    public final int checkSignatures(@NonNull String pkg1, @NonNull String pkg2) {
-        return snapshot().checkSignatures(pkg1, pkg2);
+    public final int checkSignatures(@NonNull String pkg1, @NonNull String pkg2, int userId) {
+        return snapshot().checkSignatures(pkg1, pkg2, userId);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 2312011..5459df5 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -907,6 +907,9 @@
                         getFlags |= PackageManager.MATCH_APEX;
                         listApexOnly = true;
                         break;
+                    case "--factory-only":
+                        getFlags |= PackageManager.MATCH_FACTORY_ONLY;
+                        break;
                     case "--user":
                         defaultUserId = UserHandle.parseUserArg(getNextArgRequired());
                         break;
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index ba7dee6..9a18d7e 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -32,6 +32,7 @@
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
 import android.app.ActivityManagerNative;
+import android.app.ActivityThread;
 import android.app.IActivityManager;
 import android.app.IStopUserCallback;
 import android.app.KeyguardManager;
@@ -121,9 +122,11 @@
 import com.android.server.LocalServices;
 import com.android.server.LockGuard;
 import com.android.server.SystemService;
+import com.android.server.UiThread;
 import com.android.server.am.UserState;
 import com.android.server.pm.UserManagerInternal.UserLifecycleListener;
 import com.android.server.pm.UserManagerInternal.UserRestrictionsListener;
+import com.android.server.power.ShutdownThread;
 import com.android.server.storage.DeviceStorageMonitorInternal;
 import com.android.server.utils.Slogf;
 import com.android.server.utils.TimingsTraceAndSlog;
@@ -487,7 +490,7 @@
     private final ArrayList<UserRestrictionsListener> mUserRestrictionsListeners =
             new ArrayList<>();
 
-    @GuardedBy("mUserRemovedListeners")
+    @GuardedBy("mUserLifecycleListeners")
     private final ArrayList<UserLifecycleListener> mUserLifecycleListeners = new ArrayList<>();
 
     private final LockPatternUtils mLockPatternUtils;
@@ -5602,11 +5605,16 @@
             pw.println("      (where MODE is the allowlist mode integer as defined by "
                     + "config_userTypePackageWhitelistMode)");
             pw.println();
-            pw.println("  set-system-user-mode-emulation [headless | full | default]");
-            pw.println("    Changes whether the system user is headless or full.");
+            pw.println("  set-system-user-mode-emulation [--reboot | --no-restart] "
+                    + "<headless | full | default>");
+            pw.println("    Changes whether the system user is headless, full, or default (as "
+                    + "defined by OEM).");
             pw.println("    WARNING: this command is meant just for development and debugging "
                     + "purposes.");
             pw.println("             It should NEVER be used on automated tests.");
+            pw.println("    NOTE: by default it restarts the Android runtime, unless called with");
+            pw.println("          --reboot (which does a full reboot) or");
+            pw.println("          --no-restart (which requires a manual restart)");
             pw.println();
         }
 
@@ -5769,6 +5777,27 @@
                 return -1;
             }
 
+            boolean restart = true;
+            boolean reboot = false;
+            String opt;
+            while ((opt = getNextOption()) != null) {
+                switch (opt) {
+                    case "--reboot":
+                        reboot = true;
+                        break;
+                    case "--no-restart":
+                        restart = false;
+                        break;
+                    default:
+                        pw.println("Invalid option: " + opt);
+                        return -1;
+                }
+            }
+            if (reboot && !restart) {
+                getErrPrintWriter().println("You can use --reboot or --no-restart, but not both");
+                return -1;
+            }
+
             final String mode = getNextArgRequired();
             final boolean isHeadlessSystemUserModeCurrently = UserManager
                     .isHeadlessSystemUserMode();
@@ -5785,7 +5814,7 @@
                     changed = true; // Always update when resetting to default
                     break;
                 default:
-                    pw.printf("Invalid arg: %s\n", mode);
+                    getErrPrintWriter().printf("Invalid arg: %s\n", mode);
                     return -1;
             }
 
@@ -5799,10 +5828,46 @@
                     UserManager.SYSTEM_USER_MODE_EMULATION_PROPERTY, mode);
 
             SystemProperties.set(UserManager.SYSTEM_USER_MODE_EMULATION_PROPERTY, mode);
-            pw.println("System user mode changed - please reboot (or restart Android runtime) "
-                    + "to continue");
-            pw.println("NOTICE: after restart, some apps might be uninstalled (and their data "
-                    + "will be lost)");
+
+            if (reboot) {
+                Slog.i(LOG_TAG, "Rebooting to finalize the changes");
+                pw.println("Rebooting to finalize changes");
+                UiThread.getHandler()
+                        .post(() -> ShutdownThread.reboot(
+                                ActivityThread.currentActivityThread().getSystemUiContext(),
+                                "To switch headless / full system user mode",
+                                /* confirm= */ false));
+            } else if (restart) {
+                Slog.i(LOG_TAG, "Shutting PackageManager down");
+                getPackageManagerInternal().shutdown();
+
+                final IActivityManager am = ActivityManager.getService();
+                if (am != null) {
+                    try {
+                        Slog.i(LOG_TAG, "Shutting ActivityManager down");
+                        am.shutdown(/* timeout= */ 10_000);
+                    } catch (RemoteException e) {
+                    }
+                }
+
+                final int pid = Process.myPid();
+                Slogf.i(LOG_TAG, "Restarting Android runtime(PID=%d) to finalize changes", pid);
+                pw.println("Restarting Android runtime to finalize changes");
+                pw.flush();
+
+                // Ideally there should be a cleaner / safer option to restart system_server, but
+                // that doesn't seems to be the case. For example, ShutdownThread.reboot() calls
+                // pm.shutdown() and am.shutdown() (which we already are calling above), but when
+                // the system is restarted through 'adb shell stop && adb shell start`, these
+                // methods are not called, so just killing the process seems to be fine.
+
+                Process.killProcess(pid);
+            } else {
+                pw.println("System user mode changed - please reboot (or restart Android runtime) "
+                        + "to continue");
+                pw.println("NOTICE: after restart, some apps might be uninstalled (and their data "
+                        + "will be lost)");
+            }
             return 0;
         }
 
diff --git a/services/core/java/com/android/server/pm/parsing/PackageCacher.java b/services/core/java/com/android/server/pm/parsing/PackageCacher.java
index 59b7cbd..f7a6eef 100644
--- a/services/core/java/com/android/server/pm/parsing/PackageCacher.java
+++ b/services/core/java/com/android/server/pm/parsing/PackageCacher.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.content.pm.PackageParserCacheHelper;
+import android.os.Environment;
 import android.os.FileUtils;
 import android.os.Parcel;
 import android.system.ErrnoException;
@@ -27,6 +28,7 @@
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.pm.ApexManager;
 import com.android.server.pm.parsing.pkg.PackageImpl;
 import com.android.server.pm.parsing.pkg.ParsedPackage;
 
@@ -118,6 +120,17 @@
      */
     private static boolean isCacheUpToDate(File packageFile, File cacheFile) {
         try {
+            // In case packageFile is located on one of /apex mount points it's mtime will always be
+            // 0. Instead, we can use mtime of the APEX file backing the corresponding mount point.
+            if (packageFile.toPath().startsWith(Environment.getApexDirectory().toPath())) {
+                File backingApexFile = ApexManager.getInstance().getBackingApexFile(packageFile);
+                if (backingApexFile == null) {
+                    Slog.w(TAG,
+                            "Failed to find APEX file backing " + packageFile.getAbsolutePath());
+                } else {
+                    packageFile = backingApexFile;
+                }
+            }
             // NOTE: We don't use the File.lastModified API because it has the very
             // non-ideal failure mode of returning 0 with no excepions thrown.
             // The nio2 Files API is a little better but is considerably more expensive.
diff --git a/services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java b/services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java
index ae23b9e..5db4a7b 100644
--- a/services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java
@@ -268,9 +268,17 @@
     }
 
     private boolean componentMapsToRecognitionService(@NonNull ComponentName serviceComponent) {
-        List<ResolveInfo> resolveInfos =
-                getContext().getPackageManager().queryIntentServicesAsUser(
-                        new Intent(RecognitionService.SERVICE_INTERFACE), 0, getUserId());
+        List<ResolveInfo> resolveInfos;
+
+        final long identityToken = Binder.clearCallingIdentity();
+        try {
+            resolveInfos =
+                    getContext().getPackageManager().queryIntentServicesAsUser(
+                            new Intent(RecognitionService.SERVICE_INTERFACE), 0, getUserId());
+        } finally {
+            Binder.restoreCallingIdentity(identityToken);
+        }
+
         if (resolveInfos == null) {
             return false;
         }
diff --git a/services/core/java/com/android/server/uri/UriPermissionOwner.java b/services/core/java/com/android/server/uri/UriPermissionOwner.java
index 0c26399..d22bb58 100644
--- a/services/core/java/com/android/server/uri/UriPermissionOwner.java
+++ b/services/core/java/com/android/server/uri/UriPermissionOwner.java
@@ -30,7 +30,9 @@
 import com.google.android.collect.Sets;
 
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.Iterator;
+import java.util.List;
 
 public class UriPermissionOwner {
     private final UriGrantsManagerInternal mService;
@@ -61,7 +63,7 @@
 
     static UriPermissionOwner fromExternalToken(IBinder token) {
         if (token instanceof ExternalToken) {
-            return ((ExternalToken)token).getOwner();
+            return ((ExternalToken) token).getOwner();
         }
         return null;
     }
@@ -79,99 +81,121 @@
     }
 
     void removeUriPermission(GrantUri grantUri, int mode, String targetPgk, int targetUserId) {
-        if ((mode & FLAG_GRANT_READ_URI_PERMISSION) != 0 && mReadPerms != null) {
-            Iterator<UriPermission> it = mReadPerms.iterator();
-            while (it.hasNext()) {
-                UriPermission perm = it.next();
-                if (grantUri != null && !grantUri.equals(perm.uri)) {
-                    continue;
+        final List<UriPermission> permissionsToRemove = new ArrayList<>();
+
+        synchronized (this) {
+            if ((mode & FLAG_GRANT_READ_URI_PERMISSION) != 0 && mReadPerms != null) {
+                final Iterator<UriPermission> it = mReadPerms.iterator();
+                while (it.hasNext()) {
+                    final UriPermission perm = it.next();
+                    if (grantUri != null && !grantUri.equals(perm.uri)) {
+                        continue;
+                    }
+                    if (targetPgk != null && !targetPgk.equals(perm.targetPkg)) {
+                        continue;
+                    }
+                    if (targetUserId != UserHandle.USER_ALL && targetUserId != perm.targetUserId) {
+                        continue;
+                    }
+                    permissionsToRemove.add(perm);
+                    perm.removeReadOwner(this);
+                    it.remove();
                 }
-                if (targetPgk != null && !targetPgk.equals(perm.targetPkg)) {
-                    continue;
+                if (mReadPerms.isEmpty()) {
+                    mReadPerms = null;
                 }
-                if (targetUserId != UserHandle.USER_ALL && targetUserId != perm.targetUserId) {
-                    continue;
-                }
-                perm.removeReadOwner(this);
-                mService.removeUriPermissionIfNeeded(perm);
-                it.remove();
             }
+
+            if ((mode & FLAG_GRANT_WRITE_URI_PERMISSION) != 0 && mWritePerms != null) {
+                final Iterator<UriPermission> it = mWritePerms.iterator();
+                while (it.hasNext()) {
+                    final UriPermission perm = it.next();
+                    if (grantUri != null && !grantUri.equals(perm.uri)) {
+                        continue;
+                    }
+                    if (targetPgk != null && !targetPgk.equals(perm.targetPkg)) {
+                        continue;
+                    }
+                    if (targetUserId != UserHandle.USER_ALL && targetUserId != perm.targetUserId) {
+                        continue;
+                    }
+                    permissionsToRemove.add(perm);
+                    perm.removeWriteOwner(this);
+                    it.remove();
+                }
+                if (mWritePerms.isEmpty()) {
+                    mWritePerms = null;
+                }
+            }
+        }
+
+        final int permissionsToRemoveSize = permissionsToRemove.size();
+        for (int i = 0; i < permissionsToRemoveSize; i++) {
+            mService.removeUriPermissionIfNeeded(permissionsToRemove.get(i));
+        }
+    }
+
+    public void addReadPermission(UriPermission perm) {
+        synchronized (this) {
+            if (mReadPerms == null) {
+                mReadPerms = Sets.newArraySet();
+            }
+            mReadPerms.add(perm);
+        }
+    }
+
+    public void addWritePermission(UriPermission perm) {
+        synchronized (this) {
+            if (mWritePerms == null) {
+                mWritePerms = Sets.newArraySet();
+            }
+            mWritePerms.add(perm);
+        }
+    }
+
+    public void removeReadPermission(UriPermission perm) {
+        synchronized (this) {
+            mReadPerms.remove(perm);
             if (mReadPerms.isEmpty()) {
                 mReadPerms = null;
             }
         }
-        if ((mode & FLAG_GRANT_WRITE_URI_PERMISSION) != 0 && mWritePerms != null) {
-            Iterator<UriPermission> it = mWritePerms.iterator();
-            while (it.hasNext()) {
-                UriPermission perm = it.next();
-                if (grantUri != null && !grantUri.equals(perm.uri)) {
-                    continue;
-                }
-                if (targetPgk != null && !targetPgk.equals(perm.targetPkg)) {
-                    continue;
-                }
-                if (targetUserId != UserHandle.USER_ALL && targetUserId != perm.targetUserId) {
-                    continue;
-                }
-                perm.removeWriteOwner(this);
-                mService.removeUriPermissionIfNeeded(perm);
-                it.remove();
-            }
+    }
+
+    public void removeWritePermission(UriPermission perm) {
+        synchronized (this) {
+            mWritePerms.remove(perm);
             if (mWritePerms.isEmpty()) {
                 mWritePerms = null;
             }
         }
     }
 
-    public void addReadPermission(UriPermission perm) {
-        if (mReadPerms == null) {
-            mReadPerms = Sets.newArraySet();
-        }
-        mReadPerms.add(perm);
-    }
-
-    public void addWritePermission(UriPermission perm) {
-        if (mWritePerms == null) {
-            mWritePerms = Sets.newArraySet();
-        }
-        mWritePerms.add(perm);
-    }
-
-    public void removeReadPermission(UriPermission perm) {
-        mReadPerms.remove(perm);
-        if (mReadPerms.isEmpty()) {
-            mReadPerms = null;
-        }
-    }
-
-    public void removeWritePermission(UriPermission perm) {
-        mWritePerms.remove(perm);
-        if (mWritePerms.isEmpty()) {
-            mWritePerms = null;
-        }
-    }
-
     public void dump(PrintWriter pw, String prefix) {
-        if (mReadPerms != null) {
-            pw.print(prefix); pw.print("readUriPermissions="); pw.println(mReadPerms);
-        }
-        if (mWritePerms != null) {
-            pw.print(prefix); pw.print("writeUriPermissions="); pw.println(mWritePerms);
+        synchronized (this) {
+            if (mReadPerms != null) {
+                pw.print(prefix);
+                pw.print("readUriPermissions=");
+                pw.println(mReadPerms);
+            }
+            if (mWritePerms != null) {
+                pw.print(prefix);
+                pw.print("writeUriPermissions=");
+                pw.println(mWritePerms);
+            }
         }
     }
 
     public void dumpDebug(ProtoOutputStream proto, long fieldId) {
         long token = proto.start(fieldId);
         proto.write(UriPermissionOwnerProto.OWNER, mOwner.toString());
-        if (mReadPerms != null) {
-            synchronized (mReadPerms) {
+        synchronized (this) {
+            if (mReadPerms != null) {
                 for (UriPermission p : mReadPerms) {
                     p.uri.dumpDebug(proto, UriPermissionOwnerProto.READ_PERMS);
                 }
             }
-        }
-        if (mWritePerms != null) {
-            synchronized (mWritePerms) {
+            if (mWritePerms != null) {
                 for (UriPermission p : mWritePerms) {
                     p.uri.dumpDebug(proto, UriPermissionOwnerProto.WRITE_PERMS);
                 }
diff --git a/services/core/java/com/android/server/wm/ConfigurationContainer.java b/services/core/java/com/android/server/wm/ConfigurationContainer.java
index dbc08cd..e7c03aa 100644
--- a/services/core/java/com/android/server/wm/ConfigurationContainer.java
+++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java
@@ -637,12 +637,19 @@
     }
 
     void registerConfigurationChangeListener(ConfigurationContainerListener listener) {
+        registerConfigurationChangeListener(listener, true /* shouldDispatchConfig */);
+    }
+
+    void registerConfigurationChangeListener(ConfigurationContainerListener listener,
+            boolean shouldDispatchConfig) {
         if (mChangeListeners.contains(listener)) {
             return;
         }
         mChangeListeners.add(listener);
-        listener.onRequestedOverrideConfigurationChanged(mResolvedOverrideConfiguration);
-        listener.onMergedOverrideConfigurationChanged(mMergedOverrideConfiguration);
+        if (shouldDispatchConfig) {
+            listener.onRequestedOverrideConfigurationChanged(mResolvedOverrideConfiguration);
+            listener.onMergedOverrideConfigurationChanged(mMergedOverrideConfiguration);
+        }
     }
 
     void unregisterConfigurationChangeListener(ConfigurationContainerListener listener) {
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 2d7d705..014bb9f 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -138,8 +138,8 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.policy.ForceShowNavBarSettingsObserver;
 import com.android.internal.policy.GestureNavigationSettingsObserver;
-import com.android.internal.policy.KidsModeSettingsObserver;
 import com.android.internal.policy.ScreenDecorationsUtils;
 import com.android.internal.policy.SystemBarUtils;
 import com.android.internal.protolog.common.ProtoLog;
@@ -378,7 +378,7 @@
 
     private final WindowManagerInternal.AppTransitionListener mAppTransitionListener;
 
-    private final KidsModeSettingsObserver mKidsModeSettingsObserver;
+    private final ForceShowNavBarSettingsObserver mForceShowNavBarSettingsObserver;
     private boolean mForceShowNavigationBarEnabled;
 
     private class PolicyHandler extends Handler {
@@ -653,17 +653,17 @@
         });
         mHandler.post(mGestureNavigationSettingsObserver::register);
 
-        mKidsModeSettingsObserver = new KidsModeSettingsObserver(
+        mForceShowNavBarSettingsObserver = new ForceShowNavBarSettingsObserver(
                 mHandler, mContext);
-        mKidsModeSettingsObserver.setOnChangeRunnable(() -> {
+        mForceShowNavBarSettingsObserver.setOnChangeRunnable(() -> {
             synchronized (mLock) {
                 mForceShowNavigationBarEnabled =
-                        mKidsModeSettingsObserver.isEnabled();
+                        mForceShowNavBarSettingsObserver.isEnabled();
                 updateSystemBarAttributes();
             }
         });
-        mForceShowNavigationBarEnabled = mKidsModeSettingsObserver.isEnabled();
-        mHandler.post(mKidsModeSettingsObserver::register);
+        mForceShowNavigationBarEnabled = mForceShowNavBarSettingsObserver.isEnabled();
+        mHandler.post(mForceShowNavBarSettingsObserver::register);
     }
 
     /**
@@ -2861,7 +2861,7 @@
     void release() {
         mDisplayContent.mTransitionController.unregisterLegacyListener(mAppTransitionListener);
         mHandler.post(mGestureNavigationSettingsObserver::unregister);
-        mHandler.post(mKidsModeSettingsObserver::unregister);
+        mHandler.post(mForceShowNavBarSettingsObserver::unregister);
         mImmersiveModeConfirmation.release();
     }
 
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index e04644c..8413c54 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -123,7 +123,7 @@
         mDisplayContent = displayContent;
         mStateController = stateController;
         mFakeControl = new InsetsSourceControl(
-                source.getType(), null /* leash */, new Point(), Insets.NONE);
+                source.getType(), null /* leash */, new Point(), InsetsSourceControl.INVALID_HINTS);
         mControllable = InsetsPolicy.isInsetsTypeControllable(source.getType());
     }
 
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 1beb32c..4cb4e91 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -591,8 +591,9 @@
      * @see #isAllowedToEmbedActivityInTrustedMode(ActivityRecord)
      */
     boolean isAllowedToBeEmbeddedInTrustedMode() {
-        final Predicate<ActivityRecord> callback = this::isAllowedToEmbedActivityInTrustedMode;
-        return forAllActivities(callback);
+        // Traverse all activities to see if any of them are not in the trusted mode.
+        final Predicate<ActivityRecord> callback = r -> !isAllowedToEmbedActivityInTrustedMode(r);
+        return !forAllActivities(callback);
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 82a00b2..60188f5 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -3747,13 +3747,20 @@
     }
 
     void registerWindowContainerListener(WindowContainerListener listener) {
+        registerWindowContainerListener(listener, true /* shouldPropConfig */);
+    }
+
+    void registerWindowContainerListener(WindowContainerListener listener,
+            boolean shouldDispatchConfig) {
         if (mListeners.contains(listener)) {
             return;
         }
         mListeners.add(listener);
         // Also register to ConfigurationChangeListener to receive configuration changes.
-        registerConfigurationChangeListener(listener);
-        listener.onDisplayChanged(getDisplayContent());
+        registerConfigurationChangeListener(listener, shouldDispatchConfig);
+        if (shouldDispatchConfig) {
+            listener.onDisplayChanged(getDisplayContent());
+        }
     }
 
     void unregisterWindowContainerListener(WindowContainerListener listener) {
diff --git a/services/core/java/com/android/server/wm/WindowContextListenerController.java b/services/core/java/com/android/server/wm/WindowContextListenerController.java
index 7956a11..912fdb2 100644
--- a/services/core/java/com/android/server/wm/WindowContextListenerController.java
+++ b/services/core/java/com/android/server/wm/WindowContextListenerController.java
@@ -69,6 +69,16 @@
     final ArrayMap<IBinder, WindowContextListenerImpl> mListeners = new ArrayMap<>();
 
     /**
+     * @see #registerWindowContainerListener(IBinder, WindowContainer, int, int, Bundle, boolean)
+     */
+    void registerWindowContainerListener(@NonNull IBinder clientToken,
+            @NonNull WindowContainer<?> container, int ownerUid, @WindowType int type,
+            @Nullable Bundle options) {
+        registerWindowContainerListener(clientToken, container, ownerUid, type, options,
+                true /* shouDispatchConfigWhenRegistering */);
+    }
+
+    /**
      * Registers the listener to a {@code container} which is associated with
      * a {@code clientToken}, which is a {@link android.window.WindowContext} representation. If the
      * listener associated with {@code clientToken} hasn't been initialized yet, create one
@@ -80,15 +90,18 @@
      * @param ownerUid the caller UID
      * @param type the window type
      * @param options a bundle used to pass window-related options.
+     * @param shouDispatchConfigWhenRegistering {@code true} to indicate the current
+     *                {@code container}'s config will dispatch to the client side when
+     *                registering the {@link WindowContextListenerImpl}
      */
     void registerWindowContainerListener(@NonNull IBinder clientToken,
             @NonNull WindowContainer<?> container, int ownerUid, @WindowType int type,
-            @Nullable Bundle options) {
+            @Nullable Bundle options, boolean shouDispatchConfigWhenRegistering) {
         WindowContextListenerImpl listener = mListeners.get(clientToken);
         if (listener == null) {
             listener = new WindowContextListenerImpl(clientToken, container, ownerUid, type,
                     options);
-            listener.register();
+            listener.register(shouDispatchConfigWhenRegistering);
         } else {
             listener.updateContainer(container);
         }
@@ -228,12 +241,16 @@
         }
 
         private void register() {
+            register(true /* shouldDispatchConfig */);
+        }
+
+        private void register(boolean shouldDispatchConfig) {
             final IBinder token = mClientToken.asBinder();
             if (mDeathRecipient == null) {
                 throw new IllegalStateException("Invalid client token: " + token);
             }
             mListeners.putIfAbsent(token, this);
-            mContainer.registerWindowContainerListener(this);
+            mContainer.registerWindowContainerListener(this, shouldDispatchConfig);
         }
 
         private void unregister() {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 6393edc..016a401 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -423,7 +423,7 @@
             "persist.wm.enable_remote_keyguard_animation";
 
     private static final int sEnableRemoteKeyguardAnimation =
-            SystemProperties.getInt(ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY, 1);
+            SystemProperties.getInt(ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY, 2);
 
     /**
      * @see #ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY
@@ -2761,12 +2761,10 @@
                 }
                 // TODO(b/155340867): Investigate if we still need roundedCornerOverlay after
                 // the feature b/155340867 is completed.
-                final DisplayArea da = dc.findAreaForWindowType(type, options,
+                final DisplayArea<?> da = dc.findAreaForWindowType(type, options,
                         callerCanManageAppTokens, false /* roundedCornerOverlay */);
-                // TODO(b/190019118): Avoid to send onConfigurationChanged because it has been done
-                //  in return value of attachWindowContextToDisplayArea.
                 mWindowContextListenerController.registerWindowContainerListener(clientToken, da,
-                        callingUid, type, options);
+                        callingUid, type, options, false /* shouDispatchConfigWhenRegistering */);
                 return da.getConfiguration();
             }
         } finally {
@@ -2862,7 +2860,8 @@
                 }
 
                 mWindowContextListenerController.registerWindowContainerListener(clientToken, dc,
-                        callingUid, INVALID_WINDOW_TYPE, null /* options */);
+                        callingUid, INVALID_WINDOW_TYPE, null /* options */,
+                        false /* shouDispatchConfigWhenRegistering */);
                 return dc.getConfiguration();
             }
         } finally {
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 598569f..afeede7 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -30,6 +30,7 @@
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_CHILDREN;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_RESTORE_TRANSIENT_ORDER;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS;
@@ -777,6 +778,29 @@
                 }
                 break;
             }
+            case HIERARCHY_OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT: {
+                final TaskFragment tf = mLaunchTaskFragments.get(hop.getContainer());
+                if (tf == null || !tf.isAttached()) {
+                    Slog.e(TAG, "Attempt to operate on detached container: " + tf);
+                    break;
+                }
+                final ActivityRecord curFocus = tf.getDisplayContent().mFocusedApp;
+                if (curFocus != null && curFocus.getTaskFragment() == tf) {
+                    Slog.d(TAG, "The requested TaskFragment already has the focus.");
+                    break;
+                }
+                if (curFocus != null && curFocus.getTask() != tf.getTask()) {
+                    Slog.d(TAG, "The Task of the requested TaskFragment doesn't have focus.");
+                    break;
+                }
+                final ActivityRecord targetFocus = tf.getTopResumedActivity();
+                if (targetFocus == null) {
+                    Slog.d(TAG, "There is no resumed activity in the requested TaskFragment.");
+                    break;
+                }
+                tf.getDisplayContent().setFocusedApp(targetFocus);
+                break;
+            }
             default: {
                 // The other operations may change task order so they are skipped while in lock
                 // task mode. The above operations are still allowed because they don't move
@@ -1320,6 +1344,7 @@
                 case HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT:
                 case HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT:
                 case HIERARCHY_OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS:
+                case HIERARCHY_OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT:
                     // We are allowing organizer to start/reparent activity to a TaskFragment it
                     // created, or set two TaskFragments adjacent to each other. Nothing to check
                     // here because the TaskFragment may not be created yet, but will be created in
@@ -1415,7 +1440,8 @@
         }
         final WindowConfiguration requestedWindowConfig = requestedConfig.windowConfiguration;
         final WindowConfiguration parentWindowConfig = parentConfig.windowConfiguration;
-        if (!parentWindowConfig.getBounds().contains(requestedWindowConfig.getBounds())) {
+        if (!requestedWindowConfig.getBounds().isEmpty()
+                && !parentWindowConfig.getBounds().contains(requestedWindowConfig.getBounds())) {
             String msg = "Permission Denial: " + func + " from pid="
                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
                     + " trying to apply bounds outside of parent for non-trusted host,"
@@ -1424,6 +1450,7 @@
             throw new SecurityException(msg);
         }
         if (requestedWindowConfig.getAppBounds() != null
+                && !requestedWindowConfig.getAppBounds().isEmpty()
                 && parentWindowConfig.getAppBounds() != null
                 && !parentWindowConfig.getAppBounds().contains(
                         requestedWindowConfig.getAppBounds())) {
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index ffda8be..d551944 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -71,7 +71,6 @@
 
 using android::base::ParseUint;
 using android::base::StringPrintf;
-using android::os::BlockUntrustedTouchesMode;
 using android::os::InputEventInjectionResult;
 using android::os::InputEventInjectionSync;
 
@@ -108,7 +107,6 @@
     jmethodID notifySensorEvent;
     jmethodID notifySensorAccuracy;
     jmethodID notifyVibratorState;
-    jmethodID notifyUntrustedTouch;
     jmethodID filterInputEvent;
     jmethodID interceptKeyBeforeQueueing;
     jmethodID interceptMotionBeforeQueueingNonInteractive;
@@ -330,7 +328,6 @@
     void notifySensorAccuracy(int32_t deviceId, InputDeviceSensorType sensorType,
                               InputDeviceSensorAccuracy accuracy) override;
     void notifyVibratorState(int32_t deviceId, bool isOn) override;
-    void notifyUntrustedTouch(const std::string& obscuringPackage) override;
     bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) override;
     void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) override;
     void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags) override;
@@ -898,17 +895,6 @@
     }
 }
 
-void NativeInputManager::notifyUntrustedTouch(const std::string& obscuringPackage) {
-#if DEBUG_INPUT_DISPATCHER_POLICY
-    ALOGD("notifyUntrustedTouch - obscuringPackage=%s", obscuringPackage.c_str());
-#endif
-    ATRACE_CALL();
-    JNIEnv* env = jniEnv();
-    jstring jPackage = env->NewStringUTF(obscuringPackage.c_str());
-    env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyUntrustedTouch, jPackage);
-    checkAndClearExceptionFromCallback(env, "notifyUntrustedTouch");
-}
-
 void NativeInputManager::notifyFocusChanged(const sp<IBinder>& oldToken,
         const sp<IBinder>& newToken) {
 #if DEBUG_INPUT_DISPATCHER_POLICY
@@ -1712,13 +1698,6 @@
     im->getInputManager()->getDispatcher().setMaximumObscuringOpacityForTouch(opacity);
 }
 
-static void nativeSetBlockUntrustedTouchesMode(JNIEnv* env, jobject nativeImplObj, jint mode) {
-    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
-
-    im->getInputManager()->getDispatcher().setBlockUntrustedTouchesMode(
-            static_cast<BlockUntrustedTouchesMode>(mode));
-}
-
 static jint nativeInjectInputEvent(JNIEnv* env, jobject nativeImplObj, jobject inputEventObj,
                                    jint injectorPid, jint injectorUid, jint syncMode,
                                    jint timeoutMillis, jint policyFlags) {
@@ -2357,7 +2336,6 @@
         {"setInTouchMode", "(ZIIZ)Z", (void*)nativeSetInTouchMode},
         {"setMaximumObscuringOpacityForTouch", "(F)V",
          (void*)nativeSetMaximumObscuringOpacityForTouch},
-        {"setBlockUntrustedTouchesMode", "(I)V", (void*)nativeSetBlockUntrustedTouchesMode},
         {"injectInputEvent", "(Landroid/view/InputEvent;IIIII)I", (void*)nativeInjectInputEvent},
         {"verifyInputEvent", "(Landroid/view/InputEvent;)Landroid/view/VerifiedInputEvent;",
          (void*)nativeVerifyInputEvent},
@@ -2476,9 +2454,6 @@
 
     GET_METHOD_ID(gServiceClassInfo.notifyVibratorState, clazz, "notifyVibratorState", "(IZ)V");
 
-    GET_METHOD_ID(gServiceClassInfo.notifyUntrustedTouch, clazz, "notifyUntrustedTouch",
-                  "(Ljava/lang/String;)V");
-
     GET_METHOD_ID(gServiceClassInfo.notifyNoFocusedWindowAnr, clazz, "notifyNoFocusedWindowAnr",
                   "(Landroid/view/InputApplicationHandle;)V");
 
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
index aca1389..3912991 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
@@ -21,6 +21,7 @@
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
 import static android.app.admin.WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_ALLOWLIST;
 import static android.app.admin.WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_DENYLIST;
+import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1;
 
 import static com.android.server.devicepolicy.DevicePolicyManagerService.LOG_TAG;
 
@@ -159,6 +160,10 @@
     private static final String ATTR_VALUE = "value";
     private static final String ATTR_LAST_NETWORK_LOGGING_NOTIFICATION = "last-notification";
     private static final String ATTR_NUM_NETWORK_LOGGING_NOTIFICATIONS = "num-notifications";
+    private static final String TAG_PREFERENTIAL_NETWORK_SERVICE_CONFIGS =
+            "preferential_network_service_configs";
+    private static final String TAG_PREFERENTIAL_NETWORK_SERVICE_CONFIG =
+            "preferential_network_service_config";
 
     DeviceAdminInfo info;
 
@@ -587,8 +592,6 @@
         }
         writeAttributeValueToXml(out, TAG_ADMIN_CAN_GRANT_SENSORS_PERMISSIONS,
                 mAdminCanGrantSensorsPermissions);
-        writeAttributeValueToXml(out, TAG_PREFERENTIAL_NETWORK_SERVICE_ENABLED,
-                mPreferentialNetworkServiceEnabled);
         if (mUsbDataSignalingEnabled != USB_DATA_SIGNALING_ENABLED_DEFAULT) {
             writeAttributeValueToXml(out, TAG_USB_DATA_SIGNALING, mUsbDataSignalingEnabled);
         }
@@ -603,6 +606,13 @@
                 writeAttributeValuesToXml(out, TAG_SSID_DENYLIST, TAG_SSID, ssids);
             }
         }
+        if (!mPreferentialNetworkServiceConfigs.isEmpty()) {
+            out.startTag(null, TAG_PREFERENTIAL_NETWORK_SERVICE_CONFIGS);
+            for (PreferentialNetworkServiceConfig config : mPreferentialNetworkServiceConfigs) {
+                config.writeToXml(out);
+            }
+            out.endTag(null, TAG_PREFERENTIAL_NETWORK_SERVICE_CONFIGS);
+        }
     }
 
     private List<String> ssidsToStrings(Set<WifiSsid> ssids) {
@@ -833,6 +843,14 @@
             } else if (TAG_PREFERENTIAL_NETWORK_SERVICE_ENABLED.equals(tag)) {
                 mPreferentialNetworkServiceEnabled = parser.getAttributeBoolean(null, ATTR_VALUE,
                         DevicePolicyManager.PREFERENTIAL_NETWORK_SERVICE_ENABLED_DEFAULT);
+                if (mPreferentialNetworkServiceEnabled) {
+                    PreferentialNetworkServiceConfig.Builder configBuilder =
+                            new PreferentialNetworkServiceConfig.Builder();
+                    configBuilder.setEnabled(mPreferentialNetworkServiceEnabled);
+                    configBuilder.setNetworkId(NET_ENTERPRISE_ID_1);
+                    mPreferentialNetworkServiceConfigs = List.of(configBuilder.build());
+                    mPreferentialNetworkServiceEnabled = false;
+                }
             } else if (TAG_COMMON_CRITERIA_MODE.equals(tag)) {
                 mCommonCriteriaMode = parser.getAttributeBoolean(null, ATTR_VALUE, false);
             } else if (TAG_PASSWORD_COMPLEXITY.equals(tag)) {
@@ -871,6 +889,12 @@
                 List<WifiSsid> ssids = readWifiSsids(parser, TAG_SSID);
                 mWifiSsidPolicy = new WifiSsidPolicy(
                         WIFI_SSID_POLICY_TYPE_DENYLIST, new ArraySet<>(ssids));
+            } else if (TAG_PREFERENTIAL_NETWORK_SERVICE_CONFIGS.equals(tag)) {
+                List<PreferentialNetworkServiceConfig> configs =
+                        getPreferentialNetworkServiceConfigs(parser, tag);
+                if (!configs.isEmpty()) {
+                    mPreferentialNetworkServiceConfigs = configs;
+                }
             } else {
                 Slogf.w(LOG_TAG, "Unknown admin tag: %s", tag);
                 XmlUtils.skipCurrentTag(parser);
@@ -956,19 +980,43 @@
         return result;
     }
 
-    private TrustAgentInfo getTrustAgentInfo(TypedXmlPullParser parser, String tag)
+    private TrustAgentInfo getTrustAgentInfo(TypedXmlPullParser parser, String outerTag)
             throws XmlPullParserException, IOException  {
-        int outerDepthDAM = parser.getDepth();
-        int typeDAM;
+        int outerDepth = parser.getDepth();
+        int type;
         TrustAgentInfo result = new TrustAgentInfo(null);
+        while ((type = parser.next()) != END_DOCUMENT
+                && (type != END_TAG || parser.getDepth() > outerDepth)) {
+            if (type == END_TAG || type == TEXT) {
+                continue;
+            }
+            String tag = parser.getName();
+            if (TAG_TRUST_AGENT_COMPONENT_OPTIONS.equals(tag)) {
+                result.options = PersistableBundle.restoreFromXml(parser);
+            } else {
+                Slogf.w(LOG_TAG, "Unknown tag under %s: %s", outerTag, tag);
+            }
+        }
+        return result;
+    }
+
+    @NonNull
+    private List<PreferentialNetworkServiceConfig> getPreferentialNetworkServiceConfigs(
+            TypedXmlPullParser parser, String tag) throws XmlPullParserException, IOException {
+        int outerDepth = parser.getDepth();
+        int typeDAM;
+        final List<PreferentialNetworkServiceConfig> result = new ArrayList<>();
         while ((typeDAM = parser.next()) != END_DOCUMENT
-                && (typeDAM != END_TAG || parser.getDepth() > outerDepthDAM)) {
+            && (typeDAM != END_TAG || parser.getDepth() > outerDepth)) {
             if (typeDAM == END_TAG || typeDAM == TEXT) {
                 continue;
             }
             String tagDAM = parser.getName();
-            if (TAG_TRUST_AGENT_COMPONENT_OPTIONS.equals(tagDAM)) {
-                result.options = PersistableBundle.restoreFromXml(parser);
+            if (TAG_PREFERENTIAL_NETWORK_SERVICE_CONFIG.equals(tagDAM)) {
+                final PreferentialNetworkServiceConfig preferentialNetworkServiceConfig =
+                        PreferentialNetworkServiceConfig.getPreferentialNetworkServiceConfig(
+                                parser, tag);
+                result.add(preferentialNetworkServiceConfig);
             } else {
                 Slogf.w(LOG_TAG, "Unknown tag under %s: %s", tag, tagDAM);
             }
@@ -1258,5 +1306,14 @@
             mFactoryResetProtectionPolicy.dump(pw);
             pw.decreaseIndent();
         }
+
+        if (mPreferentialNetworkServiceConfigs != null) {
+            pw.println("mPreferentialNetworkServiceConfigs:");
+            pw.increaseIndent();
+            for (PreferentialNetworkServiceConfig config : mPreferentialNetworkServiceConfigs) {
+                config.dump(pw);
+            }
+            pw.decreaseIndent();
+        }
     }
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyData.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyData.java
index 9a0b5c7..48a436f 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyData.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyData.java
@@ -69,6 +69,7 @@
     private static final String TAG_PASSWORD_VALIDITY = "password-validity";
     private static final String TAG_PASSWORD_TOKEN_HANDLE = "password-token";
     private static final String TAG_PROTECTED_PACKAGES = "protected-packages";
+    private static final String TAG_BYPASS_ROLE_QUALIFICATIONS = "bypass-role-qualifications";
     private static final String ATTR_VALUE = "value";
     private static final String ATTR_ALIAS = "alias";
     private static final String ATTR_ID = "id";
@@ -107,6 +108,8 @@
     int mPasswordOwner = -1;
     long mLastMaximumTimeToLock = -1;
     boolean mUserSetupComplete = false;
+    boolean mBypassDevicePolicyManagementRoleQualifications = false;
+    String mCurrentRoleHolder;
     boolean mPaired = false;
     int mUserProvisioningState;
     int mPermissionPolicy;
@@ -374,6 +377,12 @@
                 out.endTag(null, TAG_APPS_SUSPENDED);
             }
 
+            if (policyData.mBypassDevicePolicyManagementRoleQualifications) {
+                out.startTag(null, TAG_BYPASS_ROLE_QUALIFICATIONS);
+                out.attribute(null, ATTR_VALUE, policyData.mCurrentRoleHolder);
+                out.endTag(null, TAG_BYPASS_ROLE_QUALIFICATIONS);
+            }
+
             out.endTag(null, "policies");
 
             out.endDocument();
@@ -558,6 +567,9 @@
                 } else if (TAG_APPS_SUSPENDED.equals(tag)) {
                     policy.mAppsSuspended =
                             parser.getAttributeBoolean(null, ATTR_VALUE, false);
+                } else if (TAG_BYPASS_ROLE_QUALIFICATIONS.equals(tag)) {
+                    policy.mBypassDevicePolicyManagementRoleQualifications = true;
+                    policy.mCurrentRoleHolder =  parser.getAttributeValue(null, ATTR_VALUE);
                 } else {
                     Slogf.w(TAG, "Unknown tag: %s", tag);
                     XmlUtils.skipCurrentTag(parser);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 417aba1..59aba48 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -138,7 +138,6 @@
 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE;
 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK;
 import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
-import static android.provider.Settings.Global.BYPASS_DEVICE_POLICY_MANAGEMENT_ROLE_QUALIFICATIONS;
 import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
 import static android.provider.Settings.Secure.MANAGED_PROVISIONING_DPC_DOWNLOADED;
 import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
@@ -222,6 +221,7 @@
 import android.app.admin.WifiSsidPolicy;
 import android.app.backup.IBackupManager;
 import android.app.compat.CompatChanges;
+import android.app.role.OnRoleHoldersChangedListener;
 import android.app.role.RoleManager;
 import android.app.trust.TrustManager;
 import android.app.usage.UsageStatsManagerInternal;
@@ -255,6 +255,7 @@
 import android.content.pm.PermissionInfo;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
+import android.content.pm.Signature;
 import android.content.pm.StringParceledListSlice;
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
@@ -409,6 +410,7 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.concurrent.Executor;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Function;
 import java.util.function.Predicate;
@@ -756,6 +758,7 @@
     private @UserIdInt int mNetworkLoggingNotificationUserId = UserHandle.USER_NULL;
 
     private final DeviceManagementResourcesProvider mDeviceManagementResourcesProvider;
+    private final DevicePolicyManagementRoleObserver mDevicePolicyManagementRoleObserver;
 
     private static final boolean ENABLE_LOCK_GUARD = true;
 
@@ -1823,6 +1826,8 @@
         mBugreportCollectionManager = new RemoteBugreportManager(this, mInjector);
 
         mDeviceManagementResourcesProvider = mInjector.getDeviceManagementResourcesProvider();
+        mDevicePolicyManagementRoleObserver = new DevicePolicyManagementRoleObserver(mContext);
+        mDevicePolicyManagementRoleObserver.register();
 
         // "Lite" interface is available even when the device doesn't have the feature
         LocalServices.addService(DevicePolicyManagerLiteInternal.class, mLocalService);
@@ -8515,13 +8520,6 @@
         }
     }
 
-    private boolean isDeviceOwnerUserId(int userId) {
-        synchronized (getLockObject()) {
-            return mOwners.hasDeviceOwner()
-                    && mOwners.getDeviceOwnerUserId() == userId;
-        }
-    }
-
     private boolean isDeviceOwnerPackage(String packageName, int userId) {
         synchronized (getLockObject()) {
             return mOwners.hasDeviceOwner()
@@ -14655,6 +14653,13 @@
             throw new SecurityException(
                     "Only the system can mark a profile owner of organization-owned device.");
         }
+        // Only a test admin can be unmarked as a profile owner on an organization-owned device.
+        synchronized (getLockObject()) {
+            if (!isProfileOwnerOnOrganizationOwnedDevice && !isAdminTestOnlyLocked(who, userId)) {
+                throw new SecurityException("Only a test admin can be unmarked as a "
+                        + "profile owner of organization-owned device.");
+            }
+        }
 
         if (isAdb(caller)) {
             if (hasIncompatibleAccountsOrNonAdbNoLock(caller, userId, who)) {
@@ -18267,7 +18272,7 @@
 
     private void updateNetworkPreferenceForUser(int userId,
             List<PreferentialNetworkServiceConfig> preferentialNetworkServiceConfigs) {
-        if (!isManagedProfile(userId) && !isDeviceOwnerUserId(userId)) {
+        if (!isManagedProfile(userId)) {
             return;
         }
         List<ProfileNetworkPreference> preferences = new ArrayList<>();
@@ -18282,16 +18287,20 @@
                     preferenceBuilder.setPreference(
                             PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK);
                 }
+                preferenceBuilder.setIncludedUids(
+                        preferentialNetworkServiceConfig.getIncludedUids());
+                preferenceBuilder.setExcludedUids(
+                        preferentialNetworkServiceConfig.getExcludedUids());
+                preferenceBuilder.setPreferenceEnterpriseId(
+                        preferentialNetworkServiceConfig.getNetworkId());
             } else {
                 preferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT);
             }
-            preferenceBuilder.setIncludedUids(preferentialNetworkServiceConfig.getIncludedUids());
-            preferenceBuilder.setExcludedUids(preferentialNetworkServiceConfig.getExcludedUids());
-            preferenceBuilder.setPreferenceEnterpriseId(
-                    preferentialNetworkServiceConfig.getNetworkId());
+
 
             preferences.add(preferenceBuilder.build());
         }
+        Slogf.d(LOG_TAG, "updateNetworkPreferenceForUser to " + preferences);
         mInjector.binderWithCleanCallingIdentity(() ->
                 mInjector.getConnectivityManager().setProfileNetworkPreferences(
                         UserHandle.of(userId), preferences,
@@ -18658,16 +18667,11 @@
         Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(
                 android.Manifest.permission.MANAGE_ROLE_HOLDERS));
         return mInjector.binderWithCleanCallingIdentity(() -> {
-            if (mInjector.settingsGlobalGetInt(
-                    BYPASS_DEVICE_POLICY_MANAGEMENT_ROLE_QUALIFICATIONS, /* def= */ 0) == 1) {
+            if (getUserData(
+                    UserHandle.USER_SYSTEM).mBypassDevicePolicyManagementRoleQualifications) {
                 return true;
             }
-            if (shouldAllowBypassingDevicePolicyManagementRoleQualificationInternal()) {
-                mInjector.settingsGlobalPutInt(
-                        BYPASS_DEVICE_POLICY_MANAGEMENT_ROLE_QUALIFICATIONS, /* value= */ 1);
-                return true;
-            }
-            return false;
+            return shouldAllowBypassingDevicePolicyManagementRoleQualificationInternal();
         });
     }
 
@@ -18680,6 +18684,142 @@
         return accounts.length == 0;
     }
 
+    private void setBypassDevicePolicyManagementRoleQualificationStateInternal(
+            String currentRoleHolder, boolean allowBypass) {
+        boolean stateChanged = false;
+        DevicePolicyData policy = getUserData(UserHandle.USER_SYSTEM);
+        if (policy.mBypassDevicePolicyManagementRoleQualifications != allowBypass) {
+            policy.mBypassDevicePolicyManagementRoleQualifications = allowBypass;
+            stateChanged = true;
+        }
+        if (!Objects.equals(currentRoleHolder, policy.mCurrentRoleHolder)) {
+            policy.mCurrentRoleHolder = currentRoleHolder;
+            stateChanged = true;
+        }
+        if (stateChanged) {
+            synchronized (getLockObject()) {
+                saveSettingsLocked(UserHandle.USER_SYSTEM);
+            }
+        }
+    }
+
+    private final class DevicePolicyManagementRoleObserver implements OnRoleHoldersChangedListener {
+        private RoleManager mRm;
+        private final Executor mExecutor;
+        private final Context mContext;
+
+        DevicePolicyManagementRoleObserver(@NonNull Context context) {
+            mContext = context;
+            mExecutor = mContext.getMainExecutor();
+            mRm = mContext.getSystemService(RoleManager.class);
+        }
+
+        public void register() {
+            mRm.addOnRoleHoldersChangedListenerAsUser(mExecutor, this, UserHandle.SYSTEM);
+        }
+
+        @Override
+        public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) {
+            if (!RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT.equals(roleName)) {
+                return;
+            }
+            String newRoleHolder = getRoleHolder();
+            if (isDefaultRoleHolder(newRoleHolder)) {
+                Slogf.i(LOG_TAG,
+                        "onRoleHoldersChanged: Default role holder is set, returning early");
+                return;
+            }
+            if (newRoleHolder == null) {
+                Slogf.i(LOG_TAG,
+                        "onRoleHoldersChanged: New role holder is null, returning early");
+                return;
+            }
+            if (shouldAllowBypassingDevicePolicyManagementRoleQualificationInternal()) {
+                Slogf.w(LOG_TAG,
+                        "onRoleHoldersChanged: Updating current role holder to " + newRoleHolder);
+                setBypassDevicePolicyManagementRoleQualificationStateInternal(
+                        newRoleHolder, /* allowBypass= */ true);
+                return;
+            }
+            DevicePolicyData policy = getUserData(UserHandle.USER_SYSTEM);
+            if (!newRoleHolder.equals(policy.mCurrentRoleHolder)) {
+                Slogf.w(LOG_TAG,
+                        "onRoleHoldersChanged: You can't set a different role holder, role "
+                                + "is getting revoked from " + newRoleHolder);
+                setBypassDevicePolicyManagementRoleQualificationStateInternal(
+                        /* currentRoleHolder= */ null, /* allowBypass= */ false);
+                mRm.removeRoleHolderAsUser(
+                        RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT,
+                        newRoleHolder,
+                        /* flags= */ 0,
+                        user,
+                        mExecutor,
+                        successful -> {});
+            }
+        }
+
+        private String getRoleHolder() {
+            return DevicePolicyManagerService.this.getDevicePolicyManagementRoleHolderPackageName(
+                    mContext);
+        }
+
+        private boolean isDefaultRoleHolder(String packageName) {
+            String defaultRoleHolder = getDefaultRoleHolderPackageName();
+            if (packageName == null || defaultRoleHolder == null) {
+                return false;
+            }
+            if (!defaultRoleHolder.equals(packageName)) {
+                return false;
+            }
+            return hasSigningCertificate(
+                    packageName, getDefaultRoleHolderPackageSignature());
+        }
+
+        private boolean hasSigningCertificate(String packageName, String  certificateString) {
+            if (packageName == null || certificateString == null) {
+                return false;
+            }
+            byte[] certificate;
+            try {
+                certificate = new Signature(certificateString).toByteArray();
+            } catch (IllegalArgumentException e) {
+                Slogf.w(LOG_TAG, "Cannot parse signing certificate: " + certificateString, e);
+                return false;
+            }
+            PackageManager pm = mInjector.getPackageManager();
+            return pm.hasSigningCertificate(
+                    packageName, certificate, PackageManager.CERT_INPUT_SHA256);
+        }
+
+        private String getDefaultRoleHolderPackageName() {
+            String[] info = getDefaultRoleHolderPackageNameAndSignature();
+            if (info == null) {
+                return null;
+            }
+            return info[0];
+        }
+
+        private String getDefaultRoleHolderPackageSignature() {
+            String[] info = getDefaultRoleHolderPackageNameAndSignature();
+            if (info == null || info.length < 2) {
+                return null;
+            }
+            return info[1];
+        }
+
+        private String[] getDefaultRoleHolderPackageNameAndSignature() {
+            String packageNameAndSignature = mContext.getString(
+                    com.android.internal.R.string.config_devicePolicyManagement);
+            if (TextUtils.isEmpty(packageNameAndSignature)) {
+                return null;
+            }
+            if (packageNameAndSignature.contains(":")) {
+                return packageNameAndSignature.split(":");
+            }
+            return new String[]{packageNameAndSignature};
+        }
+    }
+
     @Override
     public List<UserHandle> getPolicyManagedProfiles(@NonNull UserHandle user) {
         Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 449177e..0afb182 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -102,6 +102,7 @@
     <uses-permission android:name="android.permission.READ_NEARBY_STREAMING_POLICY" />
     <uses-permission android:name="android.permission.MODIFY_AUDIO_ROUTING" />
     <uses-permission android:name="android.permission.PACKAGE_VERIFICATION_AGENT" />
+    <uses-permission android:name="android.permission.OBSERVE_ROLE_HOLDERS" />
 
     <queries>
         <package android:name="com.android.servicestests.apps.suspendtestapp" />
diff --git a/services/tests/servicestests/src/com/android/server/BinaryTransparencyServiceTest.java b/services/tests/servicestests/src/com/android/server/BinaryTransparencyServiceTest.java
index 0e84e04..42c4129 100644
--- a/services/tests/servicestests/src/com/android/server/BinaryTransparencyServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/BinaryTransparencyServiceTest.java
@@ -16,6 +16,10 @@
 
 package com.android.server;
 
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.app.job.JobScheduler;
 import android.content.Context;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
@@ -43,13 +47,15 @@
 
     @Before
     public void setUp() {
-        mContext = ApplicationProvider.getApplicationContext();
+        mContext = spy(ApplicationProvider.getApplicationContext());
         mBinaryTransparencyService = new BinaryTransparencyService(mContext);
         mTestInterface = mBinaryTransparencyService.new BinaryTransparencyServiceImpl();
     }
 
     private void prepSignedInfo() {
         // simulate what happens on boot completed phase
+        // but we avoid calling JobScheduler.schedule by returning a null.
+        doReturn(null).when(mContext).getSystemService(JobScheduler.class);
         mBinaryTransparencyService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/am/DropboxRateLimiterTest.java b/services/tests/servicestests/src/com/android/server/am/DropboxRateLimiterTest.java
index 00f4c39..5c91b8b 100644
--- a/services/tests/servicestests/src/com/android/server/am/DropboxRateLimiterTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/DropboxRateLimiterTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.am;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
@@ -43,34 +44,52 @@
     @Test
     public void testMultipleProcesses() {
         // The first 5 entries should not be rate limited.
-        assertFalse(mRateLimiter.shouldRateLimit("tag", "process"));
-        assertFalse(mRateLimiter.shouldRateLimit("tag", "process"));
-        assertFalse(mRateLimiter.shouldRateLimit("tag", "process"));
-        assertFalse(mRateLimiter.shouldRateLimit("tag", "process"));
-        assertFalse(mRateLimiter.shouldRateLimit("tag", "process"));
+        assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
+        assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
+        assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
+        assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
+        assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
         // Different processes and tags should not get rate limited either.
-        assertFalse(mRateLimiter.shouldRateLimit("tag", "process2"));
-        assertFalse(mRateLimiter.shouldRateLimit("tag2", "process"));
+        assertFalse(mRateLimiter.shouldRateLimit("tag", "process2").shouldRateLimit());
+        assertFalse(mRateLimiter.shouldRateLimit("tag2", "process").shouldRateLimit());
         // The 6th entry of the same process should be rate limited.
-        assertTrue(mRateLimiter.shouldRateLimit("tag", "process"));
+        assertTrue(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
     }
 
     @Test
     public void testBufferClearing() throws Exception {
         // The first 5 entries should not be rate limited.
-        assertFalse(mRateLimiter.shouldRateLimit("tag", "process"));
-        assertFalse(mRateLimiter.shouldRateLimit("tag", "process"));
-        assertFalse(mRateLimiter.shouldRateLimit("tag", "process"));
-        assertFalse(mRateLimiter.shouldRateLimit("tag", "process"));
-        assertFalse(mRateLimiter.shouldRateLimit("tag", "process"));
+        assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
+        assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
+        assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
+        assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
+        assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
         // The 6th entry of the same process should be rate limited.
-        assertTrue(mRateLimiter.shouldRateLimit("tag", "process"));
+        assertTrue(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
 
         // After 11 seconds there should be nothing left in the buffer and the same type of entry
         // should not get rate limited anymore.
         mClock.setOffsetMillis(11000);
 
-        assertFalse(mRateLimiter.shouldRateLimit("tag", "process"));
+        assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
+    }
+
+    @Test
+    public void testRecentlyDroppedCount() throws Exception {
+        assertEquals(0,
+                mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated());
+        assertEquals(0,
+                mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated());
+        assertEquals(0,
+                mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated());
+        assertEquals(0,
+                mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated());
+        assertEquals(0,
+                mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated());
+        assertEquals(1,
+                mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated());
+        assertEquals(2,
+                mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated());
     }
 
     private static class TestClock implements DropboxRateLimiter.Clock {
diff --git a/services/tests/servicestests/src/com/android/server/ambientcontext/AmbientContextManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/ambientcontext/AmbientContextManagerServiceTest.java
new file mode 100644
index 0000000..6bb494d
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/ambientcontext/AmbientContextManagerServiceTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.ambientcontext;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.PendingIntent;
+import android.app.ambientcontext.AmbientContextEvent;
+import android.app.ambientcontext.AmbientContextEventRequest;
+import android.content.Intent;
+import android.os.RemoteCallback;
+import android.os.UserHandle;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+
+/**
+ * Unit test for {@link AmbientContextManagerService}.
+ * atest FrameworksServicesTests:AmbientContextManagerServiceTest
+ */
+public class AmbientContextManagerServiceTest {
+    public static final String SYSTEM_PACKAGE_NAME = "com.android.frameworks.servicestests";
+    private static final int USER_ID = UserHandle.USER_SYSTEM;
+
+    @SmallTest
+    @Test
+    public void testClientRequest() {
+        AmbientContextEventRequest request = new AmbientContextEventRequest.Builder()
+                .addEventType(AmbientContextEvent.EVENT_COUGH)
+                .build();
+        Intent intent = new Intent();
+        PendingIntent pendingIntent = PendingIntent.getBroadcast(
+                InstrumentationRegistry.getTargetContext(), 0,
+                intent, PendingIntent.FLAG_IMMUTABLE);
+        AmbientContextManagerService.ClientRequest clientRequest =
+                new AmbientContextManagerService.ClientRequest(USER_ID, request,
+                        pendingIntent, new RemoteCallback(result -> {}));
+
+        assertThat(clientRequest.getRequest()).isEqualTo(request);
+        assertThat(clientRequest.getPackageName()).isEqualTo(SYSTEM_PACKAGE_NAME);
+        assertThat(clientRequest.hasUserId(USER_ID)).isTrue();
+        assertThat(clientRequest.hasUserId(-1)).isFalse();
+        assertThat(clientRequest.hasUserIdAndPackageName(USER_ID, SYSTEM_PACKAGE_NAME)).isTrue();
+        assertThat(clientRequest.hasUserIdAndPackageName(-1, SYSTEM_PACKAGE_NAME)).isFalse();
+        assertThat(clientRequest.hasUserIdAndPackageName(USER_ID, "random.package.name"))
+                .isFalse();
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/ambientcontext/OWNERS b/services/tests/servicestests/src/com/android/server/ambientcontext/OWNERS
new file mode 100644
index 0000000..ddfb6e3
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/ambientcontext/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/ambientcontext/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java
index f40b31a..abf992b 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java
@@ -415,7 +415,7 @@
         // Auth was attempted
         when(mUdfpsClient.getState())
                 .thenReturn(AuthenticationClient.STATE_STARTED_PAUSED_ATTEMPTED);
-        verify(mCallback, never()).sendHapticFeedback();
+        verify(mCallback).sendHapticFeedback();
         verify(mCallback).handleLifecycleAfterAuth();
 
         // Then face rejected. Note that scheduler leaves UDFPS in the CoexCoordinator since
@@ -425,7 +425,7 @@
                 LockoutTracker.LOCKOUT_NONE, faceCallback);
         verify(faceCallback).sendHapticFeedback();
         verify(faceCallback).sendAuthenticationResult(eq(false) /* addAuthTokenIfStrong */);
-        verify(mCallback, never()).sendHapticFeedback();
+        verify(mCallback).sendHapticFeedback();
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java
new file mode 100644
index 0000000..ca3677e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.biometrics.sensors.fingerprint;
+
+import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.pm.PackageManager;
+import android.hardware.biometrics.IBiometricService;
+import android.hardware.biometrics.common.CommonProps;
+import android.hardware.biometrics.common.SensorStrength;
+import android.hardware.biometrics.fingerprint.FingerprintSensorType;
+import android.hardware.biometrics.fingerprint.IFingerprint;
+import android.hardware.biometrics.fingerprint.SensorLocation;
+import android.hardware.biometrics.fingerprint.SensorProps;
+import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
+import android.provider.Settings;
+import android.testing.TestableContext;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.internal.util.test.FakeSettingsProvider;
+import com.android.internal.util.test.FakeSettingsProviderRule;
+import com.android.server.biometrics.log.BiometricContext;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import java.util.List;
+
+@Presubmit
+@SmallTest
+public class FingerprintServiceTest {
+
+    private static final int ID_DEFAULT = 2;
+    private static final int ID_VIRTUAL = 6;
+    private static final String NAME_DEFAULT = "default";
+    private static final String NAME_VIRTUAL = "virtual";
+
+    @Rule
+    public final MockitoRule mMockito = MockitoJUnit.rule();
+    @Rule
+    public final TestableContext mContext = new TestableContext(
+            InstrumentationRegistry.getInstrumentation().getTargetContext(), null);
+    @Rule
+    public final FakeSettingsProviderRule mSettingsRule = FakeSettingsProvider.rule();
+
+    @Mock
+    private BiometricContext mBiometricContext;
+    @Mock
+    private IBiometricService mIBiometricService;
+    @Mock
+    private IFingerprint mIFingerprintDefault;
+    @Mock
+    private IFingerprint mIFingerprintVirtual;
+
+    private final SensorProps mSensorPropsDefault = createProps(ID_DEFAULT,
+            SensorStrength.STRONG, FingerprintSensorType.POWER_BUTTON);
+    private final SensorProps mSensorPropsVirtual = createProps(ID_VIRTUAL,
+            SensorStrength.STRONG, FingerprintSensorType.UNDER_DISPLAY_OPTICAL);
+    private FingerprintService mService;
+
+    @Before
+    public void setup() throws Exception {
+        when(mIFingerprintDefault.getSensorProps()).thenReturn(
+                new SensorProps[]{mSensorPropsDefault});
+        when(mIFingerprintVirtual.getSensorProps()).thenReturn(
+                new SensorProps[]{mSensorPropsVirtual});
+
+        mContext.getTestablePermissions().setPermission(
+                USE_BIOMETRIC_INTERNAL, PackageManager.PERMISSION_GRANTED);
+
+        mService = new FingerprintService(mContext, mBiometricContext,
+                () -> mIBiometricService,
+                (fqName) -> {
+                    if (fqName.endsWith(NAME_DEFAULT)) return mIFingerprintDefault;
+                    if (fqName.endsWith(NAME_VIRTUAL)) return mIFingerprintVirtual;
+                    return null;
+                });
+    }
+
+    @Test
+    public void registerAuthenticators_defaultOnly() throws RemoteException {
+        mService.registerAuthenticatorsForService(List.of(NAME_DEFAULT, NAME_VIRTUAL), List.of());
+
+        verify(mIBiometricService).registerAuthenticator(eq(ID_DEFAULT), anyInt(), anyInt(), any());
+    }
+
+    @Test
+    public void registerAuthenticators_virtualOnly() throws RemoteException {
+        Settings.Secure.putInt(mSettingsRule.mockContentResolver(mContext),
+                Settings.Secure.BIOMETRIC_VIRTUAL_ENABLED, 1);
+
+        mService.registerAuthenticatorsForService(List.of(NAME_DEFAULT, NAME_VIRTUAL), List.of());
+
+        verify(mIBiometricService).registerAuthenticator(eq(ID_VIRTUAL), anyInt(), anyInt(), any());
+    }
+
+    @Test
+    public void registerAuthenticators_virtualAlwaysWhenNoOther() throws RemoteException {
+        mService.registerAuthenticatorsForService(List.of(NAME_VIRTUAL), List.of());
+
+        verify(mIBiometricService).registerAuthenticator(eq(ID_VIRTUAL), anyInt(), anyInt(), any());
+    }
+
+    private static SensorProps createProps(int id, byte strength, byte type) {
+        final SensorProps props = new SensorProps();
+        props.commonProps = new CommonProps();
+        props.commonProps.sensorId = id;
+        props.commonProps.sensorStrength = strength;
+        props.sensorType = type;
+        props.sensorLocations = new SensorLocation[]{new SensorLocation()};
+        return props;
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
index 2cf67f8..e991ec6 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
@@ -237,6 +237,8 @@
                 return mMockSystemServices.devicePolicyManager;
             case Context.LOCATION_SERVICE:
                 return mMockSystemServices.locationManager;
+            case Context.ROLE_SERVICE:
+                return mMockSystemServices.roleManager;
         }
         throw new UnsupportedOperationException();
     }
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
index 34c9f7c..884ffce 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
@@ -33,6 +33,7 @@
 import android.app.NotificationManager;
 import android.app.admin.DevicePolicyManager;
 import android.app.backup.IBackupManager;
+import android.app.role.RoleManager;
 import android.app.usage.UsageStatsManagerInternal;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -131,6 +132,7 @@
     public final VpnManager vpnManager;
     public final DevicePolicyManager devicePolicyManager;
     public final LocationManager locationManager;
+    public final RoleManager roleManager;
     /** Note this is a partial mock, not a real mock. */
     public final PackageManager packageManager;
     public final BuildMock buildMock = new BuildMock();
@@ -181,6 +183,7 @@
         vpnManager = mock(VpnManager.class);
         devicePolicyManager = mock(DevicePolicyManager.class);
         locationManager = mock(LocationManager.class);
+        roleManager = realContext.getSystemService(RoleManager.class);
 
         // Package manager is huge, so we use a partial mock instead.
         packageManager = spy(realContext.getPackageManager());
diff --git a/services/tests/servicestests/src/com/android/server/display/TEST_MAPPING b/services/tests/servicestests/src/com/android/server/display/TEST_MAPPING
new file mode 100644
index 0000000..9f1a209
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/display/TEST_MAPPING
@@ -0,0 +1,21 @@
+{
+  "presubmit": [
+    {
+      "name": "FrameworksServicesTests",
+      "options": [
+        {
+          "include-filter": "com.android.server.display."
+        },
+        {
+          "include-annotation": "android.platform.test.annotations.Presubmit"
+        },
+        {
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
+        },
+        {
+          "exclude-annotation": "org.junit.Ignore"
+        }
+      ]
+    }
+  ]
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java
index 1538f06..03d4e9e 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java
@@ -39,6 +39,7 @@
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
+import android.os.Environment;
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
 import android.platform.test.annotations.Presubmit;
@@ -531,6 +532,48 @@
                 .isEqualTo(TEST_APEX_PKG);
     }
 
+    @Test
+    public void testGetBackingApexFiles() throws Exception {
+        final ApexInfo apex = createApexInfoForTestPkg(true, true, 37);
+        when(mApexService.getActivePackages()).thenReturn(new ApexInfo[]{apex});
+
+        final File backingApexFile = mApexManager.getBackingApexFile(
+                new File("/apex/" + TEST_APEX_PKG + "/apk/App/App.apk"));
+        assertThat(backingApexFile.getAbsolutePath()).isEqualTo(apex.modulePath);
+    }
+
+    @Test
+    public void testGetBackingApexFile_fileNotOnApexMountPoint_returnsNull() throws Exception {
+        File result = mApexManager.getBackingApexFile(
+                new File("/data/local/tmp/whatever/does-not-matter"));
+        assertThat(result).isNull();
+    }
+
+    @Test
+    public void testGetBackingApexFiles_unknownApex_returnsNull() throws Exception {
+        final ApexInfo apex = createApexInfoForTestPkg(true, true, 37);
+        when(mApexService.getActivePackages()).thenReturn(new ApexInfo[]{apex});
+
+        final File backingApexFile = mApexManager.getBackingApexFile(
+                new File("/apex/com.wrong.apex/apk/App"));
+        assertThat(backingApexFile).isNull();
+    }
+
+    @Test
+    public void testGetBackingApexFiles_topLevelApexDir_returnsNull() throws Exception {
+        assertThat(mApexManager.getBackingApexFile(Environment.getApexDirectory())).isNull();
+        assertThat(mApexManager.getBackingApexFile(new File("/apex/"))).isNull();
+        assertThat(mApexManager.getBackingApexFile(new File("/apex//"))).isNull();
+    }
+
+    @Test
+    public void testGetBackingApexFiles_flattenedApex() throws Exception {
+        ApexManager flattenedApexManager = new ApexManager.ApexManagerFlattenedApex();
+        final File backingApexFile = flattenedApexManager.getBackingApexFile(
+                new File("/apex/com.android.apex.cts.shim/app/CtsShim/CtsShim.apk"));
+        assertThat(backingApexFile).isNull();
+    }
+
     private ApexInfo createApexInfoForTestPkg(boolean isActive, boolean isFactory, int version) {
         File apexFile = extractResource(TEST_APEX_PKG,  TEST_APEX_FILE_NAME);
         ApexInfo apexInfo = new ApexInfo();
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
index 4425962..7a70474 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
@@ -522,6 +522,55 @@
     }
 
     @Test
+    public void testApplyTransaction_requestFocusOnTaskFragment() {
+        mOrganizer.applyTransaction(mTransaction);
+        mController.registerOrganizer(mIOrganizer);
+        final Task task = createTask(mDisplayContent);
+        final IBinder token0 = new Binder();
+        final TaskFragment tf0 = new TaskFragmentBuilder(mAtm)
+                .setParentTask(task)
+                .setFragmentToken(token0)
+                .setOrganizer(mOrganizer)
+                .createActivityCount(1)
+                .build();
+        final IBinder token1 = new Binder();
+        final TaskFragment tf1 = new TaskFragmentBuilder(mAtm)
+                .setParentTask(task)
+                .setFragmentToken(token1)
+                .setOrganizer(mOrganizer)
+                .createActivityCount(1)
+                .build();
+        mAtm.mWindowOrganizerController.mLaunchTaskFragments.put(token0, tf0);
+        mAtm.mWindowOrganizerController.mLaunchTaskFragments.put(token1, tf1);
+        final ActivityRecord activity0 = tf0.getTopMostActivity();
+        final ActivityRecord activity1 = tf1.getTopMostActivity();
+
+        // No effect if the current focus is in a different Task.
+        final ActivityRecord activityInOtherTask = createActivityRecord(mDefaultDisplay);
+        mDisplayContent.setFocusedApp(activityInOtherTask);
+        mTransaction.requestFocusOnTaskFragment(token0);
+        mAtm.mWindowOrganizerController.applyTransaction(mTransaction);
+
+        assertEquals(activityInOtherTask, mDisplayContent.mFocusedApp);
+
+        // No effect if there is no resumed activity in the request TaskFragment.
+        activity0.setState(ActivityRecord.State.PAUSED, "test");
+        activity1.setState(ActivityRecord.State.RESUMED, "test");
+        mDisplayContent.setFocusedApp(activity1);
+        mAtm.mWindowOrganizerController.applyTransaction(mTransaction);
+
+        assertEquals(activity1, mDisplayContent.mFocusedApp);
+
+        // Set focus to the request TaskFragment when the current focus is in the same Task, and it
+        // has a resumed activity.
+        activity0.setState(ActivityRecord.State.RESUMED, "test");
+        mDisplayContent.setFocusedApp(activity1);
+        mAtm.mWindowOrganizerController.applyTransaction(mTransaction);
+
+        assertEquals(activity0, mDisplayContent.mFocusedApp);
+    }
+
+    @Test
     public void testTaskFragmentInPip_startActivityInTaskFragment() {
         setupTaskFragmentInPip();
         final ActivityRecord activity = mTaskFragment.getTopMostActivity();
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
index 3c14777..b2043c3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
@@ -403,4 +403,29 @@
         assertFalse(activity0.hasOverlayOverUntrustedModeEmbedded());
         assertFalse(activity1.hasOverlayOverUntrustedModeEmbedded());
     }
+
+    @Test
+    public void testIsAllowedToBeEmbeddedInTrustedMode() {
+        final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
+                .setCreateParentTask()
+                .createActivityCount(2)
+                .build();
+        final ActivityRecord activity0 = taskFragment.getBottomMostActivity();
+        final ActivityRecord activity1 = taskFragment.getTopMostActivity();
+
+        // Allowed if all children activities are allowed.
+        doReturn(true).when(taskFragment).isAllowedToEmbedActivityInTrustedMode(activity0);
+        doReturn(true).when(taskFragment).isAllowedToEmbedActivityInTrustedMode(activity1);
+
+        assertTrue(taskFragment.isAllowedToBeEmbeddedInTrustedMode());
+
+        // Disallowed if any child activity is not allowed.
+        doReturn(false).when(taskFragment).isAllowedToEmbedActivityInTrustedMode(activity0);
+
+        assertFalse(taskFragment.isAllowedToBeEmbeddedInTrustedMode());
+
+        doReturn(false).when(taskFragment).isAllowedToEmbedActivityInTrustedMode(activity1);
+
+        assertFalse(taskFragment.isAllowedToBeEmbeddedInTrustedMode());
+    }
 }
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 6f89bb2..04c3615 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -626,6 +626,10 @@
         mAppStandby.initializeDefaultsForSystemApps(userId);
     }
 
+    private boolean isInstantApp(String packageName, int userId) {
+        return mPackageManagerInternal.isPackageEphemeral(userId, packageName);
+    }
+
     private boolean shouldObfuscateInstantAppsForCaller(int callingUid, int userId) {
         return !mPackageManagerInternal.canAccessInstantApps(callingUid, userId);
     }
@@ -1013,8 +1017,7 @@
                 uid = 0;
         }
 
-        if (event.mPackage != null
-                && mPackageManagerInternal.isPackageEphemeral(userId, event.mPackage)) {
+        if (event.mPackage != null && isInstantApp(event.mPackage, userId)) {
             event.mFlags |= Event.FLAG_IS_PACKAGE_INSTANT_APP;
         }
 
@@ -1346,7 +1349,7 @@
             if (obfuscateInstantApps) {
                 for (int i = list.size() - 1; i >= 0; i--) {
                     final UsageStats stats = list.get(i);
-                    if (mPackageManagerInternal.isPackageEphemeral(userId, stats.mPackageName)) {
+                    if (isInstantApp(stats.mPackageName, userId)) {
                         list.set(i, stats.getObfuscatedForInstantApp());
                     }
                 }
@@ -2343,16 +2346,18 @@
                             "Don't have permission to query app standby bucket");
                 }
             }
-            if (packageUid < 0) {
+
+            final boolean isInstantApp = isInstantApp(packageName, userId);
+            final boolean cannotAccessInstantApps = shouldObfuscateInstantAppsForCaller(callingUid,
+                    userId);
+            if (packageUid < 0 || (isInstantApp && cannotAccessInstantApps)) {
                 throw new IllegalArgumentException(
                         "Cannot get standby bucket for non existent package (" + packageName + ")");
             }
-            final boolean obfuscateInstantApps = shouldObfuscateInstantAppsForCaller(callingUid,
-                    userId);
             final long token = Binder.clearCallingIdentity();
             try {
                 return mAppStandby.getAppStandbyBucket(packageName, userId,
-                        SystemClock.elapsedRealtime(), obfuscateInstantApps);
+                        SystemClock.elapsedRealtime(), false /* obfuscateInstantApps */);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
@@ -2389,12 +2394,19 @@
                 throw new SecurityException(
                         "Don't have permission to query app standby bucket");
             }
+            final boolean cannotAccessInstantApps = shouldObfuscateInstantAppsForCaller(callingUid,
+                    userId);
             final long token = Binder.clearCallingIdentity();
             try {
                 final List<AppStandbyInfo> standbyBucketList =
                         mAppStandby.getAppStandbyBuckets(userId);
-                return (standbyBucketList == null) ? ParceledListSlice.emptyList()
-                        : new ParceledListSlice<>(standbyBucketList);
+                if (standbyBucketList == null) {
+                    return ParceledListSlice.emptyList();
+                }
+                final int targetUserId = userId;
+                standbyBucketList.removeIf(
+                        i -> cannotAccessInstantApps && isInstantApp(i.mPackageName, targetUserId));
+                return new ParceledListSlice<>(standbyBucketList);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
@@ -2434,17 +2446,18 @@
                             "Don't have permission to query min app standby bucket");
                 }
             }
-            if (packageUid < 0) {
+            final boolean isInstantApp = isInstantApp(packageName, userId);
+            final boolean cannotAccessInstantApps = shouldObfuscateInstantAppsForCaller(callingUid,
+                    userId);
+            if (packageUid < 0 || (isInstantApp && cannotAccessInstantApps)) {
                 throw new IllegalArgumentException(
                         "Cannot get min standby bucket for non existent package ("
                                 + packageName + ")");
             }
-            final boolean obfuscateInstantApps = shouldObfuscateInstantAppsForCaller(callingUid,
-                    userId);
             final long token = Binder.clearCallingIdentity();
             try {
-                return mAppStandby.getAppMinStandbyBucket(
-                        packageName, UserHandle.getAppId(packageUid), userId, obfuscateInstantApps);
+                return mAppStandby.getAppMinStandbyBucket(packageName,
+                        UserHandle.getAppId(packageUid), userId, false /* obfuscateInstantApps */);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 8cbbe94..f31cdcb 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -1824,6 +1824,32 @@
             }
         }
 
+        public void setSessionWindowVisible(IBinder token, boolean visible) {
+            synchronized (this) {
+                if (mImpl == null) {
+                    Slog.w(TAG, "setSessionWindowVisible called without running voice interaction "
+                            + "service");
+                    return;
+                }
+                if (mImpl.mActiveSession == null || token != mImpl.mActiveSession.mToken) {
+                    Slog.w(TAG, "setSessionWindowVisible does not match active session");
+                    return;
+                }
+                final long caller = Binder.clearCallingIdentity();
+                try {
+                    mVoiceInteractionSessionListeners.broadcast(listener -> {
+                        try {
+                            listener.onVoiceSessionWindowVisibilityChanged(visible);
+                        } catch (RemoteException e) {
+                            Slog.e(TAG, "Error delivering window visibility event to listener.", e);
+                        }
+                    });
+                } finally {
+                    Binder.restoreCallingIdentity(caller);
+                }
+            }
+        }
+
         @Override
         public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
             if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index c56cc62..235ed84 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -1293,8 +1293,8 @@
                 && Objects.equals(this.mOperatorNumeric, other.mOperatorNumeric)
                 && Objects.equals(this.mProtocol, other.mProtocol)
                 && Objects.equals(this.mRoamingProtocol, other.mRoamingProtocol)
-                && xorEqualsInt(this.mMtuV4, other.mMtuV4)
-                && xorEqualsInt(this.mMtuV6, other.mMtuV6)
+                && mtuUnsetOrEquals(this.mMtuV4, other.mMtuV4)
+                && mtuUnsetOrEquals(this.mMtuV6, other.mMtuV6)
                 && Objects.equals(this.mCarrierEnabled, other.mCarrierEnabled)
                 && Objects.equals(this.mNetworkTypeBitmask, other.mNetworkTypeBitmask)
                 && Objects.equals(this.mLingeringNetworkTypeBitmask,
@@ -1322,7 +1322,12 @@
     // Equal or one is not specified.
     private boolean xorEqualsInt(int first, int second) {
         return first == UNSPECIFIED_INT || second == UNSPECIFIED_INT
-            || Objects.equals(first, second);
+                || first == second;
+    }
+
+    // Equal or one is not specified. Specific to MTU where <= 0 indicates unset.
+    private boolean mtuUnsetOrEquals(int first, int second) {
+        return first <= 0 || second <= 0 || first == second;
     }
 
     private String nullToEmpty(String stringValue) {
diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp
index 0849600..cee3e5c 100644
--- a/tools/aapt2/Android.bp
+++ b/tools/aapt2/Android.bp
@@ -24,6 +24,7 @@
 }
 
 toolSources = [
+    "cmd/ApkInfo.cpp",
     "cmd/Command.cpp",
     "cmd/Compile.cpp",
     "cmd/Convert.cpp",
@@ -159,6 +160,7 @@
         "xml/XmlDom.cpp",
         "xml/XmlPullParser.cpp",
         "xml/XmlUtil.cpp",
+        "ApkInfo.proto",
         "Configuration.proto",
         "Resources.proto",
         "ResourcesInternal.proto",
@@ -191,6 +193,7 @@
         "integration-tests/CompileTest/**/*",
         "integration-tests/CommandTests/**/*",
         "integration-tests/ConvertTest/**/*",
+        "integration-tests/DumpTest/**/*",
     ],
 }
 
diff --git a/tools/aapt2/ApkInfo.proto b/tools/aapt2/ApkInfo.proto
new file mode 100644
index 0000000..80bdccb
--- /dev/null
+++ b/tools/aapt2/ApkInfo.proto
@@ -0,0 +1,338 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto3";
+
+import "frameworks/base/tools/aapt2/Resources.proto";
+
+package aapt.pb;
+
+option java_package = "com.android.aapt";
+
+// Top level message representing data extracted from the APK for 'apkinfo'
+// command.
+message ApkInfo {
+  message XmlFile {
+    string path = 1;
+    XmlNode root = 2;
+  }
+
+  Badging badging = 1;
+  ResourceTable resource_table = 2;
+  repeated XmlFile xml_files = 3;
+}
+
+// Data extracted from the manifest of the APK.
+message Badging {
+  PackageInfo package = 1;
+  Application application = 2;
+  UsesSdk uses_sdk = 3;
+  UsesConfiguration uses_configuration = 4;
+  SupportsScreen supports_screen = 5;
+  SupportsInput supports_input = 6;
+  LaunchableActivity launchable_activity = 7;
+  LeanbackLaunchableActivity leanback_launchable_activity = 8;
+  StaticLibrary static_library = 9;
+  SdkLibrary sdk_library = 10;
+  Overlay overlay = 11;
+  PackageVerifier package_verifier = 12;
+  CompatibleScreens compatible_screens = 13;
+  Architectures architectures = 14;
+  SupportsGlTexture supports_gl_texture = 15;
+  Components components = 16;
+
+  repeated string locales = 17;
+  repeated int32 densities = 18;
+
+  repeated FeatureGroup feature_groups = 53;
+  repeated UsesPermission uses_permissions = 54;
+  repeated Permission permissions = 55;
+  repeated UsesLibrary uses_libraries = 56;
+  repeated UsesStaticLibrary uses_static_libraries = 57;
+  repeated UsesSdkLibrary uses_sdk_libraries = 58;
+  repeated UsesNativeLibrary uses_native_libraries = 59;
+  repeated UsesPackage uses_packages = 51;
+
+  repeated Metadata metadata = 62;
+  repeated Property properties = 63;
+}
+
+// Information extracted about package from <manifest> and
+// <original-package> tags.
+message PackageInfo {
+  enum InstallLocation {
+    DEFAULT_INSTALL_LOCATION = 0;
+    AUTO = 1;
+    INTERNAL_ONLY = 2;
+    PREFER_EXTERNAL = 3;
+  }
+
+  string package = 1;
+  int32 version_code = 2;
+  string version_name = 3;
+
+  string split = 4;
+
+  string platform_version_name = 5;
+  string platform_version_code = 6;
+
+  int32 compile_sdk_version = 7;
+  string compile_sdk_version_codename = 8;
+
+  InstallLocation install_location = 9;
+
+  string original_package = 10;
+}
+
+// Information extracted from <application> element.
+message Application {
+  string label = 1;
+  string icon = 2;
+  string banner = 3;
+
+  bool test_only = 4;
+  bool game = 5;
+  bool debuggable = 6;
+
+  map<string, string> locale_labels = 8;
+  map<int32, string> density_icons = 9;
+}
+
+// Components defined in the APK.
+message Components {
+  bool main = 1;
+  bool other_activities = 2;
+  bool other_receivers = 3;
+  bool other_services = 4;
+
+  repeated string provided_components = 5;
+}
+
+// Application's min and target SDKs.
+message UsesSdk {
+  oneof min_sdk {
+    int32 min_sdk_version = 2;
+    string min_sdk_version_name = 3;
+  }
+  int32 max_sdk_version = 4;
+  oneof target_sdk {
+    int32 target_sdk_version = 5;
+    string target_sdk_version_name = 6;
+  }
+}
+
+message UsesConfiguration {
+  int32 req_touch_screen = 1;
+  int32 req_keyboard_type = 2;
+  int32 req_hard_keyboard = 3;
+  int32 req_navigation = 4;
+  int32 req_five_way_nav = 5;
+}
+
+// Screens supported by this application.
+message SupportsScreen {
+  enum ScreenType {
+    UNSPECIFIED_SCREEN_TYPE = 0;
+    SMALL = 1;
+    NORMAL = 2;
+    LARGE = 3;
+    XLARGE = 4;
+  }
+  repeated ScreenType screens = 1;
+  bool supports_any_densities = 2;
+  int32 requires_smallest_width_dp = 3;
+  int32 compatible_width_limit_dp = 4;
+  int32 largest_width_limit_dp = 5;
+}
+
+// Inputs supported by this application.
+message SupportsInput {
+  repeated string inputs = 1;
+}
+
+// Information about used features which is extracted from <uses-permission>
+// elements or implied from permissions.
+message Feature {
+  message ImpliedData {
+      bool from_sdk_23_permission = 1;
+      repeated string reasons = 2;
+  }
+
+  string name = 1;
+  bool required = 2;
+  int32 version = 3;
+
+  ImpliedData implied_data = 4;
+}
+
+message FeatureGroup {
+  string label = 1;
+  int32 open_gles_version = 2;
+  repeated Feature features = 3;
+}
+
+// Information about permission requested by the application.
+message UsesPermission {
+  message PermissionFlags {
+    bool never_for_location = 1;
+  }
+
+  string name = 1;
+  int32 max_sdk_version = 2;
+  bool required = 3;
+  bool implied = 4;
+  bool sdk23_and_above = 5;
+
+  repeated string required_features = 6;
+  repeated string required_not_features = 7;
+
+  PermissionFlags permission_flags = 8;
+}
+
+// Permission defined by the application.
+message Permission {
+  string name = 1;
+}
+
+// Data extracted about launchable activity. Launchable activity is an entry
+// point on phone and tablet devices.
+message LaunchableActivity {
+  string name = 1;
+  string icon = 2;
+  string label = 3;
+}
+
+// Data extracted about leanback launchable activity. Leanback launchable
+// activity is an entry point on TV devices.
+message LeanbackLaunchableActivity {
+  string name = 1;
+  string icon = 2;
+  string label = 3;
+  string banner = 4;
+}
+
+// Library used by the application.
+message UsesLibrary {
+  string name = 1;
+  bool required = 2;
+}
+
+// Static library this APK declares.
+message StaticLibrary {
+  string name = 1;
+  int32 version = 2;
+  int32 version_major = 3;
+}
+
+// Static library used by the application.
+message UsesStaticLibrary {
+  string name = 1;
+  int32 version = 2;
+  int32 version_major = 3;
+  repeated string certificates = 4;
+}
+
+// SDK library this APK declares.
+message SdkLibrary {
+  string name = 1;
+  int32 version_major = 2;
+}
+
+// SDK library used by the application.
+message UsesSdkLibrary {
+  string name = 1;
+  int32 version_major = 2;
+  repeated string certificates = 3;
+}
+
+// Native library used by the application.
+message UsesNativeLibrary {
+  string name = 1;
+  bool required = 2;
+}
+
+// Information extracted from <meta-data> elements defined across
+// AndroidManifest.xml.
+message Metadata {
+  string name = 1;
+  oneof value {
+    string value_string = 2;
+    int32 value_int = 3;
+  }
+  oneof resource {
+    string resource_string = 4;
+    int32 resource_int = 5;
+  }
+}
+
+// Information about overlay that is declared in the APK.
+message Overlay {
+  string target_package = 1;
+  int32 priority = 2;
+  bool static = 3;
+  string required_property_name = 4;
+  string required_property_value = 5;
+}
+
+// Data extracted from <package-verifier> element.
+message PackageVerifier {
+  string name = 1;
+  string public_key = 2;
+}
+
+// External packages used by the application
+message UsesPackage {
+  string name = 1;
+  string package_type = 2;
+  int32 version = 3;
+  int32 version_major = 4;
+  repeated string certificates = 5;
+}
+
+// Open GL textures format supported by the current application.
+message SupportsGlTexture {
+  repeated string name = 1;
+}
+
+// Screens compatible with the application.
+message CompatibleScreens {
+  message Screen {
+    int32 size = 1;
+    int32 density = 2;
+  }
+
+  repeated Screen screens = 1;
+}
+
+// Architectures supported by the application.
+message Architectures {
+  repeated string architectures = 1;
+  repeated string alt_architectures = 2;
+}
+
+// Information extracted from <property> elements defined across
+// AndroidManifest.xml.
+message Property {
+  string name = 1;
+  oneof value {
+    string value_string = 2;
+    int32 value_int = 3;
+  }
+  oneof resource {
+    string resource_string = 4;
+    int32 resource_int = 5;
+  }
+}
\ No newline at end of file
diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp
index b249c6c..e47bd67 100644
--- a/tools/aapt2/Main.cpp
+++ b/tools/aapt2/Main.cpp
@@ -24,11 +24,11 @@
 #include <iostream>
 #include <vector>
 
+#include "Diagnostics.h"
 #include "android-base/stringprintf.h"
 #include "android-base/utf8.h"
 #include "androidfw/StringPiece.h"
-
-#include "Diagnostics.h"
+#include "cmd/ApkInfo.h"
 #include "cmd/Command.h"
 #include "cmd/Compile.h"
 #include "cmd/Convert.h"
@@ -72,6 +72,7 @@
     AddOptionalSubcommand(util::make_unique<OptimizeCommand>());
     AddOptionalSubcommand(util::make_unique<ConvertCommand>());
     AddOptionalSubcommand(util::make_unique<VersionCommand>());
+    AddOptionalSubcommand(util::make_unique<ApkInfoCommand>(diagnostics));
   }
 
   int Action(const std::vector<std::string>& args) override {
diff --git a/tools/aapt2/cmd/ApkInfo.cpp b/tools/aapt2/cmd/ApkInfo.cpp
new file mode 100644
index 0000000..7c9df4c
--- /dev/null
+++ b/tools/aapt2/cmd/ApkInfo.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ApkInfo.h"
+
+#include <fcntl.h>
+
+#include <iostream>
+#include <memory>
+
+#include "Diagnostics.h"
+#include "LoadedApk.h"
+#include "android-base/file.h"  // for O_BINARY
+#include "android-base/utf8.h"
+#include "androidfw/StringPiece.h"
+#include "dump/DumpManifest.h"
+#include "format/proto/ProtoSerialize.h"
+
+using ::android::StringPiece;
+
+namespace aapt {
+
+int ExportApkInfo(LoadedApk* apk, bool include_resource_table,
+                  const std::unordered_set<std::string>& xml_resources, pb::ApkInfo* out_apk_info,
+                  IDiagnostics* diag) {
+  auto result = DumpBadgingProto(apk, out_apk_info->mutable_badging(), diag);
+  if (result != 0) {
+    return result;
+  }
+
+  if (include_resource_table) {
+    SerializeTableToPb(*apk->GetResourceTable(), out_apk_info->mutable_resource_table(), diag);
+  }
+
+  for (auto& xml_resource : xml_resources) {
+    auto xml = apk->LoadXml(xml_resource, diag);
+    if (xml) {
+      auto out_xml = out_apk_info->add_xml_files();
+      out_xml->set_path(xml_resource);
+      SerializeXmlResourceToPb(*xml, out_xml->mutable_root(),
+                               {/* remove_empty_text_nodes= */ true});
+    }
+  }
+
+  return 0;
+}
+
+int ApkInfoCommand::Action(const std::vector<std::string>& args) {
+  if (args.size() != 1) {
+    std::cerr << "must supply a single APK\n";
+    Usage(&std::cerr);
+    return 1;
+  }
+  const StringPiece& path = args[0];
+  std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(path, diag_);
+  if (!apk) {
+    return 1;
+  }
+
+  pb::ApkInfo out_apk_info;
+  int result =
+      ExportApkInfo(apk.get(), include_resource_table_, xml_resources_, &out_apk_info, diag_);
+  if (result != 0) {
+    diag_->Error(DiagMessage() << "Failed to serialize ApkInfo into proto.");
+    return result;
+  }
+
+  int mode = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY;
+  int outfd = ::android::base::utf8::open(output_path_.c_str(), mode, 0666);
+  if (outfd == -1) {
+    diag_->Error(DiagMessage() << "Failed to open output file.");
+    return 1;
+  }
+
+  bool is_serialized = out_apk_info.SerializeToFileDescriptor(outfd);
+  close(outfd);
+
+  return is_serialized ? 0 : 1;
+}
+
+}  // namespace aapt
\ No newline at end of file
diff --git a/tools/aapt2/cmd/ApkInfo.h b/tools/aapt2/cmd/ApkInfo.h
new file mode 100644
index 0000000..d682678
--- /dev/null
+++ b/tools/aapt2/cmd/ApkInfo.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AAPT2_APKINFO_H
+#define AAPT2_APKINFO_H
+
+#include "Command.h"
+#include "Diagnostics.h"
+
+namespace aapt {
+
+class ApkInfoCommand : public Command {
+ public:
+  explicit ApkInfoCommand(IDiagnostics* diag) : Command("apkinfo"), diag_(diag) {
+    SetDescription("Dump information about an APK in binary proto format.");
+    AddRequiredFlag("-o", "Output path", &output_path_, Command::kPath);
+    AddOptionalSwitch("--include-resource-table", "Include the resource table data into output.",
+                      &include_resource_table_);
+    AddOptionalFlagList("--include-xml",
+                        "Include an XML file content into output. Multiple XML files might be "
+                        "requested during single invocation.",
+                        &xml_resources_);
+  }
+
+  int Action(const std::vector<std::string>& args) override;
+
+ private:
+  IDiagnostics* diag_;
+  std::string output_path_;
+  bool include_resource_table_ = false;
+  std::unordered_set<std::string> xml_resources_;
+};
+
+}  // namespace aapt
+
+#endif  // AAPT2_APKINFO_H
diff --git a/tools/aapt2/cmd/ApkInfo_test.cpp b/tools/aapt2/cmd/ApkInfo_test.cpp
new file mode 100644
index 0000000..70539c0
--- /dev/null
+++ b/tools/aapt2/cmd/ApkInfo_test.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ApkInfo.h"
+
+#include "ApkInfo.pb.h"
+#include "LoadedApk.h"
+#include "android-base/unique_fd.h"
+#include "io/StringStream.h"
+#include "test/Test.h"
+
+using testing::Eq;
+using testing::Ne;
+
+namespace aapt {
+
+using ApkInfoTest = CommandTestFixture;
+
+void AssertProducedAndExpectedInfo(const std::string& produced_path,
+                                   const std::string& expected_path) {
+  android::base::unique_fd fd(open(produced_path.c_str(), O_RDONLY));
+  ASSERT_NE(fd.get(), -1);
+
+  pb::ApkInfo produced_apk_info;
+  produced_apk_info.ParseFromFileDescriptor(fd.get());
+
+  std::string expected;
+  ::android::base::ReadFileToString(expected_path, &expected);
+
+  EXPECT_EQ(produced_apk_info.DebugString(), expected);
+}
+
+class NoopDiagnostics : public IDiagnostics {
+ public:
+  void Log(Level level, DiagMessageActual& actualMsg) override {
+  }
+};
+static NoopDiagnostics noop_diag;
+
+TEST_F(ApkInfoTest, ApkInfoWithBadging) {
+  auto apk_path = file::BuildPath(
+      {android::base::GetExecutableDirectory(), "integration-tests", "DumpTest", "components.apk"});
+  auto out_info_path = GetTestPath("apk_info.pb");
+
+  ApkInfoCommand command(&noop_diag);
+  command.Execute({"-o", out_info_path, apk_path}, &std::cerr);
+
+  auto expected_path =
+      file::BuildPath({android::base::GetExecutableDirectory(), "integration-tests", "DumpTest",
+                       "components_expected_proto.txt"});
+  AssertProducedAndExpectedInfo(out_info_path, expected_path);
+}
+
+TEST_F(ApkInfoTest, FullApkInfo) {
+  auto apk_path = file::BuildPath(
+      {android::base::GetExecutableDirectory(), "integration-tests", "DumpTest", "components.apk"});
+  auto out_info_path = GetTestPath("apk_info.pb");
+
+  ApkInfoCommand command(&noop_diag);
+  command.Execute({"-o", out_info_path, "--include-resource-table", "--include-xml",
+                   "AndroidManifest.xml", "--include-xml", "res/oy.xml", apk_path},
+                  &std::cerr);
+
+  auto expected_path =
+      file::BuildPath({android::base::GetExecutableDirectory(), "integration-tests", "DumpTest",
+                       "components_full_proto.txt"});
+  AssertProducedAndExpectedInfo(out_info_path, expected_path);
+}
+
+}  // namespace aapt
\ No newline at end of file
diff --git a/tools/aapt2/cmd/Convert.cpp b/tools/aapt2/cmd/Convert.cpp
index 3b097e0..d8c541d 100644
--- a/tools/aapt2/cmd/Convert.cpp
+++ b/tools/aapt2/cmd/Convert.cpp
@@ -18,11 +18,10 @@
 
 #include <vector>
 
-#include "android-base/macros.h"
-#include "androidfw/StringPiece.h"
-
 #include "LoadedApk.h"
 #include "ValueVisitor.h"
+#include "android-base/macros.h"
+#include "androidfw/StringPiece.h"
 #include "cmd/Util.h"
 #include "format/binary/TableFlattener.h"
 #include "format/binary/XmlFlattener.h"
@@ -240,7 +239,7 @@
   }
 
   int GetMinSdkVersion() override {
-    return 0u;
+    return min_sdk_;
   }
 
   const std::set<std::string>& GetSplitNameDependencies() override {
@@ -251,6 +250,7 @@
 
   bool verbose_ = false;
   std::string package_;
+  int32_t min_sdk_ = 0;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(Context);
@@ -373,6 +373,7 @@
   }
 
   context.package_ = app_info.value().package;
+  context.min_sdk_ = app_info.value().min_sdk_version.value_or(0);
   unique_ptr<IArchiveWriter> writer = CreateZipFileArchiveWriter(context.GetDiagnostics(),
                                                                  output_path_);
   if (writer == nullptr) {
diff --git a/tools/aapt2/cmd/Dump.h b/tools/aapt2/cmd/Dump.h
index ec320ec..c7a3567 100644
--- a/tools/aapt2/cmd/Dump.h
+++ b/tools/aapt2/cmd/Dump.h
@@ -131,6 +131,14 @@
                       &options_.include_meta_data);
   }
 
+  void SetIncludeMetaData(bool value) {
+    options_.include_meta_data = value;
+  }
+
+  void SetOnlyPermissions(bool value) {
+    options_.only_permissions = value;
+  }
+
   int Dump(LoadedApk* apk) override {
     return DumpManifest(apk, options_, GetPrinter(), GetDiagnostics());
   }
diff --git a/tools/aapt2/cmd/Dump_test.cpp b/tools/aapt2/cmd/Dump_test.cpp
new file mode 100644
index 0000000..d018882
--- /dev/null
+++ b/tools/aapt2/cmd/Dump_test.cpp
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Dump.h"
+
+#include "LoadedApk.h"
+#include "io/StringStream.h"
+#include "test/Test.h"
+#include "text/Printer.h"
+
+using ::aapt::io::StringOutputStream;
+using ::aapt::text::Printer;
+using testing::Eq;
+using testing::Ne;
+
+namespace aapt {
+
+using DumpTest = CommandTestFixture;
+
+class NoopDiagnostics : public IDiagnostics {
+ public:
+  void Log(Level level, DiagMessageActual& actualMsg) override {
+  }
+};
+static NoopDiagnostics noop_diag;
+
+void DumpBadgingToString(LoadedApk* loaded_apk, std::string* output, bool include_meta_data = false,
+                         bool only_permissions = false) {
+  StringOutputStream output_stream(output);
+  Printer printer(&output_stream);
+
+  DumpBadgingCommand command(&printer, &noop_diag);
+  command.SetIncludeMetaData(include_meta_data);
+  command.SetOnlyPermissions(only_permissions);
+  ASSERT_EQ(command.Dump(loaded_apk), 0);
+  output_stream.Flush();
+}
+
+TEST_F(DumpTest, DumpBadging) {
+  auto apk_path = file::BuildPath(
+      {android::base::GetExecutableDirectory(), "integration-tests", "DumpTest", "minimal.apk"});
+  auto loaded_apk = LoadedApk::LoadApkFromPath(apk_path, &noop_diag);
+
+  std::string output;
+  DumpBadgingToString(loaded_apk.get(), &output);
+
+  std::string expected;
+  auto expected_path = file::BuildPath({android::base::GetExecutableDirectory(),
+                                        "integration-tests", "DumpTest", "minimal_expected.txt"});
+  ::android::base::ReadFileToString(expected_path, &expected);
+  ASSERT_EQ(output, expected);
+}
+
+TEST_F(DumpTest, DumpBadgingAllComponents) {
+  auto apk_path = file::BuildPath(
+      {android::base::GetExecutableDirectory(), "integration-tests", "DumpTest", "components.apk"});
+  auto loaded_apk = LoadedApk::LoadApkFromPath(apk_path, &noop_diag);
+
+  std::string output;
+  DumpBadgingToString(loaded_apk.get(), &output, /* include_meta_data= */ true);
+
+  std::string expected;
+  auto expected_path =
+      file::BuildPath({android::base::GetExecutableDirectory(), "integration-tests", "DumpTest",
+                       "components_expected.txt"});
+  ::android::base::ReadFileToString(expected_path, &expected);
+  ASSERT_EQ(output, expected);
+}
+
+TEST_F(DumpTest, DumpBadgingPermissionsOnly) {
+  auto apk_path = file::BuildPath(
+      {android::base::GetExecutableDirectory(), "integration-tests", "DumpTest", "components.apk"});
+  auto loaded_apk = LoadedApk::LoadApkFromPath(apk_path, &noop_diag);
+
+  std::string output;
+  DumpBadgingToString(loaded_apk.get(), &output, /* include_meta_data= */ false,
+                      /* only_permissions= */ true);
+
+  std::string expected;
+  auto expected_path =
+      file::BuildPath({android::base::GetExecutableDirectory(), "integration-tests", "DumpTest",
+                       "components_permissions_expected.txt"});
+  ::android::base::ReadFileToString(expected_path, &expected);
+  ASSERT_EQ(output, expected);
+}
+
+}  // namespace aapt
\ No newline at end of file
diff --git a/tools/aapt2/dump/DumpManifest.cpp b/tools/aapt2/dump/DumpManifest.cpp
index 9828b97..e36112d 100644
--- a/tools/aapt2/dump/DumpManifest.cpp
+++ b/tools/aapt2/dump/DumpManifest.cpp
@@ -17,17 +17,21 @@
 #include "DumpManifest.h"
 
 #include <algorithm>
+#include <array>
+#include <memory>
+#include <set>
+#include <string_view>
+#include <vector>
 
 #include "LoadedApk.h"
 #include "SdkConstants.h"
 #include "ValueVisitor.h"
+#include "androidfw/ConfigDescription.h"
 #include "io/File.h"
 #include "io/FileStream.h"
 #include "process/IResourceTableConsumer.h"
 #include "xml/XmlDom.h"
 
-#include "androidfw/ConfigDescription.h"
-
 using ::android::base::StringPrintf;
 using ::android::ConfigDescription;
 
@@ -112,7 +116,101 @@
   return el->FindAttribute(package, name);
 }
 
+class Architectures {
+ public:
+  std::set<std::string> architectures;
+  std::set<std::string> alt_architectures;
+
+  void Print(text::Printer* printer) {
+    if (!architectures.empty()) {
+      printer->Print("native-code:");
+      for (auto& arch : architectures) {
+        printer->Print(StringPrintf(" '%s'", arch.data()));
+      }
+      printer->Print("\n");
+    }
+    if (!alt_architectures.empty()) {
+      printer->Print("alt-native-code:");
+      for (auto& arch : alt_architectures) {
+        printer->Print(StringPrintf(" '%s'", arch.data()));
+      }
+      printer->Print("\n");
+    }
+  }
+
+  void ToProto(pb::Badging* out_badging) {
+    auto out_architectures = out_badging->mutable_architectures();
+    for (auto& arch : architectures) {
+      out_architectures->add_architectures(arch);
+    }
+    for (auto& arch : alt_architectures) {
+      out_architectures->add_alt_architectures(arch);
+    }
+  }
+};
+
+const static std::array<std::string_view, 14> printable_components{"app-widget",
+                                                                   "device-admin",
+                                                                   "ime",
+                                                                   "wallpaper",
+                                                                   "accessibility",
+                                                                   "print-service",
+                                                                   "payment",
+                                                                   "search",
+                                                                   "document-provider",
+                                                                   "launcher",
+                                                                   "notification-listener",
+                                                                   "dream",
+                                                                   "camera",
+                                                                   "camera-secure"};
+
+class Components {
+ public:
+  std::set<std::string, std::less<>> discovered_components;
+  bool other_activities = false;
+  bool other_receivers = false;
+  bool other_services = false;
+
+  void Print(text::Printer* printer) {
+    for (auto& component : printable_components) {
+      if (discovered_components.find(component) != discovered_components.end()) {
+        printer->Print(StringPrintf("provides-component:'%s'\n", component.data()));
+      }
+    }
+    // Print presence of main activity
+    if (discovered_components.find("main") != discovered_components.end()) {
+      printer->Print("main\n");
+    }
+
+    if (other_activities) {
+      printer->Print("other-activities\n");
+    }
+    if (other_receivers) {
+      printer->Print("other-receivers\n");
+    }
+    if (other_services) {
+      printer->Print("other-services\n");
+    }
+  }
+
+  void ToProto(pb::Badging* out_badging) {
+    auto out_components = out_badging->mutable_components();
+    for (auto& component : printable_components) {
+      auto discovered = discovered_components.find(component);
+      if (discovered != discovered_components.end()) {
+        out_components->add_provided_components(*discovered);
+      }
+    }
+    out_components->set_main(discovered_components.find("main") != discovered_components.end());
+    out_components->set_other_activities(other_activities);
+    out_components->set_other_receivers(other_receivers);
+    out_components->set_other_services(other_services);
+  }
+};
+
 class CommonFeatureGroup;
+class FeatureGroup;
+class SupportsScreen;
 
 class ManifestExtractor {
  public:
@@ -128,7 +226,12 @@
     static std::unique_ptr<Element> Inflate(ManifestExtractor* extractor, xml::Element* el);
 
     /** Writes out the extracted contents of the element. */
-    virtual void Print(text::Printer* printer) { }
+    virtual void Print(text::Printer* printer) {
+    }
+
+    /** Saves extracted information into Badging proto. */
+    virtual void ToProto(pb::Badging* out_badging) {
+    }
 
     /** Adds an element to the list of children of the element. */
     void AddChild(std::unique_ptr<Element>& child) { children_.push_back(std::move(child)); }
@@ -338,7 +441,9 @@
     return config;
   }
 
-  bool Dump(text::Printer* printer, IDiagnostics* diag);
+  bool Extract(IDiagnostics* diag);
+  bool Dump(text::Printer* printer);
+  bool DumpProto(pb::Badging* out_badging);
 
   /** Recursively visit the xml element tree and return a processed badging element tree. */
   std::unique_ptr<Element> Visit(xml::Element* element);
@@ -354,7 +459,7 @@
    * Retrieves the default feature group that features are added into when <uses-feature>
    * are not in a <feature-group> element.
    **/
-  CommonFeatureGroup* GetCommonFeatureGroup() {
+  CommonFeatureGroup* common_feature_group() {
     return commonFeatureGroup_.get();
   }
 
@@ -387,11 +492,19 @@
   DumpManifestOptions& options_;
 
  private:
+  std::unique_ptr<xml::XmlResource> doc_;
   std::unique_ptr<CommonFeatureGroup> commonFeatureGroup_ = util::make_unique<CommonFeatureGroup>();
   std::map<std::string, ConfigDescription> locales_;
   std::map<uint16_t, ConfigDescription> densities_;
   std::vector<Element*> parent_stack_;
   int32_t target_sdk_ = 0;
+
+  std::unique_ptr<ManifestExtractor::Element> root_element_;
+  std::vector<std::unique_ptr<ManifestExtractor::Element>> implied_permissions_;
+  std::vector<FeatureGroup*> feature_groups_;
+  Components components_;
+  Architectures architectures_;
+  const SupportsScreen* supports_screen_;
 };
 
 template<typename T> T* ElementCast(ManifestExtractor::Element* element);
@@ -427,6 +540,7 @@
 class Manifest : public ManifestExtractor::Element {
  public:
   Manifest() = default;
+  bool only_package_name;
   std::string package;
   int32_t versionCode;
   std::string versionName;
@@ -462,7 +576,54 @@
     installLocation = GetAttributeInteger(FindAttribute(manifest, INSTALL_LOCATION_ATTR));
   }
 
+  void ToProto(pb::Badging* out_badging) override {
+    auto out_package = out_badging->mutable_package();
+    out_package->set_package(package);
+    out_package->set_version_code(versionCode);
+    out_package->set_version_name(versionName);
+    if (compilesdkVersion) {
+      out_package->set_compile_sdk_version(*compilesdkVersion);
+    }
+    if (compilesdkVersionCodename) {
+      out_package->set_compile_sdk_version_codename(*compilesdkVersionCodename);
+    }
+    if (platformVersionName) {
+      out_package->set_platform_version_name(*platformVersionName);
+    } else if (platformVersionNameInt) {
+      out_package->set_platform_version_name(std::to_string(*platformVersionNameInt));
+    }
+    if (platformVersionCode) {
+      out_package->set_platform_version_code(*platformVersionCode);
+    } else if (platformVersionCodeInt) {
+      out_package->set_platform_version_code(std::to_string(*platformVersionCodeInt));
+    }
+
+    if (installLocation) {
+      switch (*installLocation) {
+        case 0:
+          out_package->set_install_location(pb::PackageInfo_InstallLocation_AUTO);
+          break;
+        case 1:
+          out_package->set_install_location(pb::PackageInfo_InstallLocation_INTERNAL_ONLY);
+          break;
+        case 2:
+          out_package->set_install_location(pb::PackageInfo_InstallLocation_PREFER_EXTERNAL);
+          break;
+        default:
+          break;
+      }
+    }
+  }
+
   void Print(text::Printer* printer) override {
+    if (only_package_name) {
+      printer->Println(StringPrintf("package: %s", package.data()));
+    } else {
+      PrintFull(printer);
+    }
+  }
+
+  void PrintFull(text::Printer* printer) {
     printer->Print(StringPrintf("package: name='%s' ", package.data()));
     printer->Print(StringPrintf("versionCode='%s' ",
                                (versionCode > 0) ? std::to_string(versionCode).data() : ""));
@@ -598,6 +759,27 @@
       printer->Print("application-debuggable\n");
     }
   }
+
+  void ToProto(pb::Badging* out_badging) override {
+    auto application = out_badging->mutable_application();
+    application->set_label(android::ResTable::normalizeForOutput(label.data()));
+    application->set_icon(icon);
+    application->set_banner(banner);
+    application->set_test_only(test_only != 0);
+    application->set_game(is_game != 0);
+    application->set_debuggable(debuggable != 0);
+
+    auto out_locale_labels = application->mutable_locale_labels();
+    for (auto& p : locale_labels) {
+      if (!p.first.empty()) {
+        (*out_locale_labels)[p.first] = p.second;
+      }
+    }
+    auto out_density_icons = application->mutable_density_icons();
+    for (auto& p : density_icons) {
+      (*out_density_icons)[p.first] = p.second;
+    }
+  }
 };
 
 /** Represents <uses-sdk> elements. **/
@@ -647,6 +829,23 @@
       printer->Print(StringPrintf("targetSdkVersion:'%s'\n", target_sdk_name->data()));
     }
   }
+
+  void ToProto(pb::Badging* out_badging) override {
+    auto out_sdks = out_badging->mutable_uses_sdk();
+    if (min_sdk) {
+      out_sdks->set_min_sdk_version(*min_sdk);
+    } else if (min_sdk_name) {
+      out_sdks->set_min_sdk_version_name(*min_sdk_name);
+    }
+    if (max_sdk) {
+      out_sdks->set_max_sdk_version(*max_sdk);
+    }
+    if (target_sdk) {
+      out_sdks->set_target_sdk_version(*target_sdk);
+    } else if (target_sdk_name) {
+      out_sdks->set_target_sdk_version_name(*target_sdk_name);
+    }
+  }
 };
 
 /** Represents <uses-configuration> elements. **/
@@ -691,6 +890,15 @@
     }
     printer->Print("\n");
   }
+
+  void ToProto(pb::Badging* out_badging) override {
+    auto out_configuration = out_badging->mutable_uses_configuration();
+    out_configuration->set_req_touch_screen(req_touch_screen);
+    out_configuration->set_req_keyboard_type(req_keyboard_type);
+    out_configuration->set_req_hard_keyboard(req_hard_keyboard);
+    out_configuration->set_req_navigation(req_navigation);
+    out_configuration->set_req_five_way_nav(req_five_way_nav);
+  }
 };
 
 /** Represents <supports-screen> elements. **/
@@ -733,54 +941,24 @@
     }
   }
 
-  void PrintScreens(text::Printer* printer, int32_t target_sdk) {
-    int32_t small_screen_temp = small_screen;
-    int32_t normal_screen_temp  = normal_screen;
-    int32_t large_screen_temp  = large_screen;
-    int32_t xlarge_screen_temp  = xlarge_screen;
-    int32_t any_density_temp  = any_density;
-
-    // Determine default values for any unspecified screen sizes,
-    // based on the target SDK of the package.  As of 4 (donut)
-    // the screen size support was introduced, so all default to
-    // enabled.
-    if (small_screen_temp  > 0) {
-      small_screen_temp = target_sdk >= SDK_DONUT ? -1 : 0;
-    }
-    if (normal_screen_temp  > 0) {
-      normal_screen_temp  = -1;
-    }
-    if (large_screen_temp  > 0) {
-      large_screen_temp = target_sdk >= SDK_DONUT ? -1 : 0;
-    }
-    if (xlarge_screen_temp  > 0) {
-      // Introduced in Gingerbread.
-      xlarge_screen_temp = target_sdk >= SDK_GINGERBREAD ? -1 : 0;
-    }
-    if (any_density_temp  > 0) {
-      any_density_temp = (target_sdk >= SDK_DONUT || requires_smallest_width_dp > 0 ||
-                          compatible_width_limit_dp > 0)
-                             ? -1
-                             : 0;
-    }
-
+  void PrintScreens(text::Printer* printer, int32_t target_sdk) const {
     // Print the formatted screen info
     printer->Print("supports-screens:");
-    if (small_screen_temp  != 0) {
+    if (IsSmallScreenSupported(target_sdk)) {
       printer->Print(" 'small'");
     }
-    if (normal_screen_temp  != 0) {
+    if (normal_screen != 0) {
       printer->Print(" 'normal'");
     }
-    if (large_screen_temp   != 0) {
+    if (IsLargeScreenSupported(target_sdk)) {
       printer->Print(" 'large'");
     }
-    if (xlarge_screen_temp  != 0) {
+    if (IsXLargeScreenSupported(target_sdk)) {
       printer->Print(" 'xlarge'");
     }
     printer->Print("\n");
     printer->Print(StringPrintf("supports-any-density: '%s'\n",
-                                (any_density_temp ) ? "true" : "false"));
+                                (IsAnyDensitySupported(target_sdk)) ? "true" : "false"));
     if (requires_smallest_width_dp > 0) {
       printer->Print(StringPrintf("requires-smallest-width:'%d'\n", requires_smallest_width_dp));
     }
@@ -791,6 +969,60 @@
       printer->Print(StringPrintf("largest-width-limit:'%d'\n", largest_width_limit_dp));
     }
   }
+
+  void ToProtoScreens(pb::Badging* out_badging, int32_t target_sdk) const {
+    auto supports_screen = out_badging->mutable_supports_screen();
+    if (IsSmallScreenSupported(target_sdk)) {
+      supports_screen->add_screens(pb::SupportsScreen_ScreenType_SMALL);
+    }
+    if (normal_screen != 0) {
+      supports_screen->add_screens(pb::SupportsScreen_ScreenType_NORMAL);
+    }
+    if (IsLargeScreenSupported(target_sdk)) {
+      supports_screen->add_screens(pb::SupportsScreen_ScreenType_LARGE);
+    }
+    if (IsXLargeScreenSupported(target_sdk)) {
+      supports_screen->add_screens(pb::SupportsScreen_ScreenType_XLARGE);
+    }
+    supports_screen->set_supports_any_densities(IsAnyDensitySupported(target_sdk));
+    supports_screen->set_requires_smallest_width_dp(requires_smallest_width_dp);
+    supports_screen->set_compatible_width_limit_dp(compatible_width_limit_dp);
+    supports_screen->set_largest_width_limit_dp(largest_width_limit_dp);
+  }
+
+ private:
+  // Determine default values for any unspecified screen sizes,
+  // based on the target SDK of the package.  As of 4 (donut)
+  // the screen size support was introduced, so all default to
+  // enabled.
+  bool IsSmallScreenSupported(int32_t target_sdk) const {
+    if (small_screen > 0) {
+      return target_sdk >= SDK_DONUT;
+    }
+    return small_screen != 0;
+  }
+
+  bool IsLargeScreenSupported(int32_t target_sdk) const {
+    if (large_screen > 0) {
+      return target_sdk >= SDK_DONUT;
+    }
+    return large_screen != 0;
+  }
+
+  bool IsXLargeScreenSupported(int32_t target_sdk) const {
+    if (xlarge_screen > 0) {
+      return target_sdk >= SDK_GINGERBREAD;
+    }
+    return xlarge_screen != 0;
+  }
+
+  bool IsAnyDensitySupported(int32_t target_sdk) const {
+    if (any_density > 0) {
+      return target_sdk >= SDK_DONUT || requires_smallest_width_dp > 0 ||
+             compatible_width_limit_dp > 0;
+    }
+    return any_density != 0;
+  }
 };
 
 /** Represents <feature-group> elements. **/
@@ -821,6 +1053,18 @@
     }
   }
 
+  virtual void GroupToProto(pb::Badging* out_badging) {
+    auto feature_group = out_badging->add_feature_groups();
+    feature_group->set_label(label);
+    feature_group->set_open_gles_version(open_gles_version);
+    for (auto& feature : features_) {
+      auto out_feature = feature_group->add_features();
+      out_feature->set_name(feature.first);
+      out_feature->set_required(feature.second.required);
+      out_feature->set_version(feature.second.version);
+    }
+  }
+
   /** Adds a feature to the feature group. */
   void AddFeature(const std::string& name, bool required = true, int32_t version = -1) {
     features_.insert(std::make_pair(name, Feature{ required, version }));
@@ -910,6 +1154,23 @@
     }
   }
 
+  virtual void GroupToProto(pb::Badging* out_badging) override {
+    FeatureGroup::GroupToProto(out_badging);
+    auto feature_group =
+        out_badging->mutable_feature_groups(out_badging->feature_groups_size() - 1);
+    for (auto& feature : implied_features_) {
+      if (features_.find(feature.first) == features_.end()) {
+        auto out_feature = feature_group->add_features();
+        out_feature->set_name(feature.first);
+        auto implied_data = out_feature->mutable_implied_data();
+        implied_data->set_from_sdk_23_permission(feature.second.implied_from_sdk_k23);
+        for (auto& reason : feature.second.reasons) {
+          implied_data->add_reasons(reason);
+        }
+      }
+    }
+  }
+
   /** Returns true if the feature group has the given feature. */
   bool HasFeature(const std::string& name) override {
     return FeatureGroup::HasFeature(name)
@@ -1050,7 +1311,7 @@
     // common feature group
     FeatureGroup* feature_group = ElementCast<FeatureGroup>(extractor()->parent_stack()[0]);
     if (!feature_group) {
-      feature_group = extractor()->GetCommonFeatureGroup();
+      feature_group = extractor()->common_feature_group();
     } else {
       // All features in side of <feature-group> elements are required.
       required = true;
@@ -1068,12 +1329,14 @@
 class UsesPermission : public ManifestExtractor::Element {
  public:
   UsesPermission() = default;
+  bool implied;
   std::string name;
   std::vector<std::string> requiredFeatures;
   std::vector<std::string> requiredNotFeatures;
   int32_t required = true;
   int32_t maxSdkVersion = -1;
   int32_t usesPermissionFlags = 0;
+  std::string impliedReason;
 
   void Extract(xml::Element* element) override {
     name = GetAttributeStringDefault(FindAttribute(element, NAME_ATTR), "");
@@ -1094,7 +1357,7 @@
         FindAttribute(element, USES_PERMISSION_FLAGS_ATTR), 0);
 
     if (!name.empty()) {
-      CommonFeatureGroup* common = extractor()->GetCommonFeatureGroup();
+      CommonFeatureGroup* common = extractor()->common_feature_group();
       common->addImpliedFeaturesForPermission(extractor()->target_sdk(), name, false);
     }
   }
@@ -1126,17 +1389,37 @@
         printer->Print("\n");
       }
     }
+    if (implied) {
+      printer->Print(StringPrintf("uses-implied-permission: name='%s'", name.data()));
+      if (maxSdkVersion >= 0) {
+        printer->Print(StringPrintf(" maxSdkVersion='%d'", maxSdkVersion));
+      }
+      if ((usesPermissionFlags & kNeverForLocation) != 0) {
+        printer->Print(StringPrintf(" usesPermissionFlags='neverForLocation'"));
+      }
+      printer->Print(StringPrintf(" reason='%s'\n", impliedReason.data()));
+    }
   }
 
-  void PrintImplied(text::Printer* printer, const std::string& reason) {
-    printer->Print(StringPrintf("uses-implied-permission: name='%s'", name.data()));
-    if (maxSdkVersion >= 0) {
-      printer->Print(StringPrintf(" maxSdkVersion='%d'", maxSdkVersion));
+  void ToProto(pb::Badging* out_badging) override {
+    if (!name.empty()) {
+      auto permission = out_badging->add_uses_permissions();
+      permission->set_name(name);
+      if (maxSdkVersion > 0) {
+        permission->set_max_sdk_version(maxSdkVersion);
+      }
+      if ((usesPermissionFlags & kNeverForLocation) != 0) {
+        permission->mutable_permission_flags()->set_never_for_location(true);
+      }
+      for (auto& requiredFeature : requiredFeatures) {
+        permission->add_required_features(requiredFeature);
+      }
+      for (auto& requiredNotFeature : requiredNotFeatures) {
+        permission->add_required_not_features(requiredNotFeature);
+      }
+      permission->set_required(required != 0);
+      permission->set_implied(implied);
     }
-    if ((usesPermissionFlags & kNeverForLocation) != 0) {
-      printer->Print(StringPrintf(" usesPermissionFlags='neverForLocation'"));
-    }
-    printer->Print(StringPrintf(" reason='%s'\n", reason.data()));
   }
 };
 
@@ -1184,7 +1467,7 @@
     maxSdkVersion = GetAttributeInteger(FindAttribute(element, MAX_SDK_VERSION_ATTR));
 
     if (name) {
-      CommonFeatureGroup* common = extractor()->GetCommonFeatureGroup();
+      CommonFeatureGroup* common = extractor()->common_feature_group();
       common->addImpliedFeaturesForPermission(extractor()->target_sdk(), *name, true);
     }
   }
@@ -1198,6 +1481,17 @@
       printer->Print("\n");
     }
   }
+
+  void ToProto(pb::Badging* out_badging) override {
+    if (name) {
+      auto permission = out_badging->add_uses_permissions();
+      permission->set_sdk23_and_above(true);
+      permission->set_name(*name);
+      if (maxSdkVersion) {
+        permission->set_max_sdk_version(*maxSdkVersion);
+      }
+    }
+  }
 };
 
 /** Represents <permission> elements. These elements are only printing when dumping permissions. **/
@@ -1215,6 +1509,12 @@
       printer->Print(StringPrintf("permission: %s\n", name.data()));
     }
   }
+
+  void ToProto(pb::Badging* out_badging) override {
+    if (!name.empty()) {
+      out_badging->add_permissions()->set_name(name);
+    }
+  }
 };
 
 /** Represents <activity> elements. **/
@@ -1256,7 +1556,7 @@
 
     auto orientation = GetAttributeInteger(FindAttribute(element, SCREEN_ORIENTATION_ATTR));
     if (orientation) {
-      CommonFeatureGroup* common = extractor()->GetCommonFeatureGroup();
+      CommonFeatureGroup* common = extractor()->common_feature_group();
       int orien = *orientation;
       if (orien == 0 || orien == 6 || orien == 8) {
         // Requests landscape, sensorLandscape, or reverseLandscape.
@@ -1295,6 +1595,22 @@
                                   icon.data(), banner.data()));
     }
   }
+
+  void ToProto(pb::Badging* out_badging) override {
+    if (has_main_action && has_launcher_category) {
+      auto activity = out_badging->mutable_launchable_activity();
+      activity->set_name(name);
+      activity->set_label(android::ResTable::normalizeForOutput(label.data()));
+      activity->set_icon(icon);
+    }
+    if (has_leanback_launcher_category) {
+      auto activity = out_badging->mutable_leanback_launchable_activity();
+      activity->set_name(name);
+      activity->set_label(android::ResTable::normalizeForOutput(label.data()));
+      activity->set_icon(icon);
+      activity->set_banner(banner);
+    }
+  }
 };
 
 /** Represents <intent-filter> elements. */
@@ -1395,6 +1711,14 @@
                                  (required == 0) ? "-not-required" : "", name.data()));
     }
   }
+
+  void ToProto(pb::Badging* out_badging) override {
+    if (!name.empty()) {
+      auto uses_library = out_badging->add_uses_libraries();
+      uses_library->set_name(name);
+      uses_library->set_required(required != 0);
+    }
+  }
 };
 
 /** Represents <static-library> elements. **/
@@ -1419,6 +1743,13 @@
       "static-library: name='%s' version='%d' versionMajor='%d'\n",
       name.data(), version, versionMajor));
   }
+
+  void ToProto(pb::Badging* out_badging) override {
+    auto static_library = out_badging->mutable_static_library();
+    static_library->set_name(name);
+    static_library->set_version(version);
+    static_library->set_version_major(versionMajor);
+  }
 };
 
 /** Represents <uses-static-library> elements. **/
@@ -1459,6 +1790,16 @@
     }
     printer->Print("\n");
   }
+
+  void ToProto(pb::Badging* out_badging) override {
+    auto uses_static_library = out_badging->add_uses_static_libraries();
+    uses_static_library->set_name(name);
+    uses_static_library->set_version(version);
+    uses_static_library->set_version_major(versionMajor);
+    for (auto& cert : certDigests) {
+      uses_static_library->add_certificates(cert);
+    }
+  }
 };
 
 /** Represents <sdk-library> elements. **/
@@ -1480,6 +1821,12 @@
     printer->Print(
         StringPrintf("sdk-library: name='%s' versionMajor='%d'\n", name.data(), versionMajor));
   }
+
+  void ToProto(pb::Badging* out_badging) override {
+    auto sdk_library = out_badging->mutable_sdk_library();
+    sdk_library->set_name(name);
+    sdk_library->set_version_major(versionMajor);
+  }
 };
 
 /** Represents <uses-sdk-library> elements. **/
@@ -1517,6 +1864,15 @@
     }
     printer->Print("\n");
   }
+
+  void ToProto(pb::Badging* out_badging) override {
+    auto uses_sdk_library = out_badging->add_uses_sdk_libraries();
+    uses_sdk_library->set_name(name);
+    uses_sdk_library->set_version_major(versionMajor);
+    for (auto& cert : certDigests) {
+      uses_sdk_library->add_certificates(cert);
+    }
+  }
 };
 
 /** Represents <uses-native-library> elements. **/
@@ -1540,6 +1896,14 @@
                                  (required == 0) ? "-not-required" : "", name.data()));
     }
   }
+
+  void ToProto(pb::Badging* out_badging) override {
+    if (!name.empty()) {
+      auto uses_native_library = out_badging->add_uses_native_libraries();
+      uses_native_library->set_name(name);
+      uses_native_library->set_required(required != 0);
+    }
+  }
 };
 
 /**
@@ -1565,21 +1929,39 @@
 
   void Print(text::Printer* printer) override {
     if (extractor()->options_.include_meta_data && !name.empty()) {
-      printer->Print(StringPrintf("meta-data: name='%s' ", name.data()));
+      printer->Print(StringPrintf("meta-data: name='%s'", name.data()));
       if (!value.empty()) {
-        printer->Print(StringPrintf("value='%s' ", value.data()));
+        printer->Print(StringPrintf(" value='%s'", value.data()));
       } else if (value_int) {
-        printer->Print(StringPrintf("value='%d' ", *value_int));
+        printer->Print(StringPrintf(" value='%d'", *value_int));
       } else {
         if (!resource.empty()) {
-          printer->Print(StringPrintf("resource='%s' ", resource.data()));
+          printer->Print(StringPrintf(" resource='%s'", resource.data()));
         } else if (resource_int) {
-          printer->Print(StringPrintf("resource='%d' ", *resource_int));
+          printer->Print(StringPrintf(" resource='%d'", *resource_int));
         }
       }
       printer->Print("\n");
     }
   }
+
+  void ToProto(pb::Badging* out_badging) override {
+    if (!name.empty()) {
+      auto metadata = out_badging->add_metadata();
+      metadata->set_name(name);
+      if (!value.empty()) {
+        metadata->set_value_string(value);
+      } else if (value_int) {
+        metadata->set_value_int(*value_int);
+      } else {
+        if (!resource.empty()) {
+          metadata->set_resource_string(resource);
+        } else if (resource_int) {
+          metadata->set_resource_int(*resource_int);
+        }
+      }
+    }
+  }
 };
 
 /**
@@ -1709,6 +2091,13 @@
       printer->Print("\n");
     }
   }
+
+  void ToProto(pb::Badging* out_badging) override {
+    auto supports_input = out_badging->mutable_supports_input();
+    for (auto& input : inputs) {
+      supports_input->add_inputs(input);
+    }
+  }
 };
 
 /** Represents <input-type> elements. **/
@@ -1742,6 +2131,12 @@
       printer->Print(StringPrintf("original-package:'%s'\n", name->data()));
     }
   }
+
+  void ToProto(pb::Badging* out_badging) override {
+    if (name) {
+      out_badging->mutable_package()->set_original_package(*name);
+    }
+  }
 };
 
 
@@ -1780,6 +2175,21 @@
     }
     printer->Print("\n");
   }
+
+  void ToProto(pb::Badging* out_badging) override {
+    auto overlay = out_badging->mutable_overlay();
+    if (target_package) {
+      overlay->set_target_package(*target_package);
+    }
+    overlay->set_priority(priority);
+    overlay->set_static_(is_static);
+    if (required_property_name) {
+      overlay->set_required_property_name(*required_property_name);
+    }
+    if (required_property_value) {
+      overlay->set_required_property_value(*required_property_value);
+    }
+  }
 };
 
 /** * Represents <package-verifier> elements. **/
@@ -1800,6 +2210,14 @@
                                  name->data(), public_key->data()));
     }
   }
+
+  void ToProto(pb::Badging* out_badging) override {
+    auto package_verifier = out_badging->mutable_package_verifier();
+    if (name && public_key) {
+      package_verifier->set_name(*name);
+      package_verifier->set_public_key(*public_key);
+    }
+  }
 };
 
 /** Represents <uses-package> elements. **/
@@ -1848,6 +2266,21 @@
       }
     }
   }
+
+  void ToProto(pb::Badging* out_badging) override {
+    if (name) {
+      auto uses_package = out_badging->add_uses_packages();
+      uses_package->set_name(*name);
+      if (packageType) {
+        uses_package->set_package_type(*packageType);
+        uses_package->set_version(version);
+        uses_package->set_version_major(versionMajor);
+        for (auto& cert : certDigests) {
+          uses_package->add_certificates(cert);
+        }
+      }
+    }
+  }
 };
 
 /** Represents <additional-certificate> elements. **/
@@ -1880,6 +2313,14 @@
     size = GetAttributeInteger(FindAttribute(element, SCREEN_SIZE_ATTR));
     density = GetAttributeInteger(FindAttribute(element, SCREEN_DENSITY_ATTR));
   }
+
+  void ToProto(pb::Badging* out_badging) override {
+    if (size && density) {
+      auto screen = out_badging->mutable_compatible_screens()->add_screens();
+      screen->set_density(*density);
+      screen->set_size(*size);
+    }
+  }
 };
 
 /**
@@ -1925,6 +2366,12 @@
       printer->Print(StringPrintf("supports-gl-texture:'%s'\n", name->data()));
     }
   }
+
+  void ToProto(pb::Badging* out_badging) override {
+    if (name) {
+      out_badging->mutable_supports_gl_texture()->add_name(*name);
+    }
+  }
 };
 
 /** Represents <property> elements. **/
@@ -1960,6 +2407,24 @@
     }
     printer->Print("\n");
   }
+
+  void ToProto(pb::Badging* out_badging) override {
+    if (!name.empty()) {
+      auto property = out_badging->add_properties();
+      property->set_name(name);
+      if (!value.empty()) {
+        property->set_value_string(value);
+      } else if (value_int) {
+        property->set_value_int(*value_int);
+      } else {
+        if (!resource.empty()) {
+          property->set_resource_string(resource);
+        } else if (resource_int) {
+          property->set_resource_int(*resource_int);
+        }
+      }
+    }
+  }
 };
 
 /** Recursively prints the extracted badging element. */
@@ -1970,15 +2435,23 @@
   }
 }
 
-bool ManifestExtractor::Dump(text::Printer* printer, IDiagnostics* diag) {
+/** Recursively serializes extracted badging elements to proto. */
+static void ToProto(ManifestExtractor::Element* el, pb::Badging* out_badging) {
+  el->ToProto(out_badging);
+  for (auto& child : el->children()) {
+    ToProto(child.get(), out_badging);
+  }
+}
+
+bool ManifestExtractor::Extract(IDiagnostics* diag) {
   // Load the manifest
-  std::unique_ptr<xml::XmlResource> doc = apk_->LoadXml("AndroidManifest.xml", diag);
-  if (doc == nullptr) {
+  doc_ = apk_->LoadXml("AndroidManifest.xml", diag);
+  if (doc_ == nullptr) {
     diag->Error(DiagMessage() << "failed to find AndroidManifest.xml");
     return false;
   }
 
-  xml::Element* element = doc->root.get();
+  xml::Element* element = doc_->root.get();
   if (element->name != "manifest") {
     diag->Error(DiagMessage() << "manifest does not start with <manifest> tag");
     return false;
@@ -1987,10 +2460,11 @@
   // Print only the <uses-permission>, <uses-permission-sdk23>, and <permission> elements if
   // printing only permission elements is requested
   if (options_.only_permissions) {
-    std::unique_ptr<ManifestExtractor::Element> manifest_element =
-        ManifestExtractor::Element::Inflate(this, element);
+    root_element_ = ManifestExtractor::Element::Inflate(this, element);
 
-    if (auto manifest = ElementCast<Manifest>(manifest_element.get())) {
+    if (auto manifest = ElementCast<Manifest>(root_element_.get())) {
+      manifest->only_package_name = true;
+
       for (xml::Element* child : element->GetChildElements()) {
         if (child->name == "uses-permission" || child->name == "uses-permission-sdk-23"
             || child->name == "permission") {
@@ -1999,15 +2473,8 @@
           manifest->AddChild(permission_element);
         }
       }
-
-      printer->Print(StringPrintf("package: %s\n", manifest->package.data()));
-      ForEachChild(manifest, [&printer](ManifestExtractor::Element* el) -> void {
-        el->Print(printer);
-      });
-
       return true;
     }
-
     return false;
   }
 
@@ -2041,27 +2508,24 @@
   }
 
   // Extract badging information
-  auto root = Visit(element);
+  root_element_ = Visit(element);
 
   // Filter out all "uses-sdk" tags besides the very last tag. The android runtime only uses the
   // attribute values from the last defined tag.
   std::vector<UsesSdkBadging*> filtered_uses_sdk_tags;
-  for (const auto& child : root->children()) {
+  for (const auto& child : root_element_->children()) {
     if (auto uses_sdk = ElementCast<UsesSdkBadging>(child.get())) {
       filtered_uses_sdk_tags.emplace_back(uses_sdk);
     }
   }
   if (filtered_uses_sdk_tags.size() >= 2U) {
     filtered_uses_sdk_tags.pop_back();
-    root->Filter([&](const ManifestExtractor::Element* e) {
+    root_element_->Filter([&](const ManifestExtractor::Element* e) {
       return std::find(filtered_uses_sdk_tags.begin(), filtered_uses_sdk_tags.end(), e) !=
              filtered_uses_sdk_tags.end();
     });
   }
 
-  // Print the elements in order seen
-  Print(root.get(), printer);
-
   /** Recursively checks the extracted elements for the specified permission. **/
   auto FindPermission = [&](ManifestExtractor::Element* root,
                             const std::string& name) -> ManifestExtractor::Element* {
@@ -2073,30 +2537,30 @@
     });
   };
 
-  auto PrintPermission = [&printer](const std::string& name, const std::string& reason,
-                                    int32_t max_sdk_version) -> void {
+  auto AddImpliedPermission = [&](const std::string& name, const std::string& reason,
+                                  int32_t max_sdk_version) -> void {
     auto permission = util::make_unique<UsesPermission>();
     permission->name = name;
     permission->maxSdkVersion = max_sdk_version;
-    permission->Print(printer);
-    permission->PrintImplied(printer, reason);
+    permission->implied = true;
+    permission->impliedReason = reason;
+    implied_permissions_.push_back(std::move(permission));
   };
 
   // Implied permissions
   // Pre-1.6 implicitly granted permission compatibility logic
-  CommonFeatureGroup* common_feature_group = GetCommonFeatureGroup();
   bool insert_write_external = false;
   auto write_external_permission = ElementCast<UsesPermission>(
-      FindPermission(root.get(), "android.permission.WRITE_EXTERNAL_STORAGE"));
+      FindPermission(root_element_.get(), "android.permission.WRITE_EXTERNAL_STORAGE"));
 
   if (target_sdk() < SDK_DONUT) {
     if (!write_external_permission) {
-      PrintPermission("android.permission.WRITE_EXTERNAL_STORAGE", "targetSdkVersion < 4", -1);
+      AddImpliedPermission("android.permission.WRITE_EXTERNAL_STORAGE", "targetSdkVersion < 4", -1);
       insert_write_external = true;
     }
 
-    if (!FindPermission(root.get(), "android.permission.READ_PHONE_STATE")) {
-      PrintPermission("android.permission.READ_PHONE_STATE", "targetSdkVersion < 4", -1);
+    if (!FindPermission(root_element_.get(), "android.permission.READ_PHONE_STATE")) {
+      AddImpliedPermission("android.permission.READ_PHONE_STATE", "targetSdkVersion < 4", -1);
     }
   }
 
@@ -2104,62 +2568,60 @@
   // force them to always take READ_EXTERNAL_STORAGE as well.  We always
   // do this (regardless of target API version) because we can't have
   // an app with write permission but not read permission.
-  auto read_external = FindPermission(root.get(), "android.permission.READ_EXTERNAL_STORAGE");
+  auto read_external =
+      FindPermission(root_element_.get(), "android.permission.READ_EXTERNAL_STORAGE");
   if (!read_external && (insert_write_external || write_external_permission)) {
-    PrintPermission("android.permission.READ_EXTERNAL_STORAGE",
-                    "requested WRITE_EXTERNAL_STORAGE",
-                    (write_external_permission) ? write_external_permission->maxSdkVersion : -1);
+    AddImpliedPermission(
+        "android.permission.READ_EXTERNAL_STORAGE", "requested WRITE_EXTERNAL_STORAGE",
+        (write_external_permission) ? write_external_permission->maxSdkVersion : -1);
   }
 
   // Pre-JellyBean call log permission compatibility.
   if (target_sdk() < SDK_JELLY_BEAN) {
-    if (!FindPermission(root.get(), "android.permission.READ_CALL_LOG")
-        && FindPermission(root.get(), "android.permission.READ_CONTACTS")) {
-      PrintPermission("android.permission.READ_CALL_LOG",
-                      "targetSdkVersion < 16 and requested READ_CONTACTS", -1);
+    if (!FindPermission(root_element_.get(), "android.permission.READ_CALL_LOG") &&
+        FindPermission(root_element_.get(), "android.permission.READ_CONTACTS")) {
+      AddImpliedPermission("android.permission.READ_CALL_LOG",
+                           "targetSdkVersion < 16 and requested READ_CONTACTS", -1);
     }
 
-    if (!FindPermission(root.get(), "android.permission.WRITE_CALL_LOG")
-        && FindPermission(root.get(), "android.permission.WRITE_CONTACTS")) {
-      PrintPermission("android.permission.WRITE_CALL_LOG",
-                      "targetSdkVersion < 16 and requested WRITE_CONTACTS", -1);
+    if (!FindPermission(root_element_.get(), "android.permission.WRITE_CALL_LOG") &&
+        FindPermission(root_element_.get(), "android.permission.WRITE_CONTACTS")) {
+      AddImpliedPermission("android.permission.WRITE_CALL_LOG",
+                           "targetSdkVersion < 16 and requested WRITE_CONTACTS", -1);
     }
   }
 
   // If the app hasn't declared the touchscreen as a feature requirement (either
   // directly or implied, required or not), then the faketouch feature is implied.
-  if (!common_feature_group->HasFeature("android.hardware.touchscreen")) {
-    common_feature_group->addImpliedFeature("android.hardware.faketouch",
-                                            "default feature for all apps", false);
+  if (!common_feature_group()->HasFeature("android.hardware.touchscreen")) {
+    common_feature_group()->addImpliedFeature("android.hardware.faketouch",
+                                              "default feature for all apps", false);
   }
 
   // Only print the common feature group if no feature group is defined
   std::vector<FeatureGroup*> feature_groups;
-  ForEachChild(root.get(), [&feature_groups](ManifestExtractor::Element* el) -> void {
+  ForEachChild(root_element_.get(), [&feature_groups](ManifestExtractor::Element* el) -> void {
     if (auto feature_group = ElementCast<FeatureGroup>(el)) {
       feature_groups.push_back(feature_group);
     }
   });
 
   if (feature_groups.empty()) {
-    common_feature_group->PrintGroup(printer);
+    feature_groups_.push_back(common_feature_group());
   } else {
     // Merge the common feature group into the feature group
     for (auto& feature_group : feature_groups) {
-      feature_group->open_gles_version  = std::max(feature_group->open_gles_version,
-                                                   common_feature_group->open_gles_version);
-      feature_group->Merge(common_feature_group);
-      feature_group->PrintGroup(printer);
+      feature_group->Merge(common_feature_group());
+      feature_groups_.push_back(feature_group);
     }
   };
 
   // Collect the component types of the application
-  std::set<std::string> components;
-  ForEachChild(root.get(), [&components](ManifestExtractor::Element* el) -> void {
+  ForEachChild(root_element_.get(), [&](ManifestExtractor::Element* el) -> void {
     if (ElementCast<Action>(el)) {
       auto action = ElementCast<Action>(el);
       if (!action->component.empty()) {
-        components.insert(action->component);
+        components_.discovered_components.insert(action->component);
         return;
       }
     }
@@ -2167,15 +2629,14 @@
     if (ElementCast<Category>(el)) {
       auto category = ElementCast<Category>(el);
       if (!category->component.empty()) {
-        components.insert(category->component);
+        components_.discovered_components.insert(category->component);
         return;
       }
     }
   });
 
   // Check for the payment component
-  auto apk = apk_;
-  ForEachChild(root.get(), [&apk, &components, &diag](ManifestExtractor::Element* el) -> void {
+  ForEachChild(root_element_.get(), [this, &diag](ManifestExtractor::Element* el) -> void {
     if (auto service = ElementCast<Service>(el)) {
       auto host_apdu_action = ElementCast<Action>(FindElement(service,
         [&](ManifestExtractor::Element* el) -> bool {
@@ -2193,140 +2654,87 @@
            return false;
       }));
 
-      ForEachChild(service, [&apk, &components, &diag, &host_apdu_action,
-          &offhost_apdu_action](ManifestExtractor::Element* el) -> void {
-        if (auto meta_data = ElementCast<MetaData>(el)) {
-          if ((meta_data->name == "android.nfc.cardemulation.host_apdu_service" && host_apdu_action)
-              || (meta_data->name == "android.nfc.cardemulation.off_host_apdu_service"
-                  && offhost_apdu_action)) {
+      ForEachChild(service,
+                   [this, &diag, &host_apdu_action,
+                    &offhost_apdu_action](ManifestExtractor::Element* el) -> void {
+                     if (auto meta_data = ElementCast<MetaData>(el)) {
+                       if ((meta_data->name == "android.nfc.cardemulation.host_apdu_service" &&
+                            host_apdu_action) ||
+                           (meta_data->name == "android.nfc.cardemulation.off_host_apdu_service" &&
+                            offhost_apdu_action)) {
+                         // Attempt to load the resource file
+                         if (!meta_data->resource.empty()) {
+                           return;
+                         }
+                         auto resource = this->apk_->LoadXml(meta_data->resource, diag);
+                         if (!resource) {
+                           return;
+                         }
 
-            // Attempt to load the resource file
-            if (!meta_data->resource.empty()) {
-              return;
-            }
-            auto resource = apk->LoadXml(meta_data->resource, diag);
-            if (!resource) {
-              return;
-            }
-
-            // Look for the payment category on an <aid-group> element
-            auto& root = resource.get()->root;
-            if ((host_apdu_action && root->name == "host-apdu-service")
-                || (offhost_apdu_action && root->name == "offhost-apdu-service")) {
-
-              for (auto& child : root->GetChildElements()) {
-                if (child->name == "aid-group") {
-                  auto category = FindAttribute(child, CATEGORY_ATTR);
-                  if (category && category->value == "payment") {
-                    components.insert("payment");
-                    return;
-                  }
-                }
-              }
-            }
-          }
-        }
-      });
+                         // Look for the payment category on an <aid-group> element
+                         auto& root = resource.get()->root;
+                         if ((host_apdu_action && root->name == "host-apdu-service") ||
+                             (offhost_apdu_action && root->name == "offhost-apdu-service")) {
+                           for (auto& child : root->GetChildElements()) {
+                             if (child->name == "aid-group") {
+                               auto category = FindAttribute(child, CATEGORY_ATTR);
+                               if (category && category->value == "payment") {
+                                 this->components_.discovered_components.insert("payment");
+                                 return;
+                               }
+                             }
+                           }
+                         }
+                       }
+                     }
+                   });
     }
   });
 
-  // Print the components types if they are present
-  auto PrintComponent = [&components, &printer](const std::string& component) -> void {
-    if (components.find(component) != components.end()) {
-      printer->Print(StringPrintf("provides-component:'%s'\n", component.data()));
-    }
-  };
-
-  PrintComponent("app-widget");
-  PrintComponent("device-admin");
-  PrintComponent("ime");
-  PrintComponent("wallpaper");
-  PrintComponent("accessibility");
-  PrintComponent("print-service");
-  PrintComponent("payment");
-  PrintComponent("search");
-  PrintComponent("document-provider");
-  PrintComponent("launcher");
-  PrintComponent("notification-listener");
-  PrintComponent("dream");
-  PrintComponent("camera");
-  PrintComponent("camera-secure");
-
-  // Print presence of main activity
-  if (components.find("main") != components.end()) {
-    printer->Print("main\n");
-  }
-
-  // Print presence of activities, recivers, and services with no special components
-  FindElement(root.get(), [&printer](ManifestExtractor::Element* el) -> bool {
+  // Print presence of activities, receivers, and services with no special components
+  FindElement(root_element_.get(), [&](ManifestExtractor::Element* el) -> bool {
     if (auto activity = ElementCast<Activity>(el)) {
       if (!activity->has_component_) {
-        printer->Print("other-activities\n");
+        components_.other_activities = true;
         return true;
       }
     }
     return false;
   });
 
-  FindElement(root.get(), [&printer](ManifestExtractor::Element* el) -> bool {
+  FindElement(root_element_.get(), [&](ManifestExtractor::Element* el) -> bool {
     if (auto receiver = ElementCast<Receiver>(el)) {
       if (!receiver->has_component) {
-        printer->Print("other-receivers\n");
+        components_.other_receivers = true;
         return true;
       }
     }
     return false;
   });
 
-  FindElement(root.get(), [&printer](ManifestExtractor::Element* el) -> bool {
+  FindElement(root_element_.get(), [&](ManifestExtractor::Element* el) -> bool {
     if (auto service = ElementCast<Service>(el)) {
       if (!service->has_component) {
-        printer->Print("other-services\n");
+        components_.other_services = true;
         return true;
       }
     }
     return false;
   });
 
-  // Print the supported screens
-  SupportsScreen* screen = ElementCast<SupportsScreen>(FindElement(root.get(),
-      [&](ManifestExtractor::Element* el) -> bool {
-    return ElementCast<SupportsScreen>(el) != nullptr;
-  }));
+  // Gather the supported screens
+  const static SupportsScreen default_screens{};
+  SupportsScreen* screen = ElementCast<SupportsScreen>(
+      FindElement(root_element_.get(), [&](ManifestExtractor::Element* el) -> bool {
+        return ElementCast<SupportsScreen>(el) != nullptr;
+      }));
+  supports_screen_ = screen ? screen : &default_screens;
 
-  if (screen) {
-    screen->PrintScreens(printer, target_sdk_);
-  } else {
-    // Print the default supported screens
-    SupportsScreen default_screens;
-    default_screens.PrintScreens(printer, target_sdk_);
-  }
-
-  // Print all the unique locales of the apk
-  printer->Print("locales:");
-  for (auto& config : locales_) {
-    if (config.first.empty()) {
-      printer->Print(" '--_--'");
-    } else {
-      printer->Print(StringPrintf(" '%s'", config.first.data()));
-    }
-  }
-  printer->Print("\n");
-
-  // Print all the densities locales of the apk
-  printer->Print("densities:");
-  for (auto& config : densities_) {
-    printer->Print(StringPrintf(" '%d'", config.first));
-  }
-  printer->Print("\n");
-
-  // Print the supported architectures of the app
-  std::set<std::string> architectures;
+  // Gather the supported architectures_ of the app
+  std::set<std::string> architectures_from_apk;
   auto it = apk_->GetFileCollection()->Iterator();
   while (it->HasNext()) {
     auto file_path = it->Next()->GetSource().path;
-
-
     size_t pos = file_path.find("lib/");
     if (pos != std::string::npos) {
       file_path = file_path.substr(pos + 4);
@@ -2335,17 +2743,18 @@
         file_path = file_path.substr(0, pos);
       }
 
-      architectures.insert(file_path);
+      architectures_from_apk.insert(file_path);
     }
   }
 
   // Determine if the application has multiArch supports
-  auto has_multi_arch = FindElement(root.get(), [&](ManifestExtractor::Element* el) -> bool {
-    if (auto application = ElementCast<Application>(el)) {
-      return application->has_multi_arch;
-    }
-    return false;
-  });
+  auto has_multi_arch =
+      FindElement(root_element_.get(), [&](ManifestExtractor::Element* el) -> bool {
+        if (auto application = ElementCast<Application>(el)) {
+          return application->has_multi_arch;
+        }
+        return false;
+      });
 
   bool output_alt_native_code = false;
   // A multiArch package is one that contains 64-bit and
@@ -2366,29 +2775,85 @@
     const std::string kIntel64 = "x86_64";
     const std::string kArm64 = "arm64-v8a";
 
-    auto arch = architectures.find(kIntel64);
-    if (arch == architectures.end()) {
-      arch = architectures.find(kArm64);
+    auto arch = architectures_from_apk.find(kIntel64);
+    if (arch == architectures_from_apk.end()) {
+      arch = architectures_from_apk.find(kArm64);
     }
 
-    if (arch != architectures.end()) {
-      printer->Print(StringPrintf("native-code: '%s'\n", arch->data()));
-      architectures.erase(arch);
+    if (arch != architectures_from_apk.end()) {
+      architectures_.architectures.insert(*arch);
+      architectures_from_apk.erase(arch);
       output_alt_native_code = true;
     }
   }
-
-  if (architectures.size() > 0) {
+  for (auto& arch : architectures_from_apk) {
     if (output_alt_native_code) {
-      printer->Print("alt-");
+      architectures_.alt_architectures.insert(arch);
+    } else {
+      architectures_.architectures.insert(arch);
     }
-    printer->Print("native-code:");
-    for (auto& arch : architectures) {
-      printer->Print(StringPrintf(" '%s'", arch.data()));
-    }
-    printer->Print("\n");
+  }
+  return true;
+}
+
+bool ManifestExtractor::Dump(text::Printer* printer) {
+  Print(root_element_.get(), printer);
+  if (options_.only_permissions) {
+    return true;
   }
 
+  for (auto& implied_permission : implied_permissions_) {
+    implied_permission->Print(printer);
+  }
+  for (auto& feature_group : feature_groups_) {
+    feature_group->PrintGroup(printer);
+  }
+  components_.Print(printer);
+  supports_screen_->PrintScreens(printer, target_sdk_);
+
+  // Print all the unique locales of the apk
+  printer->Print("locales:");
+  for (auto& config : locales_) {
+    if (config.first.empty()) {
+      printer->Print(" '--_--'");
+    } else {
+      printer->Print(StringPrintf(" '%s'", config.first.data()));
+    }
+  }
+  printer->Print("\n");
+
+  // Print all the densities locales of the apk
+  printer->Print("densities:");
+  for (auto& config : densities_) {
+    printer->Print(StringPrintf(" '%d'", config.first));
+  }
+  printer->Print("\n");
+
+  architectures_.Print(printer);
+  return true;
+}
+
+bool ManifestExtractor::DumpProto(pb::Badging* out_badging) {
+  ToProto(root_element_.get(), out_badging);
+  for (auto& implied_permission : implied_permissions_) {
+    implied_permission->ToProto(out_badging);
+  }
+  for (auto& feature_group : feature_groups_) {
+    feature_group->GroupToProto(out_badging);
+  }
+  components_.ToProto(out_badging);
+  supports_screen_->ToProtoScreens(out_badging, target_sdk_);
+
+  for (auto& config : locales_) {
+    if (!config.first.empty()) {
+      out_badging->add_locales(config.first);
+    }
+  }
+  for (auto& config : densities_) {
+    out_badging->add_densities(config.first);
+  }
+
+  architectures_.ToProto(out_badging);
   return true;
 }
 
@@ -2527,11 +2992,23 @@
   return element;
 }
 
-
 int DumpManifest(LoadedApk* apk, DumpManifestOptions& options, text::Printer* printer,
                  IDiagnostics* diag) {
   ManifestExtractor extractor(apk, options);
-  return extractor.Dump(printer, diag) ? 0 : 1;
+  if (!extractor.Extract(diag)) {
+    return 1;
+  }
+  return extractor.Dump(printer) ? 0 : 1;
+}
+
+int DumpBadgingProto(LoadedApk* apk, pb::Badging* out_badging, IDiagnostics* diag) {
+  DumpManifestOptions options{/* include_meta_data= */ true,
+                              /* only_permissions= */ false};
+  ManifestExtractor extractor(apk, options);
+  if (!extractor.Extract(diag)) {
+    return 1;
+  }
+  return extractor.DumpProto(out_badging) ? 0 : 1;
 }
 
 } // namespace aapt
diff --git a/tools/aapt2/dump/DumpManifest.h b/tools/aapt2/dump/DumpManifest.h
index daf22ed..72d1b46 100644
--- a/tools/aapt2/dump/DumpManifest.h
+++ b/tools/aapt2/dump/DumpManifest.h
@@ -17,6 +17,7 @@
 #ifndef AAPT2_DUMP_MANIFEST_H
 #define AAPT2_DUMP_MANIFEST_H
 
+#include "ApkInfo.pb.h"
 #include "Diagnostics.h"
 #include "LoadedApk.h"
 #include "text/Printer.h"
@@ -34,6 +35,9 @@
 int DumpManifest(LoadedApk* apk, DumpManifestOptions& options, text::Printer* printer,
                  IDiagnostics* diag);
 
+/** Extracts badging data from the manifest of the APK and stores it in Badging proto. */
+int DumpBadgingProto(LoadedApk* apk, pb::Badging* out_badging, IDiagnostics* diag);
+
 }  // namespace aapt
 
 #endif  // AAPT2_DUMP_MANIFEST_H
\ No newline at end of file
diff --git a/tools/aapt2/integration-tests/DumpTest/components.apk b/tools/aapt2/integration-tests/DumpTest/components.apk
new file mode 100644
index 0000000..deb55ea
--- /dev/null
+++ b/tools/aapt2/integration-tests/DumpTest/components.apk
Binary files differ
diff --git a/tools/aapt2/integration-tests/DumpTest/components_expected.txt b/tools/aapt2/integration-tests/DumpTest/components_expected.txt
new file mode 100644
index 0000000..79b6706
--- /dev/null
+++ b/tools/aapt2/integration-tests/DumpTest/components_expected.txt
@@ -0,0 +1,56 @@
+package: name='com.example.bundletool.minimal' versionCode='1' versionName='1.0' platformBuildVersionName='12' platformBuildVersionCode='31' compileSdkVersion='31' compileSdkVersionCodename='12'
+sdkVersion:'21'
+targetSdkVersion:'31'
+uses-configuration: reqTouchScreen='3' reqKeyboardType='2' reqHardKeyboard='-1' reqNavigation='3' reqFiveWayNav='-1'
+supports-gl-texture:'GL_OES_compressed_paletted_texture'
+uses-permission: name='android.permission.BIND_ACCESSIBILITY_SERVICE' maxSdkVersion='24'
+uses-permission-sdk-23: name='android.permission.RECEIVE_SMS'
+uses-permission: name='android.permission.WRITE_EXTERNAL_STORAGE'
+compatible-screens:'500/240','400/160'
+application-label:'minimal'
+application-icon-160:'res/uF.xml'
+application-icon-240:'res/uF.xml'
+application-icon-320:'res/uF.xml'
+application-icon-480:'res/uF.xml'
+application-icon-640:'res/uF.xml'
+application-icon-65534:'res/uF.xml'
+application: label='minimal' icon='res/uF.xml'
+uses-library:'mylib1'
+uses-library-not-required:'my_optional_lib'
+uses-native-library:'native1'
+uses-native-library-not-required:'optional'
+launchable-activity: name='com.example.bundletool.minimal.MainActivity'  label='minimal' icon=''
+meta-data: name='android.nfc.cardemulation.host_apdu_service' resource='res/dU.xml'
+uses-permission: name='android.permission.READ_EXTERNAL_STORAGE'
+uses-implied-permission: name='android.permission.READ_EXTERNAL_STORAGE' reason='requested WRITE_EXTERNAL_STORAGE'
+feature-group: label=''
+  uses-feature: name='android.hardware.bluetooth'
+  uses-feature: name='android.hardware.camera'
+  uses-feature: name='android.hardware.faketouch'
+  uses-implied-feature: name='android.hardware.faketouch' reason='default feature for all apps'
+  uses-feature-sdk-23: name='android.hardware.telephony'
+  uses-implied-feature-sdk-23: name='android.hardware.telephony' reason='requested a telephony permission'
+provides-component:'app-widget'
+provides-component:'device-admin'
+provides-component:'ime'
+provides-component:'wallpaper'
+provides-component:'accessibility'
+provides-component:'print-service'
+provides-component:'search'
+provides-component:'document-provider'
+provides-component:'notification-listener'
+provides-component:'dream'
+provides-component:'camera'
+provides-component:'camera-secure'
+main
+other-receivers
+other-services
+supports-screens: 'normal' 'large' 'xlarge'
+supports-any-density: 'true'
+requires-smallest-width:'240'
+compatible-width-limit:'360'
+largest-width-limit:'480'
+locales: '--_--'
+densities: '160' '240' '320' '480' '640' '65534'
+native-code: 'x86_64'
+alt-native-code: 'x86'
diff --git a/tools/aapt2/integration-tests/DumpTest/components_expected_proto.txt b/tools/aapt2/integration-tests/DumpTest/components_expected_proto.txt
new file mode 100644
index 0000000..7756410
--- /dev/null
+++ b/tools/aapt2/integration-tests/DumpTest/components_expected_proto.txt
@@ -0,0 +1,165 @@
+badging {
+  package {
+    package: "com.example.bundletool.minimal"
+    version_code: 1
+    version_name: "1.0"
+    platform_version_name: "12"
+    platform_version_code: "31"
+    compile_sdk_version: 31
+    compile_sdk_version_codename: "12"
+  }
+  application {
+    label: "minimal"
+    icon: "res/uF.xml"
+    density_icons {
+      key: 160
+      value: "res/uF.xml"
+    }
+    density_icons {
+      key: 240
+      value: "res/uF.xml"
+    }
+    density_icons {
+      key: 320
+      value: "res/uF.xml"
+    }
+    density_icons {
+      key: 480
+      value: "res/uF.xml"
+    }
+    density_icons {
+      key: 640
+      value: "res/uF.xml"
+    }
+    density_icons {
+      key: 65534
+      value: "res/uF.xml"
+    }
+  }
+  uses_sdk {
+    min_sdk_version: 21
+    target_sdk_version: 31
+  }
+  uses_configuration {
+    req_touch_screen: 3
+    req_keyboard_type: 2
+    req_hard_keyboard: -1
+    req_navigation: 3
+    req_five_way_nav: -1
+  }
+  supports_screen {
+    screens: NORMAL
+    screens: LARGE
+    screens: XLARGE
+    supports_any_densities: true
+    requires_smallest_width_dp: 240
+    compatible_width_limit_dp: 360
+    largest_width_limit_dp: 480
+  }
+  launchable_activity {
+    name: "com.example.bundletool.minimal.MainActivity"
+    label: "minimal"
+  }
+  compatible_screens {
+    screens {
+      size: 500
+      density: 240
+    }
+    screens {
+      size: 400
+      density: 160
+    }
+  }
+  architectures {
+    architectures: "x86_64"
+    alt_architectures: "x86"
+  }
+  supports_gl_texture {
+    name: "GL_OES_compressed_paletted_texture"
+  }
+  components {
+    main: true
+    other_receivers: true
+    other_services: true
+    provided_components: "app-widget"
+    provided_components: "device-admin"
+    provided_components: "ime"
+    provided_components: "wallpaper"
+    provided_components: "accessibility"
+    provided_components: "print-service"
+    provided_components: "search"
+    provided_components: "document-provider"
+    provided_components: "notification-listener"
+    provided_components: "dream"
+    provided_components: "camera"
+    provided_components: "camera-secure"
+  }
+  densities: 160
+  densities: 240
+  densities: 320
+  densities: 480
+  densities: 640
+  densities: 65534
+  feature_groups {
+    features {
+      name: "android.hardware.bluetooth"
+      required: true
+    }
+    features {
+      name: "android.hardware.camera"
+      required: true
+    }
+    features {
+      name: "android.hardware.faketouch"
+      implied_data {
+        reasons: "default feature for all apps"
+      }
+    }
+    features {
+      name: "android.hardware.telephony"
+      implied_data {
+        from_sdk_23_permission: true
+        reasons: "requested a telephony permission"
+      }
+    }
+  }
+  uses_permissions {
+    name: "android.permission.BIND_ACCESSIBILITY_SERVICE"
+    max_sdk_version: 24
+    required: true
+  }
+  uses_permissions {
+    name: "android.permission.RECEIVE_SMS"
+    sdk23_and_above: true
+  }
+  uses_permissions {
+    name: "android.permission.WRITE_EXTERNAL_STORAGE"
+    required: true
+  }
+  uses_permissions {
+    name: "android.permission.READ_EXTERNAL_STORAGE"
+    required: true
+    implied: true
+  }
+  permissions {
+    name: "minimal.FIRST_PERMISSION"
+  }
+  uses_libraries {
+    name: "mylib1"
+    required: true
+  }
+  uses_libraries {
+    name: "my_optional_lib"
+  }
+  uses_native_libraries {
+    name: "native1"
+    required: true
+  }
+  uses_native_libraries {
+    name: "optional"
+  }
+  metadata {
+    name: "android.nfc.cardemulation.host_apdu_service"
+    resource_string: "res/dU.xml"
+  }
+}
diff --git a/tools/aapt2/integration-tests/DumpTest/components_full_proto.txt b/tools/aapt2/integration-tests/DumpTest/components_full_proto.txt
new file mode 100644
index 0000000..bd76736
--- /dev/null
+++ b/tools/aapt2/integration-tests/DumpTest/components_full_proto.txt
@@ -0,0 +1,2310 @@
+badging {
+  package {
+    package: "com.example.bundletool.minimal"
+    version_code: 1
+    version_name: "1.0"
+    platform_version_name: "12"
+    platform_version_code: "31"
+    compile_sdk_version: 31
+    compile_sdk_version_codename: "12"
+  }
+  application {
+    label: "minimal"
+    icon: "res/uF.xml"
+    density_icons {
+      key: 160
+      value: "res/uF.xml"
+    }
+    density_icons {
+      key: 240
+      value: "res/uF.xml"
+    }
+    density_icons {
+      key: 320
+      value: "res/uF.xml"
+    }
+    density_icons {
+      key: 480
+      value: "res/uF.xml"
+    }
+    density_icons {
+      key: 640
+      value: "res/uF.xml"
+    }
+    density_icons {
+      key: 65534
+      value: "res/uF.xml"
+    }
+  }
+  uses_sdk {
+    min_sdk_version: 21
+    target_sdk_version: 31
+  }
+  uses_configuration {
+    req_touch_screen: 3
+    req_keyboard_type: 2
+    req_hard_keyboard: -1
+    req_navigation: 3
+    req_five_way_nav: -1
+  }
+  supports_screen {
+    screens: NORMAL
+    screens: LARGE
+    screens: XLARGE
+    supports_any_densities: true
+    requires_smallest_width_dp: 240
+    compatible_width_limit_dp: 360
+    largest_width_limit_dp: 480
+  }
+  launchable_activity {
+    name: "com.example.bundletool.minimal.MainActivity"
+    label: "minimal"
+  }
+  compatible_screens {
+    screens {
+      size: 500
+      density: 240
+    }
+    screens {
+      size: 400
+      density: 160
+    }
+  }
+  architectures {
+    architectures: "x86_64"
+    alt_architectures: "x86"
+  }
+  supports_gl_texture {
+    name: "GL_OES_compressed_paletted_texture"
+  }
+  components {
+    main: true
+    other_receivers: true
+    other_services: true
+    provided_components: "app-widget"
+    provided_components: "device-admin"
+    provided_components: "ime"
+    provided_components: "wallpaper"
+    provided_components: "accessibility"
+    provided_components: "print-service"
+    provided_components: "search"
+    provided_components: "document-provider"
+    provided_components: "notification-listener"
+    provided_components: "dream"
+    provided_components: "camera"
+    provided_components: "camera-secure"
+  }
+  densities: 160
+  densities: 240
+  densities: 320
+  densities: 480
+  densities: 640
+  densities: 65534
+  feature_groups {
+    features {
+      name: "android.hardware.bluetooth"
+      required: true
+    }
+    features {
+      name: "android.hardware.camera"
+      required: true
+    }
+    features {
+      name: "android.hardware.faketouch"
+      implied_data {
+        reasons: "default feature for all apps"
+      }
+    }
+    features {
+      name: "android.hardware.telephony"
+      implied_data {
+        from_sdk_23_permission: true
+        reasons: "requested a telephony permission"
+      }
+    }
+  }
+  uses_permissions {
+    name: "android.permission.BIND_ACCESSIBILITY_SERVICE"
+    max_sdk_version: 24
+    required: true
+  }
+  uses_permissions {
+    name: "android.permission.RECEIVE_SMS"
+    sdk23_and_above: true
+  }
+  uses_permissions {
+    name: "android.permission.WRITE_EXTERNAL_STORAGE"
+    required: true
+  }
+  uses_permissions {
+    name: "android.permission.READ_EXTERNAL_STORAGE"
+    required: true
+    implied: true
+  }
+  permissions {
+    name: "minimal.FIRST_PERMISSION"
+  }
+  uses_libraries {
+    name: "mylib1"
+    required: true
+  }
+  uses_libraries {
+    name: "my_optional_lib"
+  }
+  uses_native_libraries {
+    name: "native1"
+    required: true
+  }
+  uses_native_libraries {
+    name: "optional"
+  }
+  metadata {
+    name: "android.nfc.cardemulation.host_apdu_service"
+    resource_string: "res/dU.xml"
+  }
+}
+resource_table {
+  source_pool {
+    data: "\001\000\034\000$\000\000\000\001\000\000\000\000\000\000\000\000\001\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
+  }
+  package {
+    package_id {
+      id: 127
+    }
+    package_name: "com.example.bundletool.minimal"
+    type {
+      type_id {
+        id: 1
+      }
+      name: "color"
+      entry {
+        entry_id {
+        }
+        name: "black"
+        visibility {
+          source {
+          }
+        }
+        config_value {
+          config {
+          }
+          value {
+            source {
+            }
+            item {
+              prim {
+                color_argb8_value: 4278190080
+              }
+            }
+          }
+        }
+      }
+      entry {
+        entry_id {
+          id: 1
+        }
+        name: "purple_200"
+        visibility {
+          source {
+          }
+        }
+        config_value {
+          config {
+          }
+          value {
+            source {
+            }
+            item {
+              prim {
+                color_argb8_value: 4290479868
+              }
+            }
+          }
+        }
+      }
+      entry {
+        entry_id {
+          id: 2
+        }
+        name: "purple_500"
+        visibility {
+          source {
+          }
+        }
+        config_value {
+          config {
+          }
+          value {
+            source {
+            }
+            item {
+              prim {
+                color_argb8_value: 4284612846
+              }
+            }
+          }
+        }
+      }
+      entry {
+        entry_id {
+          id: 3
+        }
+        name: "purple_700"
+        visibility {
+          source {
+          }
+        }
+        config_value {
+          config {
+          }
+          value {
+            source {
+            }
+            item {
+              prim {
+                color_argb8_value: 4281794739
+              }
+            }
+          }
+        }
+      }
+      entry {
+        entry_id {
+          id: 4
+        }
+        name: "teal_200"
+        visibility {
+          source {
+          }
+        }
+        config_value {
+          config {
+          }
+          value {
+            source {
+            }
+            item {
+              prim {
+                color_argb8_value: 4278442693
+              }
+            }
+          }
+        }
+      }
+      entry {
+        entry_id {
+          id: 5
+        }
+        name: "teal_700"
+        visibility {
+          source {
+          }
+        }
+        config_value {
+          config {
+          }
+          value {
+            source {
+            }
+            item {
+              prim {
+                color_argb8_value: 4278290310
+              }
+            }
+          }
+        }
+      }
+      entry {
+        entry_id {
+          id: 6
+        }
+        name: "white"
+        visibility {
+          source {
+          }
+        }
+        config_value {
+          config {
+          }
+          value {
+            source {
+            }
+            item {
+              prim {
+                color_argb8_value: 4294967295
+              }
+            }
+          }
+        }
+      }
+    }
+    type {
+      type_id {
+        id: 2
+      }
+      name: "dimen"
+      entry {
+        entry_id {
+        }
+        name: "fab_margin"
+        visibility {
+          source {
+          }
+        }
+        config_value {
+          config {
+          }
+          value {
+            source {
+            }
+            item {
+              prim {
+                dimension_value: 4097
+              }
+            }
+          }
+        }
+      }
+    }
+    type {
+      type_id {
+        id: 3
+      }
+      name: "drawable"
+      entry {
+        entry_id {
+        }
+        name: "$ic_launcher_foreground__0"
+        visibility {
+          source {
+          }
+        }
+        config_value {
+          config {
+            density: 65534
+            sdk_version: 24
+          }
+          value {
+            source {
+            }
+            item {
+              file {
+                path: "res/Za.xml"
+                type: BINARY_XML
+              }
+            }
+          }
+        }
+      }
+      entry {
+        entry_id {
+          id: 1
+        }
+        name: "ic_launcher_background"
+        visibility {
+          source {
+          }
+        }
+        config_value {
+          config {
+          }
+          value {
+            source {
+            }
+            item {
+              file {
+                path: "res/3N.xml"
+                type: BINARY_XML
+              }
+            }
+          }
+        }
+      }
+      entry {
+        entry_id {
+          id: 2
+        }
+        name: "ic_launcher_foreground"
+        visibility {
+          source {
+          }
+        }
+        config_value {
+          config {
+            density: 65534
+            sdk_version: 24
+          }
+          value {
+            source {
+            }
+            item {
+              file {
+                path: "res/qm.xml"
+                type: BINARY_XML
+              }
+            }
+          }
+        }
+      }
+    }
+    type {
+      type_id {
+        id: 4
+      }
+      name: "mipmap"
+      entry {
+        entry_id {
+        }
+        name: "ic_launcher"
+        visibility {
+          source {
+          }
+        }
+        config_value {
+          config {
+            density: 160
+          }
+          value {
+            source {
+            }
+            item {
+              file {
+                path: "res/u3.png"
+                type: PNG
+              }
+            }
+          }
+        }
+        config_value {
+          config {
+            density: 240
+          }
+          value {
+            source {
+            }
+            item {
+              file {
+                path: "res/SD.png"
+                type: PNG
+              }
+            }
+          }
+        }
+        config_value {
+          config {
+            density: 320
+          }
+          value {
+            source {
+            }
+            item {
+              file {
+                path: "res/jy.png"
+                type: PNG
+              }
+            }
+          }
+        }
+        config_value {
+          config {
+            density: 480
+          }
+          value {
+            source {
+            }
+            item {
+              file {
+                path: "res/D2.png"
+                type: PNG
+              }
+            }
+          }
+        }
+        config_value {
+          config {
+            density: 640
+          }
+          value {
+            source {
+            }
+            item {
+              file {
+                path: "res/CG.png"
+                type: PNG
+              }
+            }
+          }
+        }
+        config_value {
+          config {
+            density: 65534
+            sdk_version: 26
+          }
+          value {
+            source {
+            }
+            item {
+              file {
+                path: "res/uF.xml"
+                type: BINARY_XML
+              }
+            }
+          }
+        }
+      }
+      entry {
+        entry_id {
+          id: 1
+        }
+        name: "ic_launcher_round"
+        visibility {
+          source {
+          }
+        }
+        config_value {
+          config {
+            density: 160
+          }
+          value {
+            source {
+            }
+            item {
+              file {
+                path: "res/7c.png"
+                type: PNG
+              }
+            }
+          }
+        }
+        config_value {
+          config {
+            density: 240
+          }
+          value {
+            source {
+            }
+            item {
+              file {
+                path: "res/tf.png"
+                type: PNG
+              }
+            }
+          }
+        }
+        config_value {
+          config {
+            density: 320
+          }
+          value {
+            source {
+            }
+            item {
+              file {
+                path: "res/1S.png"
+                type: PNG
+              }
+            }
+          }
+        }
+        config_value {
+          config {
+            density: 480
+          }
+          value {
+            source {
+            }
+            item {
+              file {
+                path: "res/5Q.png"
+                type: PNG
+              }
+            }
+          }
+        }
+        config_value {
+          config {
+            density: 640
+          }
+          value {
+            source {
+            }
+            item {
+              file {
+                path: "res/C9.png"
+                type: PNG
+              }
+            }
+          }
+        }
+        config_value {
+          config {
+            density: 65534
+            sdk_version: 26
+          }
+          value {
+            source {
+            }
+            item {
+              file {
+                path: "res/oy.xml"
+                type: BINARY_XML
+              }
+            }
+          }
+        }
+      }
+    }
+    type {
+      type_id {
+        id: 5
+      }
+      name: "string"
+      entry {
+        entry_id {
+        }
+        name: "action_settings"
+        visibility {
+          source {
+          }
+        }
+        config_value {
+          config {
+          }
+          value {
+            source {
+            }
+            item {
+              str {
+                value: "Settings"
+              }
+            }
+          }
+        }
+      }
+      entry {
+        entry_id {
+          id: 1
+        }
+        name: "app_name"
+        visibility {
+          source {
+          }
+        }
+        config_value {
+          config {
+          }
+          value {
+            source {
+            }
+            item {
+              str {
+                value: "minimal"
+              }
+            }
+          }
+        }
+      }
+      entry {
+        entry_id {
+          id: 2
+        }
+        name: "first_fragment_label"
+        visibility {
+          source {
+          }
+        }
+        config_value {
+          config {
+          }
+          value {
+            source {
+            }
+            item {
+              str {
+                value: "First Fragment"
+              }
+            }
+          }
+        }
+      }
+      entry {
+        entry_id {
+          id: 3
+        }
+        name: "hello_first_fragment"
+        visibility {
+          source {
+          }
+        }
+        config_value {
+          config {
+          }
+          value {
+            source {
+            }
+            item {
+              str {
+                value: "Hello first fragment"
+              }
+            }
+          }
+        }
+      }
+      entry {
+        entry_id {
+          id: 4
+        }
+        name: "hello_second_fragment"
+        visibility {
+          source {
+          }
+        }
+        config_value {
+          config {
+          }
+          value {
+            source {
+            }
+            item {
+              str {
+                value: "Hello second fragment. Arg: %1$s"
+              }
+            }
+          }
+        }
+      }
+      entry {
+        entry_id {
+          id: 5
+        }
+        name: "next"
+        visibility {
+          source {
+          }
+        }
+        config_value {
+          config {
+          }
+          value {
+            source {
+            }
+            item {
+              str {
+                value: "Next"
+              }
+            }
+          }
+        }
+      }
+      entry {
+        entry_id {
+          id: 6
+        }
+        name: "previous"
+        visibility {
+          source {
+          }
+        }
+        config_value {
+          config {
+          }
+          value {
+            source {
+            }
+            item {
+              str {
+                value: "Previous"
+              }
+            }
+          }
+        }
+      }
+      entry {
+        entry_id {
+          id: 7
+        }
+        name: "second_fragment_label"
+        visibility {
+          source {
+          }
+        }
+        config_value {
+          config {
+          }
+          value {
+            source {
+            }
+            item {
+              str {
+                value: "Second Fragment"
+              }
+            }
+          }
+        }
+      }
+    }
+    type {
+      type_id {
+        id: 6
+      }
+      name: "xml"
+      entry {
+        entry_id {
+        }
+        name: "apduservice"
+        visibility {
+          source {
+          }
+        }
+        config_value {
+          config {
+          }
+          value {
+            source {
+            }
+            item {
+              file {
+                path: "res/dU.xml"
+                type: BINARY_XML
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  tool_fingerprint {
+    tool: "Android Asset Packaging Tool (aapt)"
+    version: "2.19-SOONG BUILD NUMBER PLACEHOLDER"
+  }
+}
+xml_files {
+  path: "res/oy.xml"
+  root {
+    element {
+      namespace_declaration {
+        prefix: "android"
+        uri: "http://schemas.android.com/apk/res/android"
+        source {
+          line_number: 2
+        }
+      }
+      name: "adaptive-icon"
+      child {
+        element {
+          name: "background"
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "drawable"
+            source {
+            }
+            resource_id: 16843161
+            compiled_item {
+              ref {
+                id: 2130903041
+              }
+            }
+          }
+        }
+        source {
+          line_number: 3
+        }
+      }
+      child {
+        element {
+          name: "foreground"
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "drawable"
+            source {
+            }
+            resource_id: 16843161
+            compiled_item {
+              ref {
+                id: 2130903042
+              }
+            }
+          }
+        }
+        source {
+          line_number: 4
+        }
+      }
+    }
+    source {
+      line_number: 2
+    }
+  }
+}
+xml_files {
+  path: "AndroidManifest.xml"
+  root {
+    element {
+      namespace_declaration {
+        prefix: "android"
+        uri: "http://schemas.android.com/apk/res/android"
+        source {
+          line_number: 2
+        }
+      }
+      name: "manifest"
+      attribute {
+        namespace_uri: "http://schemas.android.com/apk/res/android"
+        name: "versionCode"
+        source {
+        }
+        resource_id: 16843291
+        compiled_item {
+          prim {
+            int_decimal_value: 1
+          }
+        }
+      }
+      attribute {
+        namespace_uri: "http://schemas.android.com/apk/res/android"
+        name: "versionName"
+        value: "1.0"
+        resource_id: 16843292
+      }
+      attribute {
+        namespace_uri: "http://schemas.android.com/apk/res/android"
+        name: "compileSdkVersion"
+        source {
+        }
+        resource_id: 16844146
+        compiled_item {
+          prim {
+            int_decimal_value: 31
+          }
+        }
+      }
+      attribute {
+        namespace_uri: "http://schemas.android.com/apk/res/android"
+        name: "compileSdkVersionCodename"
+        value: "12"
+        resource_id: 16844147
+      }
+      attribute {
+        name: "package"
+        value: "com.example.bundletool.minimal"
+      }
+      attribute {
+        name: "platformBuildVersionCode"
+        source {
+        }
+        compiled_item {
+          prim {
+            int_decimal_value: 31
+          }
+        }
+      }
+      attribute {
+        name: "platformBuildVersionName"
+        source {
+        }
+        compiled_item {
+          prim {
+            int_decimal_value: 12
+          }
+        }
+      }
+      child {
+        element {
+          name: "uses-sdk"
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "minSdkVersion"
+            source {
+            }
+            resource_id: 16843276
+            compiled_item {
+              prim {
+                int_decimal_value: 21
+              }
+            }
+          }
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "targetSdkVersion"
+            source {
+            }
+            resource_id: 16843376
+            compiled_item {
+              prim {
+                int_decimal_value: 31
+              }
+            }
+          }
+        }
+        source {
+          line_number: 7
+        }
+      }
+      child {
+        element {
+          name: "supports-screens"
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "anyDensity"
+            source {
+            }
+            resource_id: 16843372
+            compiled_item {
+              prim {
+                boolean_value: true
+              }
+            }
+          }
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "smallScreens"
+            source {
+            }
+            resource_id: 16843396
+            compiled_item {
+              prim {
+                boolean_value: false
+              }
+            }
+          }
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "normalScreens"
+            source {
+            }
+            resource_id: 16843397
+            compiled_item {
+              prim {
+                boolean_value: true
+              }
+            }
+          }
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "largeScreens"
+            source {
+            }
+            resource_id: 16843398
+            compiled_item {
+              prim {
+                boolean_value: true
+              }
+            }
+          }
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "requiresSmallestWidthDp"
+            source {
+            }
+            resource_id: 16843620
+            compiled_item {
+              prim {
+                int_decimal_value: 240
+              }
+            }
+          }
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "compatibleWidthLimitDp"
+            source {
+            }
+            resource_id: 16843621
+            compiled_item {
+              prim {
+                int_decimal_value: 360
+              }
+            }
+          }
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "largestWidthLimitDp"
+            source {
+            }
+            resource_id: 16843622
+            compiled_item {
+              prim {
+                int_decimal_value: 480
+              }
+            }
+          }
+        }
+        source {
+          line_number: 11
+        }
+      }
+      child {
+        element {
+          name: "uses-configuration"
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "reqTouchScreen"
+            source {
+            }
+            resource_id: 16843303
+            compiled_item {
+              prim {
+                int_decimal_value: 3
+              }
+            }
+          }
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "reqKeyboardType"
+            source {
+            }
+            resource_id: 16843304
+            compiled_item {
+              prim {
+                int_decimal_value: 2
+              }
+            }
+          }
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "reqHardKeyboard"
+            source {
+            }
+            resource_id: 16843305
+            compiled_item {
+              prim {
+                boolean_value: true
+              }
+            }
+          }
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "reqNavigation"
+            source {
+            }
+            resource_id: 16843306
+            compiled_item {
+              prim {
+                int_decimal_value: 3
+              }
+            }
+          }
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "reqFiveWayNav"
+            source {
+            }
+            resource_id: 16843314
+            compiled_item {
+              prim {
+                boolean_value: true
+              }
+            }
+          }
+        }
+        source {
+          line_number: 20
+        }
+      }
+      child {
+        element {
+          name: "supports-gl-texture"
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "name"
+            value: "GL_OES_compressed_paletted_texture"
+            resource_id: 16842755
+          }
+        }
+        source {
+          line_number: 27
+        }
+      }
+      child {
+        element {
+          name: "permission"
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "name"
+            value: "minimal.FIRST_PERMISSION"
+            resource_id: 16842755
+          }
+        }
+        source {
+          line_number: 29
+        }
+      }
+      child {
+        element {
+          name: "uses-feature"
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "name"
+            value: "android.hardware.camera"
+            resource_id: 16842755
+          }
+        }
+        source {
+          line_number: 31
+        }
+      }
+      child {
+        element {
+          name: "uses-feature"
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "name"
+            value: "android.hardware.bluetooth"
+            resource_id: 16842755
+          }
+        }
+        source {
+          line_number: 32
+        }
+      }
+      child {
+        element {
+          name: "uses-permission"
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "name"
+            value: "android.permission.BIND_ACCESSIBILITY_SERVICE"
+            resource_id: 16842755
+          }
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "maxSdkVersion"
+            source {
+            }
+            resource_id: 16843377
+            compiled_item {
+              prim {
+                int_decimal_value: 24
+              }
+            }
+          }
+        }
+        source {
+          line_number: 34
+        }
+      }
+      child {
+        element {
+          name: "uses-permission-sdk-23"
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "name"
+            value: "android.permission.RECEIVE_SMS"
+            resource_id: 16842755
+          }
+        }
+        source {
+          line_number: 38
+        }
+      }
+      child {
+        element {
+          name: "uses-permission"
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "name"
+            value: "android.permission.WRITE_EXTERNAL_STORAGE"
+            resource_id: 16842755
+          }
+        }
+        source {
+          line_number: 40
+        }
+      }
+      child {
+        element {
+          name: "compatible-screens"
+          child {
+            element {
+              name: "screen"
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "screenSize"
+                source {
+                }
+                resource_id: 16843466
+                compiled_item {
+                  prim {
+                    int_decimal_value: 500
+                  }
+                }
+              }
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "screenDensity"
+                source {
+                }
+                resource_id: 16843467
+                compiled_item {
+                  prim {
+                    int_decimal_value: 240
+                  }
+                }
+              }
+            }
+            source {
+              line_number: 43
+            }
+          }
+          child {
+            element {
+              name: "screen"
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "screenSize"
+                source {
+                }
+                resource_id: 16843466
+                compiled_item {
+                  prim {
+                    int_decimal_value: 400
+                  }
+                }
+              }
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "screenDensity"
+                source {
+                }
+                resource_id: 16843467
+                compiled_item {
+                  prim {
+                    int_decimal_value: 160
+                  }
+                }
+              }
+            }
+            source {
+              line_number: 46
+            }
+          }
+        }
+        source {
+          line_number: 42
+        }
+      }
+      child {
+        element {
+          name: "application"
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "label"
+            source {
+            }
+            resource_id: 16842753
+            compiled_item {
+              ref {
+                id: 2131034113
+              }
+            }
+          }
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "icon"
+            source {
+            }
+            resource_id: 16842754
+            compiled_item {
+              ref {
+                id: 2130968576
+              }
+            }
+          }
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "allowBackup"
+            source {
+            }
+            resource_id: 16843392
+            compiled_item {
+              prim {
+                boolean_value: true
+              }
+            }
+          }
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "supportsRtl"
+            source {
+            }
+            resource_id: 16843695
+            compiled_item {
+              prim {
+                boolean_value: true
+              }
+            }
+          }
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "multiArch"
+            source {
+            }
+            resource_id: 16843918
+            compiled_item {
+              prim {
+                boolean_value: true
+              }
+            }
+          }
+          attribute {
+            namespace_uri: "http://schemas.android.com/apk/res/android"
+            name: "roundIcon"
+            source {
+            }
+            resource_id: 16844076
+            compiled_item {
+              ref {
+                id: 2130968577
+              }
+            }
+          }
+          child {
+            element {
+              name: "uses-library"
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "name"
+                value: "mylib1"
+                resource_id: 16842755
+              }
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "required"
+                source {
+                }
+                resource_id: 16843406
+                compiled_item {
+                  prim {
+                    boolean_value: true
+                  }
+                }
+              }
+            }
+            source {
+              line_number: 58
+            }
+          }
+          child {
+            element {
+              name: "uses-library"
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "name"
+                value: "my_optional_lib"
+                resource_id: 16842755
+              }
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "required"
+                source {
+                }
+                resource_id: 16843406
+                compiled_item {
+                  prim {
+                    boolean_value: false
+                  }
+                }
+              }
+            }
+            source {
+              line_number: 61
+            }
+          }
+          child {
+            element {
+              name: "uses-native-library"
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "name"
+                value: "native1"
+                resource_id: 16842755
+              }
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "required"
+                source {
+                }
+                resource_id: 16843406
+                compiled_item {
+                  prim {
+                    boolean_value: true
+                  }
+                }
+              }
+            }
+            source {
+              line_number: 65
+            }
+          }
+          child {
+            element {
+              name: "uses-native-library"
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "name"
+                value: "optional"
+                resource_id: 16842755
+              }
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "required"
+                source {
+                }
+                resource_id: 16843406
+                compiled_item {
+                  prim {
+                    boolean_value: false
+                  }
+                }
+              }
+            }
+            source {
+              line_number: 68
+            }
+          }
+          child {
+            element {
+              name: "activity"
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "label"
+                source {
+                }
+                resource_id: 16842753
+                compiled_item {
+                  ref {
+                    id: 2131034113
+                  }
+                }
+              }
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "name"
+                value: "com.example.bundletool.minimal.MainActivity"
+                resource_id: 16842755
+              }
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "exported"
+                source {
+                }
+                resource_id: 16842768
+                compiled_item {
+                  prim {
+                    boolean_value: false
+                  }
+                }
+              }
+              child {
+                element {
+                  name: "intent-filter"
+                  child {
+                    element {
+                      name: "action"
+                      attribute {
+                        namespace_uri: "http://schemas.android.com/apk/res/android"
+                        name: "name"
+                        value: "android.intent.action.MAIN"
+                        resource_id: 16842755
+                      }
+                    }
+                    source {
+                      line_number: 77
+                    }
+                  }
+                  child {
+                    element {
+                      name: "category"
+                      attribute {
+                        namespace_uri: "http://schemas.android.com/apk/res/android"
+                        name: "name"
+                        value: "android.intent.category.LAUNCHER"
+                        resource_id: 16842755
+                      }
+                    }
+                    source {
+                      line_number: 79
+                    }
+                  }
+                }
+                source {
+                  line_number: 76
+                }
+              }
+            }
+            source {
+              line_number: 72
+            }
+          }
+          child {
+            element {
+              name: "activity"
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "label"
+                source {
+                }
+                resource_id: 16842753
+                compiled_item {
+                  ref {
+                    id: 2131034113
+                  }
+                }
+              }
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "name"
+                value: "com.example.bundletool.minimal.AnotherActivity"
+                resource_id: 16842755
+              }
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "exported"
+                source {
+                }
+                resource_id: 16842768
+                compiled_item {
+                  prim {
+                    boolean_value: false
+                  }
+                }
+              }
+              child {
+                element {
+                  name: "intent-filter"
+                  child {
+                    element {
+                      name: "action"
+                      attribute {
+                        namespace_uri: "http://schemas.android.com/apk/res/android"
+                        name: "name"
+                        value: "android.intent.action.VIDEO_CAMERA"
+                        resource_id: 16842755
+                      }
+                    }
+                    source {
+                      line_number: 87
+                    }
+                  }
+                  child {
+                    element {
+                      name: "action"
+                      attribute {
+                        namespace_uri: "http://schemas.android.com/apk/res/android"
+                        name: "name"
+                        value: "android.intent.action.STILL_IMAGE_CAMERA_SECURE"
+                        resource_id: 16842755
+                      }
+                    }
+                    source {
+                      line_number: 88
+                    }
+                  }
+                  child {
+                    element {
+                      name: "action"
+                      attribute {
+                        namespace_uri: "http://schemas.android.com/apk/res/android"
+                        name: "name"
+                        value: "android.intent.action.SEARCH"
+                        resource_id: 16842755
+                      }
+                    }
+                    source {
+                      line_number: 89
+                    }
+                  }
+                }
+                source {
+                  line_number: 86
+                }
+              }
+            }
+            source {
+              line_number: 82
+            }
+          }
+          child {
+            element {
+              name: "receiver"
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "name"
+                value: "com.example.bundletool.minimal.OneReceiver"
+                resource_id: 16842755
+              }
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "exported"
+                source {
+                }
+                resource_id: 16842768
+                compiled_item {
+                  prim {
+                    boolean_value: false
+                  }
+                }
+              }
+              child {
+                element {
+                  name: "intent-filter"
+                  child {
+                    element {
+                      name: "action"
+                      attribute {
+                        namespace_uri: "http://schemas.android.com/apk/res/android"
+                        name: "name"
+                        value: "android.appwidget.action.APPWIDGET_UPDATE"
+                        resource_id: 16842755
+                      }
+                    }
+                    source {
+                      line_number: 97
+                    }
+                  }
+                  child {
+                    element {
+                      name: "action"
+                      attribute {
+                        namespace_uri: "http://schemas.android.com/apk/res/android"
+                        name: "name"
+                        value: "android.app.action.DEVICE_ADMIN_ENABLED"
+                        resource_id: 16842755
+                      }
+                    }
+                    source {
+                      line_number: 98
+                    }
+                  }
+                }
+                source {
+                  line_number: 96
+                }
+              }
+            }
+            source {
+              line_number: 93
+            }
+          }
+          child {
+            element {
+              name: "receiver"
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "name"
+                value: "com.example.bundletool.minimal.TwoReceiver"
+                resource_id: 16842755
+              }
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "permission"
+                value: "android.permission.BIND_DEVICE_ADMIN"
+                resource_id: 16842758
+              }
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "exported"
+                source {
+                }
+                resource_id: 16842768
+                compiled_item {
+                  prim {
+                    boolean_value: false
+                  }
+                }
+              }
+              child {
+                element {
+                  name: "intent-filter"
+                  child {
+                    element {
+                      name: "action"
+                      attribute {
+                        namespace_uri: "http://schemas.android.com/apk/res/android"
+                        name: "name"
+                        value: "android.app.action.DEVICE_ADMIN_ENABLED"
+                        resource_id: 16842755
+                      }
+                    }
+                    source {
+                      line_number: 106
+                    }
+                  }
+                }
+                source {
+                  line_number: 105
+                }
+              }
+            }
+            source {
+              line_number: 101
+            }
+          }
+          child {
+            element {
+              name: "receiver"
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "name"
+                value: "com.example.bundletool.minimal.ThreeReceiver"
+                resource_id: 16842755
+              }
+            }
+            source {
+              line_number: 109
+            }
+          }
+          child {
+            element {
+              name: "service"
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "name"
+                value: "com.example.bundletool.minimal.OneService"
+                resource_id: 16842755
+              }
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "exported"
+                source {
+                }
+                resource_id: 16842768
+                compiled_item {
+                  prim {
+                    boolean_value: false
+                  }
+                }
+              }
+              child {
+                element {
+                  name: "intent-filter"
+                  child {
+                    element {
+                      name: "action"
+                      attribute {
+                        namespace_uri: "http://schemas.android.com/apk/res/android"
+                        name: "name"
+                        value: "android.view.InputMethod"
+                        resource_id: 16842755
+                      }
+                    }
+                    source {
+                      line_number: 115
+                    }
+                  }
+                  child {
+                    element {
+                      name: "action"
+                      attribute {
+                        namespace_uri: "http://schemas.android.com/apk/res/android"
+                        name: "name"
+                        value: "android.service.wallpaper.WallpaperService"
+                        resource_id: 16842755
+                      }
+                    }
+                    source {
+                      line_number: 116
+                    }
+                  }
+                }
+                source {
+                  line_number: 114
+                }
+              }
+            }
+            source {
+              line_number: 111
+            }
+          }
+          child {
+            element {
+              name: "service"
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "name"
+                value: "com.example.bundletool.minimal.Services$TwoService"
+                resource_id: 16842755
+              }
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "permission"
+                value: "android.permission.BIND_ACCESSIBILITY_SERVICE"
+                resource_id: 16842758
+              }
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "exported"
+                source {
+                }
+                resource_id: 16842768
+                compiled_item {
+                  prim {
+                    boolean_value: false
+                  }
+                }
+              }
+              child {
+                element {
+                  name: "intent-filter"
+                  child {
+                    element {
+                      name: "action"
+                      attribute {
+                        namespace_uri: "http://schemas.android.com/apk/res/android"
+                        name: "name"
+                        value: "android.accessibilityservice.AccessibilityService"
+                        resource_id: 16842755
+                      }
+                    }
+                    source {
+                      line_number: 124
+                    }
+                  }
+                }
+                source {
+                  line_number: 123
+                }
+              }
+            }
+            source {
+              line_number: 119
+            }
+          }
+          child {
+            element {
+              name: "service"
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "name"
+                value: "com.example.bundletool.minimal.Services$ThreeService"
+                resource_id: 16842755
+              }
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "permission"
+                value: "android.permission.BIND_PRINT_SERVICE"
+                resource_id: 16842758
+              }
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "exported"
+                source {
+                }
+                resource_id: 16842768
+                compiled_item {
+                  prim {
+                    boolean_value: false
+                  }
+                }
+              }
+              child {
+                element {
+                  name: "intent-filter"
+                  child {
+                    element {
+                      name: "action"
+                      attribute {
+                        namespace_uri: "http://schemas.android.com/apk/res/android"
+                        name: "name"
+                        value: "android.printservice.PrintService"
+                        resource_id: 16842755
+                      }
+                    }
+                    source {
+                      line_number: 132
+                    }
+                  }
+                }
+                source {
+                  line_number: 131
+                }
+              }
+            }
+            source {
+              line_number: 127
+            }
+          }
+          child {
+            element {
+              name: "service"
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "name"
+                value: "com.example.bundletool.minimal.Services$FourService"
+                resource_id: 16842755
+              }
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "permission"
+                value: "android.permission.BIND_NFC_SERVICE"
+                resource_id: 16842758
+              }
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "exported"
+                source {
+                }
+                resource_id: 16842768
+                compiled_item {
+                  prim {
+                    boolean_value: false
+                  }
+                }
+              }
+              child {
+                element {
+                  name: "intent-filter"
+                  child {
+                    element {
+                      name: "action"
+                      attribute {
+                        namespace_uri: "http://schemas.android.com/apk/res/android"
+                        name: "name"
+                        value: "android.nfc.cardemulation.action.HOST_APDU_SERVICE"
+                        resource_id: 16842755
+                      }
+                    }
+                    source {
+                      line_number: 140
+                    }
+                  }
+                }
+                source {
+                  line_number: 139
+                }
+              }
+              child {
+                element {
+                  name: "meta-data"
+                  attribute {
+                    namespace_uri: "http://schemas.android.com/apk/res/android"
+                    name: "name"
+                    value: "android.nfc.cardemulation.host_apdu_service"
+                    resource_id: 16842755
+                  }
+                  attribute {
+                    namespace_uri: "http://schemas.android.com/apk/res/android"
+                    name: "resource"
+                    source {
+                    }
+                    resource_id: 16842789
+                    compiled_item {
+                      ref {
+                        id: 2131099648
+                      }
+                    }
+                  }
+                }
+                source {
+                  line_number: 143
+                }
+              }
+            }
+            source {
+              line_number: 135
+            }
+          }
+          child {
+            element {
+              name: "service"
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "name"
+                value: "com.example.bundletool.minimal.Services$FiveService"
+                resource_id: 16842755
+              }
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "permission"
+                value: "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
+                resource_id: 16842758
+              }
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "exported"
+                source {
+                }
+                resource_id: 16842768
+                compiled_item {
+                  prim {
+                    boolean_value: false
+                  }
+                }
+              }
+              child {
+                element {
+                  name: "intent-filter"
+                  child {
+                    element {
+                      name: "action"
+                      attribute {
+                        namespace_uri: "http://schemas.android.com/apk/res/android"
+                        name: "name"
+                        value: "android.service.notification.NotificationListenerService"
+                        resource_id: 16842755
+                      }
+                    }
+                    source {
+                      line_number: 152
+                    }
+                  }
+                }
+                source {
+                  line_number: 151
+                }
+              }
+            }
+            source {
+              line_number: 147
+            }
+          }
+          child {
+            element {
+              name: "service"
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "name"
+                value: "com.example.bundletool.minimal.Services$SixService"
+                resource_id: 16842755
+              }
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "permission"
+                value: "android.permission.BIND_DREAM_SERVICE"
+                resource_id: 16842758
+              }
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "exported"
+                source {
+                }
+                resource_id: 16842768
+                compiled_item {
+                  prim {
+                    boolean_value: false
+                  }
+                }
+              }
+              child {
+                element {
+                  name: "intent-filter"
+                  child {
+                    element {
+                      name: "action"
+                      attribute {
+                        namespace_uri: "http://schemas.android.com/apk/res/android"
+                        name: "name"
+                        value: "android.service.dreams.DreamService"
+                        resource_id: 16842755
+                      }
+                    }
+                    source {
+                      line_number: 160
+                    }
+                  }
+                }
+                source {
+                  line_number: 159
+                }
+              }
+            }
+            source {
+              line_number: 155
+            }
+          }
+          child {
+            element {
+              name: "service"
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "name"
+                value: "com.example.bundletool.minimal.Services$SevenService"
+                resource_id: 16842755
+              }
+            }
+            source {
+              line_number: 163
+            }
+          }
+          child {
+            element {
+              name: "provider"
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "name"
+                value: "com.example.bundletool.minimal.OneProvider"
+                resource_id: 16842755
+              }
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "permission"
+                value: "android.permission.MANAGE_DOCUMENTS"
+                resource_id: 16842758
+              }
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "exported"
+                source {
+                }
+                resource_id: 16842768
+                compiled_item {
+                  prim {
+                    boolean_value: true
+                  }
+                }
+              }
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "authorities"
+                value: "A"
+                resource_id: 16842776
+              }
+              attribute {
+                namespace_uri: "http://schemas.android.com/apk/res/android"
+                name: "grantUriPermissions"
+                source {
+                }
+                resource_id: 16842779
+                compiled_item {
+                  prim {
+                    boolean_value: true
+                  }
+                }
+              }
+              child {
+                element {
+                  name: "intent-filter"
+                  child {
+                    element {
+                      name: "action"
+                      attribute {
+                        namespace_uri: "http://schemas.android.com/apk/res/android"
+                        name: "name"
+                        value: "android.content.action.DOCUMENTS_PROVIDER"
+                        resource_id: 16842755
+                      }
+                    }
+                    source {
+                      line_number: 172
+                    }
+                  }
+                }
+                source {
+                  line_number: 171
+                }
+              }
+            }
+            source {
+              line_number: 165
+            }
+          }
+        }
+        source {
+          line_number: 51
+        }
+      }
+    }
+    source {
+      line_number: 2
+    }
+  }
+}
diff --git a/tools/aapt2/integration-tests/DumpTest/components_permissions_expected.txt b/tools/aapt2/integration-tests/DumpTest/components_permissions_expected.txt
new file mode 100644
index 0000000..f79de5c
--- /dev/null
+++ b/tools/aapt2/integration-tests/DumpTest/components_permissions_expected.txt
@@ -0,0 +1,5 @@
+package: com.example.bundletool.minimal
+permission: minimal.FIRST_PERMISSION
+uses-permission: name='android.permission.BIND_ACCESSIBILITY_SERVICE' maxSdkVersion='24'
+uses-permission-sdk-23: name='android.permission.RECEIVE_SMS'
+uses-permission: name='android.permission.WRITE_EXTERNAL_STORAGE'
diff --git a/tools/aapt2/integration-tests/DumpTest/minimal.apk b/tools/aapt2/integration-tests/DumpTest/minimal.apk
new file mode 100644
index 0000000..a8415fa
--- /dev/null
+++ b/tools/aapt2/integration-tests/DumpTest/minimal.apk
Binary files differ
diff --git a/tools/aapt2/integration-tests/DumpTest/minimal_expected.txt b/tools/aapt2/integration-tests/DumpTest/minimal_expected.txt
new file mode 100644
index 0000000..85ab5d8
--- /dev/null
+++ b/tools/aapt2/integration-tests/DumpTest/minimal_expected.txt
@@ -0,0 +1,92 @@
+package: name='com.lato.bubblegirl' versionCode='33' versionName='1.0.0' platformBuildVersionName='8.1.0' platformBuildVersionCode='27'
+sdkVersion:'19'
+targetSdkVersion:'26'
+application-label:'Bubble Girl'
+application-label-ar:'Bubble Girl'
+application-label-az:'Bubble Girl'
+application-label-be:'Bubble Girl'
+application-label-bg:'Bubble Girl'
+application-label-bn:'Bubble Girl'
+application-label-bs:'Bubble Girl'
+application-label-ca:'Bubble Girl'
+application-label-cs:'Bubble Girl'
+application-label-da:'Bubble Girl'
+application-label-de:'Bubble Girl'
+application-label-el:'Bubble Girl'
+application-label-es:'Bubble Girl'
+application-label-es-ES:'Bubble Girl'
+application-label-et:'Bubble Girl'
+application-label-eu:'Bubble Girl'
+application-label-fa:'Bubble Girl'
+application-label-fi:'Bubble Girl'
+application-label-fr:'Bubble Girl'
+application-label-fr-CA:'Bubble Girl'
+application-label-gl:'Bubble Girl'
+application-label-hi:'Bubble Girl'
+application-label-hr:'Bubble Girl'
+application-label-hu:'Bubble Girl'
+application-label-hy:'Bubble Girl'
+application-label-in:'Bubble Girl'
+application-label-is:'Bubble Girl'
+application-label-it:'Bubble Girl'
+application-label-iw:'Bubble Girl'
+application-label-ja:'Bubble Girl'
+application-label-jv:'Bubble Girl'
+application-label-ka:'Bubble Girl'
+application-label-kk:'Bubble Girl'
+application-label-kn:'Bubble Girl'
+application-label-ko:'Bubble Girl'
+application-label-lt:'Bubble Girl'
+application-label-lv:'Bubble Girl'
+application-label-mk:'Bubble Girl'
+application-label-ml:'Bubble Girl'
+application-label-mr:'Bubble Girl'
+application-label-ms:'Bubble Girl'
+application-label-nb:'Bubble Girl'
+application-label-nl:'Bubble Girl'
+application-label-pa:'Bubble Girl'
+application-label-pl:'Bubble Girl'
+application-label-pt-BR:'Bubble Girl'
+application-label-pt-PT:'Bubble Girl'
+application-label-ro:'Bubble Girl'
+application-label-ru:'Bubble Girl'
+application-label-sk:'Bubble Girl'
+application-label-sl:'Bubble Girl'
+application-label-sq:'Bubble Girl'
+application-label-sr:'Bubble Girl'
+application-label-su:'Bubble Girl'
+application-label-sv:'Bubble Girl'
+application-label-ta:'Bubble Girl'
+application-label-te:'Bubble Girl'
+application-label-th:'Bubble Girl'
+application-label-tl:'Bubble Girl'
+application-label-tr:'Bubble Girl'
+application-label-tt:'Bubble Girl'
+application-label-uk:'Bubble Girl'
+application-label-vi:'Bubble Girl'
+application-label-zh-CN:'Bubble Girl'
+application-label-zh-HK:'Bubble Girl'
+application-label-zh-TW:'Bubble Girl'
+application-icon-160:'res/theme/1f.png'
+application-icon-240:'res/theme/1f.png'
+application-icon-320:'res/theme/1f.png'
+application-icon-480:'res/theme/1f.png'
+application-icon-640:'res/theme/1f.png'
+application: label='Bubble Girl' icon='res/theme/1f.png'
+launchable-activity: name='com.sonymobile.runtimeskinning.livewallpaperlib.configactivity.LauncherActivity'  label='' icon=''
+uses-library:'com.sony.device'
+uses-permission: name='com.sonymobile.permission.RUNTIME_SKIN'
+feature-group: label=''
+  uses-gl-es: '0x30000'
+  uses-feature: name='android.software.live_wallpaper'
+  uses-feature: name='android.hardware.faketouch'
+  uses-implied-feature: name='android.hardware.faketouch' reason='default feature for all apps'
+  uses-feature: name='android.hardware.screen.portrait'
+  uses-implied-feature: name='android.hardware.screen.portrait' reason='one or more activities have specified a portrait orientation'
+provides-component:'wallpaper'
+main
+other-activities
+supports-screens: 'small' 'normal' 'large' 'xlarge'
+supports-any-density: 'true'
+locales: '--_--' 'ar' 'az' 'be' 'bg' 'bn' 'bs' 'ca' 'cs' 'da' 'de' 'el' 'es' 'es-ES' 'et' 'eu' 'fa' 'fi' 'fr' 'fr-CA' 'gl' 'hi' 'hr' 'hu' 'hy' 'in' 'is' 'it' 'iw' 'ja' 'jv' 'ka' 'kk' 'kn' 'ko' 'lt' 'lv' 'mk' 'ml' 'mr' 'ms' 'nb' 'nl' 'pa' 'pl' 'pt-BR' 'pt-PT' 'ro' 'ru' 'sk' 'sl' 'sq' 'sr' 'su' 'sv' 'ta' 'te' 'th' 'tl' 'tr' 'tt' 'uk' 'vi' 'zh-CN' 'zh-HK' 'zh-TW'
+densities: '160' '240' '320' '480' '640'
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt b/tools/lint/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
index 859961a..02d5784 100644
--- a/tools/lint/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
+++ b/tools/lint/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
@@ -36,6 +36,7 @@
             EnforcePermissionDetector.ISSUE_MISSING_ENFORCE_PERMISSION,
             EnforcePermissionDetector.ISSUE_MISMATCHING_ENFORCE_PERMISSION,
             SaferParcelChecker.ISSUE_UNSAFE_API_USAGE,
+            PackageVisibilityDetector.ISSUE_PACKAGE_NAME_NO_PACKAGE_VISIBILITY_FILTERS,
     )
 
     override val api: Int
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/PackageVisibilityDetector.kt b/tools/lint/checks/src/main/java/com/google/android/lint/PackageVisibilityDetector.kt
new file mode 100644
index 0000000..192dba1
--- /dev/null
+++ b/tools/lint/checks/src/main/java/com/google/android/lint/PackageVisibilityDetector.kt
@@ -0,0 +1,524 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.android.lint
+
+import com.android.tools.lint.client.api.UastParser
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Context
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import com.android.tools.lint.detector.api.SourceCodeScanner
+import com.android.tools.lint.detector.api.interprocedural.CallGraph
+import com.android.tools.lint.detector.api.interprocedural.CallGraphResult
+import com.android.tools.lint.detector.api.interprocedural.searchForPaths
+import com.intellij.psi.PsiAnonymousClass
+import com.intellij.psi.PsiMethod
+import org.jetbrains.uast.UCallExpression
+import org.jetbrains.uast.UElement
+import org.jetbrains.uast.UMethod
+import org.jetbrains.uast.UParameter
+import org.jetbrains.uast.USimpleNameReferenceExpression
+import org.jetbrains.uast.visitor.AbstractUastVisitor
+import java.util.LinkedList
+
+/**
+ * A lint checker to detect potential package visibility issues for system's APIs. APIs working
+ * in the system_server and taking the package name as a parameter may have chance to reveal
+ * package existence status on the device, and break the
+ * <a href="https://developer.android.com/about/versions/11/privacy/package-visibility">
+ * Package Visibility</a> that we introduced in Android 11.
+ * <p>
+ * Take an example of the API `boolean setFoo(String packageName)`, a malicious app may have chance
+ * to detect package existence state on the device from the result of the API, if there is no
+ * package visibility filtering rule or uid identify checks applying to the parameter of the
+ * package name.
+ */
+class PackageVisibilityDetector : Detector(), SourceCodeScanner {
+
+    // Enables call graph analysis
+    override fun isCallGraphRequired(): Boolean = true
+
+    override fun analyzeCallGraph(
+        context: Context,
+        callGraph: CallGraphResult
+    ) {
+        val systemServerApiNodes = callGraph.callGraph.nodes.filter(::isSystemServerApi)
+        val sinkMethodNodes = callGraph.callGraph.nodes.filter {
+            // TODO(b/228285232): Remove enforce permission sink methods
+            isNodeInList(it, ENFORCE_PERMISSION_METHODS) || isNodeInList(it, APPOPS_METHODS)
+        }
+        val parser = context.client.getUastParser(context.project)
+        analyzeApisContainPackageNameParameters(
+            context, parser, systemServerApiNodes, sinkMethodNodes)
+    }
+
+    /**
+     * Looking for API contains package name parameters, report the lint issue if the API does not
+     * invoke any sink methods.
+     */
+    private fun analyzeApisContainPackageNameParameters(
+        context: Context,
+        parser: UastParser,
+        systemServerApiNodes: List<CallGraph.Node>,
+        sinkMethodNodes: List<CallGraph.Node>
+    ) {
+        for (apiNode in systemServerApiNodes) {
+            val apiMethod = apiNode.getUMethod() ?: continue
+            val pkgNameParamIndexes = apiMethod.uastParameters.mapIndexedNotNull { index, param ->
+                if (Parameter(param) in PACKAGE_NAME_PATTERNS && apiNode.isArgumentInUse(index)) {
+                    index
+                } else {
+                    null
+                }
+            }.takeIf(List<Int>::isNotEmpty) ?: continue
+
+            for (pkgNameParamIndex in pkgNameParamIndexes) {
+                // Trace the call path of the method's argument, pass the lint checks if a sink
+                // method is found
+                if (traceArgumentCallPath(
+                        apiNode, pkgNameParamIndex, PACKAGE_NAME_SINK_METHOD_LIST)) {
+                    continue
+                }
+                // Pass the check if one of the sink methods is invoked
+                if (hasValidPath(
+                        searchForPaths(
+                            sources = listOf(apiNode),
+                            isSink = { it in sinkMethodNodes },
+                            getNeighbors = { node -> node.edges.map { it.node!! } }
+                        )
+                    )
+                ) continue
+
+                // Report issue
+                val reportElement = apiMethod.uastParameters[pkgNameParamIndex] as UElement
+                val location = parser.createLocation(reportElement)
+                context.report(
+                    ISSUE_PACKAGE_NAME_NO_PACKAGE_VISIBILITY_FILTERS,
+                    location,
+                    getMsgPackageNameNoPackageVisibilityFilters(apiMethod, pkgNameParamIndex)
+                )
+            }
+        }
+    }
+
+    /**
+     * Returns {@code true} if the method associated with the given node is a system server's
+     * public API that extends from Stub class.
+     */
+    private fun isSystemServerApi(
+        node: CallGraph.Node
+    ): Boolean {
+        val method = node.getUMethod() ?: return false
+        if (!method.hasModifierProperty("public") ||
+            method.uastBody == null ||
+            method.containingClass is PsiAnonymousClass) {
+            return false
+        }
+        val className = method.containingClass?.qualifiedName ?: return false
+        if (!className.startsWith(SYSTEM_PACKAGE_PREFIX)) {
+            return false
+        }
+        return (method.containingClass ?: return false).supers
+            .filter { it.name == CLASS_STUB }
+            .filter { it.qualifiedName !in BYPASS_STUBS }
+            .any { it.findMethodBySignature(method, /* checkBases */ true) != null }
+    }
+
+    /**
+     * Returns {@code true} if the list contains the node of the call graph.
+     */
+    private fun isNodeInList(
+        node: CallGraph.Node,
+        filters: List<Method>
+    ): Boolean {
+        val method = node.getUMethod() ?: return false
+        return Method(method) in filters
+    }
+
+    /**
+     * Trace the call paths of the argument of the method in the start entry. Return {@code true}
+     * if one of methods in the sink call list is invoked.
+     * Take an example of the call path:
+     * foo(packageName) -> a(packageName) -> b(packageName) -> filterAppAccess()
+     * It returns {@code true} if the filterAppAccess() is in the sink call list.
+     */
+    private fun traceArgumentCallPath(
+        apiNode: CallGraph.Node,
+        pkgNameParamIndex: Int,
+        sinkList: List<Method>
+    ): Boolean {
+        val startEntry = TraceEntry(apiNode, pkgNameParamIndex)
+        val traceQueue = LinkedList<TraceEntry>().apply { add(startEntry) }
+        val allVisits = mutableSetOf<TraceEntry>().apply { add(startEntry) }
+        while (!traceQueue.isEmpty()) {
+            val entry = traceQueue.poll()
+            val entryNode = entry.node
+            val entryMethod = entryNode.getUMethod() ?: continue
+            val entryArgumentName = entryMethod.uastParameters[entry.argumentIndex].name
+            for (outEdge in entryNode.edges) {
+                val outNode = outEdge.node ?: continue
+                val outMethod = outNode.getUMethod() ?: continue
+                val outArgumentIndex =
+                    outEdge.call?.findArgumentIndex(
+                        entryArgumentName, outMethod.uastParameters.size)
+                val sinkMethod = findInSinkList(outMethod, sinkList)
+                if (sinkMethod == null) {
+                    if (outArgumentIndex == null) {
+                        // Path is not relevant to the sink method and argument
+                        continue
+                    }
+                    // Path is relevant to the argument, add a new trace entry if never visit before
+                    val newEntry = TraceEntry(outNode, outArgumentIndex)
+                    if (newEntry !in allVisits) {
+                        traceQueue.add(newEntry)
+                        allVisits.add(newEntry)
+                    }
+                    continue
+                }
+                if (sinkMethod.matchArgument && outArgumentIndex == null) {
+                    // The sink call is required to match the argument, but not found
+                    continue
+                }
+                if (sinkMethod.checkCaller &&
+                    entryMethod.isInClearCallingIdentityScope(outEdge.call!!)) {
+                    // The sink call is in the scope of Binder.clearCallingIdentify
+                    continue
+                }
+                // A sink method is matched
+                return true
+            }
+        }
+        return false
+    }
+
+    /**
+     * Returns the UMethod associated with the given node of call graph.
+     */
+    private fun CallGraph.Node.getUMethod(): UMethod? = this.target.element as? UMethod
+
+    /**
+     * Returns the system module name (e.g. com.android.server.pm) of the method of the
+     * call graph node.
+     */
+    private fun CallGraph.Node.getModuleName(): String? {
+        val method = getUMethod() ?: return null
+        val className = method.containingClass?.qualifiedName ?: return null
+        if (!className.startsWith(SYSTEM_PACKAGE_PREFIX)) {
+            return null
+        }
+        val dotPos = className.indexOf(".", SYSTEM_PACKAGE_PREFIX.length)
+        if (dotPos == -1) {
+            return SYSTEM_PACKAGE_PREFIX
+        }
+        return className.substring(0, dotPos)
+    }
+
+    /**
+     * Return {@code true} if the argument in the method's body is in-use.
+     */
+    private fun CallGraph.Node.isArgumentInUse(argIndex: Int): Boolean {
+        val method = getUMethod() ?: return false
+        val argumentName = method.uastParameters[argIndex].name
+        var foundArg = false
+        val methodVisitor = object : AbstractUastVisitor() {
+            override fun visitSimpleNameReferenceExpression(
+                node: USimpleNameReferenceExpression
+            ): Boolean {
+                if (node.identifier == argumentName) {
+                    foundArg = true
+                }
+                return true
+            }
+        }
+        method.uastBody?.accept(methodVisitor)
+        return foundArg
+    }
+
+    /**
+     * Given an argument name, returns the index of argument in the call expression.
+     */
+    private fun UCallExpression.findArgumentIndex(
+        argumentName: String,
+        parameterSize: Int
+    ): Int? {
+        if (valueArgumentCount == 0 || parameterSize == 0) {
+            return null
+        }
+        var match = false
+        val argVisitor = object : AbstractUastVisitor() {
+            override fun visitSimpleNameReferenceExpression(
+                node: USimpleNameReferenceExpression
+            ): Boolean {
+                if (node.identifier == argumentName) {
+                    match = true
+                }
+                return true
+            }
+            override fun visitCallExpression(node: UCallExpression): Boolean {
+                return true
+            }
+        }
+        valueArguments.take(parameterSize).forEachIndexed { index, argument ->
+            argument.accept(argVisitor)
+            if (match) {
+                return index
+            }
+        }
+        return null
+    }
+
+    /**
+     * Given a UMethod, returns a method from the sink method list.
+     */
+    private fun findInSinkList(
+        uMethod: UMethod,
+        sinkCallList: List<Method>
+    ): Method? {
+        return sinkCallList.find {
+            it == Method(uMethod) ||
+                    it == Method(uMethod.containingClass?.qualifiedName ?: "", "*")
+        }
+    }
+
+    /**
+     * Returns {@code true} if the call expression is in the scope of the
+     * Binder.clearCallingIdentify.
+     */
+    private fun UMethod.isInClearCallingIdentityScope(call: UCallExpression): Boolean {
+        var isInScope = false
+        val methodVisitor = object : AbstractUastVisitor() {
+            private var clearCallingIdentity = 0
+            override fun visitCallExpression(node: UCallExpression): Boolean {
+                if (call == node && clearCallingIdentity != 0) {
+                    isInScope = true
+                    return true
+                }
+                val visitMethod = Method(node.resolve() ?: return false)
+                if (visitMethod == METHOD_CLEAR_CALLING_IDENTITY) {
+                    clearCallingIdentity++
+                } else if (visitMethod == METHOD_RESTORE_CALLING_IDENTITY) {
+                    clearCallingIdentity--
+                }
+                return false
+            }
+        }
+        accept(methodVisitor)
+        return isInScope
+    }
+
+    /**
+     * Checks the module name of the start node and the last node that invokes the sink method
+     * (e.g. checkPermission) in a path, returns {@code true} if one of the paths has the same
+     * module name for both nodes.
+     */
+    private fun hasValidPath(paths: Collection<List<CallGraph.Node>>): Boolean {
+        for (pathNodes in paths) {
+            if (pathNodes.size < VALID_CALL_PATH_NODES_SIZE) {
+                continue
+            }
+            val startModule = pathNodes[0].getModuleName() ?: continue
+            val lastCallModule = pathNodes[pathNodes.size - 2].getModuleName() ?: continue
+            if (startModule == lastCallModule) {
+                return true
+            }
+        }
+        return false
+    }
+
+    /**
+     * A data class to represent the method.
+     */
+    private data class Method(
+        val clazz: String,
+        val name: String
+    ) {
+        // Used by traceArgumentCallPath to indicate that the method is required to match the
+        // argument name
+        var matchArgument = true
+
+        // Used by traceArgumentCallPath to indicate that the method is required to check whether
+        // the Binder.clearCallingIdentity is invoked.
+        var checkCaller = false
+
+        constructor(
+            clazz: String,
+            name: String,
+            matchArgument: Boolean = true,
+            checkCaller: Boolean = false
+        ): this(clazz, name) {
+            this.matchArgument = matchArgument
+            this.checkCaller = checkCaller
+        }
+
+        constructor(
+            method: PsiMethod
+        ): this(method.containingClass?.qualifiedName ?: "", method.name)
+    }
+
+    /**
+     * A data class to represent the parameter of the method. The parameter name is converted to
+     * lower case letters for comparison.
+     */
+    private data class Parameter private constructor(
+        val typeName: String,
+        val parameterName: String
+    ) {
+        constructor(uParameter: UParameter): this(
+            uParameter.type.canonicalText,
+            uParameter.name.lowercase()
+        )
+
+        companion object {
+            fun create(typeName: String, parameterName: String) =
+                Parameter(typeName, parameterName.lowercase())
+        }
+    }
+
+    /**
+     * A data class wraps a method node of the call graph and an index that indicates an
+     * argument of the method to record call trace information.
+     */
+    private data class TraceEntry(
+        val node: CallGraph.Node,
+        val argumentIndex: Int
+    )
+
+    companion object {
+        private const val SYSTEM_PACKAGE_PREFIX = "com.android.server."
+        // A valid call path list needs to contain a start node and a sink node
+        private const val VALID_CALL_PATH_NODES_SIZE = 2
+
+        private const val CLASS_STUB = "Stub"
+        private const val CLASS_STRING = "java.lang.String"
+        private const val CLASS_PACKAGE_MANAGER = "android.content.pm.PackageManager"
+        private const val CLASS_IPACKAGE_MANAGER = "android.content.pm.IPackageManager"
+        private const val CLASS_APPOPS_MANAGER = "android.app.AppOpsManager"
+        private const val CLASS_CONTEXT = "android.content.Context"
+        private const val CLASS_BINDER = "android.os.Binder"
+        private const val CLASS_PACKAGE_MANAGER_INTERNAL =
+            "android.content.pm.PackageManagerInternal"
+        private const val CLASS_ACTIVITY_MANAGER_SERVICE =
+            "com.android.server.am.ActivityManagerService"
+        private const val CLASS_ACTIVITY_MANAGER_INTERNAL =
+            "android.app.ActivityManagerInternal"
+
+        // Patterns of package name parameter
+        private val PACKAGE_NAME_PATTERNS = setOf(
+            Parameter.create(CLASS_STRING, "packageName"),
+            Parameter.create(CLASS_STRING, "callingPackage"),
+            Parameter.create(CLASS_STRING, "callingPackageName"),
+            Parameter.create(CLASS_STRING, "pkgName"),
+            Parameter.create(CLASS_STRING, "callingPkg"),
+            Parameter.create(CLASS_STRING, "pkg")
+        )
+
+        // Package manager APIs
+        private val PACKAGE_NAME_SINK_METHOD_LIST = listOf(
+            Method(CLASS_PACKAGE_MANAGER_INTERNAL, "filterAppAccess", matchArgument = false),
+            Method(CLASS_PACKAGE_MANAGER_INTERNAL, "canQueryPackage"),
+            Method(CLASS_PACKAGE_MANAGER_INTERNAL, "isSameApp"),
+            Method(CLASS_PACKAGE_MANAGER, "*", checkCaller = true),
+            Method(CLASS_IPACKAGE_MANAGER, "*", checkCaller = true),
+            Method(CLASS_PACKAGE_MANAGER, "getPackagesForUid", matchArgument = false),
+            Method(CLASS_IPACKAGE_MANAGER, "getPackagesForUid", matchArgument = false)
+        )
+
+        // AppOps APIs which include uid and package visibility filters checks
+        private val APPOPS_METHODS = listOf(
+            Method(CLASS_APPOPS_MANAGER, "noteOp"),
+            Method(CLASS_APPOPS_MANAGER, "noteOpNoThrow"),
+            Method(CLASS_APPOPS_MANAGER, "noteOperation"),
+            Method(CLASS_APPOPS_MANAGER, "noteProxyOp"),
+            Method(CLASS_APPOPS_MANAGER, "noteProxyOpNoThrow"),
+            Method(CLASS_APPOPS_MANAGER, "startOp"),
+            Method(CLASS_APPOPS_MANAGER, "startOpNoThrow"),
+            Method(CLASS_APPOPS_MANAGER, "FinishOp"),
+            Method(CLASS_APPOPS_MANAGER, "finishProxyOp"),
+            Method(CLASS_APPOPS_MANAGER, "checkPackage")
+        )
+
+        // Enforce permission APIs
+        private val ENFORCE_PERMISSION_METHODS = listOf(
+            Method(CLASS_CONTEXT, "checkPermission"),
+            Method(CLASS_CONTEXT, "checkCallingPermission"),
+            Method(CLASS_CONTEXT, "checkCallingOrSelfPermission"),
+            Method(CLASS_CONTEXT, "enforcePermission"),
+            Method(CLASS_CONTEXT, "enforceCallingPermission"),
+            Method(CLASS_CONTEXT, "enforceCallingOrSelfPermission"),
+            Method(CLASS_ACTIVITY_MANAGER_SERVICE, "checkPermission"),
+            Method(CLASS_ACTIVITY_MANAGER_INTERNAL, "enforceCallingPermission")
+        )
+
+        private val BYPASS_STUBS = listOf(
+            "android.content.pm.IPackageDataObserver.Stub",
+            "android.content.pm.IPackageDeleteObserver.Stub",
+            "android.content.pm.IPackageDeleteObserver2.Stub",
+            "android.content.pm.IPackageInstallObserver2.Stub",
+            "com.android.internal.app.IAppOpsCallback.Stub",
+
+            // TODO(b/228285637): Do not bypass PackageManagerService API
+            "android.content.pm.IPackageManager.Stub",
+            "android.content.pm.IPackageManagerNative.Stub"
+        )
+
+        private val METHOD_CLEAR_CALLING_IDENTITY =
+            Method(CLASS_BINDER, "clearCallingIdentity")
+        private val METHOD_RESTORE_CALLING_IDENTITY =
+            Method(CLASS_BINDER, "restoreCallingIdentity")
+
+        private fun getMsgPackageNameNoPackageVisibilityFilters(
+            method: UMethod,
+            argumentIndex: Int
+        ): String = "Api: ${method.name} contains a package name parameter: " +
+                "${method.uastParameters[argumentIndex].name} does not apply " +
+                "package visibility filtering rules."
+
+        private val EXPLANATION = """
+            APIs working in the system_server and taking the package name as a parameter may have
+            chance to reveal package existence status on the device, and break the package
+            visibility that we introduced in Android 11.
+            (https://developer.android.com/about/versions/11/privacy/package-visibility)
+
+            Take an example of the API `boolean setFoo(String packageName)`, a malicious app may
+            have chance to get package existence state on the device from the result of the API,
+            if there is no package visibility filtering rule or uid identify checks applying to
+            the parameter of the package name.
+
+            To resolve it, you could apply package visibility filtering rules to the package name
+            via PackageManagerInternal.filterAppAccess API, before starting to use the package name.
+            If the parameter is a calling package name, use the PackageManager API such as
+            PackageManager.getPackagesForUid to verify the calling identify.
+            """
+
+        val ISSUE_PACKAGE_NAME_NO_PACKAGE_VISIBILITY_FILTERS = Issue.create(
+            id = "ApiMightLeakAppVisibility",
+            briefDescription = "Api takes package name parameter doesn't apply " +
+                    "package visibility filters",
+            explanation = EXPLANATION,
+            category = Category.SECURITY,
+            priority = 1,
+            severity = Severity.WARNING,
+            implementation = Implementation(
+                PackageVisibilityDetector::class.java,
+                Scope.JAVA_FILE_SCOPE
+            )
+        )
+    }
+}
diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/PackageVisibilityDetectorTest.kt b/tools/lint/checks/src/test/java/com/google/android/lint/PackageVisibilityDetectorTest.kt
new file mode 100644
index 0000000..a70644a
--- /dev/null
+++ b/tools/lint/checks/src/test/java/com/google/android/lint/PackageVisibilityDetectorTest.kt
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.android.lint
+
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.checks.infrastructure.TestFile
+import com.android.tools.lint.checks.infrastructure.TestLintTask
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Issue
+
+@Suppress("UnstableApiUsage")
+class PackageVisibilityDetectorTest : LintDetectorTest() {
+    override fun getDetector(): Detector = PackageVisibilityDetector()
+
+    override fun getIssues(): MutableList<Issue> = mutableListOf(
+        PackageVisibilityDetector.ISSUE_PACKAGE_NAME_NO_PACKAGE_VISIBILITY_FILTERS
+    )
+
+    override fun lint(): TestLintTask = super.lint().allowMissingSdk(true)
+
+    fun testDetectIssuesParameterDoesNotApplyPackageVisibilityFilters() {
+        lint().files(java(
+            """
+            package com.android.server.lint.test;
+            import android.internal.test.IFoo;
+
+            public class TestClass extends IFoo.Stub {
+                @Override
+                public boolean hasPackage(String packageName) {
+                    return packageName != null;
+                }
+            }
+            """).indented(), *stubs
+        ).run().expect(
+                """
+                src/com/android/server/lint/test/TestClass.java:6: Warning: \
+                Api: hasPackage contains a package name parameter: packageName does not apply \
+                package visibility filtering rules. \
+                [ApiMightLeakAppVisibility]
+                    public boolean hasPackage(String packageName) {
+                                              ~~~~~~~~~~~~~~~~~~
+                0 errors, 1 warnings
+                """.addLineContinuation()
+        )
+    }
+
+    fun testDoesNotDetectIssuesApiInvokesAppOps() {
+        lint().files(java(
+            """
+            package com.android.server.lint.test;
+            import android.app.AppOpsManager;
+            import android.os.Binder;
+            import android.internal.test.IFoo;
+
+            public class TestClass extends IFoo.Stub {
+                private AppOpsManager mAppOpsManager;
+
+                @Override
+                public boolean hasPackage(String packageName) {
+                    checkPackage(packageName);
+                    return packageName != null;
+                }
+
+                private void checkPackage(String packageName) {
+                    mAppOpsManager.checkPackage(Binder.getCallingUid(), packageName);
+                }
+            }
+            """
+        ).indented(), *stubs).run().expectClean()
+    }
+
+    fun testDoesNotDetectIssuesApiInvokesEnforcePermission() {
+        lint().files(java(
+            """
+            package com.android.server.lint.test;
+            import android.content.Context;
+            import android.internal.test.IFoo;
+
+            public class TestClass extends IFoo.Stub {
+                private Context mContext;
+
+                @Override
+                public boolean hasPackage(String packageName) {
+                    enforcePermission();
+                    return packageName != null;
+                }
+
+                private void enforcePermission() {
+                    mContext.checkCallingPermission(
+                            android.Manifest.permission.ACCESS_INPUT_FLINGER);
+                }
+            }
+            """
+        ).indented(), *stubs).run().expectClean()
+    }
+
+    fun testDoesNotDetectIssuesApiInvokesPackageManager() {
+        lint().files(java(
+            """
+            package com.android.server.lint.test;
+            import android.content.pm.PackageInfo;
+            import android.content.pm.PackageManager;
+            import android.internal.test.IFoo;
+
+            public class TestClass extends IFoo.Stub {
+                private PackageManager mPackageManager;
+
+                @Override
+                public boolean hasPackage(String packageName) {
+                    return getPackageInfo(packageName) != null;
+                }
+
+                private PackageInfo getPackageInfo(String packageName) {
+                    try {
+                        return mPackageManager.getPackageInfo(packageName, 0);
+                    } catch (PackageManager.NameNotFoundException e) {
+                        return null;
+                    }
+                }
+            }
+            """
+        ).indented(), *stubs).run().expectClean()
+    }
+
+    fun testDetectIssuesApiInvokesPackageManagerAndClearCallingIdentify() {
+        lint().files(java(
+            """
+            package com.android.server.lint.test;
+            import android.content.pm.PackageInfo;
+            import android.content.pm.PackageManager;
+            import android.internal.test.IFoo;import android.os.Binder;
+
+            public class TestClass extends IFoo.Stub {
+                private PackageManager mPackageManager;
+
+                @Override
+                public boolean hasPackage(String packageName) {
+                    return getPackageInfo(packageName) != null;
+                }
+
+                private PackageInfo getPackageInfo(String packageName) {
+                    long token = Binder.clearCallingIdentity();
+                    try {
+                        try {
+                            return mPackageManager.getPackageInfo(packageName, 0);
+                        } catch (PackageManager.NameNotFoundException e) {
+                            return null;
+                        }
+                    } finally{
+                        Binder.restoreCallingIdentity(token);
+                    }
+                }
+            }
+            """).indented(), *stubs
+        ).run().expect(
+                """
+                src/com/android/server/lint/test/TestClass.java:10: Warning: \
+                Api: hasPackage contains a package name parameter: packageName does not apply \
+                package visibility filtering rules. \
+                [ApiMightLeakAppVisibility]
+                    public boolean hasPackage(String packageName) {
+                                              ~~~~~~~~~~~~~~~~~~
+                0 errors, 1 warnings
+                """.addLineContinuation()
+        )
+    }
+
+    fun testDoesNotDetectIssuesApiNotSystemPackagePrefix() {
+        lint().files(java(
+            """
+            package com.test.not.system.prefix;
+            import android.internal.test.IFoo;
+
+            public class TestClass extends IFoo.Stub {
+                @Override
+                public boolean hasPackage(String packageName) {
+                    return packageName != null;
+                }
+            }
+            """
+        ).indented(), *stubs).run().expectClean()
+    }
+
+    private val contextStub: TestFile = java(
+        """
+        package android.content;
+
+        public abstract class Context {
+            public abstract int checkCallingPermission(String permission);
+        }
+        """
+    ).indented()
+
+    private val appOpsManagerStub: TestFile = java(
+        """
+        package android.app;
+
+        public class AppOpsManager {
+            public void checkPackage(int uid, String packageName) {
+            }
+        }
+        """
+    ).indented()
+
+    private val packageManagerStub: TestFile = java(
+        """
+        package android.content.pm;
+        import android.content.pm.PackageInfo;
+
+        public abstract class PackageManager {
+            public static class NameNotFoundException extends AndroidException {
+            }
+
+            public abstract PackageInfo getPackageInfo(String packageName, int flags)
+                    throws NameNotFoundException;
+        }
+        """
+    ).indented()
+
+    private val packageInfoStub: TestFile = java(
+        """
+        package android.content.pm;
+        public class PackageInfo {}
+        """
+    ).indented()
+
+    private val binderStub: TestFile = java(
+        """
+        package android.os;
+
+        public class Binder {
+            public static final native long clearCallingIdentity();
+            public static final native void restoreCallingIdentity(long token);
+            public static final native int getCallingUid();
+        }
+        """
+    ).indented()
+
+    private val interfaceIFooStub: TestFile = java(
+        """
+        package android.internal.test;
+        import android.os.Binder;
+
+        public interface IFoo {
+            boolean hasPackage(String packageName);
+            public abstract static class Stub extends Binder implements IFoo {
+            }
+        }
+        """
+    ).indented()
+
+    private val stubs = arrayOf(contextStub, appOpsManagerStub, packageManagerStub,
+        packageInfoStub, binderStub, interfaceIFooStub)
+
+    // Substitutes "backslash + new line" with an empty string to imitate line continuation
+    private fun String.addLineContinuation(): String = this.trimIndent().replace("\\\n", "")
+}