From 87e81c22fa3531b378ef4bce06026c0f602ff5a1 Mon Sep 17 00:00:00 2001
From: Dmitry Dementyev <dementyev@google.com>
Date: Fri, 4 Aug 2023 13:19:00 -0700
Subject: [PATCH 01/95] Update simple_list_item_single_choice to work better
 with large fonts.

The list is used by newChooseAccountIntent.

Test: manual - b/279879914#comment8
Bug: 279879914
Change-Id: I499d73f14301ac873218cd57ef032d64f572886d
---
 core/res/res/layout/simple_list_item_multiple_choice.xml | 3 ++-
 core/res/res/layout/simple_list_item_single_choice.xml   | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/core/res/res/layout/simple_list_item_multiple_choice.xml b/core/res/res/layout/simple_list_item_multiple_choice.xml
index 440b6fd8e1b1..fd9bf76aade5 100644
--- a/core/res/res/layout/simple_list_item_multiple_choice.xml
+++ b/core/res/res/layout/simple_list_item_multiple_choice.xml
@@ -17,7 +17,8 @@
 <CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@android:id/text1"
     android:layout_width="match_parent"
-    android:layout_height="?android:attr/listPreferredItemHeightSmall"
+    android:layout_height="wrap_content"
+    android:minHeight="?android:attr/listPreferredItemHeightSmall"
     android:textAppearance="?android:attr/textAppearanceListItemSmall"
     android:gravity="center_vertical"
     android:checkMark="?android:attr/listChoiceIndicatorMultiple"
diff --git a/core/res/res/layout/simple_list_item_single_choice.xml b/core/res/res/layout/simple_list_item_single_choice.xml
index 02cb7f77645c..a66308e1ad02 100644
--- a/core/res/res/layout/simple_list_item_single_choice.xml
+++ b/core/res/res/layout/simple_list_item_single_choice.xml
@@ -17,7 +17,8 @@
 <CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@android:id/text1"
     android:layout_width="match_parent"
-    android:layout_height="?android:attr/listPreferredItemHeightSmall"
+    android:layout_height="wrap_content"
+    android:minHeight="?android:attr/listPreferredItemHeightSmall"
     android:textAppearance="?android:attr/textAppearanceListItemSmall"
     android:gravity="center_vertical"
     android:checkMark="?android:attr/listChoiceIndicatorSingle"
-- 
GitLab


From 2841f107e08cdff5d9b43f63d6c6bbd76a2235e7 Mon Sep 17 00:00:00 2001
From: Sudheer Shanka <sudheersai@google.com>
Date: Fri, 8 Sep 2023 10:05:03 +0000
Subject: [PATCH 02/95] Add a hidden API to query quarantine state.

Bug: 297934650
Test: manual
Change-Id: Ic1f295e61cdbc2c51d04c998c08d7bd4c7cb9aae
---
 core/java/android/app/ApplicationPackageManager.java | 11 +++++++++++
 core/java/android/content/pm/PackageManager.java     | 12 ++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index fcd13b840cb1..7b128f53857f 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -2945,6 +2945,17 @@ public class ApplicationPackageManager extends PackageManager {
         return isPackageSuspendedForUser(mContext.getOpPackageName(), getUserId());
     }
 
+    @Override
+    public boolean isPackageQuarantined(@NonNull String packageName) throws NameNotFoundException {
+        try {
+            return mPM.isPackageQuarantinedForUser(packageName, getUserId());
+        } catch (IllegalArgumentException ie) {
+            throw new NameNotFoundException(packageName);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     /** @hide */
     @Override
     public void setApplicationCategoryHint(String packageName, int categoryHint) {
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 9a53a2a60076..2980134f3fb4 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -9859,6 +9859,18 @@ public abstract class PackageManager {
         throw new UnsupportedOperationException("getSuspendedPackageAppExtras not implemented");
     }
 
+    /**
+     * Query if an app is currently quarantined.
+     *
+     * @return {@code true} if the given package is quarantined, {@code false} otherwise
+     * @throws NameNotFoundException if the package could not be found.
+     *
+     * @hide
+     */
+    public boolean isPackageQuarantined(@NonNull String packageName) throws NameNotFoundException {
+        throw new UnsupportedOperationException("isPackageQuarantined not implemented");
+    }
+
     /**
      * Provide a hint of what the {@link ApplicationInfo#category} value should
      * be for the given package.
-- 
GitLab


From 38dc14e8e0dc1e2fb96e7220502cbeb40fdd7f92 Mon Sep 17 00:00:00 2001
From: Prashant Patil <patilprashant@google.com>
Date: Wed, 16 Aug 2023 15:00:24 +0000
Subject: [PATCH 03/95] Fix attestation properties reading logic

Fixed the logic of reading attestation specific properties in
Build.java.

Bug: 110779648
Test: atest CtsKeystoreTestCases:android.keystore.cts.KeyAttestationTest CtsKeystoreTestCases:DeviceOwnerKeyManagementTest
(cherry picked from https://android-review.googlesource.com/q/commit:316e3d16c9f34212f3beace7695289651d15a071)
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:4edeaffcbb9d39efaf49d3e24a621110c367c560)
Merged-In: I9af7daa08cbd8bb52f3509fe93f787ba94b7bbc3
Change-Id: I9af7daa08cbd8bb52f3509fe93f787ba94b7bbc3
---
 core/java/android/os/Build.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 9f9c2222f9d9..cd6acfe149f8 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -1555,7 +1555,7 @@ public class Build {
         String attestProp = getString(
                 TextUtils.formatSimple("ro.product.%s_for_attestation", property));
         return attestProp.equals(UNKNOWN)
-                ? getString(TextUtils.formatSimple("ro.product.vendor.%s", property)) : UNKNOWN;
+                ? getString(TextUtils.formatSimple("ro.product.vendor.%s", property)) : attestProp;
     }
 
     private static String[] getStringList(String property, String separator) {
-- 
GitLab


From 4aed12b94ca786dfc2e6bbeb5e8b527209654207 Mon Sep 17 00:00:00 2001
From: Haoran Zhang <haoranzhang@google.com>
Date: Thu, 7 Sep 2023 22:42:01 +0000
Subject: [PATCH 04/95] [Webview-FillDialog Support] Fix autofill framework
 issue found when testing webView prorotype

There are two issues I found:

1. Instead of SparseArray.indexOf(i), framework should use SparseArray.keyOf(i) to get the virtual id for virtual views that Chrome passed in.

2. Framework should ignore case when checking whether view's autofill hints is in fill dialog supported hints. In the webview prototype, Chrome is passing "PASSWORD" as autofill hints

Also I found it's easy to create null pointer exception when referencing
AutofillHints in notifyViewReadyInner(). It's not obvious that this
array could be null also. Annotated it with @Nullable to make it obvious.

Bug:b/299532529
Test: atest CtsAutoFillServiceTestCases

Change-Id: Ie1ed6f0fbe806826a1844d85a74767ca946e55b8
---
 .../view/autofill/AutofillManager.java        | 39 ++++++++++++-------
 1 file changed, 26 insertions(+), 13 deletions(-)

diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index d729d494e104..a7fbaf63eaed 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -1436,7 +1436,7 @@ public final class AutofillManager {
         }
         for (int i = 0; i < infos.size(); i++) {
             final VirtualViewFillInfo info = infos.valueAt(i);
-            final int virtualId = infos.indexOfKey(i);
+            final int virtualId = infos.keyAt(i);
             notifyViewReadyInner(getAutofillId(view, virtualId),
                     (info == null) ? null : info.getAutofillHints());
         }
@@ -1450,9 +1450,6 @@ public final class AutofillManager {
      * @hide
      */
     public void notifyViewEnteredForFillDialog(View v) {
-        if (sDebug) {
-            Log.d(TAG, "notifyViewEnteredForFillDialog:" + v.getAutofillId());
-        }
         if (v.isCredential()
                 && mIsFillAndSaveDialogDisabledForCredentialManager) {
             if (sDebug) {
@@ -1465,11 +1462,14 @@ public final class AutofillManager {
         notifyViewReadyInner(v.getAutofillId(), v.getAutofillHints());
     }
 
-    private void notifyViewReadyInner(AutofillId id, String[] autofillHints) {
+    private void notifyViewReadyInner(AutofillId id, @Nullable String[] autofillHints) {
+        if (sDebug) {
+            Log.d(TAG, "notifyViewReadyInner:" + id);
+        }
+
         if (!hasAutofillFeature()) {
             return;
         }
-
         synchronized (mLock) {
             if (mAllTrackedViews.contains(id)) {
                 // The id is tracked and will not trigger pre-fill request again.
@@ -1505,26 +1505,38 @@ public final class AutofillManager {
                     final boolean clientAdded = tryAddServiceClientIfNeededLocked();
                     if (clientAdded) {
                         startSessionLocked(/* id= */ AutofillId.NO_AUTOFILL_ID, /* bounds= */ null,
-                                /* value= */ null, /* flags= */ FLAG_PCC_DETECTION);
+                            /* value= */ null, /* flags= */ FLAG_PCC_DETECTION);
                     } else {
                         if (sVerbose) {
                             Log.v(TAG, "not starting session: no service client");
                         }
                     }
-
                 }
             }
         }
 
-        if (mIsFillDialogEnabled
-                || ArrayUtils.containsAny(autofillHints, mFillDialogEnabledHints)) {
+        // Check if framework should send pre-fill request for fill dialog
+        boolean shouldSendPreFillRequestForFillDialog = false;
+        if (mIsFillDialogEnabled) {
+            shouldSendPreFillRequestForFillDialog = true;
+        } else if (autofillHints != null) {
+            // check if supported autofill hint is present
+            for (String autofillHint : autofillHints) {
+                for (String filldialogEnabledHint : mFillDialogEnabledHints) {
+                    if (filldialogEnabledHint.equalsIgnoreCase(autofillHint)) {
+                        shouldSendPreFillRequestForFillDialog = true;
+                        break;
+                    }
+                }
+                if (shouldSendPreFillRequestForFillDialog) break;
+            }
+        }
+        if (shouldSendPreFillRequestForFillDialog) {
             if (sDebug) {
                 Log.d(TAG, "Triggering pre-emptive request for fill dialog.");
             }
-
             int flags = FLAG_SUPPORTS_FILL_DIALOG;
             flags |= FLAG_VIEW_NOT_FOCUSED;
-
             synchronized (mLock) {
                 // To match the id of the IME served view, used AutofillId.NO_AUTOFILL_ID on prefill
                 // request, because IME will reset the id of IME served view to 0 when activity
@@ -1532,9 +1544,10 @@ public final class AutofillManager {
                 // not match the IME served view's, Autofill will be blocking to wait inline
                 // request from the IME.
                 notifyViewEnteredLocked(/* view= */ null, AutofillId.NO_AUTOFILL_ID,
-                        /* bounds= */ null,  /* value= */ null, flags);
+                    /* bounds= */ null,  /* value= */ null, flags);
             }
         }
+        return;
     }
 
     private boolean hasFillDialogUiFeature() {
-- 
GitLab


From 114d7f81e9136b9353a4e739cc19d02dabad229c Mon Sep 17 00:00:00 2001
From: Beverly <beverlyt@google.com>
Date: Mon, 11 Sep 2023 19:06:31 +0000
Subject: [PATCH 05/95] Remove delay_bouncer flag

Test: builds
Fixes: 279794160
Change-Id: I88312a4c690a46fee56ebb8fb3d3872ed1746c05
---
 .../domain/interactor/PrimaryBouncerInteractor.kt | 15 ++++-----------
 .../src/com/android/systemui/flags/Flags.kt       |  4 ----
 ...guardViewLegacyControllerWithCoroutinesTest.kt |  3 ---
 .../interactor/PrimaryBouncerInteractorTest.kt    |  5 -----
 .../PrimaryBouncerInteractorWithCoroutinesTest.kt |  3 ---
 .../ui/viewmodel/KeyguardBouncerViewModelTest.kt  |  3 ---
 .../interactor/KeyguardFaceAuthInteractorTest.kt  |  1 -
 .../OccludingAppDeviceEntryInteractorTest.kt      |  7 +------
 .../KeyguardDismissInteractorFactory.kt           |  2 --
 9 files changed, 5 insertions(+), 38 deletions(-)

diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractor.kt
index 579f0b7b3185..3fd6617d5a81 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractor.kt
@@ -38,8 +38,6 @@ import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.DismissCallbackRegistry
 import com.android.systemui.keyguard.data.repository.TrustRepository
 import com.android.systemui.plugins.ActivityStarter
@@ -74,7 +72,6 @@ constructor(
     private val context: Context,
     private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
     private val trustRepository: TrustRepository,
-    private val featureFlags: FeatureFlags,
     @Application private val applicationScope: CoroutineScope,
 ) {
     private val passiveAuthBouncerDelay =
@@ -135,11 +132,9 @@ constructor(
 
     init {
         keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback)
-        if (featureFlags.isEnabled(Flags.DELAY_BOUNCER)) {
-            applicationScope.launch {
-                trustRepository.isCurrentUserActiveUnlockRunning.collect {
-                    currentUserActiveUnlockRunning = it
-                }
+        applicationScope.launch {
+            trustRepository.isCurrentUserActiveUnlockRunning.collect {
+                currentUserActiveUnlockRunning = it
             }
         }
     }
@@ -415,9 +410,7 @@ constructor(
             currentUserActiveUnlockRunning &&
                 keyguardUpdateMonitor.canTriggerActiveUnlockBasedOnDeviceState()
 
-        return featureFlags.isEnabled(Flags.DELAY_BOUNCER) &&
-            !needsFullscreenBouncer() &&
-            (canRunFaceAuth || canRunActiveUnlock)
+        return !needsFullscreenBouncer() && (canRunFaceAuth || canRunActiveUnlock)
     }
 
     companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 7e8f68225070..7527587c4067 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -253,10 +253,6 @@ object Flags {
     // TODO(b/277961132): Tracking bug.
     @JvmField val REVAMPED_BOUNCER_MESSAGES = unreleasedFlag("revamped_bouncer_messages")
 
-    /** Whether to delay showing bouncer UI when face auth or active unlock are enrolled. */
-    // TODO(b/279794160): Tracking bug.
-    @JvmField val DELAY_BOUNCER = releasedFlag("delay_bouncer")
-
     /** Keyguard Migration */
 
     /**
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt
index 1885f6499299..17f435b75d5a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt
@@ -30,8 +30,6 @@ import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
 import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants
 import com.android.systemui.bouncer.ui.BouncerView
 import com.android.systemui.classifier.FalsingCollector
-import com.android.systemui.flags.FakeFeatureFlags
-import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.DismissCallbackRegistry
 import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository
 import com.android.systemui.keyguard.data.repository.FakeTrustRepository
@@ -99,7 +97,6 @@ class UdfpsKeyguardViewLegacyControllerWithCoroutinesTest :
                 context,
                 mKeyguardUpdateMonitor,
                 FakeTrustRepository(),
-                FakeFeatureFlags().apply { set(Flags.DELAY_BOUNCER, true) },
                 testScope.backgroundScope,
             )
         mAlternateBouncerInteractor =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorTest.kt
index 420fdba7fde2..a68e0192e951 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorTest.kt
@@ -34,8 +34,6 @@ import com.android.systemui.bouncer.shared.model.BouncerShowMessageModel
 import com.android.systemui.bouncer.ui.BouncerView
 import com.android.systemui.bouncer.ui.BouncerViewDelegate
 import com.android.systemui.classifier.FalsingCollector
-import com.android.systemui.flags.FakeFeatureFlags
-import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.DismissCallbackRegistry
 import com.android.systemui.keyguard.data.repository.FakeTrustRepository
 import com.android.systemui.plugins.ActivityStarter
@@ -76,7 +74,6 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() {
     private lateinit var underTest: PrimaryBouncerInteractor
     private lateinit var resources: TestableResources
     private lateinit var trustRepository: FakeTrustRepository
-    private lateinit var featureFlags: FakeFeatureFlags
     private lateinit var testScope: TestScope
 
     @Before
@@ -89,7 +86,6 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() {
         testScope = TestScope()
         mainHandler = FakeHandler(android.os.Looper.getMainLooper())
         trustRepository = FakeTrustRepository()
-        featureFlags = FakeFeatureFlags().apply { set(Flags.DELAY_BOUNCER, true) }
         underTest =
             PrimaryBouncerInteractor(
                 repository,
@@ -103,7 +99,6 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() {
                 context,
                 keyguardUpdateMonitor,
                 trustRepository,
-                featureFlags,
                 testScope.backgroundScope,
             )
         whenever(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt
index 665456d5cd80..cb0b74f3015d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt
@@ -27,8 +27,6 @@ import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepositor
 import com.android.systemui.bouncer.ui.BouncerView
 import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.flags.FakeFeatureFlags
-import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.DismissCallbackRegistry
 import com.android.systemui.keyguard.data.repository.TrustRepository
 import com.android.systemui.statusbar.phone.KeyguardBypassController
@@ -77,7 +75,6 @@ class PrimaryBouncerInteractorWithCoroutinesTest : SysuiTestCase() {
                 context,
                 keyguardUpdateMonitor,
                 Mockito.mock(TrustRepository::class.java),
-                FakeFeatureFlags().apply { set(Flags.DELAY_BOUNCER, true) },
                 TestScope().backgroundScope,
             )
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt
index d4bba723a989..333bd214fe9a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt
@@ -31,8 +31,6 @@ import com.android.systemui.bouncer.ui.BouncerView
 import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.flags.FakeFeatureFlags
-import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.DismissCallbackRegistry
 import com.android.systemui.keyguard.data.repository.TrustRepository
 import com.android.systemui.statusbar.phone.KeyguardBypassController
@@ -85,7 +83,6 @@ class KeyguardBouncerViewModelTest : SysuiTestCase() {
                 context,
                 keyguardUpdateMonitor,
                 Mockito.mock(TrustRepository::class.java),
-                FakeFeatureFlags().apply { set(Flags.DELAY_BOUNCER, true) },
                 TestScope().backgroundScope,
             )
         underTest = KeyguardBouncerViewModel(bouncerView, bouncerInteractor)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt
index da70a9ff036f..4d3ed75de8a0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt
@@ -126,7 +126,6 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() {
                     context,
                     keyguardUpdateMonitor,
                     FakeTrustRepository(),
-                    FakeFeatureFlags().apply { set(Flags.DELAY_BOUNCER, true) },
                     testScope.backgroundScope,
                 ),
                 AlternateBouncerInteractor(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/OccludingAppDeviceEntryInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/OccludingAppDeviceEntryInteractorTest.kt
index b81a3d46b434..47365457d9e4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/OccludingAppDeviceEntryInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/OccludingAppDeviceEntryInteractorTest.kt
@@ -100,11 +100,7 @@ class OccludingAppDeviceEntryInteractorTest : SysuiTestCase() {
         keyguardRepository = FakeKeyguardRepository()
         bouncerRepository = FakeKeyguardBouncerRepository()
         configurationRepository = FakeConfigurationRepository()
-        featureFlags =
-            FakeFeatureFlags().apply {
-                set(Flags.FACE_AUTH_REFACTOR, false)
-                set(Flags.DELAY_BOUNCER, false)
-            }
+        featureFlags = FakeFeatureFlags().apply { set(Flags.FACE_AUTH_REFACTOR, false) }
         trustRepository = FakeTrustRepository()
         powerRepository = FakePowerRepository()
         underTest =
@@ -138,7 +134,6 @@ class OccludingAppDeviceEntryInteractorTest : SysuiTestCase() {
                     context,
                     keyguardUpdateMonitor,
                     trustRepository,
-                    featureFlags,
                     testScope.backgroundScope,
                 ),
                 AlternateBouncerInteractor(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorFactory.kt
index 6dd41f488e2d..ceab8e9e52ee 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorFactory.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorFactory.kt
@@ -72,7 +72,6 @@ object KeyguardDismissInteractorFactory {
         keyguardUpdateMonitor: KeyguardUpdateMonitor = mock(KeyguardUpdateMonitor::class.java),
         featureFlags: FakeFeatureFlagsClassic =
             FakeFeatureFlagsClassic().apply {
-                set(Flags.DELAY_BOUNCER, true)
                 set(Flags.REFACTOR_KEYGUARD_DISMISS_INTENT, true)
                 set(Flags.FULL_SCREEN_USER_SWITCHER, false)
             },
@@ -92,7 +91,6 @@ object KeyguardDismissInteractorFactory {
                 context,
                 keyguardUpdateMonitor,
                 trustRepository,
-                featureFlags,
                 testScope.backgroundScope,
             )
         val alternateBouncerInteractor =
-- 
GitLab


From 8d2fb5b77bf8018833c3e9b70464b173d5c9099b Mon Sep 17 00:00:00 2001
From: Chris Li <lihongyu@google.com>
Date: Mon, 4 Sep 2023 14:43:52 +0800
Subject: [PATCH 06/95] Synchronize window config updates (5/n)

ActivityToken is included in individual transaction item. Cleanup the
activityToken in ClientTransaction.

Bug: 260873529
Test: atest FrameworksCoreTests:ObjectPoolTests
Test: atest FrameworksCoreTests:TransactionExecutorTests
Change-Id: Ib6e953728b9886eee3d1223befd46b58a3cedbf5
---
 core/java/android/app/ActivityThread.java     | 12 +--
 .../ActivityConfigurationChangeItem.java      |  5 +-
 .../ActivityRelaunchItem.java                 |  4 +-
 .../ActivityTransactionItem.java              | 15 +++-
 .../servertransaction/BaseClientRequest.java  | 21 +++--
 .../servertransaction/ClientTransaction.java  | 76 +++++++++---------
 .../ClientTransactionItem.java                | 11 ++-
 .../ConfigurationChangeItem.java              |  8 +-
 .../DestroyActivityItem.java                  |  2 +-
 .../servertransaction/LaunchActivityItem.java |  6 +-
 .../servertransaction/MoveToDisplayItem.java  |  2 +-
 .../servertransaction/PauseActivityItem.java  |  2 +-
 .../RefreshCallbackItem.java                  |  2 +-
 .../servertransaction/ResumeActivityItem.java |  4 +-
 .../servertransaction/StopActivityItem.java   |  2 +-
 .../TopResumedActivityChangeItem.java         |  2 +-
 .../TransactionExecutor.java                  | 24 +++---
 .../TransactionExecutorHelper.java            |  9 +--
 .../WindowContextInfoChangeItem.java          |  5 +-
 .../WindowContextWindowRemovalItem.java       |  2 +-
 .../app/activity/ActivityThreadTest.java      | 40 ++++++----
 .../ActivityConfigurationChangeItemTest.java  |  2 +-
 .../ClientTransactionTests.java               | 20 +++--
 .../ConfigurationChangeItemTest.java          |  5 +-
 .../servertransaction/ObjectPoolTests.java    | 20 ++++-
 .../TransactionExecutorTests.java             | 36 ++++-----
 .../TransactionParcelTests.java               | 12 +--
 .../WindowContextInfoChangeItemTest.java      |  6 +-
 .../WindowContextWindowRemovalItemTest.java   |  4 +-
 .../server/wm/ActivityClientController.java   |  6 +-
 .../com/android/server/wm/ActivityRecord.java | 28 +++----
 .../server/wm/ActivityTaskSupervisor.java     |  2 +-
 .../server/wm/ClientLifecycleManager.java     | 80 +++----------------
 .../wm/DisplayRotationCompatPolicy.java       |  2 +-
 .../com/android/server/wm/TaskFragment.java   |  6 +-
 .../server/wm/ActivityRecordTests.java        | 11 +--
 .../wm/ClientLifecycleManagerTests.java       |  7 +-
 .../wm/DisplayRotationCompatPolicyTests.java  |  3 +-
 .../WindowContextListenerControllerTests.java |  2 +-
 .../wm/WindowProcessControllerTests.java      |  2 +-
 40 files changed, 231 insertions(+), 277 deletions(-)

diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 00e546ad25b0..77c239a60844 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -36,6 +36,7 @@ import static android.view.Display.INVALID_DISPLAY;
 import static android.window.ConfigurationHelper.freeTextLayoutCachesIfNeeded;
 import static android.window.ConfigurationHelper.isDifferentDisplay;
 import static android.window.ConfigurationHelper.shouldUpdateResources;
+
 import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
 import static com.android.internal.os.SafeZipPathValidatorCallback.VALIDATE_ZIP_PATH_FOR_PATH_TRAVERSAL;
 import static com.android.sdksandbox.flags.Flags.sandboxActivitySdkBasedContext;
@@ -3663,10 +3664,9 @@ public final class ActivityThread extends ClientTransactionHandler
             int resultCode, Intent data) {
         if (DEBUG_RESULTS) Slog.v(TAG, "sendActivityResult: id=" + id
                 + " req=" + requestCode + " res=" + resultCode + " data=" + data);
-        ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
+        final ArrayList<ResultInfo> list = new ArrayList<>();
         list.add(new ResultInfo(id, requestCode, resultCode, data));
-        final ClientTransaction clientTransaction = ClientTransaction.obtain(mAppThread,
-                activityToken);
+        final ClientTransaction clientTransaction = ClientTransaction.obtain(mAppThread);
         clientTransaction.addCallback(ActivityResultItem.obtain(activityToken, list));
         try {
             mAppThread.scheduleTransaction(clientTransaction);
@@ -4429,7 +4429,7 @@ public final class ActivityThread extends ClientTransactionHandler
     }
 
     private void schedulePauseWithUserLeavingHint(ActivityClientRecord r) {
-        final ClientTransaction transaction = ClientTransaction.obtain(this.mAppThread, r.token);
+        final ClientTransaction transaction = ClientTransaction.obtain(mAppThread);
         transaction.setLifecycleStateRequest(PauseActivityItem.obtain(r.token,
                 r.activity.isFinishing(), /* userLeaving */ true, r.activity.mConfigChangeFlags,
                 /* dontReport */ false, /* autoEnteringPip */ false));
@@ -4437,7 +4437,7 @@ public final class ActivityThread extends ClientTransactionHandler
     }
 
     private void scheduleResume(ActivityClientRecord r) {
-        final ClientTransaction transaction = ClientTransaction.obtain(this.mAppThread, r.token);
+        final ClientTransaction transaction = ClientTransaction.obtain(mAppThread);
         transaction.setLifecycleStateRequest(ResumeActivityItem.obtain(r.token,
                 /* isForward */ false, /* shouldSendCompatFakeFocus */ false));
         executeTransaction(transaction);
@@ -6029,7 +6029,7 @@ public final class ActivityThread extends ClientTransactionHandler
         final ActivityLifecycleItem lifecycleRequest =
                 TransactionExecutorHelper.getLifecycleRequestForCurrentState(r);
         // Schedule the transaction.
-        final ClientTransaction transaction = ClientTransaction.obtain(this.mAppThread, r.token);
+        final ClientTransaction transaction = ClientTransaction.obtain(mAppThread);
         transaction.addCallback(activityRelaunchItem);
         transaction.setLifecycleStateRequest(lifecycleRequest);
         executeTransaction(transaction);
diff --git a/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java b/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java
index c2c54278a84e..dd332c850d5d 100644
--- a/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java
+++ b/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java
@@ -41,7 +41,7 @@ public class ActivityConfigurationChangeItem extends ActivityTransactionItem {
     private Configuration mConfiguration;
 
     @Override
-    public void preExecute(@NonNull ClientTransactionHandler client, @Nullable IBinder token) {
+    public void preExecute(@NonNull ClientTransactionHandler client) {
         CompatibilityInfo.applyOverrideScaleIfNeeded(mConfiguration);
         // Notify the client of an upcoming change in the token configuration. This ensures that
         // batches of config change items only process the newest configuration.
@@ -59,8 +59,7 @@ public class ActivityConfigurationChangeItem extends ActivityTransactionItem {
 
     @Nullable
     @Override
-    public Context getContextToUpdate(@NonNull ClientTransactionHandler client,
-            @Nullable IBinder token) {
+    public Context getContextToUpdate(@NonNull ClientTransactionHandler client) {
         return client.getActivity(getActivityToken());
     }
 
diff --git a/core/java/android/app/servertransaction/ActivityRelaunchItem.java b/core/java/android/app/servertransaction/ActivityRelaunchItem.java
index 491d0260f6fb..a5dd115d78b3 100644
--- a/core/java/android/app/servertransaction/ActivityRelaunchItem.java
+++ b/core/java/android/app/servertransaction/ActivityRelaunchItem.java
@@ -56,7 +56,7 @@ public class ActivityRelaunchItem extends ActivityTransactionItem {
     private ActivityClientRecord mActivityClientRecord;
 
     @Override
-    public void preExecute(@NonNull ClientTransactionHandler client, @NonNull IBinder token) {
+    public void preExecute(@NonNull ClientTransactionHandler client) {
         // The local config is already scaled so only apply if this item is from server side.
         if (!client.isExecutingLocalTransaction()) {
             CompatibilityInfo.applyOverrideScaleIfNeeded(mConfig);
@@ -78,7 +78,7 @@ public class ActivityRelaunchItem extends ActivityTransactionItem {
     }
 
     @Override
-    public void postExecute(@NonNull ClientTransactionHandler client, @NonNull IBinder token,
+    public void postExecute(@NonNull ClientTransactionHandler client,
             @NonNull PendingTransactionActions pendingActions) {
         final ActivityClientRecord r = getActivityClientRecord(client);
         client.reportRelaunch(r);
diff --git a/core/java/android/app/servertransaction/ActivityTransactionItem.java b/core/java/android/app/servertransaction/ActivityTransactionItem.java
index 0f8879e1429b..2a65b3528145 100644
--- a/core/java/android/app/servertransaction/ActivityTransactionItem.java
+++ b/core/java/android/app/servertransaction/ActivityTransactionItem.java
@@ -16,6 +16,8 @@
 
 package android.app.servertransaction;
 
+import static android.app.servertransaction.TransactionExecutorHelper.getActivityName;
+
 import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
 
 import android.annotation.CallSuper;
@@ -28,6 +30,7 @@ import android.os.Parcel;
 
 import com.android.internal.annotations.VisibleForTesting;
 
+import java.io.PrintWriter;
 import java.util.Objects;
 
 /**
@@ -49,14 +52,14 @@ public abstract class ActivityTransactionItem extends ClientTransactionItem {
     ActivityTransactionItem() {}
 
     @Override
-    public final void execute(@NonNull ClientTransactionHandler client, @NonNull IBinder token,
+    public final void execute(@NonNull ClientTransactionHandler client,
             @NonNull PendingTransactionActions pendingActions) {
         final ActivityClientRecord r = getActivityClientRecord(client);
         execute(client, r, pendingActions);
     }
 
     /**
-     * Like {@link #execute(ClientTransactionHandler, IBinder, PendingTransactionActions)},
+     * Like {@link #execute(ClientTransactionHandler, PendingTransactionActions)},
      * but take non-null {@link ActivityClientRecord} as a parameter.
      */
     @VisibleForTesting(visibility = PACKAGE)
@@ -111,6 +114,14 @@ public abstract class ActivityTransactionItem extends ClientTransactionItem {
         mActivityToken = null;
     }
 
+    @Override
+    void dump(@NonNull String prefix, @NonNull PrintWriter pw,
+            @NonNull ClientTransactionHandler transactionHandler) {
+        super.dump(prefix, pw, transactionHandler);
+        pw.append(prefix).append("Target activity: ")
+                .println(getActivityName(mActivityToken, transactionHandler));
+    }
+
     // Subclass must override and call super.equals to compare the mActivityToken.
     @SuppressWarnings("EqualsGetClass")
     @CallSuper
diff --git a/core/java/android/app/servertransaction/BaseClientRequest.java b/core/java/android/app/servertransaction/BaseClientRequest.java
index c91e0ca5ffc1..f2751752abd8 100644
--- a/core/java/android/app/servertransaction/BaseClientRequest.java
+++ b/core/java/android/app/servertransaction/BaseClientRequest.java
@@ -16,8 +16,8 @@
 
 package android.app.servertransaction;
 
+import android.annotation.NonNull;
 import android.app.ClientTransactionHandler;
-import android.os.IBinder;
 
 /**
  * Base interface for individual requests from server to client.
@@ -27,31 +27,28 @@ import android.os.IBinder;
 public interface BaseClientRequest extends ObjectPoolItem {
 
     /**
-     * Prepare the client request before scheduling.
+     * Prepares the client request before scheduling.
      * An example of this might be informing about pending updates for some values.
      *
      * @param client Target client handler.
-     * @param token  Target activity token.
      */
-    default void preExecute(ClientTransactionHandler client, IBinder token) {
+    default void preExecute(@NonNull ClientTransactionHandler client) {
     }
 
     /**
-     * Execute the request.
+     * Executes the request.
      * @param client Target client handler.
-     * @param token Target activity token.
      * @param pendingActions Container that may have data pending to be used.
      */
-    void execute(ClientTransactionHandler client, IBinder token,
-            PendingTransactionActions pendingActions);
+    void execute(@NonNull ClientTransactionHandler client,
+            @NonNull PendingTransactionActions pendingActions);
 
     /**
-     * Perform all actions that need to happen after execution, e.g. report the result to server.
+     * Performs all actions that need to happen after execution, e.g. report the result to server.
      * @param client Target client handler.
-     * @param token Target activity token.
      * @param pendingActions Container that may have data pending to be used.
      */
-    default void postExecute(ClientTransactionHandler client, IBinder token,
-            PendingTransactionActions pendingActions) {
+    default void postExecute(@NonNull ClientTransactionHandler client,
+            @NonNull PendingTransactionActions pendingActions) {
     }
 }
diff --git a/core/java/android/app/servertransaction/ClientTransaction.java b/core/java/android/app/servertransaction/ClientTransaction.java
index ee14708c38a8..a5b0f18dad3b 100644
--- a/core/java/android/app/servertransaction/ClientTransaction.java
+++ b/core/java/android/app/servertransaction/ClientTransaction.java
@@ -16,6 +16,9 @@
 
 package android.app.servertransaction;
 
+import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
+
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ClientTransactionHandler;
 import android.app.IApplicationThread;
@@ -36,7 +39,7 @@ import java.util.Objects;
  * A container that holds a sequence of messages, which may be sent to a client.
  * This includes a list of callbacks and a final lifecycle state.
  *
- * @see com.android.server.am.ClientLifecycleManager
+ * @see com.android.server.wm.ClientLifecycleManager
  * @see ClientTransactionItem
  * @see ActivityLifecycleItem
  * @hide
@@ -56,9 +59,6 @@ public class ClientTransaction implements Parcelable, ObjectPoolItem {
     /** Target client. */
     private IApplicationThread mClient;
 
-    /** Target client activity. Might be null if the entire transaction is targeting an app. */
-    private IBinder mActivityToken;
-
     /** Get the target client of the transaction. */
     public IApplicationThread getClient() {
         return mClient;
@@ -68,7 +68,7 @@ public class ClientTransaction implements Parcelable, ObjectPoolItem {
      * Add a message to the end of the sequence of callbacks.
      * @param activityCallback A single message that can contain a lifecycle request/callback.
      */
-    public void addCallback(ClientTransactionItem activityCallback) {
+    public void addCallback(@NonNull ClientTransactionItem activityCallback) {
         if (mActivityCallbacks == null) {
             mActivityCallbacks = new ArrayList<>();
         }
@@ -87,11 +87,21 @@ public class ClientTransaction implements Parcelable, ObjectPoolItem {
     @Nullable
     @UnsupportedAppUsage
     public IBinder getActivityToken() {
-        return mActivityToken;
+        // TODO(b/260873529): remove after we allow multiple activity items in one transaction.
+        if (mLifecycleStateRequest != null) {
+            return mLifecycleStateRequest.getActivityToken();
+        }
+        for (int i = mActivityCallbacks.size() - 1; i >= 0; i--) {
+            final IBinder token = mActivityCallbacks.get(i).getActivityToken();
+            if (token != null) {
+                return token;
+            }
+        }
+        return null;
     }
 
     /** Get the target state lifecycle request. */
-    @VisibleForTesting
+    @VisibleForTesting(visibility = PACKAGE)
     @UnsupportedAppUsage
     public ActivityLifecycleItem getLifecycleStateRequest() {
         return mLifecycleStateRequest;
@@ -101,7 +111,7 @@ public class ClientTransaction implements Parcelable, ObjectPoolItem {
      * Set the lifecycle state in which the client should be after executing the transaction.
      * @param stateRequest A lifecycle request initialized with right parameters.
      */
-    public void setLifecycleStateRequest(ActivityLifecycleItem stateRequest) {
+    public void setLifecycleStateRequest(@NonNull ActivityLifecycleItem stateRequest) {
         mLifecycleStateRequest = stateRequest;
     }
 
@@ -110,15 +120,15 @@ public class ClientTransaction implements Parcelable, ObjectPoolItem {
      * @param clientTransactionHandler Handler on the client side that will executed all operations
      *                                 requested by transaction items.
      */
-    public void preExecute(android.app.ClientTransactionHandler clientTransactionHandler) {
+    public void preExecute(@NonNull ClientTransactionHandler clientTransactionHandler) {
         if (mActivityCallbacks != null) {
             final int size = mActivityCallbacks.size();
             for (int i = 0; i < size; ++i) {
-                mActivityCallbacks.get(i).preExecute(clientTransactionHandler, mActivityToken);
+                mActivityCallbacks.get(i).preExecute(clientTransactionHandler);
             }
         }
         if (mLifecycleStateRequest != null) {
-            mLifecycleStateRequest.preExecute(clientTransactionHandler, mActivityToken);
+            mLifecycleStateRequest.preExecute(clientTransactionHandler);
         }
     }
 
@@ -141,14 +151,14 @@ public class ClientTransaction implements Parcelable, ObjectPoolItem {
 
     private ClientTransaction() {}
 
-    /** Obtain an instance initialized with provided params. */
-    public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) {
+    /** Obtains an instance initialized with provided params. */
+    @NonNull
+    public static ClientTransaction obtain(@Nullable IApplicationThread client) {
         ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class);
         if (instance == null) {
             instance = new ClientTransaction();
         }
         instance.mClient = client;
-        instance.mActivityToken = activityToken;
 
         return instance;
     }
@@ -167,7 +177,6 @@ public class ClientTransaction implements Parcelable, ObjectPoolItem {
             mLifecycleStateRequest = null;
         }
         mClient = null;
-        mActivityToken = null;
         ObjectPool.recycle(this);
     }
 
@@ -175,12 +184,7 @@ public class ClientTransaction implements Parcelable, ObjectPoolItem {
 
     /** Write to Parcel. */
     @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        final boolean writeActivityToken = mActivityToken != null;
-        dest.writeBoolean(writeActivityToken);
-        if (writeActivityToken) {
-            dest.writeStrongBinder(mActivityToken);
-        }
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
         dest.writeParcelable(mLifecycleStateRequest, flags);
         final boolean writeActivityCallbacks = mActivityCallbacks != null;
         dest.writeBoolean(writeActivityCallbacks);
@@ -190,11 +194,7 @@ public class ClientTransaction implements Parcelable, ObjectPoolItem {
     }
 
     /** Read from Parcel. */
-    private ClientTransaction(Parcel in) {
-        final boolean readActivityToken = in.readBoolean();
-        if (readActivityToken) {
-            mActivityToken = in.readStrongBinder();
-        }
+    private ClientTransaction(@NonNull Parcel in) {
         mLifecycleStateRequest = in.readParcelable(getClass().getClassLoader(), android.app.servertransaction.ActivityLifecycleItem.class);
         final boolean readActivityCallbacks = in.readBoolean();
         if (readActivityCallbacks) {
@@ -203,9 +203,8 @@ public class ClientTransaction implements Parcelable, ObjectPoolItem {
         }
     }
 
-    public static final @android.annotation.NonNull Creator<ClientTransaction> CREATOR =
-            new Creator<ClientTransaction>() {
-        public ClientTransaction createFromParcel(Parcel in) {
+    public static final @NonNull Creator<ClientTransaction> CREATOR = new Creator<>() {
+        public ClientTransaction createFromParcel(@NonNull Parcel in) {
             return new ClientTransaction(in);
         }
 
@@ -230,8 +229,7 @@ public class ClientTransaction implements Parcelable, ObjectPoolItem {
         final ClientTransaction other = (ClientTransaction) o;
         return Objects.equals(mActivityCallbacks, other.mActivityCallbacks)
                 && Objects.equals(mLifecycleStateRequest, other.mLifecycleStateRequest)
-                && mClient == other.mClient
-                && mActivityToken == other.mActivityToken;
+                && mClient == other.mClient;
     }
 
     @Override
@@ -240,26 +238,32 @@ public class ClientTransaction implements Parcelable, ObjectPoolItem {
         result = 31 * result + Objects.hashCode(mActivityCallbacks);
         result = 31 * result + Objects.hashCode(mLifecycleStateRequest);
         result = 31 * result + Objects.hashCode(mClient);
-        result = 31 * result + Objects.hashCode(mActivityToken);
         return result;
     }
 
     /** Dump transaction items callback items and final lifecycle state request. */
-    public void dump(String prefix, PrintWriter pw) {
+    void dump(@NonNull String prefix, @NonNull PrintWriter pw,
+            @NonNull ClientTransactionHandler transactionHandler) {
         pw.append(prefix).println("ClientTransaction{");
         pw.append(prefix).print("  callbacks=[");
+        final String itemPrefix = prefix + "    ";
         final int size = mActivityCallbacks != null ? mActivityCallbacks.size() : 0;
         if (size > 0) {
             pw.println();
             for (int i = 0; i < size; i++) {
-                pw.append(prefix).append("    ").println(mActivityCallbacks.get(i).toString());
+                mActivityCallbacks.get(i).dump(itemPrefix, pw, transactionHandler);
             }
             pw.append(prefix).println("  ]");
         } else {
             pw.println("]");
         }
-        pw.append(prefix).append("  stateRequest=").println(mLifecycleStateRequest != null
-                ? mLifecycleStateRequest.toString() : null);
+
+        pw.append(prefix).println("  stateRequest=");
+        if (mLifecycleStateRequest != null) {
+            mLifecycleStateRequest.dump(itemPrefix, pw, transactionHandler);
+        } else {
+            pw.append(itemPrefix).println("null");
+        }
         pw.append(prefix).println("}");
     }
 }
diff --git a/core/java/android/app/servertransaction/ClientTransactionItem.java b/core/java/android/app/servertransaction/ClientTransactionItem.java
index 30fc104a71b7..07e5a7dc5f02 100644
--- a/core/java/android/app/servertransaction/ClientTransactionItem.java
+++ b/core/java/android/app/servertransaction/ClientTransactionItem.java
@@ -30,6 +30,8 @@ import android.os.Parcelable;
 
 import com.android.internal.annotations.VisibleForTesting;
 
+import java.io.PrintWriter;
+
 /**
  * A callback message to a client that can be scheduled and executed.
  * Examples of these might be activity configuration change, multi-window mode change, activity
@@ -56,8 +58,7 @@ public abstract class ClientTransactionItem implements BaseClientRequest, Parcel
      * it is updating; otherwise, returns {@code null}.
      */
     @Nullable
-    public Context getContextToUpdate(@NonNull ClientTransactionHandler client,
-            @NonNull IBinder token) {
+    public Context getContextToUpdate(@NonNull ClientTransactionHandler client) {
         return null;
     }
 
@@ -71,6 +72,12 @@ public abstract class ClientTransactionItem implements BaseClientRequest, Parcel
         return null;
     }
 
+    /** Dumps this transaction item. */
+    void dump(@NonNull String prefix, @NonNull PrintWriter pw,
+            @NonNull ClientTransactionHandler transactionHandler) {
+        pw.append(prefix).println(this);
+    }
+
     // Parcelable
 
     @Override
diff --git a/core/java/android/app/servertransaction/ConfigurationChangeItem.java b/core/java/android/app/servertransaction/ConfigurationChangeItem.java
index f72e2e04deca..96961aced987 100644
--- a/core/java/android/app/servertransaction/ConfigurationChangeItem.java
+++ b/core/java/android/app/servertransaction/ConfigurationChangeItem.java
@@ -23,7 +23,6 @@ import android.app.ClientTransactionHandler;
 import android.content.Context;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
-import android.os.IBinder;
 import android.os.Parcel;
 
 import java.util.Objects;
@@ -38,21 +37,20 @@ public class ConfigurationChangeItem extends ClientTransactionItem {
     private int mDeviceId;
 
     @Override
-    public void preExecute(@NonNull ClientTransactionHandler client, @Nullable IBinder token) {
+    public void preExecute(@NonNull ClientTransactionHandler client) {
         CompatibilityInfo.applyOverrideScaleIfNeeded(mConfiguration);
         client.updatePendingConfiguration(mConfiguration);
     }
 
     @Override
-    public void execute(@NonNull ClientTransactionHandler client, @Nullable IBinder token,
+    public void execute(@NonNull ClientTransactionHandler client,
             @NonNull PendingTransactionActions pendingActions) {
         client.handleConfigurationChanged(mConfiguration, mDeviceId);
     }
 
     @Nullable
     @Override
-    public Context getContextToUpdate(@NonNull ClientTransactionHandler client,
-            @Nullable IBinder token) {
+    public Context getContextToUpdate(@NonNull ClientTransactionHandler client) {
         return ActivityThread.currentApplication();
     }
 
diff --git a/core/java/android/app/servertransaction/DestroyActivityItem.java b/core/java/android/app/servertransaction/DestroyActivityItem.java
index a327a99435ce..ddb6df10517c 100644
--- a/core/java/android/app/servertransaction/DestroyActivityItem.java
+++ b/core/java/android/app/servertransaction/DestroyActivityItem.java
@@ -36,7 +36,7 @@ public class DestroyActivityItem extends ActivityLifecycleItem {
     private int mConfigChanges;
 
     @Override
-    public void preExecute(@NonNull ClientTransactionHandler client, @NonNull IBinder token) {
+    public void preExecute(@NonNull ClientTransactionHandler client) {
         client.getActivitiesToBeDestroyed().put(getActivityToken(), this);
     }
 
diff --git a/core/java/android/app/servertransaction/LaunchActivityItem.java b/core/java/android/app/servertransaction/LaunchActivityItem.java
index 9b37a35cdb8f..a64c744c70ba 100644
--- a/core/java/android/app/servertransaction/LaunchActivityItem.java
+++ b/core/java/android/app/servertransaction/LaunchActivityItem.java
@@ -84,7 +84,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
     private IActivityClientController mActivityClientController;
 
     @Override
-    public void preExecute(@NonNull ClientTransactionHandler client, @NonNull IBinder token) {
+    public void preExecute(@NonNull ClientTransactionHandler client) {
         client.countLaunchingActivities(1);
         client.updateProcessState(mProcState, false);
         CompatibilityInfo.applyOverrideScaleIfNeeded(mCurConfig);
@@ -96,7 +96,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
     }
 
     @Override
-    public void execute(@NonNull ClientTransactionHandler client, @NonNull IBinder token,
+    public void execute(@NonNull ClientTransactionHandler client,
             @NonNull PendingTransactionActions pendingActions) {
         Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
         ActivityClientRecord r = new ActivityClientRecord(mActivityToken, mIntent, mIdent, mInfo,
@@ -109,7 +109,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
     }
 
     @Override
-    public void postExecute(@NonNull ClientTransactionHandler client, @NonNull IBinder token,
+    public void postExecute(@NonNull ClientTransactionHandler client,
             @NonNull PendingTransactionActions pendingActions) {
         client.countLaunchingActivities(-1);
     }
diff --git a/core/java/android/app/servertransaction/MoveToDisplayItem.java b/core/java/android/app/servertransaction/MoveToDisplayItem.java
index fb57bed94160..e56d3f862b1b 100644
--- a/core/java/android/app/servertransaction/MoveToDisplayItem.java
+++ b/core/java/android/app/servertransaction/MoveToDisplayItem.java
@@ -40,7 +40,7 @@ public class MoveToDisplayItem extends ActivityTransactionItem {
     private Configuration mConfiguration;
 
     @Override
-    public void preExecute(@NonNull ClientTransactionHandler client, @NonNull IBinder token) {
+    public void preExecute(@NonNull ClientTransactionHandler client) {
         CompatibilityInfo.applyOverrideScaleIfNeeded(mConfiguration);
         // Notify the client of an upcoming change in the token configuration. This ensures that
         // batches of config change items only process the newest configuration.
diff --git a/core/java/android/app/servertransaction/PauseActivityItem.java b/core/java/android/app/servertransaction/PauseActivityItem.java
index a8e6772b4e32..8f1e90b985e6 100644
--- a/core/java/android/app/servertransaction/PauseActivityItem.java
+++ b/core/java/android/app/servertransaction/PauseActivityItem.java
@@ -56,7 +56,7 @@ public class PauseActivityItem extends ActivityLifecycleItem {
     }
 
     @Override
-    public void postExecute(@NonNull ClientTransactionHandler client, @NonNull IBinder token,
+    public void postExecute(@NonNull ClientTransactionHandler client,
             @NonNull PendingTransactionActions pendingActions) {
         if (mDontReport) {
             return;
diff --git a/core/java/android/app/servertransaction/RefreshCallbackItem.java b/core/java/android/app/servertransaction/RefreshCallbackItem.java
index 00128f0d298f..368ed765b922 100644
--- a/core/java/android/app/servertransaction/RefreshCallbackItem.java
+++ b/core/java/android/app/servertransaction/RefreshCallbackItem.java
@@ -51,7 +51,7 @@ public class RefreshCallbackItem extends ActivityTransactionItem {
             @NonNull ActivityClientRecord r, @NonNull PendingTransactionActions pendingActions) {}
 
     @Override
-    public void postExecute(@NonNull ClientTransactionHandler client, @NonNull IBinder token,
+    public void postExecute(@NonNull ClientTransactionHandler client,
             @NonNull PendingTransactionActions pendingActions) {
         final ActivityClientRecord r = getActivityClientRecord(client);
         client.reportRefresh(r);
diff --git a/core/java/android/app/servertransaction/ResumeActivityItem.java b/core/java/android/app/servertransaction/ResumeActivityItem.java
index b11e73cbef96..4a0ea98ccb89 100644
--- a/core/java/android/app/servertransaction/ResumeActivityItem.java
+++ b/core/java/android/app/servertransaction/ResumeActivityItem.java
@@ -44,7 +44,7 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
     private boolean mShouldSendCompatFakeFocus;
 
     @Override
-    public void preExecute(@NonNull ClientTransactionHandler client, @NonNull IBinder token) {
+    public void preExecute(@NonNull ClientTransactionHandler client) {
         if (mUpdateProcState) {
             client.updateProcessState(mProcState, false);
         }
@@ -60,7 +60,7 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
     }
 
     @Override
-    public void postExecute(@NonNull ClientTransactionHandler client, IBinder token,
+    public void postExecute(@NonNull ClientTransactionHandler client,
             @NonNull PendingTransactionActions pendingActions) {
         // TODO(lifecycler): Use interface callback instead of actual implementation.
         ActivityClient.getInstance().activityResumed(getActivityToken(),
diff --git a/core/java/android/app/servertransaction/StopActivityItem.java b/core/java/android/app/servertransaction/StopActivityItem.java
index f4325670c4fc..b8ce52da5a0c 100644
--- a/core/java/android/app/servertransaction/StopActivityItem.java
+++ b/core/java/android/app/servertransaction/StopActivityItem.java
@@ -46,7 +46,7 @@ public class StopActivityItem extends ActivityLifecycleItem {
     }
 
     @Override
-    public void postExecute(@NonNull ClientTransactionHandler client, @NonNull IBinder token,
+    public void postExecute(@NonNull ClientTransactionHandler client,
             @NonNull PendingTransactionActions pendingActions) {
         client.reportStop(pendingActions);
     }
diff --git a/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java b/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java
index 693599fa229c..23d4505c1c9e 100644
--- a/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java
+++ b/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java
@@ -43,7 +43,7 @@ public class TopResumedActivityChangeItem extends ActivityTransactionItem {
     }
 
     @Override
-    public void postExecute(@NonNull ClientTransactionHandler client, @NonNull IBinder token,
+    public void postExecute(@NonNull ClientTransactionHandler client,
             @NonNull PendingTransactionActions pendingActions) {
         if (mOnTop) {
             return;
diff --git a/core/java/android/app/servertransaction/TransactionExecutor.java b/core/java/android/app/servertransaction/TransactionExecutor.java
index d080162e4b8c..44336735254d 100644
--- a/core/java/android/app/servertransaction/TransactionExecutor.java
+++ b/core/java/android/app/servertransaction/TransactionExecutor.java
@@ -74,7 +74,7 @@ public class TransactionExecutor {
      * Then the client will cycle to the final lifecycle state if provided. Otherwise, it will
      * either remain in the initial state, or last state needed by a callback.
      */
-    public void execute(ClientTransaction transaction) {
+    public void execute(@NonNull ClientTransaction transaction) {
         if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");
 
         final IBinder token = transaction.getActivityToken();
@@ -109,7 +109,7 @@ public class TransactionExecutor {
 
     /** Cycle through all states requested by callbacks and execute them at proper times. */
     @VisibleForTesting
-    public void executeCallbacks(ClientTransaction transaction) {
+    public void executeCallbacks(@NonNull ClientTransaction transaction) {
         final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
         if (callbacks == null || callbacks.isEmpty()) {
             // No callbacks to execute, return early.
@@ -117,9 +117,6 @@ public class TransactionExecutor {
         }
         if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callbacks in transaction");
 
-        final IBinder token = transaction.getActivityToken();
-        ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
-
         // In case when post-execution state of the last callback matches the final state requested
         // for the activity in this transaction, we won't do the last transition here and do it when
         // moving to final state instead (because it may contain additional parameters from server).
@@ -135,6 +132,9 @@ public class TransactionExecutor {
         final int size = callbacks.size();
         for (int i = 0; i < size; ++i) {
             final ClientTransactionItem item = callbacks.get(i);
+            final IBinder token = item.getActivityToken();
+            ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
+
             if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callback: " + item);
             final int postExecutionState = item.getPostExecutionState();
 
@@ -150,13 +150,13 @@ public class TransactionExecutor {
             final boolean isSyncWindowConfigUpdateFlagEnabled = !Process.isIsolated()
                     && syncWindowConfigUpdateFlag();
             final Context configUpdatedContext = isSyncWindowConfigUpdateFlagEnabled
-                    ? item.getContextToUpdate(mTransactionHandler, token)
+                    ? item.getContextToUpdate(mTransactionHandler)
                     : null;
             final Configuration preExecutedConfig = configUpdatedContext != null
                     ? new Configuration(configUpdatedContext.getResources().getConfiguration())
                     : null;
 
-            item.execute(mTransactionHandler, token, mPendingActions);
+            item.execute(mTransactionHandler, mPendingActions);
 
             if (configUpdatedContext != null) {
                 final Configuration postExecutedConfig = configUpdatedContext.getResources()
@@ -169,7 +169,7 @@ public class TransactionExecutor {
                 }
             }
 
-            item.postExecute(mTransactionHandler, token, mPendingActions);
+            item.postExecute(mTransactionHandler, mPendingActions);
             if (r == null) {
                 // Launch activity request will create an activity record.
                 r = mTransactionHandler.getActivityClient(token);
@@ -195,14 +195,14 @@ public class TransactionExecutor {
     }
 
     /** Transition to the final state if requested by the transaction. */
-    private void executeLifecycleState(ClientTransaction transaction) {
+    private void executeLifecycleState(@NonNull ClientTransaction transaction) {
         final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
         if (lifecycleItem == null) {
             // No lifecycle request, return early.
             return;
         }
 
-        final IBinder token = transaction.getActivityToken();
+        final IBinder token = lifecycleItem.getActivityToken();
         final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
         if (DEBUG_RESOLVER) {
             Slog.d(TAG, tId(transaction) + "Resolving lifecycle state: "
@@ -219,8 +219,8 @@ public class TransactionExecutor {
         cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);
 
         // Execute the final transition with proper parameters.
-        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
-        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
+        lifecycleItem.execute(mTransactionHandler, mPendingActions);
+        lifecycleItem.postExecute(mTransactionHandler, mPendingActions);
     }
 
     /** Transition the client between states. */
diff --git a/core/java/android/app/servertransaction/TransactionExecutorHelper.java b/core/java/android/app/servertransaction/TransactionExecutorHelper.java
index 0f9c517e2916..7e89a5b45a2d 100644
--- a/core/java/android/app/servertransaction/TransactionExecutorHelper.java
+++ b/core/java/android/app/servertransaction/TransactionExecutorHelper.java
@@ -26,6 +26,7 @@ import static android.app.servertransaction.ActivityLifecycleItem.ON_STOP;
 import static android.app.servertransaction.ActivityLifecycleItem.PRE_ON_CREATE;
 import static android.app.servertransaction.ActivityLifecycleItem.UNDEFINED;
 
+import android.annotation.NonNull;
 import android.app.Activity;
 import android.app.ActivityThread.ActivityClientRecord;
 import android.app.ClientTransactionHandler;
@@ -266,14 +267,12 @@ public class TransactionExecutorHelper {
     }
 
     /** Dump transaction to string. */
-    static String transactionToString(ClientTransaction transaction,
-            ClientTransactionHandler transactionHandler) {
+    static String transactionToString(@NonNull ClientTransaction transaction,
+            @NonNull ClientTransactionHandler transactionHandler) {
         final StringWriter stringWriter = new StringWriter();
         final PrintWriter pw = new PrintWriter(stringWriter);
         final String prefix = tId(transaction);
-        transaction.dump(prefix, pw);
-        pw.append(prefix + "Target activity: ")
-                .println(getActivityName(transaction.getActivityToken(), transactionHandler));
+        transaction.dump(prefix, pw, transactionHandler);
         return stringWriter.toString();
     }
 
diff --git a/core/java/android/app/servertransaction/WindowContextInfoChangeItem.java b/core/java/android/app/servertransaction/WindowContextInfoChangeItem.java
index 99824b000b70..375d1bf57174 100644
--- a/core/java/android/app/servertransaction/WindowContextInfoChangeItem.java
+++ b/core/java/android/app/servertransaction/WindowContextInfoChangeItem.java
@@ -41,15 +41,14 @@ public class WindowContextInfoChangeItem extends ClientTransactionItem {
     private WindowContextInfo mInfo;
 
     @Override
-    public void execute(@NonNull ClientTransactionHandler client, @NonNull IBinder token,
+    public void execute(@NonNull ClientTransactionHandler client,
             @NonNull PendingTransactionActions pendingActions) {
         client.handleWindowContextInfoChanged(mClientToken, mInfo);
     }
 
     @Nullable
     @Override
-    public Context getContextToUpdate(@NonNull ClientTransactionHandler client,
-            @Nullable IBinder token) {
+    public Context getContextToUpdate(@NonNull ClientTransactionHandler client) {
         return client.getWindowContext(mClientToken);
     }
 
diff --git a/core/java/android/app/servertransaction/WindowContextWindowRemovalItem.java b/core/java/android/app/servertransaction/WindowContextWindowRemovalItem.java
index ed52a6496e95..1bea4682928a 100644
--- a/core/java/android/app/servertransaction/WindowContextWindowRemovalItem.java
+++ b/core/java/android/app/servertransaction/WindowContextWindowRemovalItem.java
@@ -36,7 +36,7 @@ public class WindowContextWindowRemovalItem extends ClientTransactionItem {
     private IBinder mClientToken;
 
     @Override
-    public void execute(@NonNull ClientTransactionHandler client, @NonNull IBinder token,
+    public void execute(@NonNull ClientTransactionHandler client,
             @NonNull PendingTransactionActions pendingActions) {
         client.handleWindowContextWindowRemoval(mClientToken);
     }
diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
index 89355072e29e..36e122301ba2 100644
--- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
+++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
@@ -33,7 +33,7 @@ import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
-import android.annotation.Nullable;
+import android.annotation.NonNull;
 import android.app.Activity;
 import android.app.ActivityThread;
 import android.app.ActivityThread.ActivityClientRecord;
@@ -226,7 +226,7 @@ public class ActivityThreadTest {
         CompatibilityInfo.setOverrideInvertedScale(scale);
         try {
             // Send process level config change.
-            ClientTransaction transaction = newTransaction(activityThread, null);
+            ClientTransaction transaction = newTransaction(activityThread);
             transaction.addCallback(ConfigurationChangeItem.obtain(
                     new Configuration(newConfig), DEVICE_ID_INVALID));
             appThread.scheduleTransaction(transaction);
@@ -243,7 +243,7 @@ public class ActivityThreadTest {
             // Send activity level config change.
             newConfig.seq++;
             newConfig.smallestScreenWidthDp++;
-            transaction = newTransaction(activityThread, activity.getActivityToken());
+            transaction = newTransaction(activityThread);
             transaction.addCallback(ActivityConfigurationChangeItem.obtain(
                     activity.getActivityToken(), new Configuration(newConfig)));
             appThread.scheduleTransaction(transaction);
@@ -444,12 +444,12 @@ public class ActivityThreadTest {
         activity.mConfigLatch = new CountDownLatch(1);
         activity.mTestLatch = new CountDownLatch(1);
 
-        ClientTransaction transaction = newTransaction(activityThread, null);
+        ClientTransaction transaction = newTransaction(activityThread);
         transaction.addCallback(ConfigurationChangeItem.obtain(
                 processConfigLandscape, DEVICE_ID_INVALID));
         appThread.scheduleTransaction(transaction);
 
-        transaction = newTransaction(activityThread, activity.getActivityToken());
+        transaction = newTransaction(activityThread);
         transaction.addCallback(ActivityConfigurationChangeItem.obtain(
                 activity.getActivityToken(), activityConfigLandscape));
         transaction.addCallback(ConfigurationChangeItem.obtain(
@@ -829,7 +829,8 @@ public class ActivityThreadTest {
         return thread.getActivityClient(token);
     }
 
-    private static ClientTransaction newRelaunchResumeTransaction(Activity activity) {
+    @NonNull
+    private static ClientTransaction newRelaunchResumeTransaction(@NonNull Activity activity) {
         final Configuration currentConfig = activity.getResources().getConfiguration();
         final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(
                 activity.getActivityToken(), null, null, 0,
@@ -846,7 +847,8 @@ public class ActivityThreadTest {
         return transaction;
     }
 
-    private static ClientTransaction newResumeTransaction(Activity activity) {
+    @NonNull
+    private static ClientTransaction newResumeTransaction(@NonNull Activity activity) {
         final ResumeActivityItem resumeStateRequest =
                 ResumeActivityItem.obtain(activity.getActivityToken(), true /* isForward */,
                         false /* shouldSendCompatFakeFocus */);
@@ -857,7 +859,8 @@ public class ActivityThreadTest {
         return transaction;
     }
 
-    private static ClientTransaction newStopTransaction(Activity activity) {
+    @NonNull
+    private static ClientTransaction newStopTransaction(@NonNull Activity activity) {
         final StopActivityItem stopStateRequest = StopActivityItem.obtain(
                 activity.getActivityToken(), 0 /* configChanges */);
 
@@ -867,8 +870,9 @@ public class ActivityThreadTest {
         return transaction;
     }
 
-    private static ClientTransaction newActivityConfigTransaction(Activity activity,
-            Configuration config) {
+    @NonNull
+    private static ClientTransaction newActivityConfigTransaction(@NonNull Activity activity,
+            @NonNull Configuration config) {
         final ActivityConfigurationChangeItem item = ActivityConfigurationChangeItem.obtain(
                 activity.getActivityToken(), config);
 
@@ -878,8 +882,9 @@ public class ActivityThreadTest {
         return transaction;
     }
 
-    private static ClientTransaction newNewIntentTransaction(Activity activity,
-            List<ReferrerIntent> intents, boolean resume) {
+    @NonNull
+    private static ClientTransaction newNewIntentTransaction(@NonNull Activity activity,
+            @NonNull List<ReferrerIntent> intents, boolean resume) {
         final NewIntentItem item = NewIntentItem.obtain(activity.getActivityToken(), intents,
                 resume);
 
@@ -889,13 +894,14 @@ public class ActivityThreadTest {
         return transaction;
     }
 
-    private static ClientTransaction newTransaction(Activity activity) {
-        return newTransaction(activity.getActivityThread(), activity.getActivityToken());
+    @NonNull
+    private static ClientTransaction newTransaction(@NonNull Activity activity) {
+        return newTransaction(activity.getActivityThread());
     }
 
-    private static ClientTransaction newTransaction(ActivityThread activityThread,
-            @Nullable IBinder activityToken) {
-        return ClientTransaction.obtain(activityThread.getApplicationThread(), activityToken);
+    @NonNull
+    private static ClientTransaction newTransaction(@NonNull ActivityThread activityThread) {
+        return ClientTransaction.obtain(activityThread.getApplicationThread());
     }
 
     // Test activity
diff --git a/core/tests/coretests/src/android/app/servertransaction/ActivityConfigurationChangeItemTest.java b/core/tests/coretests/src/android/app/servertransaction/ActivityConfigurationChangeItemTest.java
index 08033cc4009c..785a8a1ced60 100644
--- a/core/tests/coretests/src/android/app/servertransaction/ActivityConfigurationChangeItemTest.java
+++ b/core/tests/coretests/src/android/app/servertransaction/ActivityConfigurationChangeItemTest.java
@@ -66,7 +66,7 @@ public class ActivityConfigurationChangeItemTest {
 
         final ActivityConfigurationChangeItem item = ActivityConfigurationChangeItem
                 .obtain(mToken, mConfiguration);
-        final Context context = item.getContextToUpdate(mHandler, mToken);
+        final Context context = item.getContextToUpdate(mHandler);
 
         assertEquals(mActivity, context);
     }
diff --git a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java
index 3d252fbddb80..531404bffd50 100644
--- a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java
@@ -21,7 +21,6 @@ import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
 import android.app.ClientTransactionHandler;
-import android.os.IBinder;
 import android.platform.test.annotations.Presubmit;
 
 import androidx.test.filters.SmallTest;
@@ -46,22 +45,21 @@ public class ClientTransactionTests {
 
     @Test
     public void testPreExecute() {
-        ClientTransactionItem callback1 = mock(ClientTransactionItem.class);
-        ClientTransactionItem callback2 = mock(ClientTransactionItem.class);
-        ActivityLifecycleItem stateRequest = mock(ActivityLifecycleItem.class);
-        ClientTransactionHandler clientTransactionHandler = mock(ClientTransactionHandler.class);
-        IBinder token = mock(IBinder.class);
+        final ClientTransactionItem callback1 = mock(ClientTransactionItem.class);
+        final ClientTransactionItem callback2 = mock(ClientTransactionItem.class);
+        final ActivityLifecycleItem stateRequest = mock(ActivityLifecycleItem.class);
+        final ClientTransactionHandler clientTransactionHandler =
+                mock(ClientTransactionHandler.class);
 
-        ClientTransaction transaction = ClientTransaction.obtain(null /* client */,
-                token /* activityToken */);
+        final ClientTransaction transaction = ClientTransaction.obtain(null /* client */);
         transaction.addCallback(callback1);
         transaction.addCallback(callback2);
         transaction.setLifecycleStateRequest(stateRequest);
 
         transaction.preExecute(clientTransactionHandler);
 
-        verify(callback1, times(1)).preExecute(clientTransactionHandler, token);
-        verify(callback2, times(1)).preExecute(clientTransactionHandler, token);
-        verify(stateRequest, times(1)).preExecute(clientTransactionHandler, token);
+        verify(callback1, times(1)).preExecute(clientTransactionHandler);
+        verify(callback2, times(1)).preExecute(clientTransactionHandler);
+        verify(stateRequest, times(1)).preExecute(clientTransactionHandler);
     }
 }
diff --git a/core/tests/coretests/src/android/app/servertransaction/ConfigurationChangeItemTest.java b/core/tests/coretests/src/android/app/servertransaction/ConfigurationChangeItemTest.java
index 3926cfb14194..d9f5523c9782 100644
--- a/core/tests/coretests/src/android/app/servertransaction/ConfigurationChangeItemTest.java
+++ b/core/tests/coretests/src/android/app/servertransaction/ConfigurationChangeItemTest.java
@@ -24,7 +24,6 @@ import android.app.ActivityThread;
 import android.app.ClientTransactionHandler;
 import android.content.Context;
 import android.content.res.Configuration;
-import android.os.IBinder;
 import android.platform.test.annotations.Presubmit;
 
 import androidx.test.filters.SmallTest;
@@ -49,8 +48,6 @@ public class ConfigurationChangeItemTest {
 
     @Mock
     private ClientTransactionHandler mHandler;
-    @Mock
-    private IBinder mToken;
     // Can't mock final class.
     private final Configuration mConfiguration = new Configuration();
 
@@ -63,7 +60,7 @@ public class ConfigurationChangeItemTest {
     public void testGetContextToUpdate() {
         final ConfigurationChangeItem item = ConfigurationChangeItem
                 .obtain(mConfiguration, DEVICE_ID_DEFAULT);
-        final Context context = item.getContextToUpdate(mHandler, mToken);
+        final Context context = item.getContextToUpdate(mHandler);
 
         assertEquals(ActivityThread.currentApplication(), context);
     }
diff --git a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
index c8d8f4be9e0a..4bbde0cd6366 100644
--- a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
@@ -27,6 +27,7 @@ import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.assertSame;
 
 import android.app.ActivityOptions;
+import android.app.IApplicationThread;
 import android.app.servertransaction.TestUtils.LaunchActivityItemBuilder;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
@@ -41,8 +42,11 @@ import android.platform.test.annotations.Presubmit;
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 import java.util.function.Supplier;
 
@@ -60,7 +64,15 @@ import java.util.function.Supplier;
 @Presubmit
 public class ObjectPoolTests {
 
-    private final IBinder mActivityToken = new Binder();
+    @Mock
+    private IApplicationThread mApplicationThread;
+    @Mock
+    private IBinder mActivityToken;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+    }
 
     // 1. Check if two obtained objects from pool are not the same.
     // 2. Check if the state of the object is cleared after recycling.
@@ -309,15 +321,15 @@ public class ObjectPoolTests {
 
     @Test
     public void testRecycleClientTransaction() {
-        ClientTransaction emptyItem = ClientTransaction.obtain(null, null);
-        ClientTransaction item = ClientTransaction.obtain(null, new Binder());
+        ClientTransaction emptyItem = ClientTransaction.obtain(null);
+        ClientTransaction item = ClientTransaction.obtain(mApplicationThread);
         assertNotSame(item, emptyItem);
         assertNotEquals(item, emptyItem);
 
         item.recycle();
         assertEquals(item, emptyItem);
 
-        ClientTransaction item2 = ClientTransaction.obtain(null, new Binder());
+        ClientTransaction item2 = ClientTransaction.obtain(mApplicationThread);
         assertSame(item, item2);
         assertNotEquals(item2, emptyItem);
     }
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
index a998b26b09c1..a1a2bdbe0f15 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
@@ -37,6 +37,7 @@ import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.annotation.NonNull;
 import android.app.Activity;
 import android.app.ActivityThread.ActivityClientRecord;
 import android.app.ClientTransactionHandler;
@@ -230,8 +231,7 @@ public class TransactionExecutorTests {
         when(stateRequest.getActivityToken()).thenReturn(token);
         when(mTransactionHandler.getActivity(token)).thenReturn(mock(Activity.class));
 
-        ClientTransaction transaction = ClientTransaction.obtain(null /* client */,
-                token /* activityToken */);
+        ClientTransaction transaction = ClientTransaction.obtain(null /* client */);
         transaction.addCallback(callback1);
         transaction.addCallback(callback2);
         transaction.setLifecycleStateRequest(stateRequest);
@@ -240,8 +240,8 @@ public class TransactionExecutorTests {
         mExecutor.execute(transaction);
 
         InOrder inOrder = inOrder(mTransactionHandler, callback1, callback2, stateRequest);
-        inOrder.verify(callback1).execute(eq(mTransactionHandler), eq(token), any());
-        inOrder.verify(callback2).execute(eq(mTransactionHandler), eq(token), any());
+        inOrder.verify(callback1).execute(eq(mTransactionHandler), any());
+        inOrder.verify(callback2).execute(eq(mTransactionHandler), any());
         inOrder.verify(stateRequest).execute(eq(mTransactionHandler), eq(mClientRecord), any());
     }
 
@@ -254,8 +254,7 @@ public class TransactionExecutorTests {
 
         // An incoming destroy transaction enters binder thread (preExecute).
         final IBinder token = mock(IBinder.class);
-        final ClientTransaction destroyTransaction = ClientTransaction.obtain(null /* client */,
-                token /* activityToken */);
+        final ClientTransaction destroyTransaction = ClientTransaction.obtain(null /* client */);
         destroyTransaction.setLifecycleStateRequest(
                 DestroyActivityItem.obtain(token, false /* finished */, 0 /* configChanges */));
         destroyTransaction.preExecute(mTransactionHandler);
@@ -263,8 +262,7 @@ public class TransactionExecutorTests {
         assertEquals(1, mTransactionHandler.getActivitiesToBeDestroyed().size());
 
         // A previous queued launch transaction runs on main thread (execute).
-        final ClientTransaction launchTransaction = ClientTransaction.obtain(null /* client */,
-                token /* activityToken */);
+        final ClientTransaction launchTransaction = ClientTransaction.obtain(null /* client */);
         final LaunchActivityItem launchItem =
                 spy(new LaunchActivityItemBuilder().setActivityToken(token).build());
         launchTransaction.addCallback(launchItem);
@@ -272,7 +270,7 @@ public class TransactionExecutorTests {
 
         // The launch transaction should not be executed because its token is in the
         // to-be-destroyed container.
-        verify(launchItem, never()).execute(any(), any(), any());
+        verify(launchItem, never()).execute(any(), any());
 
         // After the destroy transaction has been executed, the token should be removed.
         mExecutor.execute(destroyTransaction);
@@ -286,8 +284,7 @@ public class TransactionExecutorTests {
         PostExecItem postExecItem = new PostExecItem(ON_RESUME);
 
         IBinder token = mock(IBinder.class);
-        ClientTransaction transaction = ClientTransaction.obtain(null /* client */,
-                token /* activityToken */);
+        ClientTransaction transaction = ClientTransaction.obtain(null /* client */);
         transaction.addCallback(postExecItem);
 
         // Verify resolution that should get to onPause
@@ -439,7 +436,7 @@ public class TransactionExecutorTests {
         final ActivityTransactionItem activityItem = mock(ActivityTransactionItem.class);
         when(activityItem.getPostExecutionState()).thenReturn(UNDEFINED);
         final IBinder token = mock(IBinder.class);
-        final ClientTransaction transaction = ClientTransaction.obtain(null /* client */, token);
+        final ClientTransaction transaction = ClientTransaction.obtain(null /* client */);
         transaction.addCallback(activityItem);
         when(mTransactionHandler.getActivityClient(token)).thenReturn(null);
 
@@ -449,7 +446,7 @@ public class TransactionExecutorTests {
     @Test
     public void testActivityItemExecute() {
         final IBinder token = mock(IBinder.class);
-        final ClientTransaction transaction = ClientTransaction.obtain(null /* client */, token);
+        final ClientTransaction transaction = ClientTransaction.obtain(null /* client */);
         final ActivityTransactionItem activityItem = mock(ActivityTransactionItem.class);
         when(activityItem.getPostExecutionState()).thenReturn(UNDEFINED);
         when(activityItem.getActivityToken()).thenReturn(token);
@@ -504,12 +501,12 @@ public class TransactionExecutorTests {
         private StubItem() {
         }
 
-        private StubItem(Parcel in) {
+        private StubItem(@NonNull Parcel in) {
         }
 
         @Override
-        public void execute(ClientTransactionHandler client, IBinder token,
-                PendingTransactionActions pendingActions) {
+        public void execute(@NonNull ClientTransactionHandler client,
+                @NonNull PendingTransactionActions pendingActions) {
         }
 
         @Override
@@ -517,12 +514,11 @@ public class TransactionExecutorTests {
         }
 
         @Override
-        public void writeToParcel(Parcel dest, int flags) {
+        public void writeToParcel(@NonNull Parcel dest, int flags) {
         }
 
-        public static final Parcelable.Creator<StubItem> CREATOR =
-                new Parcelable.Creator<StubItem>() {
-            public StubItem createFromParcel(Parcel in) {
+        public static final Parcelable.Creator<StubItem> CREATOR = new Parcelable.Creator<>() {
+            public StubItem createFromParcel(@NonNull Parcel in) {
                 return new StubItem(in);
             }
 
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
index abc5d6b35b02..7d047c93520f 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
@@ -284,9 +284,7 @@ public class TransactionParcelTests {
         StopActivityItem lifecycleRequest = StopActivityItem.obtain(mActivityToken,
                 78 /* configChanges */);
 
-        Binder activityToken = new Binder();
-
-        ClientTransaction transaction = ClientTransaction.obtain(null, activityToken);
+        ClientTransaction transaction = ClientTransaction.obtain(null /* client */);
         transaction.addCallback(callback1);
         transaction.addCallback(callback2);
         transaction.setLifecycleStateRequest(lifecycleRequest);
@@ -307,9 +305,7 @@ public class TransactionParcelTests {
         ActivityConfigurationChangeItem callback2 = ActivityConfigurationChangeItem.obtain(
                 mActivityToken, config());
 
-        Binder activityToken = new Binder();
-
-        ClientTransaction transaction = ClientTransaction.obtain(null, activityToken);
+        ClientTransaction transaction = ClientTransaction.obtain(null /* client */);
         transaction.addCallback(callback1);
         transaction.addCallback(callback2);
 
@@ -328,9 +324,7 @@ public class TransactionParcelTests {
         StopActivityItem lifecycleRequest = StopActivityItem.obtain(mActivityToken,
                 78 /* configChanges */);
 
-        Binder activityToken = new Binder();
-
-        ClientTransaction transaction = ClientTransaction.obtain(null, activityToken);
+        ClientTransaction transaction = ClientTransaction.obtain(null /* client */);
         transaction.setLifecycleStateRequest(lifecycleRequest);
 
         writeAndPrepareForReading(transaction);
diff --git a/core/tests/coretests/src/android/app/servertransaction/WindowContextInfoChangeItemTest.java b/core/tests/coretests/src/android/app/servertransaction/WindowContextInfoChangeItemTest.java
index db76d26b063e..a801a76d16c9 100644
--- a/core/tests/coretests/src/android/app/servertransaction/WindowContextInfoChangeItemTest.java
+++ b/core/tests/coretests/src/android/app/servertransaction/WindowContextInfoChangeItemTest.java
@@ -53,8 +53,6 @@ public class WindowContextInfoChangeItemTest {
     @Mock
     private ClientTransactionHandler mHandler;
     @Mock
-    private IBinder mToken;
-    @Mock
     private PendingTransactionActions mPendingActions;
     @Mock
     private IBinder mClientToken;
@@ -72,7 +70,7 @@ public class WindowContextInfoChangeItemTest {
     public void testExecute() {
         final WindowContextInfoChangeItem item = WindowContextInfoChangeItem
                 .obtain(mClientToken, mConfiguration, DEFAULT_DISPLAY);
-        item.execute(mHandler, mToken, mPendingActions);
+        item.execute(mHandler, mPendingActions);
 
         verify(mHandler).handleWindowContextInfoChanged(mClientToken,
                 new WindowContextInfo(mConfiguration, DEFAULT_DISPLAY));
@@ -84,7 +82,7 @@ public class WindowContextInfoChangeItemTest {
 
         final WindowContextInfoChangeItem item = WindowContextInfoChangeItem
                 .obtain(mClientToken, mConfiguration, DEFAULT_DISPLAY);
-        final Context context = item.getContextToUpdate(mHandler, mToken);
+        final Context context = item.getContextToUpdate(mHandler);
 
         assertEquals(mWindowContext, context);
     }
diff --git a/core/tests/coretests/src/android/app/servertransaction/WindowContextWindowRemovalItemTest.java b/core/tests/coretests/src/android/app/servertransaction/WindowContextWindowRemovalItemTest.java
index 17e0ebc1edbc..cf9935f2822f 100644
--- a/core/tests/coretests/src/android/app/servertransaction/WindowContextWindowRemovalItemTest.java
+++ b/core/tests/coretests/src/android/app/servertransaction/WindowContextWindowRemovalItemTest.java
@@ -45,8 +45,6 @@ public class WindowContextWindowRemovalItemTest {
     @Mock
     private ClientTransactionHandler mHandler;
     @Mock
-    private IBinder mToken;
-    @Mock
     private PendingTransactionActions mPendingActions;
     @Mock
     private IBinder mClientToken;
@@ -60,7 +58,7 @@ public class WindowContextWindowRemovalItemTest {
     public void testExecute() {
         final WindowContextWindowRemovalItem item = WindowContextWindowRemovalItem.obtain(
                 mClientToken);
-        item.execute(mHandler, mToken, mPendingActions);
+        item.execute(mHandler, mPendingActions);
 
         verify(mHandler).handleWindowContextWindowRemoval(mClientToken);
     }
diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java
index 4c9ec9d863bb..3c8e630dba2b 100644
--- a/services/core/java/com/android/server/wm/ActivityClientController.java
+++ b/services/core/java/com/android/server/wm/ActivityClientController.java
@@ -1018,8 +1018,7 @@ class ActivityClientController extends IActivityClientController.Stub {
         }
 
         try {
-            final ClientTransaction transaction = ClientTransaction.obtain(
-                    r.app.getThread(), r.token);
+            final ClientTransaction transaction = ClientTransaction.obtain(r.app.getThread());
             transaction.addCallback(EnterPipRequestedItem.obtain(r.token));
             mService.getLifecycleManager().scheduleTransaction(transaction);
             return true;
@@ -1040,8 +1039,7 @@ class ActivityClientController extends IActivityClientController.Stub {
         }
 
         try {
-            final ClientTransaction transaction = ClientTransaction.obtain(
-                    r.app.getThread(), r.token);
+            final ClientTransaction transaction = ClientTransaction.obtain(r.app.getThread());
             transaction.addCallback(PipStateTransactionItem.obtain(r.token, pipState));
             mService.getLifecycleManager().scheduleTransaction(transaction);
         } catch (Exception e) {
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index dca2b6f8f2af..f42dc2564be6 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1442,7 +1442,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                     + "display, activityRecord=%s, displayId=%d, config=%s", this, displayId,
                     config);
 
-            mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), token,
+            mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(),
                     MoveToDisplayItem.obtain(token, displayId, config));
         } catch (RemoteException e) {
             // If process died, whatever.
@@ -1459,7 +1459,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
             ProtoLog.v(WM_DEBUG_CONFIGURATION, "Sending new config to %s, "
                     + "config: %s", this, config);
 
-            mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), token,
+            mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(),
                     ActivityConfigurationChangeItem.obtain(token, config));
         } catch (RemoteException e) {
             // If process died, whatever.
@@ -1480,7 +1480,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
             ProtoLog.v(WM_DEBUG_STATES, "Sending position change to %s, onTop: %b",
                     this, onTop);
 
-            mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), token,
+            mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(),
                     TopResumedActivityChangeItem.obtain(token, onTop));
         } catch (RemoteException e) {
             // If process died, whatever.
@@ -2727,7 +2727,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
         }
         try {
             mTransferringSplashScreenState = TRANSFER_SPLASH_SCREEN_ATTACH_TO_CLIENT;
-            mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), token,
+            mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(),
                     TransferSplashScreenViewStateItem.obtain(token, parcelable,
                             windowAnimationLeash));
             scheduleTransferSplashScreenTimeout();
@@ -3894,7 +3894,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
 
             try {
                 if (DEBUG_SWITCH) Slog.i(TAG_SWITCH, "Destroying: " + this);
-                mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), token,
+                mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(),
                         DestroyActivityItem.obtain(token, finishing, configChangeFlags));
             } catch (Exception e) {
                 // We can just ignore exceptions here...  if the process has crashed, our death
@@ -4800,9 +4800,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
 
         if (isState(RESUMED) && attachedToProcess()) {
             try {
-                final ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
+                final ArrayList<ResultInfo> list = new ArrayList<>();
                 list.add(new ResultInfo(resultWho, requestCode, resultCode, data));
-                mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), token,
+                mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(),
                         ActivityResultItem.obtain(token, list));
                 return;
             } catch (Exception e) {
@@ -4813,7 +4813,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
         // Schedule sending results now for Media Projection setup.
         if (forceSendForMediaProjection && attachedToProcess() && isState(STARTED, PAUSING, PAUSED,
                 STOPPING, STOPPED)) {
-            final ClientTransaction transaction = ClientTransaction.obtain(app.getThread(), token);
+            final ClientTransaction transaction = ClientTransaction.obtain(app.getThread());
             // Build result to be returned immediately.
             transaction.addCallback(ActivityResultItem.obtain(
                     token, List.of(new ResultInfo(resultWho, requestCode, resultCode, data))));
@@ -4908,7 +4908,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                 // Making sure the client state is RESUMED after transaction completed and doing
                 // so only if activity is currently RESUMED. Otherwise, client may have extra
                 // life-cycle calls to RESUMED (and PAUSED later).
-                mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), token,
+                mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(),
                         NewIntentItem.obtain(token, ar, mState == RESUMED));
                 unsent = false;
             } catch (RemoteException e) {
@@ -6143,7 +6143,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
             EventLogTags.writeWmPauseActivity(mUserId, System.identityHashCode(this),
                     shortComponentName, "userLeaving=false", "make-active");
             try {
-                mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), token,
+                mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(),
                         PauseActivityItem.obtain(token, finishing, false /* userLeaving */,
                                 configChangeFlags, false /* dontReport */, mAutoEnteringPip));
             } catch (Exception e) {
@@ -6156,7 +6156,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
             setState(STARTED, "makeActiveIfNeeded");
 
             try {
-                mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), token,
+                mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(),
                         StartActivityItem.obtain(token, takeOptions()));
             } catch (Exception e) {
                 Slog.w(TAG, "Exception thrown sending start: " + intent.getComponent(), e);
@@ -6454,7 +6454,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
             }
             EventLogTags.writeWmStopActivity(
                     mUserId, System.identityHashCode(this), shortComponentName);
-            mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), token,
+            mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(),
                     StopActivityItem.obtain(token, configChangeFlags));
 
             mAtmService.mH.postDelayed(mStopTimeoutRunnable, STOP_TIMEOUT);
@@ -9882,7 +9882,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
             } else {
                 lifecycleItem = PauseActivityItem.obtain(token);
             }
-            final ClientTransaction transaction = ClientTransaction.obtain(app.getThread(), token);
+            final ClientTransaction transaction = ClientTransaction.obtain(app.getThread());
             transaction.addCallback(callbackItem);
             transaction.setLifecycleStateRequest(lifecycleItem);
             mAtmService.getLifecycleManager().scheduleTransaction(transaction);
@@ -9976,7 +9976,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
         // The process will be killed until the activity reports stopped with saved state (see
         // {@link ActivityTaskManagerService.activityStopped}).
         try {
-            mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), token,
+            mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(),
                     StopActivityItem.obtain(token, 0 /* configChanges */));
         } catch (RemoteException e) {
             Slog.w(TAG, "Exception thrown during restart " + this, e);
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index e523119ee9a0..7266a1439ffe 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -923,7 +923,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
 
                 // Create activity launch transaction.
                 final ClientTransaction clientTransaction = ClientTransaction.obtain(
-                        proc.getThread(), r.token);
+                        proc.getThread());
 
                 final boolean isTransitionForward = r.isTransitionForward();
                 final IBinder fragmentToken = r.getTaskFragment().getFragmentToken();
diff --git a/services/core/java/com/android/server/wm/ClientLifecycleManager.java b/services/core/java/com/android/server/wm/ClientLifecycleManager.java
index 7430f0f1dc47..ef31837f810b 100644
--- a/services/core/java/com/android/server/wm/ClientLifecycleManager.java
+++ b/services/core/java/com/android/server/wm/ClientLifecycleManager.java
@@ -18,11 +18,10 @@ package com.android.server.wm;
 
 import android.annotation.NonNull;
 import android.app.IApplicationThread;
+import android.app.servertransaction.ActivityLifecycleItem;
 import android.app.servertransaction.ClientTransaction;
 import android.app.servertransaction.ClientTransactionItem;
-import android.app.servertransaction.ActivityLifecycleItem;
 import android.os.Binder;
-import android.os.IBinder;
 import android.os.RemoteException;
 
 /**
@@ -36,13 +35,13 @@ class ClientLifecycleManager {
     // TODO(lifecycler): Use object pools for transactions and transaction items.
 
     /**
-     * Schedule a transaction, which may consist of multiple callbacks and a lifecycle request.
+     * Schedules a transaction, which may consist of multiple callbacks and a lifecycle request.
      * @param transaction A sequence of client transaction items.
      * @throws RemoteException
      *
      * @see ClientTransaction
      */
-    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
+    void scheduleTransaction(@NonNull ClientTransaction transaction) throws RemoteException {
         final IApplicationThread client = transaction.getClient();
         transaction.schedule();
         if (!(client instanceof Binder)) {
@@ -54,75 +53,22 @@ class ClientLifecycleManager {
     }
 
     /**
-     * Schedule a single lifecycle request or callback to client activity.
-     * @param client Target client.
-     * @param activityToken Target activity token.
-     * @param stateRequest A request to move target activity to a desired lifecycle state.
-     * @throws RemoteException
-     *
-     * @see ClientTransactionItem
-     */
-    void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,
-            @NonNull ActivityLifecycleItem stateRequest) throws RemoteException {
-        final ClientTransaction clientTransaction = transactionWithState(client, activityToken,
-                stateRequest);
-        scheduleTransaction(clientTransaction);
-    }
-
-    /**
-     * Schedule a single callback delivery to client activity.
+     * Schedules a single transaction item, either a callback or a lifecycle request, delivery to
+     * client application.
      * @param client Target client.
-     * @param activityToken Target activity token.
-     * @param callback A request to deliver a callback.
-     * @throws RemoteException
-     *
-     * @see ClientTransactionItem
-     */
-    void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,
-            @NonNull ClientTransactionItem callback) throws RemoteException {
-        final ClientTransaction clientTransaction = transactionWithCallback(client, activityToken,
-                callback);
-        scheduleTransaction(clientTransaction);
-    }
-
-    /**
-     * Schedule a single callback delivery to client application.
-     * @param client Target client.
-     * @param callback A request to deliver a callback.
+     * @param transactionItem A transaction item to deliver a message.
      * @throws RemoteException
      *
      * @see ClientTransactionItem
      */
     void scheduleTransaction(@NonNull IApplicationThread client,
-            @NonNull ClientTransactionItem callback) throws RemoteException {
-        final ClientTransaction clientTransaction = transactionWithCallback(client,
-                null /* activityToken */, callback);
+            @NonNull ClientTransactionItem transactionItem) throws RemoteException {
+        final ClientTransaction clientTransaction = ClientTransaction.obtain(client);
+        if (transactionItem instanceof ActivityLifecycleItem) {
+            clientTransaction.setLifecycleStateRequest((ActivityLifecycleItem) transactionItem);
+        } else {
+            clientTransaction.addCallback(transactionItem);
+        }
         scheduleTransaction(clientTransaction);
     }
-
-    /**
-     * @return A new instance of {@link ClientTransaction} with a single lifecycle state request.
-     *
-     * @see ClientTransaction
-     * @see ClientTransactionItem
-     */
-    private static ClientTransaction transactionWithState(@NonNull IApplicationThread client,
-            @NonNull IBinder activityToken, @NonNull ActivityLifecycleItem stateRequest) {
-        final ClientTransaction clientTransaction = ClientTransaction.obtain(client, activityToken);
-        clientTransaction.setLifecycleStateRequest(stateRequest);
-        return clientTransaction;
-    }
-
-    /**
-     * @return A new instance of {@link ClientTransaction} with a single callback invocation.
-     *
-     * @see ClientTransaction
-     * @see ClientTransactionItem
-     */
-    private static ClientTransaction transactionWithCallback(@NonNull IApplicationThread client,
-            IBinder activityToken, @NonNull ClientTransactionItem callback) {
-        final ClientTransaction clientTransaction = ClientTransaction.obtain(client, activityToken);
-        clientTransaction.addCallback(callback);
-        return clientTransaction;
-    }
 }
diff --git a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
index c4ed0dd9d606..534cdc2015e3 100644
--- a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
@@ -227,7 +227,7 @@ final class DisplayRotationCompatPolicy {
                     "Refreshing activity for camera compatibility treatment, "
                             + "activityRecord=%s", activity);
             final ClientTransaction transaction = ClientTransaction.obtain(
-                    activity.app.getThread(), activity.token);
+                    activity.app.getThread());
             transaction.addCallback(RefreshCallbackItem.obtain(activity.token,
                             cycleThroughStop ? ON_STOP : ON_PAUSE));
             transaction.setLifecycleStateRequest(ResumeActivityItem.obtain(activity.token,
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 57f44cb599fe..1da5cc0cb865 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -1456,8 +1456,8 @@ class TaskFragment extends WindowContainer<WindowContainer> {
             }
 
             try {
-                final ClientTransaction transaction =
-                        ClientTransaction.obtain(next.app.getThread(), next.token);
+                final ClientTransaction transaction = ClientTransaction.obtain(
+                        next.app.getThread());
                 // Deliver all pending results.
                 ArrayList<ResultInfo> a = next.results;
                 if (a != null) {
@@ -1726,7 +1726,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
                     prev.shortComponentName, "userLeaving=" + userLeaving, reason);
 
             mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
-                    prev.token, PauseActivityItem.obtain(prev.token, prev.finishing, userLeaving,
+                    PauseActivityItem.obtain(prev.token, prev.finishing, userLeaving,
                             prev.configChangeFlags, pauseImmediately, autoEnteringPip));
         } catch (Exception e) {
             // Ignore exception, if process died other code will cleanup.
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index ae587003c1c2..e4a9cdda0b64 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -489,7 +489,7 @@ public class ActivityRecordTests extends WindowTestsBase {
         ensureActivityConfiguration(activity);
 
         verify(mAtm.getLifecycleManager(), never())
-                .scheduleTransaction(any(), any(), isA(ActivityConfigurationChangeItem.class));
+                .scheduleTransaction(any(), isA(ActivityConfigurationChangeItem.class));
     }
 
     @Test
@@ -519,7 +519,7 @@ public class ActivityRecordTests extends WindowTestsBase {
         final ActivityConfigurationChangeItem expected =
                 ActivityConfigurationChangeItem.obtain(activity.token, newConfig);
         verify(mAtm.getLifecycleManager()).scheduleTransaction(
-                eq(activity.app.getThread()), eq(activity.token), eq(expected));
+                eq(activity.app.getThread()), eq(expected));
     }
 
     @Test
@@ -599,7 +599,7 @@ public class ActivityRecordTests extends WindowTestsBase {
         final ActivityConfigurationChangeItem expected =
                 ActivityConfigurationChangeItem.obtain(activity.token, newConfig);
         verify(mAtm.getLifecycleManager()).scheduleTransaction(eq(activity.app.getThread()),
-                eq(activity.token), eq(expected));
+                eq(expected));
 
         verify(displayRotation).onSetRequestedOrientation();
     }
@@ -817,7 +817,7 @@ public class ActivityRecordTests extends WindowTestsBase {
             final ActivityConfigurationChangeItem expected =
                     ActivityConfigurationChangeItem.obtain(activity.token, newConfig);
             verify(mAtm.getLifecycleManager()).scheduleTransaction(
-                    eq(activity.app.getThread()), eq(activity.token), eq(expected));
+                    eq(activity.app.getThread()), eq(expected));
         } finally {
             stack.getDisplayArea().removeChild(stack);
         }
@@ -1787,9 +1787,10 @@ public class ActivityRecordTests extends WindowTestsBase {
             final ActivityRecord activity = createActivityWithTask();
             final WindowProcessController wpc = activity.app;
             setup.accept(activity);
+            clearInvocations(mAtm.getLifecycleManager());
             activity.getTask().removeImmediately("test");
             try {
-                verify(mAtm.getLifecycleManager()).scheduleTransaction(any(), eq(activity.token),
+                verify(mAtm.getLifecycleManager()).scheduleTransaction(any(),
                         isA(DestroyActivityItem.class));
             } catch (RemoteException ignored) {
             }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ClientLifecycleManagerTests.java b/services/tests/wmtests/src/com/android/server/wm/ClientLifecycleManagerTests.java
index 28dd458a786c..a18dbaf39575 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ClientLifecycleManagerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ClientLifecycleManagerTests.java
@@ -23,7 +23,6 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 
 import android.app.IApplicationThread;
 import android.app.servertransaction.ClientTransaction;
-import android.os.Binder;
 import android.platform.test.annotations.Presubmit;
 
 import androidx.test.filters.SmallTest;
@@ -40,8 +39,7 @@ public class ClientLifecycleManagerTests {
 
     @Test
     public void testScheduleAndRecycleBinderClientTransaction() throws Exception {
-        ClientTransaction item = spy(ClientTransaction.obtain(mock(IApplicationThread.class),
-                new Binder()));
+        ClientTransaction item = spy(ClientTransaction.obtain(mock(IApplicationThread.class)));
 
         ClientLifecycleManager clientLifecycleManager = new ClientLifecycleManager();
         clientLifecycleManager.scheduleTransaction(item);
@@ -51,8 +49,7 @@ public class ClientLifecycleManagerTests {
 
     @Test
     public void testScheduleNoRecycleNonBinderClientTransaction() throws Exception {
-        ClientTransaction item = spy(ClientTransaction.obtain(mock(IApplicationThread.Stub.class),
-                new Binder()));
+        ClientTransaction item = spy(ClientTransaction.obtain(mock(IApplicationThread.Stub.class)));
 
         ClientLifecycleManager clientLifecycleManager = new ClientLifecycleManager();
         clientLifecycleManager.scheduleTransaction(item);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java
index 1b44c01bfab5..2af67452283b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java
@@ -571,8 +571,7 @@ public final class DisplayRotationCompatPolicyTests extends WindowTestsBase {
         verify(mActivity.mLetterboxUiController, times(refreshRequested ? 1 : 0))
                 .setIsRefreshAfterRotationRequested(true);
 
-        final ClientTransaction transaction = ClientTransaction.obtain(
-                mActivity.app.getThread(), mActivity.token);
+        final ClientTransaction transaction = ClientTransaction.obtain(mActivity.app.getThread());
         transaction.addCallback(RefreshCallbackItem.obtain(mActivity.token,
                 cycleThroughStop ? ON_STOP : ON_PAUSE));
         transaction.setLifecycleStateRequest(ResumeActivityItem.obtain(mActivity.token,
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java
index d85d9b5729a0..2d5b72b3c680 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java
@@ -111,7 +111,7 @@ public class WindowContextListenerControllerTests extends WindowTestsBase {
                 return null;
             }
             final WindowContextInfoChangeItem infoChangeItem = (WindowContextInfoChangeItem) item;
-            infoChangeItem.execute(mHandler, null, null);
+            infoChangeItem.execute(mHandler, null /* pendingActions */);
             return null;
         }).when(mWpc).scheduleClientTransactionItem(any());
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
index ebe40b05162d..b89182d728ec 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
@@ -330,7 +330,7 @@ public class WindowProcessControllerTests extends WindowTestsBase {
                 ArgumentCaptor.forClass(ConfigurationChangeItem.class);
         verify(clientManager).scheduleTransaction(eq(thread), captor.capture());
         final ClientTransactionHandler client = mock(ClientTransactionHandler.class);
-        captor.getValue().preExecute(client, null /* token */);
+        captor.getValue().preExecute(client);
         final ArgumentCaptor<Configuration> configCaptor =
                 ArgumentCaptor.forClass(Configuration.class);
         verify(client).updatePendingConfiguration(configCaptor.capture());
-- 
GitLab


From eaa129138096bc00b663bca93a5af9786aa47154 Mon Sep 17 00:00:00 2001
From: Beverly Tai <beverlyt@google.com>
Date: Thu, 14 Sep 2023 20:51:56 +0000
Subject: [PATCH 07/95] Revert "On device lockdown, always show the keyguard"

This reverts commit c851ef6d27bf7d3193c85170706a67fb6185981a.

Reason for revert: b/300463732 regression
Bug: 300463732
Bug: 218495634

Change-Id: I314e5615b798487d9a965eaa0937905b65aa85fc
Merged-In: I314e5615b798487d9a965eaa0937905b65aa85fc
---
 .../keyguard/KeyguardViewMediator.java        | 12 ++-------
 .../keyguard/KeyguardViewMediatorTest.java    | 25 -------------------
 2 files changed, 2 insertions(+), 35 deletions(-)

diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 18474e0af5b8..015918884f2e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -768,13 +768,6 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
                 }
             }
         }
-
-        @Override
-        public void onStrongAuthStateChanged(int userId) {
-            if (mLockPatternUtils.isUserInLockdown(KeyguardUpdateMonitor.getCurrentUser())) {
-                doKeyguardLocked(null);
-            }
-        }
     };
 
     ViewMediatorCallback mViewMediatorCallback = new ViewMediatorCallback() {
@@ -2159,9 +2152,8 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
      * Enable the keyguard if the settings are appropriate.
      */
     private void doKeyguardLocked(Bundle options) {
-        // if another app is disabling us, don't show unless we're in lockdown mode
-        if (!mExternallyEnabled
-                && !mLockPatternUtils.isUserInLockdown(KeyguardUpdateMonitor.getCurrentUser())) {
+        // if another app is disabling us, don't show
+        if (!mExternallyEnabled) {
             if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled");
 
             mNeedToReshowWhenReenabled = true;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index 1c8241433172..cfe3b0d2a803 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -157,8 +157,6 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
     private @Mock AuthController mAuthController;
     private @Mock ShadeExpansionStateManager mShadeExpansionStateManager;
     private @Mock ShadeWindowLogger mShadeWindowLogger;
-    private @Captor ArgumentCaptor<KeyguardUpdateMonitorCallback>
-            mKeyguardUpdateMonitorCallbackCaptor;
     private @Captor ArgumentCaptor<KeyguardStateController.Callback>
             mKeyguardStateControllerCallback;
     private DeviceConfigProxy mDeviceConfig = new DeviceConfigProxyFake();
@@ -205,25 +203,6 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
         createAndStartViewMediator();
     }
 
-    @Test
-    @TestableLooper.RunWithLooper(setAsMainLooper = true)
-    public void onLockdown_showKeyguard_evenIfKeyguardIsNotEnabledExternally() {
-        // GIVEN keyguard is not enabled and isn't showing
-        mViewMediator.onSystemReady();
-        mViewMediator.setKeyguardEnabled(false);
-        TestableLooper.get(this).processAllMessages();
-        captureKeyguardUpdateMonitorCallback();
-        assertFalse(mViewMediator.isShowingAndNotOccluded());
-
-        // WHEN lockdown occurs
-        when(mLockPatternUtils.isUserInLockdown(anyInt())).thenReturn(true);
-        mKeyguardUpdateMonitorCallbackCaptor.getValue().onStrongAuthStateChanged(0);
-
-        // THEN keyguard is shown
-        TestableLooper.get(this).processAllMessages();
-        assertTrue(mViewMediator.isShowingAndNotOccluded());
-    }
-
     @Test
     public void testOnGoingToSleep_UpdatesKeyguardGoingAway() {
         mViewMediator.onStartedGoingToSleep(OFF_BECAUSE_OF_USER);
@@ -844,10 +823,6 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
         mViewMediator.registerCentralSurfaces(mCentralSurfaces, null, null, null, null, null);
     }
 
-    private void captureKeyguardUpdateMonitorCallback() {
-        verify(mUpdateMonitor).registerCallback(mKeyguardUpdateMonitorCallbackCaptor.capture());
-    }
-
     private void captureKeyguardStateControllerCallback() {
         verify(mKeyguardStateController).addCallback(mKeyguardStateControllerCallback.capture());
     }
-- 
GitLab


From 2d4b4e46709be968c7fb22d3f42e91cc279eefd6 Mon Sep 17 00:00:00 2001
From: Fiona Campbell <flc@google.com>
Date: Mon, 18 Sep 2023 17:01:29 +0000
Subject: [PATCH 08/95] Fix testDisplayInputFlags

- Create local display device to fix this test.

Bug: 288880734
Test: atest LogicalDisplayTest
Change-Id: I84c4e5cb6fb143c16913688b81373153f00c90ad
---
 .../server/display/LogicalDisplayTest.java    | 33 ++++++++++++++-----
 1 file changed, 25 insertions(+), 8 deletions(-)

diff --git a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayTest.java b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayTest.java
index c0128ae38a28..1c43418f9276 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayTest.java
@@ -28,7 +28,9 @@ import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.app.PropertyInvalidatedCache;
+import android.content.Context;
 import android.graphics.Point;
+import android.os.IBinder;
 import android.util.SparseArray;
 import android.view.Display;
 import android.view.DisplayInfo;
@@ -40,7 +42,6 @@ import androidx.test.filters.SmallTest;
 import com.android.server.display.layout.Layout;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 
 import java.io.InputStream;
@@ -56,6 +57,9 @@ public class LogicalDisplayTest {
 
     private LogicalDisplay mLogicalDisplay;
     private DisplayDevice mDisplayDevice;
+    private DisplayAdapter mDisplayAdapter;
+    private Context mContext;
+    private IBinder mDisplayToken;
     private DisplayDeviceRepository mDeviceRepo;
     private final DisplayDeviceInfo mDisplayDeviceInfo = new DisplayDeviceInfo();
 
@@ -64,6 +68,9 @@ public class LogicalDisplayTest {
         // Share classloader to allow package private access.
         System.setProperty("dexmaker.share_classloader", "true");
         mDisplayDevice = mock(DisplayDevice.class);
+        mDisplayAdapter = mock(DisplayAdapter.class);
+        mContext = mock(Context.class);
+        mDisplayToken = mock(IBinder.class);
         mLogicalDisplay = new LogicalDisplay(DISPLAY_ID, LAYER_STACK, mDisplayDevice);
 
         mDisplayDeviceInfo.copyFrom(new DisplayDeviceInfo());
@@ -131,33 +138,43 @@ public class LogicalDisplayTest {
         assertEquals(expectedPosition, mLogicalDisplay.getDisplayPosition());
     }
 
-    // TODO: b/288880734 - fix test after display tests migration
     @Test
-    @Ignore
     public void testDisplayInputFlags() {
+        DisplayDevice displayDevice = new DisplayDevice(mDisplayAdapter, mDisplayToken,
+                "unique_display_id", mContext) {
+            @Override
+            public boolean hasStableUniqueId() {
+                return false;
+            }
+
+            @Override
+            public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
+                return mDisplayDeviceInfo;
+            }
+        };
         SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class);
-        mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false);
+        mLogicalDisplay.configureDisplayLocked(t, displayDevice, false);
         verify(t).setDisplayFlags(any(), eq(SurfaceControl.DISPLAY_RECEIVES_INPUT));
         reset(t);
 
         mDisplayDeviceInfo.touch = DisplayDeviceInfo.TOUCH_NONE;
-        mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false);
+        mLogicalDisplay.configureDisplayLocked(t, displayDevice, false);
         verify(t).setDisplayFlags(any(), eq(0));
         reset(t);
 
         mDisplayDeviceInfo.touch = DisplayDeviceInfo.TOUCH_VIRTUAL;
-        mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false);
+        mLogicalDisplay.configureDisplayLocked(t, displayDevice, false);
         verify(t).setDisplayFlags(any(), eq(SurfaceControl.DISPLAY_RECEIVES_INPUT));
         reset(t);
 
         mLogicalDisplay.setEnabledLocked(false);
-        mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false);
+        mLogicalDisplay.configureDisplayLocked(t, displayDevice, false);
         verify(t).setDisplayFlags(any(), eq(0));
         reset(t);
 
         mLogicalDisplay.setEnabledLocked(true);
         mDisplayDeviceInfo.touch = DisplayDeviceInfo.TOUCH_EXTERNAL;
-        mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false);
+        mLogicalDisplay.configureDisplayLocked(t, displayDevice, false);
         verify(t).setDisplayFlags(any(), eq(SurfaceControl.DISPLAY_RECEIVES_INPUT));
         reset(t);
     }
-- 
GitLab


From 760f1e4f5657b3bd5126c8d5886e99f16885c735 Mon Sep 17 00:00:00 2001
From: Victor Hsieh <victorhsieh@google.com>
Date: Thu, 7 Sep 2023 15:47:55 -0700
Subject: [PATCH 09/95] Accept APK install with v4 signature to set up
 fs-verity

.idsig is recognized and staged in the installer session. When .idsig is
provided, fs-verity is enabled in validateApkInstallLocked before the
first APK signature check happens.

With fs-verity enabled, ApkSignatureSchemeV4Verifier can also work (in
additional to IncFS) over fs-verity. The verifier can build fs-verity
digest from V4Signature.HashingInfo and verify the signed data is
consistent with the actual fs-verity digest. See
VerityUtils#generateFsVerityDigest.

ApkSignatureSchemeV4Verifier#extractSignature now also throws
SignatureException. When a signature size is wrong (see CTS test
PkgInstallSignatureVerificationTest#testInstallV4WithWrongSignatureBytesSize),
V4Signature.SigningInfos.fromByteArray throws an EOFException (which is
an IOException). The IOException is handled as missing signature by
rethrowing as SignatureNotFoundException. But this allows a fallback to
other v3/v2 signature check. This change distriguishes it by rethrowing a
SignatureException instead. This is not a problem during an incremental
install, because the signature size check happens earlier when the
installer commits, and it's done inside IncFS.

Bug: 277344944
Test: Force enable the (read-only) flag, since it's off in build time, then
      atest android.appsecurity.cts.PkgInstallSignatureVerificationTest
Change-Id: I6fd22fe2e04cfc58c68e690f23f63ff268938eda
---
 .../android/os/incremental/V4Signature.java   |  5 +-
 .../apk/ApkSignatureSchemeV4Verifier.java     | 66 +++++++++++++++----
 .../internal/security/VerityUtils.java        | 37 ++++++++++-
 .../AppIntegrityManagerServiceImpl.java       |  1 +
 .../com/android/server/pm/ApkChecksums.java   |  2 +-
 .../server/pm/PackageInstallerSession.java    | 51 ++++++++++++++
 6 files changed, 147 insertions(+), 15 deletions(-)

diff --git a/core/java/android/os/incremental/V4Signature.java b/core/java/android/os/incremental/V4Signature.java
index 2044502b10e8..38d885f503c5 100644
--- a/core/java/android/os/incremental/V4Signature.java
+++ b/core/java/android/os/incremental/V4Signature.java
@@ -254,7 +254,10 @@ public class V4Signature {
         this.signingInfos = signingInfos;
     }
 
-    private static V4Signature readFrom(InputStream stream) throws IOException {
+    /**
+     * Constructs a V4Signature from an InputStream.
+     */
+    public static V4Signature readFrom(InputStream stream) throws IOException {
         final int version = readIntLE(stream);
         int maxSize = INCFS_MAX_SIGNATURE_SIZE;
         final byte[] hashingInfo = readBytes(stream, maxSize);
diff --git a/core/java/android/util/apk/ApkSignatureSchemeV4Verifier.java b/core/java/android/util/apk/ApkSignatureSchemeV4Verifier.java
index 6b26155eced4..52102714eb5f 100644
--- a/core/java/android/util/apk/ApkSignatureSchemeV4Verifier.java
+++ b/core/java/android/util/apk/ApkSignatureSchemeV4Verifier.java
@@ -27,9 +27,14 @@ import android.os.incremental.V4Signature;
 import android.util.ArrayMap;
 import android.util.Pair;
 
+import com.android.internal.security.VerityUtils;
+
 import java.io.ByteArrayInputStream;
+import java.io.EOFException;
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
+import java.security.DigestException;
 import java.security.InvalidAlgorithmParameterException;
 import java.security.InvalidKeyException;
 import java.security.KeyFactory;
@@ -60,7 +65,7 @@ public class ApkSignatureSchemeV4Verifier {
      * certificates associated with each signer.
      */
     public static VerifiedSigner extractCertificates(String apkFile)
-            throws SignatureNotFoundException, SecurityException {
+            throws SignatureNotFoundException, SignatureException, SecurityException {
         Pair<V4Signature.HashingInfo, V4Signature.SigningInfos> pair = extractSignature(apkFile);
         return verify(apkFile, pair.first, pair.second, APK_SIGNATURE_SCHEME_DEFAULT);
     }
@@ -69,15 +74,37 @@ public class ApkSignatureSchemeV4Verifier {
      * Extracts APK Signature Scheme v4 signature of the provided APK.
      */
     public static Pair<V4Signature.HashingInfo, V4Signature.SigningInfos> extractSignature(
-            String apkFile) throws SignatureNotFoundException {
-        final File apk = new File(apkFile);
-        final byte[] signatureBytes = IncrementalManager.unsafeGetFileSignature(
-                apk.getAbsolutePath());
-        if (signatureBytes == null || signatureBytes.length == 0) {
-            throw new SignatureNotFoundException("Failed to obtain signature bytes from IncFS.");
-        }
+            String apkFile) throws SignatureNotFoundException, SignatureException {
         try {
-            final V4Signature signature = V4Signature.readFrom(signatureBytes);
+            final File apk = new File(apkFile);
+            boolean needsConsistencyCheck;
+
+            // 1. Try IncFS first. IncFS verifies the file according to the integrity metadata
+            // (including the root hash of Merkle tree) it keeps track of with signature check. No
+            // further consistentcy check is needed.
+            byte[] signatureBytes = IncrementalManager.unsafeGetFileSignature(
+                    apk.getAbsolutePath());
+            V4Signature signature;
+            if (signatureBytes != null && signatureBytes.length > 0) {
+                needsConsistencyCheck = false;
+                signature = V4Signature.readFrom(signatureBytes);
+            } else if (android.security.Flags.extendVbChainToUpdatedApk()) {
+                // 2. Try fs-verity next. fs-verity checks against the Merkle tree, but the
+                // v4 signature file (including a raw root hash) is managed separately. We need to
+                // ensure the signed data from the file is consistent with the actual file.
+                needsConsistencyCheck = true;
+
+                final File idsig = new File(apk.getAbsolutePath() + V4Signature.EXT);
+                try (var fis = new FileInputStream(idsig.getAbsolutePath())) {
+                    signature = V4Signature.readFrom(fis);
+                } catch (IOException e) {
+                    throw new SignatureNotFoundException(
+                            "Failed to obtain signature bytes from .idsig");
+                }
+            } else {
+                throw new SignatureNotFoundException(
+                        "Failed to obtain signature bytes from IncFS.");
+            }
             if (!signature.isVersionSupported()) {
                 throw new SecurityException(
                         "v4 signature version " + signature.version + " is not supported");
@@ -86,9 +113,26 @@ public class ApkSignatureSchemeV4Verifier {
                     signature.hashingInfo);
             final V4Signature.SigningInfos signingInfos = V4Signature.SigningInfos.fromByteArray(
                     signature.signingInfos);
+
+            if (needsConsistencyCheck) {
+                final byte[] actualDigest = VerityUtils.getFsverityDigest(apk.getAbsolutePath());
+                if (actualDigest == null) {
+                    throw new SecurityException("The APK does not have fs-verity");
+                }
+                final byte[] computedDigest =
+                        VerityUtils.generateFsVerityDigest(apk.length(), hashingInfo);
+                if (!Arrays.equals(computedDigest, actualDigest)) {
+                    throw new SignatureException("Actual digest does not match the v4 signature");
+                }
+            }
+
             return Pair.create(hashingInfo, signingInfos);
+        } catch (EOFException e) {
+            throw new SignatureException("V4 signature is invalid.", e);
         } catch (IOException e) {
             throw new SignatureNotFoundException("Failed to read V4 signature.", e);
+        } catch (DigestException | NoSuchAlgorithmException e) {
+            throw new SecurityException("Failed to calculate the digest", e);
         }
     }
 
@@ -107,7 +151,7 @@ public class ApkSignatureSchemeV4Verifier {
                 signingInfo);
         final Pair<Certificate, byte[]> result = verifySigner(signingInfo, signedData);
 
-        // Populate digests enforced by IncFS driver.
+        // Populate digests enforced by IncFS driver and fs-verity.
         Map<Integer, byte[]> contentDigests = new ArrayMap<>();
         contentDigests.put(convertToContentDigestType(hashingInfo.hashAlgorithm),
                 hashingInfo.rawRootHash);
@@ -217,7 +261,7 @@ public class ApkSignatureSchemeV4Verifier {
         public final byte[] apkDigest;
 
         // Algorithm -> digest map of signed digests in the signature.
-        // These are continuously enforced by the IncFS driver.
+        // These are continuously enforced by the IncFS driver and fs-verity.
         public final Map<Integer, byte[]> contentDigests;
 
         public VerifiedSigner(Certificate[] certs, byte[] apkDigest,
diff --git a/core/java/com/android/internal/security/VerityUtils.java b/core/java/com/android/internal/security/VerityUtils.java
index 74a9d16c890d..7f7ea8b28546 100644
--- a/core/java/com/android/internal/security/VerityUtils.java
+++ b/core/java/com/android/internal/security/VerityUtils.java
@@ -17,8 +17,10 @@
 package com.android.internal.security;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.os.Build;
 import android.os.SystemProperties;
+import android.os.incremental.V4Signature;
 import android.system.Os;
 import android.system.OsConstants;
 import android.util.Slog;
@@ -40,6 +42,9 @@ import java.io.InputStream;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.charset.StandardCharsets;
+import java.security.DigestException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
@@ -192,9 +197,9 @@ public abstract class VerityUtils {
      *
      * @see <a href="https://www.kernel.org/doc/html/latest/filesystems/fsverity.html#file-digest-computation">
      *      File digest computation in Linux kernel documentation</a>
-     * @return Bytes of fs-verity digest
+     * @return Bytes of fs-verity digest, or null if the file does not have fs-verity enabled
      */
-    public static byte[] getFsverityDigest(@NonNull String filePath) {
+    public static @Nullable byte[] getFsverityDigest(@NonNull String filePath) {
         byte[] result = new byte[HASH_SIZE_BYTES];
         int retval = measureFsverityNative(filePath, result);
         if (retval < 0) {
@@ -206,6 +211,34 @@ public abstract class VerityUtils {
         return result;
     }
 
+    /**
+     * Generates an fs-verity digest from a V4Signature.HashingInfo and the file's size.
+     */
+    public static @NonNull byte[] generateFsVerityDigest(long fileSize,
+            @NonNull V4Signature.HashingInfo hashingInfo)
+            throws DigestException, NoSuchAlgorithmException {
+        if (hashingInfo.rawRootHash == null || hashingInfo.rawRootHash.length != 32) {
+            throw new IllegalArgumentException("Expect a 32-byte rootHash for SHA256");
+        }
+        if (hashingInfo.log2BlockSize != 12) {
+            throw new IllegalArgumentException(
+                    "Unsupported log2BlockSize: " + hashingInfo.log2BlockSize);
+        }
+
+        var buffer = ByteBuffer.allocate(256);  // sizeof(fsverity_descriptor)
+        buffer.order(ByteOrder.LITTLE_ENDIAN);
+        buffer.put((byte) 1);                   // version
+        buffer.put((byte) 1);                   // Merkle tree hash algorithm, 1 for SHA256
+        buffer.put(hashingInfo.log2BlockSize);  // log2(block-size), only log2(4096) is supported
+        buffer.put((byte) 0);                   // size of salt in bytes; 0 if none
+        buffer.putInt(0);                       // reserved, must be 0
+        buffer.putLong(fileSize);               // size of file the Merkle tree is built over
+        buffer.put(hashingInfo.rawRootHash);    // Merkle tree root hash
+        // The rest are zeros, including the latter half of root hash unused for SHA256.
+
+        return MessageDigest.getInstance("SHA-256").digest(buffer.array());
+    }
+
     /** @hide */
     @VisibleForTesting
     public static byte[] toFormattedDigest(byte[] digest) {
diff --git a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
index a7c986d04fa4..ec858ee296e1 100644
--- a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
+++ b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
@@ -513,6 +513,7 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
                 List<String> apkFiles =
                         filesList
                                 .map(path -> path.toAbsolutePath().toString())
+                                .filter(str -> str.endsWith(".apk"))
                                 .collect(Collectors.toList());
                 sourceStampVerificationResult = SourceStampVerifier.verify(apkFiles);
             } catch (IOException e) {
diff --git a/services/core/java/com/android/server/pm/ApkChecksums.java b/services/core/java/com/android/server/pm/ApkChecksums.java
index 5b93244c1710..50ed3b1859df 100644
--- a/services/core/java/com/android/server/pm/ApkChecksums.java
+++ b/services/core/java/com/android/server/pm/ApkChecksums.java
@@ -655,7 +655,7 @@ public class ApkChecksums {
             }
         } catch (SignatureNotFoundException e) {
             // Nothing
-        } catch (SecurityException e) {
+        } catch (SignatureException | SecurityException e) {
             Slog.e(TAG, "V4 signature error", e);
         }
         return null;
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 2e9da099b86c..3364b671fdb1 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -137,6 +137,7 @@ import android.os.incremental.IncrementalFileStorages;
 import android.os.incremental.IncrementalManager;
 import android.os.incremental.PerUidReadTimeouts;
 import android.os.incremental.StorageHealthCheckParams;
+import android.os.incremental.V4Signature;
 import android.os.storage.StorageManager;
 import android.provider.DeviceConfig;
 import android.provider.Settings.Global;
@@ -801,6 +802,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
             // entries like "lost+found".
             if (file.isDirectory()) return false;
             if (file.getName().endsWith(REMOVE_MARKER_EXTENSION)) return false;
+            if (file.getName().endsWith(V4Signature.EXT)) return false;
             if (isAppMetadata(file)) return false;
             if (DexMetadataHelper.isDexMetadataFile(file)) return false;
             if (VerityUtils.isFsveritySignatureFile(file)) return false;
@@ -1505,6 +1507,21 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
         return filterFiles(stageDir, names, sAddedApkFilter);
     }
 
+    @GuardedBy("mLock")
+    private void enableFsVerityToAddedApksWithIdsig() throws PackageManagerException {
+        try {
+            List<File> files = getAddedApksLocked();
+            for (var file : files) {
+                if (new File(file.getPath() + V4Signature.EXT).exists()) {
+                    VerityUtils.setUpFsverity(file.getPath());
+                }
+            }
+        } catch (IOException e) {
+            throw new PrepareFailure(PackageManager.INSTALL_FAILED_BAD_SIGNATURE,
+                    "Failed to enable fs-verity to verify with idsig: " + e);
+        }
+    }
+
     @GuardedBy("mLock")
     private List<ApkLite> getAddedApkLitesLocked() throws PackageManagerException {
         if (!isArchivedInstallation()) {
@@ -3294,6 +3311,14 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
             }
         }
 
+        // Needs to happen before the first v4 signature verification, which happens in
+        // getAddedApkLitesLocked.
+        if (android.security.Flags.extendVbChainToUpdatedApk()) {
+            if (!isIncrementalInstallation()) {
+                enableFsVerityToAddedApksWithIdsig();
+            }
+        }
+
         final List<ApkLite> addedFiles = getAddedApkLitesLocked();
         if (addedFiles.isEmpty()
                 && (removeSplitList.size() == 0 || getStagedAppMetadataFile() != null)) {
@@ -3656,6 +3681,16 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
         }
     }
 
+    @GuardedBy("mLock")
+    private void maybeStageV4SignatureLocked(File origFile, File targetFile)
+            throws PackageManagerException {
+        final File originalSignature = new File(origFile.getPath() + V4Signature.EXT);
+        if (originalSignature.exists()) {
+            final File stagedSignature = new File(targetFile.getPath() + V4Signature.EXT);
+            stageFileLocked(originalSignature, stagedSignature);
+        }
+    }
+
     @GuardedBy("mLock")
     private void maybeStageDexMetadataLocked(File origFile, File targetFile)
             throws PackageManagerException {
@@ -3783,6 +3818,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
         // Stage APK's fs-verity signature if present.
         maybeStageFsveritySignatureLocked(origFile, targetFile,
                 isFsVerityRequiredForApk(origFile, targetFile));
+        // Stage APK's v4 signature if present.
+        if (android.security.Flags.extendVbChainToUpdatedApk()) {
+            maybeStageV4SignatureLocked(origFile, targetFile);
+        }
         // Stage dex metadata (.dm) and corresponding fs-verity signature if present.
         maybeStageDexMetadataLocked(origFile, targetFile);
         // Stage checksums (.digests) if present.
@@ -3799,11 +3838,23 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
         }
     }
 
+    @GuardedBy("mLock")
+    private void maybeInheritV4SignatureLocked(File origFile) {
+        // Inherit the v4 signature file if present.
+        final File v4SignatureFile = new File(origFile.getPath() + V4Signature.EXT);
+        if (v4SignatureFile.exists()) {
+            mResolvedInheritedFiles.add(v4SignatureFile);
+        }
+    }
+
     @GuardedBy("mLock")
     private void inheritFileLocked(File origFile) {
         mResolvedInheritedFiles.add(origFile);
 
         maybeInheritFsveritySignatureLocked(origFile);
+        if (android.security.Flags.extendVbChainToUpdatedApk()) {
+            maybeInheritV4SignatureLocked(origFile);
+        }
 
         // Inherit the dex metadata if present.
         final File dexMetadataFile =
-- 
GitLab


From 3054e71ec1e57347490d5b42bf1affd06bd5e1d4 Mon Sep 17 00:00:00 2001
From: Jing Ji <jji@google.com>
Date: Mon, 18 Sep 2023 21:12:56 -0700
Subject: [PATCH 10/95] Move the binder proxy accounting to libbinder

So the android.os.Debug#getBinderProxyObjectCount will include
the binder proxies from both of the Java and native layers.

Bug: 298314844
Test: dumpsys meminfo
Change-Id: Ifb57eeacc0a4b6ee6e164e83f6f843bfe36f2b15
---
 core/jni/android_util_Binder.cpp | 21 ++-------------------
 1 file changed, 2 insertions(+), 19 deletions(-)

diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 6ed0a8a047f5..041f9c7edeef 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -158,12 +158,8 @@ static struct thread_dispatch_offsets_t
 // ****************************************************************************
 // ****************************************************************************
 
-static constexpr int32_t PROXY_WARN_INTERVAL = 5000;
 static constexpr uint32_t GC_INTERVAL = 1000;
 
-static std::atomic<uint32_t> gNumProxies(0);
-static std::atomic<uint32_t> gProxiesWarned(0);
-
 // Number of GlobalRefs held by JavaBBinders.
 static std::atomic<uint32_t> gNumLocalRefsCreated(0);
 static std::atomic<uint32_t> gNumLocalRefsDeleted(0);
@@ -776,19 +772,7 @@ jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
         return NULL;
     }
     BinderProxyNativeData* actualNativeData = getBPNativeData(env, object);
-    if (actualNativeData == nativeData) {
-        // Created a new Proxy
-        uint32_t numProxies = gNumProxies.fetch_add(1, std::memory_order_relaxed);
-        uint32_t numLastWarned = gProxiesWarned.load(std::memory_order_relaxed);
-        if (numProxies >= numLastWarned + PROXY_WARN_INTERVAL) {
-            // Multiple threads can get here, make sure only one of them gets to
-            // update the warn counter.
-            if (gProxiesWarned.compare_exchange_strong(numLastWarned,
-                        numLastWarned + PROXY_WARN_INTERVAL, std::memory_order_relaxed)) {
-                ALOGW("Unexpectedly many live BinderProxies: %d\n", numProxies);
-            }
-        }
-    } else {
+    if (actualNativeData != nativeData) {
         delete nativeData;
     }
 
@@ -1143,7 +1127,7 @@ jint android_os_Debug_getLocalObjectCount(JNIEnv* env, jobject clazz)
 
 jint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz)
 {
-    return gNumProxies.load();
+    return BpBinder::getBinderProxyCount();
 }
 
 jint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz)
@@ -1428,7 +1412,6 @@ static void BinderProxy_destroy(void* rawNativeData)
             nativeData->mObject.get(), nativeData->mOrgue.get());
     delete nativeData;
     IPCThreadState::self()->flushCommands();
-    --gNumProxies;
 }
 
 JNIEXPORT jlong JNICALL android_os_BinderProxy_getNativeFinalizer(JNIEnv*, jclass) {
-- 
GitLab


From 6c2e46027808f117b6d25587773c5581e4e9670d Mon Sep 17 00:00:00 2001
From: Pinyao Ting <pinyaoting@google.com>
Date: Tue, 19 Sep 2023 17:27:44 +0000
Subject: [PATCH 11/95] Fix NPE in getShortcutIconDrawable

Bug: 301007443
Test: manual
Change-Id: I6f42d921fbdde4a33eae66e15325ac399ed7d52e
---
 core/java/android/content/pm/LauncherApps.java | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 3165e292166b..dbaa4c93d71c 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -75,7 +75,6 @@ import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.infra.AndroidFuture;
 import com.android.internal.util.function.pooled.PooledLambda;
 
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -1424,8 +1423,8 @@ public class LauncherApps {
         }
         try {
             return mContext.getContentResolver().openFileDescriptor(Uri.parse(uri), "r");
-        } catch (FileNotFoundException e) {
-            Log.e(TAG, "Icon file not found: " + uri);
+        } catch (Exception e) {
+            Log.e(TAG, "Failed to open icon file: " + uri, e);
             return null;
         }
     }
-- 
GitLab


From 70719529eb57dd5505c9840a0211a582b93a2495 Mon Sep 17 00:00:00 2001
From: Jeremy Sim <jeremysim@google.com>
Date: Mon, 11 Sep 2023 21:55:10 -0700
Subject: [PATCH 12/95] Refactor how split ratios are stored and passed between
 Launcher and Shell

Split ratios are now stored as an int enum called @SnapPosition. For example, there is a snap position representing a 50-50 split, one for a 70-30 split, and so on.

Previously, split ratios were calculated once by the DividerSnapAlgorithm and stored only as int positions on each SnapTarget, meaning that if you wanted to know the screen split ratio, you would have to calculate it manually from the bounds of each RemoteAnimationTarget and pass it around as a float (differing across devices with different screen sizes). With SnapPosition, screen ratios are more available and less device dependent. The change should lead to cleaner (and hopefully more readable) code.

- SnapTargets now know their snapPosition in addition to their pixel position
- Launcher now requests split launches using the snapPosition rather than a float splitRatio

Bug: 274189428
Bug: 182839788
Test: Existing tests still pass
Change-Id: I50d109ee67993629c277ec65d42b68fae18082b3
---
 .../common/split/DividerSnapAlgorithm.java    | 39 +++++++--
 .../wm/shell/common/split/SplitLayout.java    | 47 ++++++----
 .../wm/shell/splitscreen/ISplitScreen.aidl    | 16 ++--
 .../splitscreen/SplitScreenController.java    | 86 ++++++++++---------
 .../shell/splitscreen/StageCoordinator.java   | 67 ++++++++-------
 .../android/wm/shell/util/SplitBounds.java    | 17 ++--
 .../shell/common/split/SplitLayoutTests.java  |  6 +-
 .../recents/GroupedRecentTaskInfoTest.kt      |  4 +-
 .../recents/RecentTasksControllerTest.java    | 20 +++--
 .../wm/shell/recents/SplitBoundsTest.java     | 14 +--
 10 files changed, 192 insertions(+), 124 deletions(-)

diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerSnapAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerSnapAlgorithm.java
index a5000feae239..f9a286ec804f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerSnapAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerSnapAlgorithm.java
@@ -19,6 +19,7 @@ package com.android.wm.shell.common.split;
 import static android.view.WindowManager.DOCKED_INVALID;
 import static android.view.WindowManager.DOCKED_LEFT;
 import static android.view.WindowManager.DOCKED_RIGHT;
+
 import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_30_70;
 import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_50_50;
 import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_70_30;
@@ -36,6 +37,8 @@ import android.hardware.display.DisplayManager;
 import android.view.Display;
 import android.view.DisplayInfo;
 
+import androidx.annotation.Nullable;
+
 import java.util.ArrayList;
 
 /**
@@ -203,6 +206,21 @@ public class DividerSnapAlgorithm {
         }
     }
 
+    /**
+     * Gets the SnapTarget corresponding to the given {@link SnapPosition}, or null if no such
+     * SnapTarget exists.
+     */
+    @Nullable
+    public SnapTarget findSnapTarget(@SnapPosition int snapPosition) {
+        for (SnapTarget t : mTargets) {
+            if (t.snapPosition == snapPosition) {
+                return t;
+            }
+        }
+
+        return null;
+    }
+
     public float calculateDismissingFraction(int position) {
         if (position < mFirstSplitTarget.position) {
             return 1f - (float) (position - getStartInset())
@@ -356,9 +374,9 @@ public class DividerSnapAlgorithm {
      * Adds a target at {@param position} but only if the area with size of {@param smallerSize}
      * meets the minimal size requirement.
      */
-    private void maybeAddTarget(int position, int smallerSize, @SnapPosition int snapTo) {
+    private void maybeAddTarget(int position, int smallerSize, @SnapPosition int snapPosition) {
         if (smallerSize >= mMinimalSizeResizableTask) {
-            mTargets.add(new SnapTarget(position, position, snapTo));
+            mTargets.add(new SnapTarget(position, position, snapPosition));
         }
     }
 
@@ -418,6 +436,13 @@ public class DividerSnapAlgorithm {
         return mLastSplitTarget != mMiddleTarget;
     }
 
+    /**
+     * Finds the {@link SnapPosition} nearest to the given position.
+     */
+    public int calculateNearestSnapPosition(int currentPosition) {
+        return snap(currentPosition, /* hardDismiss */ true).snapPosition;
+    }
+
     /**
      * Cycles through all non-dismiss targets with a stepping of {@param increment}. It moves left
      * if {@param increment} is negative and moves right otherwise.
@@ -454,7 +479,7 @@ public class DividerSnapAlgorithm {
         /**
          * An int describing the placement of the divider in this snap target.
          */
-        public final @SnapPosition int snapTo;
+        public final @SnapPosition int snapPosition;
 
         public boolean isMiddleTarget;
 
@@ -464,15 +489,15 @@ public class DividerSnapAlgorithm {
          */
         private final float distanceMultiplier;
 
-        public SnapTarget(int position, int taskPosition, @SnapPosition int snapTo) {
-            this(position, taskPosition, snapTo, 1f);
+        public SnapTarget(int position, int taskPosition, @SnapPosition int snapPosition) {
+            this(position, taskPosition, snapPosition, 1f);
         }
 
-        public SnapTarget(int position, int taskPosition, @SnapPosition int snapTo,
+        public SnapTarget(int position, int taskPosition, @SnapPosition int snapPosition,
                 float distanceMultiplier) {
             this.position = position;
             this.taskPosition = taskPosition;
-            this.snapTo = snapTo;
+            this.snapPosition = snapPosition;
             this.distanceMultiplier = distanceMultiplier;
         }
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index 4af03fd5b955..26b5a5052594 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -23,6 +23,7 @@ import static android.view.WindowManager.DOCKED_INVALID;
 import static android.view.WindowManager.DOCKED_LEFT;
 import static android.view.WindowManager.DOCKED_RIGHT;
 import static android.view.WindowManager.DOCKED_TOP;
+
 import static com.android.internal.jank.InteractionJankMonitor.CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER;
 import static com.android.internal.jank.InteractionJankMonitor.CUJ_SPLIT_SCREEN_RESIZE;
 import static com.android.wm.shell.animation.Interpolators.DIM_INTERPOLATOR;
@@ -66,6 +67,7 @@ import com.android.wm.shell.common.DisplayImeController;
 import com.android.wm.shell.common.DisplayInsetsController;
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.InteractionJankMonitorUtils;
+import com.android.wm.shell.common.split.SplitScreenConstants.SnapPosition;
 import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
 
 import java.io.PrintWriter;
@@ -115,7 +117,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
     @VisibleForTesting DividerSnapAlgorithm mDividerSnapAlgorithm;
     private WindowContainerToken mWinToken1;
     private WindowContainerToken mWinToken2;
-    private int mDividePosition;
+    private int mDividerPosition;
     private boolean mInitialized = false;
     private boolean mFreezeDividerWindow = false;
     private int mOrientation;
@@ -267,7 +269,14 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
     }
 
     int getDividePosition() {
-        return mDividePosition;
+        return mDividerPosition;
+    }
+
+    /**
+     * Finds the {@link SnapPosition} nearest to the current divider position.
+     */
+    public int calculateCurrentSnapPosition() {
+        return mDividerSnapAlgorithm.calculateNearestSnapPosition(mDividerPosition);
     }
 
     /**
@@ -344,16 +353,16 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
     }
 
     private void initDividerPosition(Rect oldBounds) {
-        final float snapRatio = (float) mDividePosition
+        final float snapRatio = (float) mDividerPosition
                 / (float) (isLandscape(oldBounds) ? oldBounds.width() : oldBounds.height());
         // Estimate position by previous ratio.
         final float length =
                 (float) (isLandscape() ? mRootBounds.width() : mRootBounds.height());
         final int estimatePosition = (int) (length * snapRatio);
         // Init divider position by estimated position using current bounds snap algorithm.
-        mDividePosition = mDividerSnapAlgorithm.calculateNonDismissingSnapTarget(
+        mDividerPosition = mDividerSnapAlgorithm.calculateNonDismissingSnapTarget(
                 estimatePosition).position;
-        updateBounds(mDividePosition);
+        updateBounds(mDividerPosition);
     }
 
     private void updateBounds(int position) {
@@ -467,27 +476,29 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
     }
 
     void setDividePosition(int position, boolean applyLayoutChange) {
-        mDividePosition = position;
-        updateBounds(mDividePosition);
+        mDividerPosition = position;
+        updateBounds(mDividerPosition);
         if (applyLayoutChange) {
             mSplitLayoutHandler.onLayoutSizeChanged(this);
         }
     }
 
     /** Updates divide position and split bounds base on the ratio within root bounds. */
-    public void setDivideRatio(float ratio) {
-        final int position = isLandscape()
-                ? mRootBounds.left + (int) (mRootBounds.width() * ratio)
-                : mRootBounds.top + (int) (mRootBounds.height() * ratio);
-        final DividerSnapAlgorithm.SnapTarget snapTarget =
-                mDividerSnapAlgorithm.calculateNonDismissingSnapTarget(position);
+    public void setDivideRatio(@SnapPosition int snapPosition) {
+        final DividerSnapAlgorithm.SnapTarget snapTarget = mDividerSnapAlgorithm.findSnapTarget(
+                snapPosition);
+
+        if (snapTarget == null) {
+            throw new IllegalArgumentException("No SnapTarget for position " + snapPosition);
+        }
+
         setDividePosition(snapTarget.position, false /* applyLayoutChange */);
     }
 
     /** Resets divider position. */
     public void resetDividerPosition() {
-        mDividePosition = mDividerSnapAlgorithm.getMiddleTarget().position;
-        updateBounds(mDividePosition);
+        mDividerPosition = mDividerSnapAlgorithm.getMiddleTarget().position;
+        updateBounds(mDividerPosition);
         mWinToken1 = null;
         mWinToken2 = null;
         mWinBounds1.setEmpty();
@@ -510,7 +521,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
      * target indicates dismissing split.
      */
     public void snapToTarget(int currentPosition, DividerSnapAlgorithm.SnapTarget snapTarget) {
-        switch (snapTarget.snapTo) {
+        switch (snapTarget.snapPosition) {
             case SNAP_TO_START_AND_DISMISS:
                 flingDividePosition(currentPosition, snapTarget.position, FLING_RESIZE_DURATION,
                         () -> mSplitLayoutHandler.onSnappedToDismiss(false /* bottomOrRight */,
@@ -668,8 +679,8 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
 
             @Override
             public void onAnimationEnd(Animator animation) {
-                mDividePosition = dividerPos;
-                updateBounds(mDividePosition);
+                mDividerPosition = dividerPos;
+                updateBounds(mDividerPosition);
                 finishCallback.accept(insets);
                 InteractionJankMonitorUtils.endTracing(CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER);
             }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl
index 14304a3c0aac..253acc49071a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl
@@ -91,42 +91,42 @@ interface ISplitScreen {
      * Starts tasks simultaneously in one transition.
      */
     oneway void startTasks(int taskId1, in Bundle options1, int taskId2, in Bundle options2,
-            int splitPosition, float splitRatio, in RemoteTransition remoteTransition,
+            int splitPosition, int snapPosition, in RemoteTransition remoteTransition,
             in InstanceId instanceId) = 10;
 
     /**
      * Starts a pair of intent and task in one transition.
      */
     oneway void startIntentAndTask(in PendingIntent pendingIntent, int userId1, in Bundle options1,
-            int taskId, in Bundle options2, int sidePosition, float splitRatio,
+            int taskId, in Bundle options2, int sidePosition, int snapPosition,
             in RemoteTransition remoteTransition, in InstanceId instanceId) = 16;
 
     /**
      * Starts a pair of shortcut and task in one transition.
      */
     oneway void startShortcutAndTask(in ShortcutInfo shortcutInfo, in Bundle options1, int taskId,
-            in Bundle options2, int splitPosition, float splitRatio,
+            in Bundle options2, int splitPosition, int snapPosition,
             in RemoteTransition remoteTransition, in InstanceId instanceId) = 17;
 
     /**
      * Version of startTasks using legacy transition system.
      */
     oneway void startTasksWithLegacyTransition(int taskId1, in Bundle options1, int taskId2,
-            in Bundle options2, int splitPosition, float splitRatio,
+            in Bundle options2, int splitPosition, int snapPosition,
             in RemoteAnimationAdapter adapter, in InstanceId instanceId) = 11;
 
     /**
      * Starts a pair of intent and task using legacy transition system.
      */
     oneway void startIntentAndTaskWithLegacyTransition(in PendingIntent pendingIntent, int userId1,
-            in Bundle options1, int taskId, in Bundle options2, int splitPosition, float splitRatio,
+            in Bundle options1, int taskId, in Bundle options2, int splitPosition, int snapPosition,
             in RemoteAnimationAdapter adapter, in InstanceId instanceId) = 12;
 
     /**
      * Starts a pair of shortcut and task using legacy transition system.
      */
     oneway void startShortcutAndTaskWithLegacyTransition(in ShortcutInfo shortcutInfo,
-            in Bundle options1, int taskId, in Bundle options2, int splitPosition, float splitRatio,
+            in Bundle options1, int taskId, in Bundle options2, int splitPosition, int snapPosition,
             in RemoteAnimationAdapter adapter, in InstanceId instanceId) = 15;
 
     /**
@@ -135,7 +135,7 @@ interface ISplitScreen {
     oneway void startIntentsWithLegacyTransition(in PendingIntent pendingIntent1, int userId1,
             in ShortcutInfo shortcutInfo1, in Bundle options1, in PendingIntent pendingIntent2,
             int userId2, in ShortcutInfo shortcutInfo2, in Bundle options2, int splitPosition,
-            float splitRatio, in RemoteAnimationAdapter adapter, in InstanceId instanceId) = 18;
+            int snapPosition, in RemoteAnimationAdapter adapter, in InstanceId instanceId) = 18;
 
     /**
      * Start a pair of intents in one transition.
@@ -143,7 +143,7 @@ interface ISplitScreen {
     oneway void startIntents(in PendingIntent pendingIntent1, int userId1,
             in ShortcutInfo shortcutInfo1, in Bundle options1, in PendingIntent pendingIntent2,
             int userId2, in ShortcutInfo shortcutInfo2, in Bundle options2, int splitPosition,
-            float splitRatio, in RemoteTransition remoteTransition, in InstanceId instanceId) = 19;
+            int snapPosition, in RemoteTransition remoteTransition, in InstanceId instanceId) = 19;
 
     /**
      * Blocking call that notifies and gets additional split-screen targets when entering
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index 991b699161ea..e02ff9876c2f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -86,6 +86,7 @@ import com.android.wm.shell.common.SingleInstanceRemoteListener;
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.common.TransactionPool;
 import com.android.wm.shell.common.annotations.ExternalThread;
+import com.android.wm.shell.common.split.SplitScreenConstants.SnapPosition;
 import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
 import com.android.wm.shell.common.split.SplitScreenUtils;
 import com.android.wm.shell.desktopmode.DesktopTasksController;
@@ -599,8 +600,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
 
     void startShortcutAndTaskWithLegacyTransition(ShortcutInfo shortcutInfo,
             @Nullable Bundle options1, int taskId, @Nullable Bundle options2,
-            @SplitPosition int splitPosition, float splitRatio, RemoteAnimationAdapter adapter,
-            InstanceId instanceId) {
+            @SplitPosition int splitPosition, @SnapPosition int snapPosition,
+            RemoteAnimationAdapter adapter, InstanceId instanceId) {
         if (options1 == null) options1 = new Bundle();
         final ActivityOptions activityOptions = ActivityOptions.fromBundle(options1);
 
@@ -624,13 +625,14 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
         }
 
         mStageCoordinator.startShortcutAndTaskWithLegacyTransition(shortcutInfo,
-                activityOptions.toBundle(), taskId, options2, splitPosition, splitRatio, adapter,
+                activityOptions.toBundle(), taskId, options2, splitPosition, snapPosition, adapter,
                 instanceId);
     }
 
     void startShortcutAndTask(ShortcutInfo shortcutInfo, @Nullable Bundle options1,
             int taskId, @Nullable Bundle options2, @SplitPosition int splitPosition,
-            float splitRatio, @Nullable RemoteTransition remoteTransition, InstanceId instanceId) {
+            @SnapPosition int snapPosition, @Nullable RemoteTransition remoteTransition,
+            InstanceId instanceId) {
         if (options1 == null) options1 = new Bundle();
         final ActivityOptions activityOptions = ActivityOptions.fromBundle(options1);
         final String packageName1 = shortcutInfo.getPackage();
@@ -657,7 +659,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
             }
         }
         mStageCoordinator.startShortcutAndTask(shortcutInfo, activityOptions.toBundle(), taskId,
-                options2, splitPosition, splitRatio, remoteTransition, instanceId);
+                options2, splitPosition, snapPosition, remoteTransition, instanceId);
     }
 
     /**
@@ -672,8 +674,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
 
     private void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent, int userId1,
             @Nullable Bundle options1, int taskId, @Nullable Bundle options2,
-            @SplitPosition int splitPosition, float splitRatio, RemoteAnimationAdapter adapter,
-            InstanceId instanceId) {
+            @SplitPosition int splitPosition, @SnapPosition int snapPosition,
+            RemoteAnimationAdapter adapter, InstanceId instanceId) {
         Intent fillInIntent = null;
         final String packageName1 = SplitScreenUtils.getPackageName(pendingIntent);
         final String packageName2 = SplitScreenUtils.getPackageName(taskId, mTaskOrganizer);
@@ -694,12 +696,12 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
             }
         }
         mStageCoordinator.startIntentAndTaskWithLegacyTransition(pendingIntent, fillInIntent,
-                options1, taskId, options2, splitPosition, splitRatio, adapter, instanceId);
+                options1, taskId, options2, splitPosition, snapPosition, adapter, instanceId);
     }
 
     private void startIntentAndTask(PendingIntent pendingIntent, int userId1,
             @Nullable Bundle options1, int taskId, @Nullable Bundle options2,
-            @SplitPosition int splitPosition, float splitRatio,
+            @SplitPosition int splitPosition, @SnapPosition int snapPosition,
             @Nullable RemoteTransition remoteTransition, InstanceId instanceId) {
         Intent fillInIntent = null;
         final String packageName1 = SplitScreenUtils.getPackageName(pendingIntent);
@@ -726,14 +728,14 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
             }
         }
         mStageCoordinator.startIntentAndTask(pendingIntent, fillInIntent, options1, taskId,
-                options2, splitPosition, splitRatio, remoteTransition, instanceId);
+                options2, splitPosition, snapPosition, remoteTransition, instanceId);
     }
 
     private void startIntentsWithLegacyTransition(PendingIntent pendingIntent1, int userId1,
             @Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1,
             PendingIntent pendingIntent2, int userId2, @Nullable ShortcutInfo shortcutInfo2,
-            @Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio,
-            RemoteAnimationAdapter adapter, InstanceId instanceId) {
+            @Nullable Bundle options2, @SplitPosition int splitPosition,
+            @SnapPosition int snapPosition, RemoteAnimationAdapter adapter, InstanceId instanceId) {
         Intent fillInIntent1 = null;
         Intent fillInIntent2 = null;
         final String packageName1 = SplitScreenUtils.getPackageName(pendingIntent1);
@@ -757,14 +759,15 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
         }
         mStageCoordinator.startIntentsWithLegacyTransition(pendingIntent1, fillInIntent1,
                 shortcutInfo1, options1, pendingIntent2, fillInIntent2, shortcutInfo2, options2,
-                splitPosition, splitRatio, adapter, instanceId);
+                splitPosition, snapPosition, adapter, instanceId);
     }
 
     private void startIntents(PendingIntent pendingIntent1, int userId1,
             @Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1,
             PendingIntent pendingIntent2, int userId2, @Nullable ShortcutInfo shortcutInfo2,
-            @Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio,
-            @Nullable RemoteTransition remoteTransition, InstanceId instanceId) {
+            @Nullable Bundle options2, @SplitPosition int splitPosition,
+            @SnapPosition int snapPosition, @Nullable RemoteTransition remoteTransition,
+            InstanceId instanceId) {
         Intent fillInIntent1 = null;
         Intent fillInIntent2 = null;
         final String packageName1 = SplitScreenUtils.getPackageName(pendingIntent1);
@@ -799,7 +802,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
         }
         mStageCoordinator.startIntents(pendingIntent1, fillInIntent1, shortcutInfo1,
                 activityOptions1.toBundle(), pendingIntent2, fillInIntent2, shortcutInfo2,
-                activityOptions2.toBundle(), splitPosition, splitRatio, remoteTransition,
+                activityOptions2.toBundle(), splitPosition, snapPosition, remoteTransition,
                 instanceId);
     }
 
@@ -1219,78 +1222,82 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
         @Override
         public void startTasksWithLegacyTransition(int taskId1, @Nullable Bundle options1,
                 int taskId2, @Nullable Bundle options2, @SplitPosition int splitPosition,
-                float splitRatio, RemoteAnimationAdapter adapter, InstanceId instanceId) {
+                @SnapPosition int snapPosition, RemoteAnimationAdapter adapter,
+                InstanceId instanceId) {
             executeRemoteCallWithTaskPermission(mController, "startTasks",
                     (controller) -> controller.mStageCoordinator.startTasksWithLegacyTransition(
-                            taskId1, options1, taskId2, options2, splitPosition,
-                            splitRatio, adapter, instanceId));
+                            taskId1, options1, taskId2, options2, splitPosition, snapPosition,
+                            adapter, instanceId));
         }
 
         @Override
         public void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent, int userId1,
-                Bundle options1, int taskId, Bundle options2, int splitPosition, float splitRatio,
-                RemoteAnimationAdapter adapter, InstanceId instanceId) {
+                Bundle options1, int taskId, Bundle options2, int splitPosition,
+                @SnapPosition int snapPosition, RemoteAnimationAdapter adapter,
+                InstanceId instanceId) {
             executeRemoteCallWithTaskPermission(mController,
                     "startIntentAndTaskWithLegacyTransition", (controller) ->
                             controller.startIntentAndTaskWithLegacyTransition(pendingIntent,
-                                    userId1, options1, taskId, options2, splitPosition, splitRatio,
-                                    adapter, instanceId));
+                                    userId1, options1, taskId, options2, splitPosition,
+                                    snapPosition, adapter, instanceId));
         }
 
         @Override
         public void startShortcutAndTaskWithLegacyTransition(ShortcutInfo shortcutInfo,
                 @Nullable Bundle options1, int taskId, @Nullable Bundle options2,
-                @SplitPosition int splitPosition, float splitRatio, RemoteAnimationAdapter adapter,
-                InstanceId instanceId) {
+                @SplitPosition int splitPosition, @SnapPosition int snapPosition,
+                RemoteAnimationAdapter adapter, InstanceId instanceId) {
             executeRemoteCallWithTaskPermission(mController,
                     "startShortcutAndTaskWithLegacyTransition", (controller) ->
                             controller.startShortcutAndTaskWithLegacyTransition(
                                     shortcutInfo, options1, taskId, options2, splitPosition,
-                                    splitRatio, adapter, instanceId));
+                                    snapPosition, adapter, instanceId));
         }
 
         @Override
         public void startTasks(int taskId1, @Nullable Bundle options1, int taskId2,
-                @Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio,
-                @Nullable RemoteTransition remoteTransition, InstanceId instanceId) {
+                @Nullable Bundle options2, @SplitPosition int splitPosition,
+                @SnapPosition int snapPosition, @Nullable RemoteTransition remoteTransition,
+                InstanceId instanceId) {
             executeRemoteCallWithTaskPermission(mController, "startTasks",
                     (controller) -> controller.mStageCoordinator.startTasks(taskId1, options1,
-                            taskId2, options2, splitPosition, splitRatio, remoteTransition,
+                            taskId2, options2, splitPosition, snapPosition, remoteTransition,
                             instanceId));
         }
 
         @Override
         public void startIntentAndTask(PendingIntent pendingIntent, int userId1,
                 @Nullable Bundle options1, int taskId, @Nullable Bundle options2,
-                @SplitPosition int splitPosition, float splitRatio,
+                @SplitPosition int splitPosition, @SnapPosition int snapPosition,
                 @Nullable RemoteTransition remoteTransition, InstanceId instanceId) {
             executeRemoteCallWithTaskPermission(mController, "startIntentAndTask",
                     (controller) -> controller.startIntentAndTask(pendingIntent, userId1, options1,
-                            taskId, options2, splitPosition, splitRatio, remoteTransition,
+                            taskId, options2, splitPosition, snapPosition, remoteTransition,
                             instanceId));
         }
 
         @Override
         public void startShortcutAndTask(ShortcutInfo shortcutInfo, @Nullable Bundle options1,
                 int taskId, @Nullable Bundle options2, @SplitPosition int splitPosition,
-                float splitRatio, @Nullable RemoteTransition remoteTransition,
+                @SnapPosition int snapPosition, @Nullable RemoteTransition remoteTransition,
                 InstanceId instanceId) {
             executeRemoteCallWithTaskPermission(mController, "startShortcutAndTask",
                     (controller) -> controller.startShortcutAndTask(shortcutInfo, options1, taskId,
-                            options2, splitPosition, splitRatio, remoteTransition, instanceId));
+                            options2, splitPosition, snapPosition, remoteTransition, instanceId));
         }
 
         @Override
         public void startIntentsWithLegacyTransition(PendingIntent pendingIntent1, int userId1,
                 @Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1,
                 PendingIntent pendingIntent2, int userId2, @Nullable ShortcutInfo shortcutInfo2,
-                @Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio,
-                RemoteAnimationAdapter adapter, InstanceId instanceId) {
+                @Nullable Bundle options2, @SplitPosition int splitPosition,
+                @SnapPosition int snapPosition, RemoteAnimationAdapter adapter,
+                InstanceId instanceId) {
             executeRemoteCallWithTaskPermission(mController, "startIntentsWithLegacyTransition",
                     (controller) ->
                         controller.startIntentsWithLegacyTransition(pendingIntent1, userId1,
                                 shortcutInfo1, options1, pendingIntent2, userId2, shortcutInfo2,
-                                options2, splitPosition, splitRatio, adapter, instanceId)
+                                options2, splitPosition, snapPosition, adapter, instanceId)
                     );
         }
 
@@ -1298,13 +1305,14 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
         public void startIntents(PendingIntent pendingIntent1, int userId1,
                 @Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1,
                 PendingIntent pendingIntent2, int userId2, @Nullable ShortcutInfo shortcutInfo2,
-                @Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio,
-                @Nullable RemoteTransition remoteTransition, InstanceId instanceId) {
+                @Nullable Bundle options2, @SplitPosition int splitPosition,
+                @SnapPosition int snapPosition, @Nullable RemoteTransition remoteTransition,
+                InstanceId instanceId) {
             executeRemoteCallWithTaskPermission(mController, "startIntents",
                     (controller) ->
                             controller.startIntents(pendingIntent1, userId1, shortcutInfo1,
                                     options1, pendingIntent2, userId2, shortcutInfo2, options2,
-                                    splitPosition, splitRatio, remoteTransition, instanceId)
+                                    splitPosition, snapPosition, remoteTransition, instanceId)
             );
         }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index 94fa485efd5c..003273fc2e3b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -128,6 +128,7 @@ import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.common.TransactionPool;
 import com.android.wm.shell.common.split.SplitLayout;
+import com.android.wm.shell.common.split.SplitScreenConstants.SnapPosition;
 import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
 import com.android.wm.shell.common.split.SplitScreenUtils;
 import com.android.wm.shell.common.split.SplitWindowManager;
@@ -631,8 +632,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
     }
 
     /** Starts 2 tasks in one transition. */
-    void startTasks(int taskId1, @Nullable Bundle options1, int taskId2,
-            @Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio,
+    void startTasks(int taskId1, @Nullable Bundle options1, int taskId2, @Nullable Bundle options2,
+            @SplitPosition int splitPosition, @SnapPosition int snapPosition,
             @Nullable RemoteTransition remoteTransition, InstanceId instanceId) {
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         if (taskId2 == INVALID_TASK_ID) {
@@ -654,13 +655,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
         addActivityOptions(options1, mSideStage);
         wct.startTask(taskId1, options1);
 
-        startWithTask(wct, taskId2, options2, splitRatio, remoteTransition, instanceId);
+        startWithTask(wct, taskId2, options2, snapPosition, remoteTransition, instanceId);
     }
 
     /** Start an intent and a task to a split pair in one transition. */
     void startIntentAndTask(PendingIntent pendingIntent, Intent fillInIntent,
             @Nullable Bundle options1, int taskId, @Nullable Bundle options2,
-            @SplitPosition int splitPosition, float splitRatio,
+            @SplitPosition int splitPosition, @SnapPosition int snapPosition,
             @Nullable RemoteTransition remoteTransition, InstanceId instanceId) {
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         if (taskId == INVALID_TASK_ID) {
@@ -676,13 +677,14 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
         addActivityOptions(options1, mSideStage);
         wct.sendPendingIntent(pendingIntent, fillInIntent, options1);
 
-        startWithTask(wct, taskId, options2, splitRatio, remoteTransition, instanceId);
+        startWithTask(wct, taskId, options2, snapPosition, remoteTransition, instanceId);
     }
 
     /** Starts a shortcut and a task to a split pair in one transition. */
     void startShortcutAndTask(ShortcutInfo shortcutInfo, @Nullable Bundle options1,
             int taskId, @Nullable Bundle options2, @SplitPosition int splitPosition,
-            float splitRatio, @Nullable RemoteTransition remoteTransition, InstanceId instanceId) {
+            @SnapPosition int snapPosition, @Nullable RemoteTransition remoteTransition,
+            InstanceId instanceId) {
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         if (taskId == INVALID_TASK_ID) {
             options1 = options1 != null ? options1 : new Bundle();
@@ -697,7 +699,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
         addActivityOptions(options1, mSideStage);
         wct.startShortcut(mContext.getPackageName(), shortcutInfo, options1);
 
-        startWithTask(wct, taskId, options2, splitRatio, remoteTransition, instanceId);
+        startWithTask(wct, taskId, options2, snapPosition, remoteTransition, instanceId);
     }
 
     /**
@@ -708,14 +710,14 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
      *                   {@link SplitscreenEventLogger#logEnter(float, int, int, int, int, boolean)}
      */
     private void startWithTask(WindowContainerTransaction wct, int mainTaskId,
-            @Nullable Bundle mainOptions, float splitRatio,
+            @Nullable Bundle mainOptions, @SnapPosition int snapPosition,
             @Nullable RemoteTransition remoteTransition, InstanceId instanceId) {
         if (!mMainStage.isActive()) {
             // Build a request WCT that will launch both apps such that task 0 is on the main stage
             // while task 1 is on the side stage.
             mMainStage.activate(wct, false /* reparent */);
         }
-        mSplitLayout.setDivideRatio(splitRatio);
+        mSplitLayout.setDivideRatio(snapPosition);
         updateWindowBounds(mSplitLayout, wct);
         wct.reorder(mRootTaskInfo.token, true);
         setRootForceTranslucent(false, wct);
@@ -740,7 +742,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
             @Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1,
             PendingIntent pendingIntent2, Intent fillInIntent2,
             @Nullable ShortcutInfo shortcutInfo2, @Nullable Bundle options2,
-            @SplitPosition int splitPosition, float splitRatio,
+            @SplitPosition int splitPosition, @SnapPosition int snapPosition,
             @Nullable RemoteTransition remoteTransition, InstanceId instanceId) {
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         if (pendingIntent2 == null) {
@@ -762,7 +764,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
         }
 
         setSideStagePosition(splitPosition, wct);
-        mSplitLayout.setDivideRatio(splitRatio);
+        mSplitLayout.setDivideRatio(snapPosition);
         updateWindowBounds(mSplitLayout, wct);
         wct.reorder(mRootTaskInfo.token, true);
         setRootForceTranslucent(false, wct);
@@ -790,7 +792,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
     /** Starts a pair of tasks using legacy transition. */
     void startTasksWithLegacyTransition(int taskId1, @Nullable Bundle options1,
             int taskId2, @Nullable Bundle options2, @SplitPosition int splitPosition,
-            float splitRatio, RemoteAnimationAdapter adapter, InstanceId instanceId) {
+            @SnapPosition int snapPosition, RemoteAnimationAdapter adapter, InstanceId instanceId) {
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         if (options1 == null) options1 = new Bundle();
         if (taskId2 == INVALID_TASK_ID) {
@@ -811,7 +813,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
         addActivityOptions(options1, mSideStage);
         wct.startTask(taskId1, options1);
         mSplitRequest = new SplitRequest(taskId1, taskId2, splitPosition);
-        startWithLegacyTransition(wct, taskId2, options2, splitPosition, splitRatio, adapter,
+        startWithLegacyTransition(wct, taskId2, options2, splitPosition, snapPosition, adapter,
                 instanceId);
     }
 
@@ -820,8 +822,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
             @Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1,
             @Nullable PendingIntent pendingIntent2, Intent fillInIntent2,
             @Nullable ShortcutInfo shortcutInfo2, @Nullable Bundle options2,
-            @SplitPosition int splitPosition, float splitRatio, RemoteAnimationAdapter adapter,
-            InstanceId instanceId) {
+            @SplitPosition int splitPosition, @SnapPosition int snapPosition,
+            RemoteAnimationAdapter adapter, InstanceId instanceId) {
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         if (options1 == null) options1 = new Bundle();
         if (pendingIntent2 == null) {
@@ -840,13 +842,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
                     pendingIntent2 != null ? pendingIntent2.getIntent() : null, splitPosition);
         }
         startWithLegacyTransition(wct, pendingIntent2, fillInIntent2, shortcutInfo2, options2,
-                splitPosition, splitRatio, adapter, instanceId);
+                splitPosition, snapPosition, adapter, instanceId);
     }
 
     void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent, Intent fillInIntent,
             @Nullable Bundle options1, int taskId, @Nullable Bundle options2,
-            @SplitPosition int splitPosition, float splitRatio, RemoteAnimationAdapter adapter,
-            InstanceId instanceId) {
+            @SplitPosition int splitPosition, @SnapPosition int snapPosition,
+            RemoteAnimationAdapter adapter, InstanceId instanceId) {
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         if (options1 == null) options1 = new Bundle();
         if (taskId == INVALID_TASK_ID) {
@@ -859,15 +861,15 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
         addActivityOptions(options1, mSideStage);
         wct.sendPendingIntent(pendingIntent, fillInIntent, options1);
         mSplitRequest = new SplitRequest(taskId, pendingIntent.getIntent(), splitPosition);
-        startWithLegacyTransition(wct, taskId, options2, splitPosition, splitRatio, adapter,
+        startWithLegacyTransition(wct, taskId, options2, splitPosition, snapPosition, adapter,
                 instanceId);
     }
 
     /** Starts a pair of shortcut and task using legacy transition. */
     void startShortcutAndTaskWithLegacyTransition(ShortcutInfo shortcutInfo,
             @Nullable Bundle options1, int taskId, @Nullable Bundle options2,
-            @SplitPosition int splitPosition, float splitRatio, RemoteAnimationAdapter adapter,
-            InstanceId instanceId) {
+            @SplitPosition int splitPosition, @SnapPosition int snapPosition,
+            RemoteAnimationAdapter adapter, InstanceId instanceId) {
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         if (options1 == null) options1 = new Bundle();
         if (taskId == INVALID_TASK_ID) {
@@ -878,7 +880,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
 
         addActivityOptions(options1, mSideStage);
         wct.startShortcut(mContext.getPackageName(), shortcutInfo, options1);
-        startWithLegacyTransition(wct, taskId, options2, splitPosition, splitRatio, adapter,
+        startWithLegacyTransition(wct, taskId, options2, splitPosition, snapPosition, adapter,
                 instanceId);
     }
 
@@ -928,18 +930,19 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
     private void startWithLegacyTransition(WindowContainerTransaction wct,
             @Nullable PendingIntent mainPendingIntent, @Nullable Intent mainFillInIntent,
             @Nullable ShortcutInfo mainShortcutInfo, @Nullable Bundle mainOptions,
-            @SplitPosition int sidePosition, float splitRatio, RemoteAnimationAdapter adapter,
-            InstanceId instanceId) {
+            @SplitPosition int sidePosition, @SnapPosition int snapPosition,
+            RemoteAnimationAdapter adapter, InstanceId instanceId) {
         startWithLegacyTransition(wct, INVALID_TASK_ID, mainPendingIntent, mainFillInIntent,
-                mainShortcutInfo, mainOptions, sidePosition, splitRatio, adapter, instanceId);
+                mainShortcutInfo, mainOptions, sidePosition, snapPosition, adapter, instanceId);
     }
 
     private void startWithLegacyTransition(WindowContainerTransaction wct, int mainTaskId,
-            @Nullable Bundle mainOptions, @SplitPosition int sidePosition, float splitRatio,
-            RemoteAnimationAdapter adapter, InstanceId instanceId) {
+            @Nullable Bundle mainOptions, @SplitPosition int sidePosition,
+            @SnapPosition int snapPosition, RemoteAnimationAdapter adapter,
+            InstanceId instanceId) {
         startWithLegacyTransition(wct, mainTaskId, null /* mainPendingIntent */,
                 null /* mainFillInIntent */, null /* mainShortcutInfo */, mainOptions, sidePosition,
-                splitRatio, adapter, instanceId);
+                snapPosition, adapter, instanceId);
     }
 
     /**
@@ -950,15 +953,15 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
     private void startWithLegacyTransition(WindowContainerTransaction wct, int mainTaskId,
             @Nullable PendingIntent mainPendingIntent, @Nullable Intent mainFillInIntent,
             @Nullable ShortcutInfo mainShortcutInfo, @Nullable Bundle options,
-            @SplitPosition int sidePosition, float splitRatio, RemoteAnimationAdapter adapter,
-            InstanceId instanceId) {
+            @SplitPosition int sidePosition, @SnapPosition int snapPosition,
+            RemoteAnimationAdapter adapter, InstanceId instanceId) {
         if (!isSplitScreenVisible()) {
             exitSplitScreen(null /* childrenToTop */, EXIT_REASON_RECREATE_SPLIT);
         }
 
         // Init divider first to make divider leash for remote animation target.
         mSplitLayout.init();
-        mSplitLayout.setDivideRatio(splitRatio);
+        mSplitLayout.setDivideRatio(snapPosition);
 
         // Apply surface bounds before animation start.
         SurfaceControl.Transaction startT = mTransactionPool.acquire();
@@ -1761,7 +1764,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
                 rightBottomTaskId = sideStageTopTaskId;
             }
             SplitBounds splitBounds = new SplitBounds(topLeftBounds, bottomRightBounds,
-                    leftTopTaskId, rightBottomTaskId);
+                    leftTopTaskId, rightBottomTaskId, mSplitLayout.calculateCurrentSnapPosition());
             if (mainStageTopTaskId != INVALID_TASK_ID && sideStageTopTaskId != INVALID_TASK_ID) {
                 // Update the pair for the top tasks
                 recentTasks.addSplitPair(mainStageTopTaskId, sideStageTopTaskId, splitBounds);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/util/SplitBounds.java b/libs/WindowManager/Shell/src/com/android/wm/shell/util/SplitBounds.java
index 0edcff45f648..a68b41d6563a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/util/SplitBounds.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/util/SplitBounds.java
@@ -19,6 +19,8 @@ import android.graphics.Rect;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import com.android.wm.shell.common.split.SplitScreenConstants.SnapPosition;
+
 import java.util.Objects;
 
 /**
@@ -37,6 +39,7 @@ public class SplitBounds implements Parcelable {
     public final float leftTaskPercent;
     public final float dividerWidthPercent;
     public final float dividerHeightPercent;
+    public final @SnapPosition int snapPosition;
     /**
      * If {@code true}, that means at the time of creation of this object, the
      * split-screened apps were vertically stacked. This is useful in scenarios like
@@ -47,12 +50,13 @@ public class SplitBounds implements Parcelable {
     public final int leftTopTaskId;
     public final int rightBottomTaskId;
 
-    public SplitBounds(Rect leftTopBounds, Rect rightBottomBounds,
-            int leftTopTaskId, int rightBottomTaskId) {
+    public SplitBounds(Rect leftTopBounds, Rect rightBottomBounds, int leftTopTaskId,
+            int rightBottomTaskId, @SnapPosition int snapPosition) {
         this.leftTopBounds = leftTopBounds;
         this.rightBottomBounds = rightBottomBounds;
         this.leftTopTaskId = leftTopTaskId;
         this.rightBottomTaskId = rightBottomTaskId;
+        this.snapPosition = snapPosition;
 
         if (rightBottomBounds.top > leftTopBounds.top) {
             // vertical apps, horizontal divider
@@ -83,8 +87,9 @@ public class SplitBounds implements Parcelable {
         appsStackedVertically = parcel.readBoolean();
         leftTopTaskId = parcel.readInt();
         rightBottomTaskId = parcel.readInt();
-        dividerWidthPercent = parcel.readInt();
-        dividerHeightPercent = parcel.readInt();
+        dividerWidthPercent = parcel.readFloat();
+        dividerHeightPercent = parcel.readFloat();
+        snapPosition = parcel.readInt();
     }
 
     @Override
@@ -99,6 +104,7 @@ public class SplitBounds implements Parcelable {
         parcel.writeInt(rightBottomTaskId);
         parcel.writeFloat(dividerWidthPercent);
         parcel.writeFloat(dividerHeightPercent);
+        parcel.writeInt(snapPosition);
     }
 
     @Override
@@ -129,7 +135,8 @@ public class SplitBounds implements Parcelable {
         return "LeftTop: " + leftTopBounds + ", taskId: " + leftTopTaskId + "\n"
                 + "RightBottom: " + rightBottomBounds + ", taskId: " + rightBottomTaskId +  "\n"
                 + "Divider: " + visualDividerBounds + "\n"
-                + "AppsVertical? " + appsStackedVertically;
+                + "AppsVertical? " + appsStackedVertically + "\n"
+                + "snapPosition: " + snapPosition;
     }
 
     public static final Creator<SplitBounds> CREATOR = new Creator<SplitBounds>() {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java
index ad84c7fb6128..56d0f8e13f08 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java
@@ -18,9 +18,13 @@ package com.android.wm.shell.common.split;
 
 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
 import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+
+import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_50_50;
 import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_END_AND_DISMISS;
 import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_START_AND_DISMISS;
+
 import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
@@ -130,7 +134,7 @@ public class SplitLayoutTests extends ShellTestCase {
     @Test
     public void testSetDivideRatio() {
         mSplitLayout.setDividePosition(200, false /* applyLayoutChange */);
-        mSplitLayout.setDivideRatio(0.5f);
+        mSplitLayout.setDivideRatio(SNAP_TO_50_50);
         assertThat(mSplitLayout.getDividePosition()).isEqualTo(
                 mSplitLayout.mDividerSnapAlgorithm.getMiddleTarget().position);
     }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedRecentTaskInfoTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedRecentTaskInfoTest.kt
index baa06f2f0c45..bbd65be9abda 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedRecentTaskInfoTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedRecentTaskInfoTest.kt
@@ -24,6 +24,7 @@ import android.window.IWindowContainerToken
 import android.window.WindowContainerToken
 import androidx.test.filters.SmallTest
 import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_50_50
 import com.android.wm.shell.util.GroupedRecentTaskInfo
 import com.android.wm.shell.util.GroupedRecentTaskInfo.CREATOR
 import com.android.wm.shell.util.GroupedRecentTaskInfo.TYPE_FREEFORM
@@ -123,6 +124,7 @@ class GroupedRecentTaskInfoTest : ShellTestCase() {
         assertThat(recentTaskInfoParcel.taskInfo2).isNotNull()
         assertThat(recentTaskInfoParcel.taskInfo2!!.taskId).isEqualTo(2)
         assertThat(recentTaskInfoParcel.splitBounds).isNotNull()
+        assertThat(recentTaskInfoParcel.splitBounds!!.snapPosition).isEqualTo(SNAP_TO_50_50)
     }
 
     @Test
@@ -156,7 +158,7 @@ class GroupedRecentTaskInfoTest : ShellTestCase() {
     private fun splitTasksGroupInfo(): GroupedRecentTaskInfo {
         val task1 = createTaskInfo(id = 1)
         val task2 = createTaskInfo(id = 2)
-        val splitBounds = SplitBounds(Rect(), Rect(), 1, 2)
+        val splitBounds = SplitBounds(Rect(), Rect(), 1, 2, SNAP_TO_50_50)
         return GroupedRecentTaskInfo.forSplitTasks(task1, task2, splitBounds)
     }
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
index 40ce7859cc7f..10e9e11e9004 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
@@ -22,6 +22,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
+import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_50_50;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -173,10 +174,10 @@ public class RecentTasksControllerTest extends ShellTestCase {
 
         // Verify only one update if the split info is the same
         SplitBounds bounds1 = new SplitBounds(new Rect(0, 0, 50, 50),
-                new Rect(50, 50, 100, 100), t1.taskId, t2.taskId);
+                new Rect(50, 50, 100, 100), t1.taskId, t2.taskId, SNAP_TO_50_50);
         mRecentTasksController.addSplitPair(t1.taskId, t2.taskId, bounds1);
         SplitBounds bounds2 = new SplitBounds(new Rect(0, 0, 50, 50),
-                new Rect(50, 50, 100, 100), t1.taskId, t2.taskId);
+                new Rect(50, 50, 100, 100), t1.taskId, t2.taskId, SNAP_TO_50_50);
         mRecentTasksController.addSplitPair(t1.taskId, t2.taskId, bounds2);
         verify(mRecentTasksController, times(1)).notifyRecentTasksChanged();
     }
@@ -207,8 +208,10 @@ public class RecentTasksControllerTest extends ShellTestCase {
         setRawList(t1, t2, t3, t4, t5, t6);
 
         // Mark a couple pairs [t2, t4], [t3, t5]
-        SplitBounds pair1Bounds = new SplitBounds(new Rect(), new Rect(), 2, 4);
-        SplitBounds pair2Bounds = new SplitBounds(new Rect(), new Rect(), 3, 5);
+        SplitBounds pair1Bounds =
+                new SplitBounds(new Rect(), new Rect(), 2, 4, SNAP_TO_50_50);
+        SplitBounds pair2Bounds =
+                new SplitBounds(new Rect(), new Rect(), 3, 5, SNAP_TO_50_50);
 
         mRecentTasksController.addSplitPair(t2.taskId, t4.taskId, pair1Bounds);
         mRecentTasksController.addSplitPair(t3.taskId, t5.taskId, pair2Bounds);
@@ -236,8 +239,10 @@ public class RecentTasksControllerTest extends ShellTestCase {
         setRawList(t1, t2, t3, t4, t5, t6);
 
         // Mark a couple pairs [t2, t4], [t3, t5]
-        SplitBounds pair1Bounds = new SplitBounds(new Rect(), new Rect(), 2, 4);
-        SplitBounds pair2Bounds = new SplitBounds(new Rect(), new Rect(), 3, 5);
+        SplitBounds pair1Bounds =
+                new SplitBounds(new Rect(), new Rect(), 2, 4, SNAP_TO_50_50);
+        SplitBounds pair2Bounds =
+                new SplitBounds(new Rect(), new Rect(), 3, 5, SNAP_TO_50_50);
 
         mRecentTasksController.addSplitPair(t2.taskId, t4.taskId, pair1Bounds);
         mRecentTasksController.addSplitPair(t3.taskId, t5.taskId, pair2Bounds);
@@ -334,7 +339,8 @@ public class RecentTasksControllerTest extends ShellTestCase {
         setRawList(t1, t2, t3);
 
         // Add a pair
-        SplitBounds pair1Bounds = new SplitBounds(new Rect(), new Rect(), 2, 3);
+        SplitBounds pair1Bounds =
+                new SplitBounds(new Rect(), new Rect(), 2, 3, SNAP_TO_50_50);
         mRecentTasksController.addSplitPair(t2.taskId, t3.taskId, pair1Bounds);
         reset(mRecentTasksController);
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/SplitBoundsTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/SplitBoundsTest.java
index 50d02ae0dccd..b790aee6fb0e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/SplitBoundsTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/SplitBoundsTest.java
@@ -1,5 +1,7 @@
 package com.android.wm.shell.recents;
 
+import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_50_50;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -44,21 +46,21 @@ public class SplitBoundsTest extends ShellTestCase {
     @Test
     public void testVerticalStacked() {
         SplitBounds ssb = new SplitBounds(mTopRect, mBottomRect,
-                TASK_ID_1, TASK_ID_2);
+                TASK_ID_1, TASK_ID_2, SNAP_TO_50_50);
         assertTrue(ssb.appsStackedVertically);
     }
 
     @Test
     public void testHorizontalStacked() {
         SplitBounds ssb = new SplitBounds(mLeftRect, mRightRect,
-                TASK_ID_1, TASK_ID_2);
+                TASK_ID_1, TASK_ID_2, SNAP_TO_50_50);
         assertFalse(ssb.appsStackedVertically);
     }
 
     @Test
     public void testHorizontalDividerBounds() {
         SplitBounds ssb = new SplitBounds(mTopRect, mBottomRect,
-                TASK_ID_1, TASK_ID_2);
+                TASK_ID_1, TASK_ID_2, SNAP_TO_50_50);
         Rect dividerBounds = ssb.visualDividerBounds;
         assertEquals(0, dividerBounds.left);
         assertEquals(DEVICE_LENGTH / 2 - DIVIDER_SIZE / 2, dividerBounds.top);
@@ -69,7 +71,7 @@ public class SplitBoundsTest extends ShellTestCase {
     @Test
     public void testVerticalDividerBounds() {
         SplitBounds ssb = new SplitBounds(mLeftRect, mRightRect,
-                TASK_ID_1, TASK_ID_2);
+                TASK_ID_1, TASK_ID_2, SNAP_TO_50_50);
         Rect dividerBounds = ssb.visualDividerBounds;
         assertEquals(DEVICE_WIDTH / 2 - DIVIDER_SIZE / 2, dividerBounds.left);
         assertEquals(0, dividerBounds.top);
@@ -80,7 +82,7 @@ public class SplitBoundsTest extends ShellTestCase {
     @Test
     public void testEqualVerticalTaskPercent() {
         SplitBounds ssb = new SplitBounds(mTopRect, mBottomRect,
-                TASK_ID_1, TASK_ID_2);
+                TASK_ID_1, TASK_ID_2, SNAP_TO_50_50);
         float topPercentSpaceTaken = (float) (DEVICE_LENGTH / 2 - DIVIDER_SIZE / 2) / DEVICE_LENGTH;
         assertEquals(topPercentSpaceTaken, ssb.topTaskPercent, 0.01);
     }
@@ -88,7 +90,7 @@ public class SplitBoundsTest extends ShellTestCase {
     @Test
     public void testEqualHorizontalTaskPercent() {
         SplitBounds ssb = new SplitBounds(mLeftRect, mRightRect,
-                TASK_ID_1, TASK_ID_2);
+                TASK_ID_1, TASK_ID_2, SNAP_TO_50_50);
         float leftPercentSpaceTaken = (float) (DEVICE_WIDTH / 2 - DIVIDER_SIZE / 2) / DEVICE_WIDTH;
         assertEquals(leftPercentSpaceTaken, ssb.leftTaskPercent, 0.01);
     }
-- 
GitLab


From 4added4d55720e70d8d8eab6489dc61e0c0b5e6b Mon Sep 17 00:00:00 2001
From: Jakob Schneider <jakobschneider@google.com>
Date: Fri, 15 Sep 2023 17:16:46 +0100
Subject: [PATCH 13/95] Check for isInstalled when checking if an app is
 actually archived.

Bug: 290776158
Test: PackageInstallArchiveTest
Change-Id: I1110e4608f27af39e0b7aed5535165b123a611f9
---
 .../com/android/server/pm/ComputerEngine.java  | 11 +++--------
 .../com/android/server/pm/PackageArchiver.java |  9 +++++++--
 .../server/pm/parsing/PackageInfoUtils.java    | 10 ++--------
 .../android/server/pm/PackageArchiverTest.java | 18 ++++++++++++++++--
 4 files changed, 28 insertions(+), 20 deletions(-)

diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index 316c4aca1891..6baa889d61ae 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -1700,7 +1700,9 @@ public class ComputerEngine implements Computer {
                 if (!listApex && ps.getPkg() != null && ps.getPkg().isApex()) {
                     continue;
                 }
-                if (listArchivedOnly && !isArchived(ps.getUserStateOrDefault(userId))) {
+                PackageUserStateInternal userState = ps.getUserStateOrDefault(userId);
+                if (listArchivedOnly && !userState.isInstalled()
+                        && userState.getArchiveState() == null) {
                     continue;
                 }
                 if (filterSharedLibPackage(ps, callingUid, userId, flags)) {
@@ -1746,13 +1748,6 @@ public class ComputerEngine implements Computer {
         return new ParceledListSlice<>(list);
     }
 
-    // TODO(b/288142708) Check for userState.isInstalled() here once this bug is fixed.
-    // If an app has isInstalled() == true - it should not be filtered above in any case, currently
-    // it is.
-    private static boolean isArchived(PackageUserStateInternal userState) {
-        return userState.getArchiveState() != null;
-    }
-
     public final ResolveInfo createForwardingResolveInfoUnchecked(WatchedIntentFilter filter,
             int sourceUserId, int targetUserId) {
         ResolveInfo forwardingResolveInfo = new ResolveInfo();
diff --git a/services/core/java/com/android/server/pm/PackageArchiver.java b/services/core/java/com/android/server/pm/PackageArchiver.java
index 803b6e45cdca..f59188e9fd93 100644
--- a/services/core/java/com/android/server/pm/PackageArchiver.java
+++ b/services/core/java/com/android/server/pm/PackageArchiver.java
@@ -58,6 +58,7 @@ import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.pm.pkg.ArchiveState;
 import com.android.server.pm.pkg.ArchiveState.ArchiveActivityInfo;
 import com.android.server.pm.pkg.PackageStateInternal;
+import com.android.server.pm.pkg.PackageUserState;
 import com.android.server.pm.pkg.PackageUserStateInternal;
 
 import java.io.ByteArrayOutputStream;
@@ -101,6 +102,11 @@ public class PackageArchiver {
         this.mPm = mPm;
     }
 
+    /** Returns whether a package is archived for a user. */
+    public static boolean isArchived(PackageUserState userState) {
+        return userState.getArchiveState() != null && !userState.isInstalled();
+    }
+
     void requestArchive(
             @NonNull String packageName,
             @NonNull String callerPackageName,
@@ -354,8 +360,7 @@ public class PackageArchiver {
     private void verifyArchived(PackageStateInternal ps, int userId)
             throws PackageManager.NameNotFoundException {
         PackageUserStateInternal userState = ps.getUserStateOrDefault(userId);
-        // TODO(b/288142708) Check for isInstalled false here too.
-        if (userState.getArchiveState() == null) {
+        if (!isArchived(userState)) {
             throw new PackageManager.NameNotFoundException(
                     TextUtils.formatSimple("Package %s is not currently archived.",
                             ps.getPackageName()));
diff --git a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
index cc8e62409597..d16a81267370 100644
--- a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
+++ b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
@@ -54,6 +54,7 @@ import android.util.Slog;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
 import com.android.server.SystemConfig;
+import com.android.server.pm.PackageArchiver;
 import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
 import com.android.server.pm.parsing.pkg.PackageImpl;
 import com.android.server.pm.pkg.AndroidPackage;
@@ -401,14 +402,7 @@ public class PackageInfoUtils {
             ai.resourceDirs = overlayPaths.getResourceDirs().toArray(new String[0]);
             ai.overlayPaths = overlayPaths.getOverlayPaths().toArray(new String[0]);
         }
-        ai.isArchived = isArchived(state);
-    }
-
-    // TODO(b/288142708) Check for userState.isInstalled() here once this bug is fixed.
-    // If an app has isInstalled() == true - it should not be filtered above in any case, currently
-    // it is.
-    private static boolean isArchived(PackageUserState userState) {
-        return userState.getArchiveState() != null;
+        ai.isArchived = PackageArchiver.isArchived(state);
     }
 
     @Nullable
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverTest.java
index b97fd4b3277b..eb50556821eb 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverTest.java
@@ -315,7 +315,8 @@ public class PackageArchiverTest {
     }
 
     @Test
-    public void unarchiveApp_notArchived() {
+    public void unarchiveApp_notArchived_missingArchiveState() {
+        mUserState.setInstalled(false);
         Exception e = assertThrows(
                 ParcelableException.class,
                 () -> mArchiveManager.requestUnarchive(PACKAGE, CALLER_PACKAGE,
@@ -326,8 +327,21 @@ public class PackageArchiverTest {
     }
 
     @Test
-    public void unarchiveApp_noInstallerFound() {
+    public void unarchiveApp_notArchived_stillInstalled() {
         mUserState.setArchiveState(createArchiveState());
+        Exception e = assertThrows(
+                ParcelableException.class,
+                () -> mArchiveManager.requestUnarchive(PACKAGE, CALLER_PACKAGE,
+                        UserHandle.CURRENT));
+        assertThat(e.getCause()).isInstanceOf(PackageManager.NameNotFoundException.class);
+        assertThat(e.getCause()).hasMessageThat().isEqualTo(
+                String.format("Package %s is not currently archived.", PACKAGE));
+    }
+
+
+    @Test
+    public void unarchiveApp_noInstallerFound() {
+        mUserState.setArchiveState(createArchiveState()).setInstalled(false);
         InstallSource otherInstallSource =
                 InstallSource.create(
                         CALLER_PACKAGE,
-- 
GitLab


From 88301fedcbff39956a0226d0f6d6e57b10f77a6f Mon Sep 17 00:00:00 2001
From: Sudheer Shanka <sudheersai@google.com>
Date: Tue, 19 Sep 2023 18:22:44 +0000
Subject: [PATCH 14/95] Revert "Add temporary logging to root cause an issue."

This reverts commit 1cdfa801f5911c76b3b8a88f7e34a9eaf30840d5.

Reason for revert: not needed any more

Change-Id: I2dfca6cbe9e79cbfcde5b4e6f77ce483b5d93642
---
 .../com/android/server/am/ActivityManagerService.java | 11 -----------
 .../android/server/am/BroadcastQueueModernImpl.java   | 11 -----------
 2 files changed, 22 deletions(-)

diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 1fa60fef401b..967177219475 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -314,7 +314,6 @@ import android.net.ConnectivityManager;
 import android.net.Proxy;
 import android.net.Uri;
 import android.os.AppZygote;
-import android.os.BatteryManager;
 import android.os.BatteryStats;
 import android.os.Binder;
 import android.os.BinderProxy;
@@ -15030,16 +15029,6 @@ public class ActivityManagerService extends IActivityManager.Stub
             }
         }
 
-        // STOPSHIP(b/298884211):  Remove this logging
-        if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
-            final int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
-            if (level < 0) {
-                Slog.wtf(BroadcastQueue.TAG, "Unexpected broadcast: " + intent
-                        + "; callingUid: " + callingUid + ", callingPid: " + callingPid,
-                        new Throwable());
-            }
-        }
-
         int[] users;
         if (userId == UserHandle.USER_ALL) {
             // Caller wants broadcast to go to all started users.
diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
index d5343a9777a7..5d0fefc75a28 100644
--- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
+++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
@@ -59,7 +59,6 @@ import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
-import android.os.BatteryManager;
 import android.os.Bundle;
 import android.os.BundleMerger;
 import android.os.Handler;
@@ -1075,16 +1074,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
                 queue.lastProcessState = app.mState.getCurProcState();
                 if (receiver instanceof BroadcastFilter) {
                     notifyScheduleRegisteredReceiver(app, r, (BroadcastFilter) receiver);
-                    // STOPSHIP(b/298884211):  Remove this logging
-                    if (Intent.ACTION_BATTERY_CHANGED.equals(receiverIntent.getAction())) {
-                        int level = receiverIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
-                        if (level < 0) {
-                            Slog.wtf(TAG, "Dispatching unexpected broadcast: " + receiverIntent
-                                    + " to " + receiver
-                                    + "; callingUid: " + r.callingUid
-                                    + ", callingPid: " + r.callingPid);
-                        }
-                    }
                     thread.scheduleRegisteredReceiver(
                         ((BroadcastFilter) receiver).receiverList.receiver,
                         receiverIntent, r.resultCode, r.resultData, r.resultExtras,
-- 
GitLab


From 2fd7a0b3be945aa7b21f84da2592204dd7025b2d Mon Sep 17 00:00:00 2001
From: Evan Laird <evanlaird@google.com>
Date: Tue, 22 Aug 2023 17:08:59 -0400
Subject: [PATCH 15/95] [StatusBar] Request layout on vis change, and move to
 CREATED

The flow that was being bound to the mobile icon group's visibility
lived in STARTED (this caused tests to pass). It also was experiencing a
race condition against the StatusIconContainer. In certain
circumstances, the view was being created and sent to have an icon state
of HIDDEN, despite having changed itself to be VISIBLE.

This is all emergent behavior from StatusIconContainer, which decides
which state to set on icons in its onMeasure(), but then applies that
state in onLayout().

To test: remove battery percent from status bar; ensure that _no other
icon_ is showing. This means disable Wi-Fi and make sure volume is set
to vibrate or on, since those states have no icon. Once you are in a
state where there is only battery and mobile showing, remove and
re-insert the SIM card to reproduce.

Test: ModernStatusBarMobileViewTest
Test: manually removing and inserting SIM card
Fixes: 291031862
Change-Id: I0e68037126a526fcf3614bf25683af3fa4e5aa96
Merged-In: I0e68037126a526fcf3614bf25683af3fa4e5aa96
---
 .../mobile/ui/binder/MobileIconBinder.kt      | 165 ++++++++++--------
 .../ShadeCarrierGroupControllerTest.java      |  12 +-
 .../systemui/util/kotlin/FlowProvider.kt      |  22 +++
 3 files changed, 122 insertions(+), 77 deletions(-)
 create mode 100644 packages/SystemUI/tests/src/com/android/systemui/util/kotlin/FlowProvider.kt

diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
index 6483b7c647e8..7ec8e12e557e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
@@ -25,6 +25,7 @@ import android.widget.ImageView
 import android.widget.Space
 import androidx.core.view.isVisible
 import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.lifecycleScope
 import androidx.lifecycle.repeatOnLifecycle
 import com.android.settingslib.graph.SignalDrawable
 import com.android.systemui.R
@@ -62,7 +63,7 @@ object MobileIconBinder {
         val roamingSpace = view.requireViewById<Space>(R.id.mobile_roaming_space)
         val dotView = view.requireViewById<StatusBarIconView>(R.id.status_bar_dot)
 
-        view.isVisible = true
+        view.isVisible = viewModel.isVisible.value
         iconView.isVisible = true
 
         // TODO(b/238425913): We should log this visibility state.
@@ -75,99 +76,113 @@ object MobileIconBinder {
         var isCollecting = false
 
         view.repeatWhenAttached {
-            repeatOnLifecycle(Lifecycle.State.STARTED) {
-                logger.logCollectionStarted(view, viewModel)
-                isCollecting = true
-
-                launch {
-                    visibilityState.collect { state ->
-                        ModernStatusBarViewVisibilityHelper.setVisibilityState(
-                            state,
-                            mobileGroupView,
-                            dotView,
-                        )
+            lifecycleScope.launch {
+                repeatOnLifecycle(Lifecycle.State.CREATED) {
+                    // isVisible controls the visibility state of the outer group, and thus it needs
+                    // to run in the CREATED lifecycle so it can continue to watch while invisible
+                    // See (b/291031862) for details
+                    launch {
+                        viewModel.isVisible.collect { isVisible ->
+                            viewModel.verboseLogger?.logBinderReceivedVisibility(
+                                view,
+                                viewModel.subscriptionId,
+                                isVisible
+                            )
+                            view.isVisible = isVisible
+                            // [StatusIconContainer] can get out of sync sometimes. Make sure to
+                            // request another layout when this changes.
+                            view.requestLayout()
+                        }
                     }
                 }
+            }
 
-                launch {
-                    viewModel.isVisible.collect { isVisible ->
-                        viewModel.verboseLogger?.logBinderReceivedVisibility(
-                            view,
-                            viewModel.subscriptionId,
-                            isVisible
-                        )
-                        view.isVisible = isVisible
+            lifecycleScope.launch {
+                repeatOnLifecycle(Lifecycle.State.STARTED) {
+                    logger.logCollectionStarted(view, viewModel)
+                    isCollecting = true
+
+                    launch {
+                        visibilityState.collect { state ->
+                            ModernStatusBarViewVisibilityHelper.setVisibilityState(
+                                state,
+                                mobileGroupView,
+                                dotView,
+                            )
+                        }
                     }
-                }
 
-                // Set the icon for the triangle
-                launch {
-                    viewModel.icon.distinctUntilChanged().collect { icon ->
-                        viewModel.verboseLogger?.logBinderReceivedSignalIcon(
-                            view,
-                            viewModel.subscriptionId,
-                            icon,
-                        )
-                        mobileDrawable.level = icon.toSignalDrawableState()
+                    // Set the icon for the triangle
+                    launch {
+                        viewModel.icon.distinctUntilChanged().collect { icon ->
+                            viewModel.verboseLogger?.logBinderReceivedSignalIcon(
+                                view,
+                                viewModel.subscriptionId,
+                                icon,
+                            )
+                            mobileDrawable.level = icon.toSignalDrawableState()
+                        }
                     }
-                }
 
-                launch {
-                    viewModel.contentDescription.distinctUntilChanged().collect {
-                        ContentDescriptionViewBinder.bind(it, view)
+                    launch {
+                        viewModel.contentDescription.distinctUntilChanged().collect {
+                            ContentDescriptionViewBinder.bind(it, view)
+                        }
                     }
-                }
 
-                // Set the network type icon
-                launch {
-                    viewModel.networkTypeIcon.distinctUntilChanged().collect { dataTypeId ->
-                        viewModel.verboseLogger?.logBinderReceivedNetworkTypeIcon(
-                            view,
-                            viewModel.subscriptionId,
-                            dataTypeId,
-                        )
-                        dataTypeId?.let { IconViewBinder.bind(dataTypeId, networkTypeView) }
-                        networkTypeView.visibility = if (dataTypeId != null) VISIBLE else GONE
+                    // Set the network type icon
+                    launch {
+                        viewModel.networkTypeIcon.distinctUntilChanged().collect { dataTypeId ->
+                            viewModel.verboseLogger?.logBinderReceivedNetworkTypeIcon(
+                                view,
+                                viewModel.subscriptionId,
+                                dataTypeId,
+                            )
+                            dataTypeId?.let { IconViewBinder.bind(dataTypeId, networkTypeView) }
+                            networkTypeView.visibility = if (dataTypeId != null) VISIBLE else GONE
+                        }
                     }
-                }
 
-                // Set the roaming indicator
-                launch {
-                    viewModel.roaming.distinctUntilChanged().collect { isRoaming ->
-                        roamingView.isVisible = isRoaming
-                        roamingSpace.isVisible = isRoaming
+                    // Set the roaming indicator
+                    launch {
+                        viewModel.roaming.distinctUntilChanged().collect { isRoaming ->
+                            roamingView.isVisible = isRoaming
+                            roamingSpace.isVisible = isRoaming
+                        }
                     }
-                }
 
-                // Set the activity indicators
-                launch { viewModel.activityInVisible.collect { activityIn.isVisible = it } }
+                    // Set the activity indicators
+                    launch { viewModel.activityInVisible.collect { activityIn.isVisible = it } }
 
-                launch { viewModel.activityOutVisible.collect { activityOut.isVisible = it } }
+                    launch { viewModel.activityOutVisible.collect { activityOut.isVisible = it } }
 
-                launch {
-                    viewModel.activityContainerVisible.collect { activityContainer.isVisible = it }
-                }
+                    launch {
+                        viewModel.activityContainerVisible.collect {
+                            activityContainer.isVisible = it
+                        }
+                    }
 
-                // Set the tint
-                launch {
-                    iconTint.collect { tint ->
-                        val tintList = ColorStateList.valueOf(tint)
-                        iconView.imageTintList = tintList
-                        networkTypeView.imageTintList = tintList
-                        roamingView.imageTintList = tintList
-                        activityIn.imageTintList = tintList
-                        activityOut.imageTintList = tintList
-                        dotView.setDecorColor(tint)
+                    // Set the tint
+                    launch {
+                        iconTint.collect { tint ->
+                            val tintList = ColorStateList.valueOf(tint)
+                            iconView.imageTintList = tintList
+                            networkTypeView.imageTintList = tintList
+                            roamingView.imageTintList = tintList
+                            activityIn.imageTintList = tintList
+                            activityOut.imageTintList = tintList
+                            dotView.setDecorColor(tint)
+                        }
                     }
-                }
 
-                launch { decorTint.collect { tint -> dotView.setDecorColor(tint) } }
+                    launch { decorTint.collect { tint -> dotView.setDecorColor(tint) } }
 
-                try {
-                    awaitCancellation()
-                } finally {
-                    isCollecting = false
-                    logger.logCollectionStopped(view, viewModel)
+                    try {
+                        awaitCancellation()
+                    } finally {
+                        isCollecting = false
+                        logger.logCollectionStopped(view, viewModel)
+                    }
                 }
             }
         }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierGroupControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierGroupControllerTest.java
index 5fa6b3a15d35..e7056c7b0b9d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierGroupControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierGroupControllerTest.java
@@ -58,6 +58,7 @@ import com.android.systemui.statusbar.pipeline.mobile.ui.MobileViewLogger;
 import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconsViewModel;
 import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.ShadeCarrierGroupMobileIconViewModel;
 import com.android.systemui.util.CarrierConfigTracker;
+import com.android.systemui.util.kotlin.FlowProviderKt;
 import com.android.systemui.utils.leaks.LeakCheckedTest;
 import com.android.systemui.utils.os.FakeHandler;
 
@@ -72,6 +73,8 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
+import kotlinx.coroutines.flow.MutableStateFlow;
+
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 @SmallTest
@@ -105,7 +108,8 @@ public class ShadeCarrierGroupControllerTest extends LeakCheckedTest {
     private ShadeCarrier mShadeCarrier3;
     private TestableLooper mTestableLooper;
     @Mock
-    private ShadeCarrierGroupController.OnSingleCarrierChangedListener mOnSingleCarrierChangedListener;
+    private ShadeCarrierGroupController.OnSingleCarrierChangedListener
+            mOnSingleCarrierChangedListener;
     @Mock
     private MobileUiAdapter mMobileUiAdapter;
     @Mock
@@ -119,6 +123,9 @@ public class ShadeCarrierGroupControllerTest extends LeakCheckedTest {
     @Mock
     private StatusBarPipelineFlags mStatusBarPipelineFlags;
 
+    private final MutableStateFlow<Boolean> mIsVisibleFlow =
+            FlowProviderKt.getMutableStateFlow(true);
+
     private FakeSlotIndexResolver mSlotIndexResolver;
     private ClickListenerTextView mNoCarrierTextView;
 
@@ -170,7 +177,7 @@ public class ShadeCarrierGroupControllerTest extends LeakCheckedTest {
                 mMobileUiAdapter,
                 mMobileContextProvider,
                 mStatusBarPipelineFlags
-            )
+        )
                 .setShadeCarrierGroup(mShadeCarrierGroup)
                 .build();
 
@@ -181,6 +188,7 @@ public class ShadeCarrierGroupControllerTest extends LeakCheckedTest {
         when(mStatusBarPipelineFlags.useNewShadeCarrierGroupMobileIcons()).thenReturn(true);
         when(mMobileContextProvider.getMobileContextForSub(anyInt(), any())).thenReturn(mContext);
         when(mMobileIconsViewModel.getLogger()).thenReturn(mMobileViewLogger);
+        when(mShadeCarrierGroupMobileIconViewModel.isVisible()).thenReturn(mIsVisibleFlow);
         when(mMobileIconsViewModel.viewModelForSub(anyInt(), any()))
                 .thenReturn(mShadeCarrierGroupMobileIconViewModel);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/kotlin/FlowProvider.kt b/packages/SystemUI/tests/src/com/android/systemui/util/kotlin/FlowProvider.kt
new file mode 100644
index 000000000000..274acc9a8c23
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/kotlin/FlowProvider.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2023 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.util.kotlin
+
+import kotlinx.coroutines.flow.MutableStateFlow
+
+/** Wrapper for flow constructors that can be retrieved from java tests */
+fun <T> getMutableStateFlow(value: T): MutableStateFlow<T> = MutableStateFlow(value)
-- 
GitLab


From 16ecfea7e5009f3b02c6121ba37dee2c7bcac698 Mon Sep 17 00:00:00 2001
From: Amith Yamasani <yamasani@google.com>
Date: Tue, 19 Sep 2023 15:17:21 -0700
Subject: [PATCH 16/95] Synchronize on ArrayList object mutations to avoid
 AIOOBE

mUnfinishedRequests is being modified in two different threads,
which is unsafe for an ArrayList. Synchronize the mutation calls.

Fixes: 294930461
Test: Manual flash and use device, as crash repro case is not
      available
Change-Id: I344d5504409cbc4d86ee52528576e965e117979c
---
 .../android/internal/infra/AbstractRemoteService.java | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/core/java/com/android/internal/infra/AbstractRemoteService.java b/core/java/com/android/internal/infra/AbstractRemoteService.java
index 18414cf93bc8..556c246e16d6 100644
--- a/core/java/com/android/internal/infra/AbstractRemoteService.java
+++ b/core/java/com/android/internal/infra/AbstractRemoteService.java
@@ -355,9 +355,10 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
                 obtainMessage(AbstractRemoteService::handleFinishRequest, this, finshedRequest));
     }
 
-    private void handleFinishRequest(@NonNull BasePendingRequest<S, I> finshedRequest) {
-        mUnfinishedRequests.remove(finshedRequest);
-
+    private void handleFinishRequest(@NonNull BasePendingRequest<S, I> finishedRequest) {
+        synchronized (mUnfinishedRequests) {
+            mUnfinishedRequests.remove(finishedRequest);
+        }
         if (mUnfinishedRequests.isEmpty()) {
             scheduleUnbind();
         }
@@ -460,7 +461,9 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
         } else {
             if (mVerbose) Slog.v(mTag, "handlePendingRequest(): " + pendingRequest);
 
-            mUnfinishedRequests.add(pendingRequest);
+            synchronized (mUnfinishedRequests) {
+                mUnfinishedRequests.add(pendingRequest);
+            }
             cancelScheduledUnbind();
 
             pendingRequest.run();
-- 
GitLab


From 70e69c013f84129150f69244c53bf55be88534c5 Mon Sep 17 00:00:00 2001
From: Hakjun Choi <hakjunc@google.com>
Date: Wed, 6 Sep 2023 07:31:32 +0000
Subject: [PATCH 17/95] Add new apis for satellite service

Added an api to find whether the subscription ID supports NTN network.
Added device overlay configuration for telephony to identify the eSIM profile preloaded on a device supports satellite service.

Bug: 299232193
Test: atest SubscriptionInfoTest, SubscriptionInfoInternalTest
Change-Id: I41ec533df142ee0c4d2bba524acddf90a16509d4
---
 core/api/current.txt                          |  1 +
 core/java/android/provider/Telephony.java     | 11 ++-
 core/res/res/values/config_telephony.xml      |  5 ++
 .../android/telephony/SubscriptionInfo.java   | 46 +++++++++-
 .../telephony/SubscriptionManager.java        |  8 ++
 .../com/android/internal/telephony/ISub.aidl  | 90 +++++++++----------
 6 files changed, 113 insertions(+), 48 deletions(-)

diff --git a/core/api/current.txt b/core/api/current.txt
index f488c82a2a60..c39c61654e61 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -44887,6 +44887,7 @@ package android.telephony {
     method public int getSubscriptionType();
     method public int getUsageSetting();
     method public boolean isEmbedded();
+    method @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) public boolean isNtn();
     method public boolean isOpportunistic();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SubscriptionInfo> CREATOR;
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index cf3707b8e105..a39157103f71 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -4915,6 +4915,14 @@ public final class Telephony {
         public static final String COLUMN_SATELLITE_ATTACH_ENABLED_FOR_CARRIER =
                 "satellite_attach_enabled_for_carrier";
 
+        /**
+         * TelephonyProvider column name to identify eSIM profile of a non-terrestrial network.
+         * By default, it's disabled.
+         *
+         * @hide
+         */
+        public static final String COLUMN_IS_NTN = "is_ntn";
+
         /** All columns in {@link SimInfo} table. */
         private static final List<String> ALL_COLUMNS = List.of(
                 COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID,
@@ -4985,7 +4993,8 @@ public final class Telephony {
                 COLUMN_TP_MESSAGE_REF,
                 COLUMN_USER_HANDLE,
                 COLUMN_SATELLITE_ENABLED,
-                COLUMN_SATELLITE_ATTACH_ENABLED_FOR_CARRIER
+                COLUMN_SATELLITE_ATTACH_ENABLED_FOR_CARRIER,
+                COLUMN_IS_NTN
         );
 
         /**
diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml
index 582153766dbe..77d0d6dc376f 100644
--- a/core/res/res/values/config_telephony.xml
+++ b/core/res/res/values/config_telephony.xml
@@ -190,6 +190,11 @@
     </string-array>
     <java-symbol type="array" name="config_satellite_services_supported_by_providers" />
 
+    <!-- The identifier of the satellite's eSIM profile preloaded on the device. The identifier is
+    composed of MCC and MNC of the satellite PLMN with the format "mccmnc". -->
+    <string name="config_satellite_esim_identifier" translatable="false"></string>
+    <java-symbol type="string" name="config_satellite_esim_identifier" />
+
     <!-- 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
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index faf97b57594e..de2e9527e7b8 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -18,6 +18,7 @@ package android.telephony;
 
 import static android.text.TextUtils.formatSimple;
 
+import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
@@ -44,6 +45,7 @@ import android.text.TextUtils;
 import android.util.DisplayMetrics;
 import android.util.Log;
 
+import com.android.internal.telephony.flags.Flags;
 import com.android.internal.telephony.util.TelephonyUtils;
 import com.android.telephony.Rlog;
 
@@ -254,6 +256,11 @@ public class SubscriptionInfo implements Parcelable {
      */
     private final boolean mIsGroupDisabled;
 
+    /**
+     * Whether this subscription is used for communicating with non-terrestrial networks.
+     */
+    private final boolean mIsNtn;
+
     /**
      * @hide
      *
@@ -378,6 +385,7 @@ public class SubscriptionInfo implements Parcelable {
         this.mAreUiccApplicationsEnabled = areUiccApplicationsEnabled;
         this.mPortIndex = portIndex;
         this.mUsageSetting = usageSetting;
+        this.mIsNtn = false;
     }
 
     /**
@@ -416,6 +424,7 @@ public class SubscriptionInfo implements Parcelable {
         this.mAreUiccApplicationsEnabled = builder.mAreUiccApplicationsEnabled;
         this.mPortIndex = builder.mPortIndex;
         this.mUsageSetting = builder.mUsageSetting;
+        this.mIsNtn = builder.mIsNtn;
     }
 
     /**
@@ -862,6 +871,17 @@ public class SubscriptionInfo implements Parcelable {
         return mUsageSetting;
     }
 
+    /**
+     * Check if the subscription is exclusively for non-terrestrial networks.
+     *
+     * @return {@code true} if it is a non-terrestrial network subscription, {@code false}
+     * otherwise.
+     */
+    @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+    public boolean isNtn() {
+        return mIsNtn;
+    }
+
     @NonNull
     public static final Parcelable.Creator<SubscriptionInfo> CREATOR =
             new Parcelable.Creator<SubscriptionInfo>() {
@@ -898,6 +918,7 @@ public class SubscriptionInfo implements Parcelable {
                             UiccAccessRule.CREATOR))
                     .setUiccApplicationsEnabled(source.readBoolean())
                     .setUsageSetting(source.readInt())
+                    .setNtn(source.readBoolean())
                     .build();
         }
 
@@ -939,6 +960,7 @@ public class SubscriptionInfo implements Parcelable {
         dest.writeTypedArray(mCarrierConfigAccessRules, flags);
         dest.writeBoolean(mAreUiccApplicationsEnabled);
         dest.writeInt(mUsageSetting);
+        dest.writeBoolean(mIsNtn);
     }
 
     @Override
@@ -1001,6 +1023,7 @@ public class SubscriptionInfo implements Parcelable {
                 + " mType=" + SubscriptionManager.subscriptionTypeToString(mType)
                 + " areUiccApplicationsEnabled=" + mAreUiccApplicationsEnabled
                 + " usageSetting=" + SubscriptionManager.usageSettingToString(mUsageSetting)
+                + " ntn=" + mIsNtn
                 + "]";
     }
 
@@ -1025,7 +1048,8 @@ public class SubscriptionInfo implements Parcelable {
                 that.mCardString) && Arrays.equals(mNativeAccessRules,
                 that.mNativeAccessRules) && Arrays.equals(mCarrierConfigAccessRules,
                 that.mCarrierConfigAccessRules) && Objects.equals(mGroupUuid, that.mGroupUuid)
-                && mCountryIso.equals(that.mCountryIso) && mGroupOwner.equals(that.mGroupOwner);
+                && mCountryIso.equals(that.mCountryIso) && mGroupOwner.equals(that.mGroupOwner)
+                && mIsNtn == that.mIsNtn;
     }
 
     @Override
@@ -1034,7 +1058,7 @@ public class SubscriptionInfo implements Parcelable {
                 mDisplayNameSource, mIconTint, mNumber, mDataRoaming, mMcc, mMnc, mIsEmbedded,
                 mCardString, mIsOpportunistic, mGroupUuid, mCountryIso, mCarrierId, mProfileClass,
                 mType, mGroupOwner, mAreUiccApplicationsEnabled, mPortIndex, mUsageSetting, mCardId,
-                mIsGroupDisabled);
+                mIsGroupDisabled, mIsNtn);
         result = 31 * result + Arrays.hashCode(mEhplmns);
         result = 31 * result + Arrays.hashCode(mHplmns);
         result = 31 * result + Arrays.hashCode(mNativeAccessRules);
@@ -1233,6 +1257,11 @@ public class SubscriptionInfo implements Parcelable {
         @UsageSetting
         private int mUsageSetting = SubscriptionManager.USAGE_SETTING_UNKNOWN;
 
+        /**
+         * {@code true} if it is a non-terrestrial network subscription, {@code false} otherwise.
+         */
+        private boolean mIsNtn = false;
+
         /**
          * Default constructor.
          */
@@ -1275,6 +1304,7 @@ public class SubscriptionInfo implements Parcelable {
             mAreUiccApplicationsEnabled = info.mAreUiccApplicationsEnabled;
             mPortIndex = info.mPortIndex;
             mUsageSetting = info.mUsageSetting;
+            mIsNtn = info.mIsNtn;
         }
 
         /**
@@ -1659,6 +1689,18 @@ public class SubscriptionInfo implements Parcelable {
             return this;
         }
 
+        /**
+         * Set whether the subscription is exclusively used for non-terrestrial networks or not.
+         *
+         * @param isNtn {@code true} if the subscription is for NTN, {@code false} otherwise.
+         * @return The builder.
+         */
+        @NonNull
+        public Builder setNtn(boolean isNtn) {
+            mIsNtn = isNtn;
+            return this;
+        }
+
         /**
          * Build the {@link SubscriptionInfo}.
          *
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 6d9c1e6f052e..29149b95e471 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -1117,6 +1117,14 @@ public class SubscriptionManager {
     public static final String SATELLITE_ATTACH_ENABLED_FOR_CARRIER =
             SimInfo.COLUMN_SATELLITE_ATTACH_ENABLED_FOR_CARRIER;
 
+    /**
+     * TelephonyProvider column name to identify eSIM profile of a non-terrestrial network.
+     * By default, it's disabled.
+     * <P>Type: INTEGER (int)</P>
+     * @hide
+     */
+    public static final String IS_NTN = SimInfo.COLUMN_IS_NTN;
+
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = {"USAGE_SETTING_"},
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index 21a6b447d6a4..a5a23e8659d8 100644
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -323,49 +323,49 @@ interface ISub {
      */
      UserHandle getSubscriptionUserHandle(int subId);
 
-     /**
-      * Check if subscription and user are associated with each other.
-      *
-      * @param subscriptionId the subId of the subscription
-      * @param userHandle user handle of the user
-      * @return {@code true} if subscription is associated with user
-      * {code true} if there are no subscriptions on device
-      * else {@code false} if subscription is not associated with user.
-      *
-      * @throws IllegalArgumentException if subscription is invalid.
-      * @throws SecurityException if the caller doesn't have permissions required.
-      * @throws IllegalStateException if subscription service is not available.
-      *
-      * @hide
-      */
-      boolean isSubscriptionAssociatedWithUser(int subscriptionId, in UserHandle userHandle);
-
-      /**
-       * Get list of subscriptions associated with user.
-       *
-       * @param userHandle user handle of the user
-       * @return list of subscriptionInfo associated with the user.
-       *
-       * @throws SecurityException if the caller doesn't have permissions required.
-       * @throws IllegalStateException if subscription service is not available.
-       *
-       * @hide
-       */
-       List<SubscriptionInfo> getSubscriptionInfoListAssociatedWithUser(in UserHandle userHandle);
-
-      /**
-       * Called during setup wizard restore flow to attempt to restore the backed up sim-specific
-       * configs to device for all existing SIMs in the subscription database
-       * {@link Telephony.SimInfo}. Internally, it will store the backup data in an internal file.
-       * This file will persist on device for device's lifetime and will be used later on when a SIM
-       * is inserted to restore that specific SIM's settings. End result is subscription database is
-       * modified to match any backed up configs for the appropriate inserted SIMs.
-       *
-       * <p>
-       * The {@link Uri} {@link #SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI} is notified if any
-       * {@link Telephony.SimInfo} entry is updated as the result of this method call.
-       *
-       * @param data with the sim specific configs to be backed up.
-       */
-       void restoreAllSimSpecificSettingsFromBackup(in byte[] data);
+    /**
+     * Check if subscription and user are associated with each other.
+     *
+     * @param subscriptionId the subId of the subscription
+     * @param userHandle user handle of the user
+     * @return {@code true} if subscription is associated with user
+     * {code true} if there are no subscriptions on device
+     * else {@code false} if subscription is not associated with user.
+     *
+     * @throws IllegalArgumentException if subscription is invalid.
+     * @throws SecurityException if the caller doesn't have permissions required.
+     * @throws IllegalStateException if subscription service is not available.
+     *
+     * @hide
+     */
+    boolean isSubscriptionAssociatedWithUser(int subscriptionId, in UserHandle userHandle);
+
+    /**
+     * Get list of subscriptions associated with user.
+     *
+     * @param userHandle user handle of the user
+     * @return list of subscriptionInfo associated with the user.
+     *
+     * @throws SecurityException if the caller doesn't have permissions required.
+     * @throws IllegalStateException if subscription service is not available.
+     *
+     * @hide
+     */
+    List<SubscriptionInfo> getSubscriptionInfoListAssociatedWithUser(in UserHandle userHandle);
+
+    /**
+     * Called during setup wizard restore flow to attempt to restore the backed up sim-specific
+     * configs to device for all existing SIMs in the subscription database
+     * {@link Telephony.SimInfo}. Internally, it will store the backup data in an internal file.
+     * This file will persist on device for device's lifetime and will be used later on when a SIM
+     * is inserted to restore that specific SIM's settings. End result is subscription database is
+     * modified to match any backed up configs for the appropriate inserted SIMs.
+     *
+     * <p>
+     * The {@link Uri} {@link #SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI} is notified if any
+     * {@link Telephony.SimInfo} entry is updated as the result of this method call.
+     *
+     * @param data with the sim specific configs to be backed up.
+     */
+    void restoreAllSimSpecificSettingsFromBackup(in byte[] data);
 }
-- 
GitLab


From e10140ee604c6b9b3dc48c5238dcbb2a8fce0106 Mon Sep 17 00:00:00 2001
From: Gustavo Pagani <gustavopagani@google.com>
Date: Wed, 13 Sep 2023 18:57:47 +0000
Subject: [PATCH 18/95] Implement cancellation request.

Bug: 300426308
Test: N/A - will manual test once phone is set up.

Change-Id: Ifedadd163e89b17a193de307cadf439c3a471bd9
---
 packages/CredentialManager/shared/Android.bp  |  18 +++
 .../shared/AndroidManifest.xml                |  22 ++++
 .../credentialmanager/ui/IntentParser.kt      |  42 +++++++
 .../credentialmanager/ui/LogConstants.kt      |  19 +++
 .../credentialmanager/ui/ktx/IntentKtx.kt     |  33 ++++++
 .../ui/ktx/PackageManagerKtx.kt               |  35 ++++++
 .../ui/mapper/RequestMapper.kt                |  25 ++++
 .../credentialmanager/ui/model/Request.kt     |  31 +++++
 packages/CredentialManager/wear/Android.bp    |   1 +
 .../ui/CredentialSelectorActivity.kt          |  59 ++++++++--
 .../ui/CredentialSelectorViewModel.kt         | 111 ++++++++++++++++++
 .../android/credentialmanager/ui/WearApp.kt   |   7 +-
 12 files changed, 392 insertions(+), 11 deletions(-)
 create mode 100644 packages/CredentialManager/shared/Android.bp
 create mode 100644 packages/CredentialManager/shared/AndroidManifest.xml
 create mode 100644 packages/CredentialManager/shared/src/com/android/credentialmanager/ui/IntentParser.kt
 create mode 100644 packages/CredentialManager/shared/src/com/android/credentialmanager/ui/LogConstants.kt
 create mode 100644 packages/CredentialManager/shared/src/com/android/credentialmanager/ui/ktx/IntentKtx.kt
 create mode 100644 packages/CredentialManager/shared/src/com/android/credentialmanager/ui/ktx/PackageManagerKtx.kt
 create mode 100644 packages/CredentialManager/shared/src/com/android/credentialmanager/ui/mapper/RequestMapper.kt
 create mode 100644 packages/CredentialManager/shared/src/com/android/credentialmanager/ui/model/Request.kt
 create mode 100644 packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorViewModel.kt

diff --git a/packages/CredentialManager/shared/Android.bp b/packages/CredentialManager/shared/Android.bp
new file mode 100644
index 000000000000..ae4281e5561c
--- /dev/null
+++ b/packages/CredentialManager/shared/Android.bp
@@ -0,0 +1,18 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_license"],
+}
+
+android_library {
+    name: "CredentialManagerShared",
+    manifest: "AndroidManifest.xml",
+    srcs: ["src/**/*.kt"],
+    static_libs: [
+        "androidx.core_core-ktx",
+        "androidx.credentials_credentials",
+    ],
+}
diff --git a/packages/CredentialManager/shared/AndroidManifest.xml b/packages/CredentialManager/shared/AndroidManifest.xml
new file mode 100644
index 000000000000..a46088783024
--- /dev/null
+++ b/packages/CredentialManager/shared/AndroidManifest.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (c) 2023 Google Inc.
+ *
+ * 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.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.credentialmanager">
+
+</manifest>
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/IntentParser.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/IntentParser.kt
new file mode 100644
index 000000000000..6627af526dee
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/IntentParser.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 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.0N
+ *
+ * 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.credentialmanager.ui
+
+import android.content.Intent
+import android.credentials.ui.RequestInfo
+import com.android.credentialmanager.ui.ktx.cancelUiRequest
+import com.android.credentialmanager.ui.ktx.requestInfo
+import com.android.credentialmanager.ui.mapper.toCancel
+import com.android.credentialmanager.ui.model.Request
+
+fun Intent.parse(): Request {
+    cancelUiRequest?.let {
+        return it.toCancel()
+    }
+
+    return when (requestInfo?.type) {
+        RequestInfo.TYPE_CREATE -> {
+            Request.Create
+        }
+        RequestInfo.TYPE_GET -> {
+            Request.Get
+        }
+        else -> {
+            throw IllegalStateException("Unrecognized request type: ${requestInfo?.type}")
+        }
+    }
+}
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/LogConstants.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/LogConstants.kt
new file mode 100644
index 000000000000..f49bb33d2e8a
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/LogConstants.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2023 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.0N
+ *
+ * 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.credentialmanager.ui
+
+const val TAG = "CredentialSelector"
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/ktx/IntentKtx.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/ktx/IntentKtx.kt
new file mode 100644
index 000000000000..a646851bf570
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/ktx/IntentKtx.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2023 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.0N
+ *
+ * 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.credentialmanager.ui.ktx
+
+import android.content.Intent
+import android.credentials.ui.CancelUiRequest
+import android.credentials.ui.RequestInfo
+
+val Intent.cancelUiRequest: CancelUiRequest?
+    get() = this.extras?.getParcelable(
+        CancelUiRequest.EXTRA_CANCEL_UI_REQUEST,
+        CancelUiRequest::class.java
+    )
+
+val Intent.requestInfo: RequestInfo?
+    get() = this.extras?.getParcelable(
+        RequestInfo.EXTRA_REQUEST_INFO,
+        RequestInfo::class.java
+    )
\ No newline at end of file
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/ktx/PackageManagerKtx.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/ktx/PackageManagerKtx.kt
new file mode 100644
index 000000000000..7fa0ca918e21
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/ktx/PackageManagerKtx.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2023 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.0N
+ *
+ * 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.credentialmanager.ui.ktx
+
+import android.content.pm.PackageManager
+import android.text.TextUtils
+import android.util.Log
+import com.android.credentialmanager.ui.TAG
+
+fun PackageManager.appLabel(appPackageName: String): String? =
+    try {
+        val pkgInfo = this.getPackageInfo(appPackageName, PackageManager.PackageInfoFlags.of(0))
+        val applicationInfo = checkNotNull(pkgInfo.applicationInfo)
+        applicationInfo.loadSafeLabel(
+            this, 0f,
+            TextUtils.SAFE_STRING_FLAG_FIRST_LINE or TextUtils.SAFE_STRING_FLAG_TRIM
+        ).toString()
+    } catch (e: Exception) {
+        Log.e(TAG, "Caller app not found", e)
+        null
+    }
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/mapper/RequestMapper.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/mapper/RequestMapper.kt
new file mode 100644
index 000000000000..89766c2ec61b
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/mapper/RequestMapper.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2023 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.0N
+ *
+ * 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.credentialmanager.ui.mapper
+
+import android.credentials.ui.CancelUiRequest
+import com.android.credentialmanager.ui.model.Request
+
+fun CancelUiRequest.toCancel() = Request.Cancel(
+    showCancellationUi = this.shouldShowCancellationUi(),
+    appPackageName = this.appPackageName
+)
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/model/Request.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/model/Request.kt
new file mode 100644
index 000000000000..3d835bebc06b
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/model/Request.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2023 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.0N
+ *
+ * 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.credentialmanager.ui.model
+
+/**
+ * Represents the request made by the CredentialManager API.
+ */
+sealed class Request {
+    data class Cancel(
+        val showCancellationUi: Boolean,
+        val appPackageName: String?
+    ) : Request()
+
+    data object Get : Request()
+
+    data object Create : Request()
+}
diff --git a/packages/CredentialManager/wear/Android.bp b/packages/CredentialManager/wear/Android.bp
index 639e8d18b306..36340fac1760 100644
--- a/packages/CredentialManager/wear/Android.bp
+++ b/packages/CredentialManager/wear/Android.bp
@@ -21,6 +21,7 @@ android_app {
     },
 
     static_libs: [
+        "CredentialManagerShared",
         "Horologist",
         "PlatformComposeCore",
         "androidx.activity_activity-compose",
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorActivity.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorActivity.kt
index 77fffaa1e04c..2c0575547162 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorActivity.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorActivity.kt
@@ -16,28 +16,73 @@
 
 package com.android.credentialmanager.ui
 
+import android.content.Intent
 import android.os.Bundle
 import androidx.activity.ComponentActivity
 import androidx.activity.compose.setContent
-import androidx.navigation.NavHostController
+import androidx.activity.viewModels
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
 import androidx.wear.compose.material.MaterialTheme
-import androidx.wear.compose.navigation.rememberSwipeDismissableNavController
+import kotlinx.coroutines.launch
 
 class CredentialSelectorActivity : ComponentActivity() {
 
-    lateinit var navController: NavHostController
+    private val viewModel: CredentialSelectorViewModel by viewModels()
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
 
         setTheme(android.R.style.Theme_DeviceDefault)
 
-        setContent {
-            navController = rememberSwipeDismissableNavController()
+        lifecycleScope.launch {
+            repeatOnLifecycle(Lifecycle.State.STARTED) {
+                viewModel.uiState.collect { uiState ->
+                    when (uiState) {
+                        CredentialSelectorUiState.Idle -> {
+                            // Don't display anything, assuming that there should be minimal latency
+                            // to parse the Credential Manager intent and define the state of the
+                            // app. If latency is big, then a "loading" screen should be displayed
+                            // to the user.
+                        }
 
-            MaterialTheme {
-                WearApp(navController = navController)
+                        CredentialSelectorUiState.Get -> {
+                            // TODO: b/301206470 - Implement get flow
+                            setContent {
+                                MaterialTheme {
+                                    WearApp()
+                                }
+                            }
+                        }
+
+                        CredentialSelectorUiState.Create -> {
+                            // TODO: b/301206624 - Implement create flow
+                            finish()
+                        }
+
+                        is CredentialSelectorUiState.Cancel -> {
+                            // TODO: b/300422310 - Implement cancel with message flow
+                            finish()
+                        }
+
+                        CredentialSelectorUiState.Finish -> {
+                            finish()
+                        }
+                    }
+                }
             }
         }
+
+        viewModel.onNewIntent(intent)
+    }
+
+    override fun onNewIntent(intent: Intent) {
+        super.onNewIntent(intent)
+
+        val previousIntent = getIntent()
+        setIntent(intent)
+
+        viewModel.onNewIntent(intent, previousIntent)
     }
 }
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorViewModel.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorViewModel.kt
new file mode 100644
index 000000000000..e46fcae78f6a
--- /dev/null
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorViewModel.kt
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2023 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.0N
+ *
+ * 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.credentialmanager.ui
+
+import android.app.Application
+import android.content.Intent
+import android.util.Log
+import androidx.lifecycle.AndroidViewModel
+import androidx.lifecycle.viewModelScope
+import com.android.credentialmanager.ui.ktx.appLabel
+import com.android.credentialmanager.ui.ktx.requestInfo
+import com.android.credentialmanager.ui.model.Request
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.launch
+
+class CredentialSelectorViewModel(
+    private val application: Application
+) : AndroidViewModel(application = application) {
+
+    private val _uiState =
+        MutableStateFlow<CredentialSelectorUiState>(CredentialSelectorUiState.Idle)
+    val uiState: StateFlow<CredentialSelectorUiState> = _uiState
+
+    fun onNewIntent(intent: Intent, previousIntent: Intent? = null) {
+        viewModelScope.launch {
+            val request = intent.parse()
+            if (shouldFinishActivity(request = request, previousIntent = previousIntent)) {
+                _uiState.value = CredentialSelectorUiState.Finish
+            } else {
+                when (request) {
+                    is Request.Cancel -> {
+                        request.appPackageName?.let { appPackageName ->
+                            application.packageManager.appLabel(appPackageName)?.let { appLabel ->
+                                _uiState.value = CredentialSelectorUiState.Cancel(appLabel)
+                            } ?: run {
+                                Log.d(TAG,
+                                    "Received UI cancel request with an invalid package name.")
+                                _uiState.value = CredentialSelectorUiState.Finish
+                            }
+                        } ?: run {
+                            Log.d(TAG, "Received UI cancel request with an invalid package name.")
+                            _uiState.value = CredentialSelectorUiState.Finish
+                        }
+                    }
+
+                    Request.Create -> {
+                        _uiState.value = CredentialSelectorUiState.Create
+                    }
+
+                    Request.Get -> {
+                        _uiState.value = CredentialSelectorUiState.Get
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Check if backend requested the UI activity to be cancelled. Different from the other
+     * finishing flows, this one does not report anything back to the Credential Manager service
+     * backend.
+     */
+    private fun shouldFinishActivity(request: Request, previousIntent: Intent? = null): Boolean {
+        if (request !is Request.Cancel) {
+            return false
+        } else {
+            Log.d(
+                TAG, "Received UI cancellation intent. Should show cancellation" +
+                " ui = ${request.showCancellationUi}")
+
+            previousIntent?.let {
+                val previousUiRequest = previousIntent.parse()
+
+                if (previousUiRequest is Request.Cancel) {
+                    val previousToken = previousIntent.requestInfo?.token
+                    val currentToken = previousIntent.requestInfo?.token
+
+                    if (previousToken != currentToken) {
+                        // Cancellation was for a different request, don't cancel the current UI.
+                        return false
+                    }
+                }
+            }
+
+            return !request.showCancellationUi
+        }
+    }
+}
+
+sealed class CredentialSelectorUiState {
+    object Idle : CredentialSelectorUiState()
+    object Get : CredentialSelectorUiState()
+    object Create : CredentialSelectorUiState()
+    data class Cancel(val appName: String) : CredentialSelectorUiState()
+    object Finish : CredentialSelectorUiState()
+}
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/WearApp.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/WearApp.kt
index 5ec0c8cd9292..19ea9ede9d98 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/WearApp.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/WearApp.kt
@@ -19,8 +19,8 @@
 package com.android.credentialmanager.ui
 
 import androidx.compose.runtime.Composable
-import androidx.navigation.NavHostController
 import androidx.wear.compose.foundation.rememberSwipeToDismissBoxState
+import androidx.wear.compose.navigation.rememberSwipeDismissableNavController
 import androidx.wear.compose.navigation.rememberSwipeDismissableNavHostState
 import com.android.credentialmanager.ui.screens.MainScreen
 import com.google.android.horologist.annotations.ExperimentalHorologistApi
@@ -28,9 +28,8 @@ import com.google.android.horologist.compose.navscaffold.WearNavScaffold
 import com.google.android.horologist.compose.navscaffold.composable
 
 @Composable
-fun WearApp(
-    navController: NavHostController
-) {
+fun WearApp() {
+    val navController = rememberSwipeDismissableNavController()
     val swipeToDismissBoxState = rememberSwipeToDismissBoxState()
     val navHostState =
         rememberSwipeDismissableNavHostState(swipeToDismissBoxState = swipeToDismissBoxState)
-- 
GitLab


From 05d5d5c2bc520ff20b6a22bf2e8dbfb9451ffad6 Mon Sep 17 00:00:00 2001
From: beatricemarch <beatricemarch@google.com>
Date: Wed, 23 Aug 2023 15:29:10 +0000
Subject: [PATCH 19/95] Overload putMonitoringExtra so that it can take an int
 as a parameter. This will allow to correcly store EXTRA_LOG_OPERATION_TYPE

Test: atest BackupManagerMonitorEventSender,
atest CtsBackupHostTestCases, GtsBackupHostTestCases
manual testing (restore to a phone and check that the backup dumpsys contain non-agent events)
Bug: 297163190

Change-Id: I6bea76f31dba66c3ad958212d77be7e00902bb2b
---
 .../BackupManagerMonitorEventSender.java      | 17 ++++++++++++
 .../BackupManagerMonitorEventSenderTest.java  | 27 +++++++++++++++++--
 2 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorEventSender.java b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorEventSender.java
index 92e3107b6977..549d08c03933 100644
--- a/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorEventSender.java
+++ b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorEventSender.java
@@ -222,4 +222,21 @@ public class BackupManagerMonitorEventSender {
         extras.putBoolean(key, value);
         return extras;
     }
+
+    /**
+     * Adds given key-value pair in the bundle and returns the bundle. If bundle was null it will
+     * be created.
+     *
+     * @param extras - bundle where to add key-value to, if null a new bundle will be created.
+     * @param key - key.
+     * @param value - value.
+     * @return extras if it was not null and new bundle otherwise.
+     */
+    public static Bundle putMonitoringExtra(Bundle extras, String key, int value) {
+        if (extras == null) {
+            extras = new Bundle();
+        }
+        extras.putInt(key, value);
+        return extras;
+    }
 }
diff --git a/services/tests/mockingservicestests/src/com/android/server/backup/utils/BackupManagerMonitorEventSenderTest.java b/services/tests/mockingservicestests/src/com/android/server/backup/utils/BackupManagerMonitorEventSenderTest.java
index 3af2932ee937..604a68d12f5e 100644
--- a/services/tests/mockingservicestests/src/com/android/server/backup/utils/BackupManagerMonitorEventSenderTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/backup/utils/BackupManagerMonitorEventSenderTest.java
@@ -340,8 +340,9 @@ public class BackupManagerMonitorEventSenderTest {
     @Test
     public void putMonitoringExtraLong_bundleExists_fillsBundleCorrectly() throws Exception {
         Bundle bundle = new Bundle();
+        long value = 123;
 
-        Bundle result = mBackupManagerMonitorEventSender.putMonitoringExtra(bundle, "key", 123);
+        Bundle result = mBackupManagerMonitorEventSender.putMonitoringExtra(bundle, "key", value);
 
         assertThat(result).isEqualTo(bundle);
         assertThat(result.size()).isEqualTo(1);
@@ -350,7 +351,8 @@ public class BackupManagerMonitorEventSenderTest {
 
     @Test
     public void putMonitoringExtraLong_bundleDoesNotExist_fillsBundleCorrectly() throws Exception {
-        Bundle result = mBackupManagerMonitorEventSender.putMonitoringExtra(null, "key", 123);
+        long value = 123;
+        Bundle result = mBackupManagerMonitorEventSender.putMonitoringExtra(null, "key", value);
 
         assertThat(result).isNotNull();
         assertThat(result.size()).isEqualTo(1);
@@ -377,4 +379,25 @@ public class BackupManagerMonitorEventSenderTest {
         assertThat(result.size()).isEqualTo(1);
         assertThat(result.getBoolean("key")).isTrue();
     }
+
+    @Test
+    public void putMonitoringExtraInt_bundleExists_fillsBundleCorrectly() throws Exception {
+        Bundle bundle = new Bundle();
+
+        Bundle result = mBackupManagerMonitorEventSender.putMonitoringExtra(bundle, "key", 1);
+
+        assertThat(result).isEqualTo(bundle);
+        assertThat(result.size()).isEqualTo(1);
+        assertThat(result.getInt("key")).isEqualTo(1);
+    }
+
+    @Test
+    public void putMonitoringExtraInt_bundleDoesNotExist_fillsBundleCorrectly()
+            throws Exception {
+        Bundle result = mBackupManagerMonitorEventSender.putMonitoringExtra(null, "key", 1);
+
+        assertThat(result).isNotNull();
+        assertThat(result.size()).isEqualTo(1);
+        assertThat(result.getInt("key")).isEqualTo(1);
+    }
 }
-- 
GitLab


From 1b649822d6203dabf2422eca9c035ce23a3e6792 Mon Sep 17 00:00:00 2001
From: Eino-Ville Talvala <etalvala@google.com>
Date: Thu, 14 Sep 2023 17:18:37 -0700
Subject: [PATCH 20/95] Camera: Add metrics for ultrawide-angle usage

Test: Verify locally that ultrawide usage is detected correctly
Bug: 300515796
Change-Id: I372a8eda235b7ddb3d146e84298b515f4ef06553
---
 .../android/hardware/CameraSessionStats.java  | 12 +++++++++++
 .../server/camera/CameraServiceProxy.java     | 21 ++++++++++++++-----
 2 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/core/java/android/hardware/CameraSessionStats.java b/core/java/android/hardware/CameraSessionStats.java
index 1c2cbbc81971..b1d6ac4b4cd2 100644
--- a/core/java/android/hardware/CameraSessionStats.java
+++ b/core/java/android/hardware/CameraSessionStats.java
@@ -64,6 +64,7 @@ public class CameraSessionStats implements Parcelable {
     private ArrayList<CameraStreamStats> mStreamStats;
     private String mUserTag;
     private int mVideoStabilizationMode;
+    private boolean mUsedUltraWide;
     private int mSessionIndex;
     private CameraExtensionSessionStats mCameraExtensionSessionStats;
 
@@ -82,6 +83,7 @@ public class CameraSessionStats implements Parcelable {
         mDeviceError = false;
         mStreamStats = new ArrayList<CameraStreamStats>();
         mVideoStabilizationMode = -1;
+        mUsedUltraWide = false;
         mSessionIndex = 0;
         mCameraExtensionSessionStats = new CameraExtensionSessionStats();
     }
@@ -102,6 +104,8 @@ public class CameraSessionStats implements Parcelable {
         mSessionType = sessionType;
         mInternalReconfigure = internalReconfigure;
         mStreamStats = new ArrayList<CameraStreamStats>();
+        mVideoStabilizationMode = -1;
+        mUsedUltraWide = false;
         mSessionIndex = sessionIdx;
         mCameraExtensionSessionStats = new CameraExtensionSessionStats();
     }
@@ -147,6 +151,7 @@ public class CameraSessionStats implements Parcelable {
         dest.writeTypedList(mStreamStats);
         dest.writeString(mUserTag);
         dest.writeInt(mVideoStabilizationMode);
+        dest.writeBoolean(mUsedUltraWide);
         dest.writeInt(mSessionIndex);
         mCameraExtensionSessionStats.writeToParcel(dest, 0);
     }
@@ -173,6 +178,9 @@ public class CameraSessionStats implements Parcelable {
 
         mUserTag = in.readString();
         mVideoStabilizationMode = in.readInt();
+
+        mUsedUltraWide = in.readBoolean();
+
         mSessionIndex = in.readInt();
         mCameraExtensionSessionStats = CameraExtensionSessionStats.CREATOR.createFromParcel(in);
     }
@@ -245,6 +253,10 @@ public class CameraSessionStats implements Parcelable {
         return mVideoStabilizationMode;
     }
 
+    public boolean getUsedUltraWide() {
+        return mUsedUltraWide;
+    }
+
     public int getSessionIndex() {
         return mSessionIndex;
     }
diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java
index df16c5bcc673..4ef2f1e98a80 100644
--- a/services/core/java/com/android/server/camera/CameraServiceProxy.java
+++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java
@@ -77,6 +77,7 @@ import android.view.WindowManagerGlobal;
 import com.android.framework.protobuf.nano.MessageNano;
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.camera.flags.Flags;
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.server.LocalServices;
 import com.android.server.ServiceThread;
@@ -244,6 +245,7 @@ public class CameraServiceProxy extends SystemService
         public List<CameraStreamStats> mStreamStats;
         public String mUserTag;
         public int mVideoStabilizationMode;
+        public boolean mUsedUltraWide;
         public final long mLogId;
         public final int mSessionIndex;
 
@@ -271,7 +273,8 @@ public class CameraServiceProxy extends SystemService
         public void markCompleted(int internalReconfigure, long requestCount,
                 long resultErrorCount, boolean deviceError,
                 List<CameraStreamStats>  streamStats, String userTag,
-                int videoStabilizationMode, CameraExtensionSessionStats extStats) {
+                int videoStabilizationMode, boolean usedUltraWide,
+                CameraExtensionSessionStats extStats) {
             if (mCompleted) {
                 return;
             }
@@ -284,6 +287,7 @@ public class CameraServiceProxy extends SystemService
             mStreamStats = streamStats;
             mUserTag = userTag;
             mVideoStabilizationMode = videoStabilizationMode;
+            mUsedUltraWide = usedUltraWide;
             mExtSessionStats = extStats;
             if (CameraServiceProxy.DEBUG) {
                 Slog.v(TAG, "A camera facing " + cameraFacingToString(mCameraFacing) +
@@ -873,6 +877,10 @@ public class CameraServiceProxy extends SystemService
                 streamCount = e.mStreamStats.size();
             }
             if (CameraServiceProxy.DEBUG) {
+                String ultrawideDebug = Flags.logUltrawideUsage()
+                        ? ", wideAngleUsage " + e.mUsedUltraWide
+                        : "";
+
                 Slog.v(TAG, "CAMERA_ACTION_EVENT: action " + e.mAction
                         + " clientName " + e.mClientName
                         + ", duration " + e.getDuration()
@@ -889,6 +897,7 @@ public class CameraServiceProxy extends SystemService
                         + ", streamCount is " + streamCount
                         + ", userTag is " + e.mUserTag
                         + ", videoStabilizationMode " + e.mVideoStabilizationMode
+                        + ultrawideDebug
                         + ", logId " + e.mLogId
                         + ", sessionIndex " + e.mSessionIndex
                         + ", mExtSessionStats {type " + extensionType
@@ -952,8 +961,9 @@ public class CameraServiceProxy extends SystemService
                     MessageNano.toByteArray(streamProtos[2]),
                     MessageNano.toByteArray(streamProtos[3]),
                     MessageNano.toByteArray(streamProtos[4]),
-                    e.mUserTag, e.mVideoStabilizationMode, e.mLogId, e.mSessionIndex,
-                    extensionType, extensionIsAdvanced);
+                    e.mUserTag, e.mVideoStabilizationMode,
+                    e.mLogId, e.mSessionIndex,
+                    extensionType, extensionIsAdvanced, e.mUsedUltraWide);
         }
     }
 
@@ -1148,6 +1158,7 @@ public class CameraServiceProxy extends SystemService
         List<CameraStreamStats> streamStats = cameraState.getStreamStats();
         String userTag = cameraState.getUserTag();
         int videoStabilizationMode = cameraState.getVideoStabilizationMode();
+        boolean usedUltraWide = Flags.logUltrawideUsage() ? cameraState.getUsedUltraWide() : false;
         long logId = cameraState.getLogId();
         int sessionIdx = cameraState.getSessionIndex();
         CameraExtensionSessionStats extSessionStats = cameraState.getExtensionSessionStats();
@@ -1205,7 +1216,7 @@ public class CameraServiceProxy extends SystemService
                         Slog.w(TAG, "Camera " + cameraId + " was already marked as active");
                         oldEvent.markCompleted(/*internalReconfigure*/0, /*requestCount*/0,
                                 /*resultErrorCount*/0, /*deviceError*/false, streamStats,
-                                /*userTag*/"", /*videoStabilizationMode*/-1,
+                                /*userTag*/"", /*videoStabilizationMode*/-1, /*usedUltraWide*/false,
                                 new CameraExtensionSessionStats());
                         mCameraUsageHistory.add(oldEvent);
                     }
@@ -1217,7 +1228,7 @@ public class CameraServiceProxy extends SystemService
 
                         doneEvent.markCompleted(internalReconfigureCount, requestCount,
                                 resultErrorCount, deviceError, streamStats, userTag,
-                                videoStabilizationMode, extSessionStats);
+                                videoStabilizationMode, usedUltraWide, extSessionStats);
                         mCameraUsageHistory.add(doneEvent);
                         // Do not double count device error
                         deviceError = false;
-- 
GitLab


From 679b34cd05cf2e4465d7f7fb05f317959e8891e2 Mon Sep 17 00:00:00 2001
From: Kevin Chyn <kchyn@google.com>
Date: Tue, 5 Sep 2023 21:26:10 +0000
Subject: [PATCH 21/95] Fix several flaky DeviceStateManagerServiceTests

Fixes: 297949293
Bug: 223153452

Test: run each test with 100 iterations
Change-Id: I333dcc2c10346ce585d1c5e7f16cad113b2b5a95
Merged-In: I333dcc2c10346ce585d1c5e7f16cad113b2b5a95
---
 .../DeviceStateManagerServiceTest.java        | 99 +++++++++----------
 1 file changed, 45 insertions(+), 54 deletions(-)

diff --git a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
index 94f88abf7301..567410145831 100644
--- a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
@@ -18,6 +18,8 @@ package com.android.server.devicestate;
 
 import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE;
 
+import static com.android.compatibility.common.util.PollingCheck.waitFor;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Mockito.mock;
@@ -40,6 +42,7 @@ import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.FlakyTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.compatibility.common.util.PollingCheck;
 import com.android.server.wm.ActivityTaskManagerInternal;
 import com.android.server.wm.WindowProcessController;
 
@@ -73,6 +76,8 @@ public final class DeviceStateManagerServiceTest {
 
     private static final int FAKE_PROCESS_ID = 100;
 
+    private static final int TIMEOUT = 2000;
+
     private TestDeviceStatePolicy mPolicy;
     private TestDeviceStateProvider mProvider;
     private DeviceStateManagerService mService;
@@ -106,6 +111,10 @@ public final class DeviceStateManagerServiceTest {
         }
     }
 
+    private void waitAndAssert(PollingCheck.PollingCheckCondition condition) {
+        waitFor(TIMEOUT, condition);
+    }
+
     @Test
     public void baseStateChanged() {
         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
@@ -272,37 +281,34 @@ public final class DeviceStateManagerServiceTest {
         mService.getBinderService().registerCallback(callback);
 
         mProvider.setState(OTHER_DEVICE_STATE.getIdentifier());
-        flushHandler();
-        assertEquals(callback.getLastNotifiedInfo().baseState,
-                OTHER_DEVICE_STATE.getIdentifier());
-        assertEquals(callback.getLastNotifiedInfo().currentState,
-                OTHER_DEVICE_STATE.getIdentifier());
+        waitAndAssert(() -> callback.getLastNotifiedInfo().baseState
+                == OTHER_DEVICE_STATE.getIdentifier());
+        waitAndAssert(() -> callback.getLastNotifiedInfo().currentState
+                == OTHER_DEVICE_STATE.getIdentifier());
 
         mProvider.setState(DEFAULT_DEVICE_STATE.getIdentifier());
-        flushHandler();
-        assertEquals(callback.getLastNotifiedInfo().baseState,
-                DEFAULT_DEVICE_STATE.getIdentifier());
-        assertEquals(callback.getLastNotifiedInfo().currentState,
-                DEFAULT_DEVICE_STATE.getIdentifier());
+        waitAndAssert(() -> callback.getLastNotifiedInfo().baseState
+                == DEFAULT_DEVICE_STATE.getIdentifier());
+
+        waitAndAssert(() -> callback.getLastNotifiedInfo().currentState
+                == DEFAULT_DEVICE_STATE.getIdentifier());
 
         mPolicy.blockConfigure();
         mProvider.setState(OTHER_DEVICE_STATE.getIdentifier());
-        flushHandler();
         // The callback should not have been notified of the state change as the policy is still
         // pending callback.
-        assertEquals(callback.getLastNotifiedInfo().baseState,
-                DEFAULT_DEVICE_STATE.getIdentifier());
-        assertEquals(callback.getLastNotifiedInfo().currentState,
-                DEFAULT_DEVICE_STATE.getIdentifier());
+        waitAndAssert(() -> callback.getLastNotifiedInfo().baseState
+                == DEFAULT_DEVICE_STATE.getIdentifier());
+        waitAndAssert(() -> callback.getLastNotifiedInfo().currentState
+                == DEFAULT_DEVICE_STATE.getIdentifier());
 
         mPolicy.resumeConfigure();
-        flushHandler();
         // Now that the policy is finished processing the callback should be notified of the state
         // change.
-        assertEquals(callback.getLastNotifiedInfo().baseState,
-                OTHER_DEVICE_STATE.getIdentifier());
-        assertEquals(callback.getLastNotifiedInfo().currentState,
-                OTHER_DEVICE_STATE.getIdentifier());
+        waitAndAssert(() -> callback.getLastNotifiedInfo().baseState
+                == OTHER_DEVICE_STATE.getIdentifier());
+        waitAndAssert(() -> callback.getLastNotifiedInfo().currentState
+                == OTHER_DEVICE_STATE.getIdentifier());
     }
 
     @Test
@@ -329,13 +335,9 @@ public final class DeviceStateManagerServiceTest {
 
         mService.getBinderService().requestState(token, OTHER_DEVICE_STATE.getIdentifier(),
                 0 /* flags */);
-        // Flush the handler twice. The first flush ensures the request is added and the policy is
-        // notified, while the second flush ensures the callback is notified once the change is
-        // committed.
-        flushHandler(2 /* count */);
 
-        assertEquals(callback.getLastNotifiedStatus(token),
-                TestDeviceStateManagerCallback.STATUS_ACTIVE);
+        waitAndAssert(() -> callback.getLastNotifiedStatus(token)
+                == TestDeviceStateManagerCallback.STATUS_ACTIVE);
         // Committed state changes as there is a requested override.
         assertEquals(mService.getCommittedState(), Optional.of(OTHER_DEVICE_STATE));
         assertEquals(mSysPropSetter.getValue(),
@@ -352,12 +354,11 @@ public final class DeviceStateManagerServiceTest {
                 OTHER_DEVICE_STATE.getIdentifier());
 
         mService.getBinderService().cancelStateRequest();
-        flushHandler();
 
-        assertEquals(callback.getLastNotifiedStatus(token),
-                TestDeviceStateManagerCallback.STATUS_CANCELED);
+        waitAndAssert(() -> callback.getLastNotifiedStatus(token)
+                == TestDeviceStateManagerCallback.STATUS_CANCELED);
         // Committed state is set back to the requested state once the override is cleared.
-        assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
+        waitAndAssert(() -> mService.getCommittedState().equals(Optional.of(DEFAULT_DEVICE_STATE)));
         assertEquals(mSysPropSetter.getValue(),
                 DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
@@ -600,13 +601,9 @@ public final class DeviceStateManagerServiceTest {
         mService.getBinderService().requestBaseStateOverride(token,
                 OTHER_DEVICE_STATE.getIdentifier(),
                 0 /* flags */);
-        // Flush the handler twice. The first flush ensures the request is added and the policy is
-        // notified, while the second flush ensures the callback is notified once the change is
-        // committed.
-        flushHandler(2 /* count */);
 
-        assertEquals(callback.getLastNotifiedStatus(token),
-                TestDeviceStateManagerCallback.STATUS_ACTIVE);
+        waitAndAssert(() -> callback.getLastNotifiedStatus(token)
+                == TestDeviceStateManagerCallback.STATUS_ACTIVE);
         // Committed state changes as there is a requested override.
         assertEquals(mService.getCommittedState(), Optional.of(OTHER_DEVICE_STATE));
         assertEquals(mSysPropSetter.getValue(),
@@ -624,12 +621,11 @@ public final class DeviceStateManagerServiceTest {
                 OTHER_DEVICE_STATE.getIdentifier());
 
         mService.getBinderService().cancelBaseStateOverride();
-        flushHandler();
 
-        assertEquals(callback.getLastNotifiedStatus(token),
-                TestDeviceStateManagerCallback.STATUS_CANCELED);
+        waitAndAssert(() -> callback.getLastNotifiedStatus(token)
+                == TestDeviceStateManagerCallback.STATUS_CANCELED);
         // Committed state is set back to the requested state once the override is cleared.
-        assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
+        waitAndAssert(() -> mService.getCommittedState().equals(Optional.of(DEFAULT_DEVICE_STATE)));
         assertEquals(mSysPropSetter.getValue(),
                 DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
@@ -638,8 +634,8 @@ public final class DeviceStateManagerServiceTest {
         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
                 DEFAULT_DEVICE_STATE.getIdentifier());
 
-        assertEquals(callback.getLastNotifiedInfo().baseState,
-                DEFAULT_DEVICE_STATE.getIdentifier());
+        waitAndAssert(() -> callback.getLastNotifiedInfo().baseState
+                == DEFAULT_DEVICE_STATE.getIdentifier());
         assertEquals(callback.getLastNotifiedInfo().currentState,
                 DEFAULT_DEVICE_STATE.getIdentifier());
     }
@@ -660,13 +656,9 @@ public final class DeviceStateManagerServiceTest {
         mService.getBinderService().requestBaseStateOverride(token,
                 OTHER_DEVICE_STATE.getIdentifier(),
                 0 /* flags */);
-        // Flush the handler twice. The first flush ensures the request is added and the policy is
-        // notified, while the second flush ensures the callback is notified once the change is
-        // committed.
-        flushHandler(2 /* count */);
 
-        assertEquals(callback.getLastNotifiedStatus(token),
-                TestDeviceStateManagerCallback.STATUS_ACTIVE);
+        waitAndAssert(() -> callback.getLastNotifiedStatus(token)
+                == TestDeviceStateManagerCallback.STATUS_ACTIVE);
         // Committed state changes as there is a requested override.
         assertEquals(mService.getCommittedState(), Optional.of(OTHER_DEVICE_STATE));
         assertEquals(mSysPropSetter.getValue(),
@@ -684,12 +676,11 @@ public final class DeviceStateManagerServiceTest {
                 OTHER_DEVICE_STATE.getIdentifier());
 
         mProvider.setState(testDeviceState.getIdentifier());
-        flushHandler();
 
-        assertEquals(callback.getLastNotifiedStatus(token),
-                TestDeviceStateManagerCallback.STATUS_CANCELED);
+        waitAndAssert(() -> callback.getLastNotifiedStatus(token)
+                == TestDeviceStateManagerCallback.STATUS_CANCELED);
         // Committed state is set to the new base state once the override is cleared.
-        assertEquals(mService.getCommittedState(), Optional.of(testDeviceState));
+        waitAndAssert(() -> mService.getCommittedState().equals(Optional.of(testDeviceState)));
         assertEquals(mSysPropSetter.getValue(),
                 testDeviceState.getIdentifier() + ":" + testDeviceState.getName());
         assertEquals(mService.getBaseState(), Optional.of(testDeviceState));
@@ -698,8 +689,8 @@ public final class DeviceStateManagerServiceTest {
         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
                 testDeviceState.getIdentifier());
 
-        assertEquals(callback.getLastNotifiedInfo().baseState,
-                testDeviceState.getIdentifier());
+        waitAndAssert(() -> callback.getLastNotifiedInfo().baseState
+                == testDeviceState.getIdentifier());
         assertEquals(callback.getLastNotifiedInfo().currentState,
                 testDeviceState.getIdentifier());
     }
-- 
GitLab


From 444e0d6c92038db69f058c18b2d0fa5fc342883d Mon Sep 17 00:00:00 2001
From: Diya Bera <diyab@google.com>
Date: Tue, 9 May 2023 16:30:57 -0700
Subject: [PATCH 22/95] Change fingerprint reenrollment to acquired message

Bug: 258901849
Test: Manual: Follow steps in https://docs.google.com/document/d/1wHQSAc0yvDBZdN4ZaXKaVi8vs1i5-u7Yh7rLfuJAQgc/edit#heading=h.c04xqjzf7saq, then unlock through keyguard, the notification should occur in 5 seconds of unlocking
Test: atest BiometricNotificationServiceTest
Test: atest BiometricNotificationDialogFactoryTest
Change-Id: Iff606eb464132493b582e8e34a72c1f23472d088
---
 .../BiometricFingerprintConstants.java        |  9 +++++-
 .../BiometricNotificationService.java         | 21 +++++++++++---
 .../FingerprintReEnrollNotification.java      | 29 +++++++++++++++++++
 .../FingerprintReEnrollNotificationImpl.java  | 29 +++++++++++++++++++
 .../systemui/dagger/SystemUIModule.java       |  4 +++
 .../BiometricNotificationServiceTest.java     | 25 ++++++++++++----
 6 files changed, 107 insertions(+), 10 deletions(-)
 create mode 100644 packages/SystemUI/src/com/android/systemui/biometrics/FingerprintReEnrollNotification.java
 create mode 100644 packages/SystemUI/src/com/android/systemui/biometrics/FingerprintReEnrollNotificationImpl.java

diff --git a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
index 257ad7162e9e..5b24fb6860a2 100644
--- a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
@@ -218,7 +218,8 @@ public interface BiometricFingerprintConstants {
             FINGERPRINT_ACQUIRED_UNKNOWN,
             FINGERPRINT_ACQUIRED_IMMOBILE,
             FINGERPRINT_ACQUIRED_TOO_BRIGHT,
-            FINGERPRINT_ACQUIRED_POWER_PRESSED})
+            FINGERPRINT_ACQUIRED_POWER_PRESSED,
+            FINGERPRINT_ACQUIRED_RE_ENROLL})
     @Retention(RetentionPolicy.SOURCE)
     @interface FingerprintAcquired {}
 
@@ -309,6 +310,12 @@ public interface BiometricFingerprintConstants {
      */
     int FINGERPRINT_ACQUIRED_POWER_PRESSED = 11;
 
+    /**
+     * This message is sent to encourage the user to re-enroll their fingerprints.
+     * @hide
+     */
+    int FINGERPRINT_ACQUIRED_RE_ENROLL = 12;
+
     /**
      * @hide
      */
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java
index dc874d83b75b..436da7cadf2f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java
@@ -29,7 +29,6 @@ import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.hardware.biometrics.BiometricFaceConstants;
-import android.hardware.biometrics.BiometricFingerprintConstants;
 import android.hardware.biometrics.BiometricSourceType;
 import android.os.Handler;
 import android.os.UserHandle;
@@ -43,6 +42,9 @@ import com.android.systemui.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
+
+import java.util.Optional;
+
 import javax.inject.Inject;
 
 /**
@@ -66,6 +68,7 @@ public class BiometricNotificationService implements CoreStartable {
     private final Handler mHandler;
     private final NotificationManager mNotificationManager;
     private final BiometricNotificationBroadcastReceiver mBroadcastReceiver;
+    private final FingerprintReEnrollNotification mFingerprintReEnrollNotification;
     private NotificationChannel mNotificationChannel;
     private boolean mFaceNotificationQueued;
     private boolean mFingerprintNotificationQueued;
@@ -102,8 +105,15 @@ public class BiometricNotificationService implements CoreStartable {
                         Settings.Secure.putIntForUser(mContext.getContentResolver(),
                                 Settings.Secure.FACE_UNLOCK_RE_ENROLL, REENROLL_REQUIRED,
                                 UserHandle.USER_CURRENT);
-                    } else if (msgId == BiometricFingerprintConstants.BIOMETRIC_ERROR_RE_ENROLL
-                            && biometricSourceType == BiometricSourceType.FINGERPRINT) {
+                    }
+                }
+
+                @Override
+                public void onBiometricHelp(int msgId, String helpString,
+                        BiometricSourceType biometricSourceType) {
+                    if (biometricSourceType == BiometricSourceType.FINGERPRINT
+                            && mFingerprintReEnrollNotification.isFingerprintReEnrollRequired(
+                                    msgId)) {
                         mFingerprintReenrollRequired = true;
                     }
                 }
@@ -115,13 +125,16 @@ public class BiometricNotificationService implements CoreStartable {
             KeyguardUpdateMonitor keyguardUpdateMonitor,
             KeyguardStateController keyguardStateController,
             Handler handler, NotificationManager notificationManager,
-            BiometricNotificationBroadcastReceiver biometricNotificationBroadcastReceiver) {
+            BiometricNotificationBroadcastReceiver biometricNotificationBroadcastReceiver,
+            Optional<FingerprintReEnrollNotification> fingerprintReEnrollNotification) {
         mContext = context;
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mKeyguardStateController = keyguardStateController;
         mHandler = handler;
         mNotificationManager = notificationManager;
         mBroadcastReceiver = biometricNotificationBroadcastReceiver;
+        mFingerprintReEnrollNotification = fingerprintReEnrollNotification.orElse(
+                new FingerprintReEnrollNotificationImpl());
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintReEnrollNotification.java b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintReEnrollNotification.java
new file mode 100644
index 000000000000..9050f26d39e4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintReEnrollNotification.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2023 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.biometrics;
+
+import android.hardware.biometrics.BiometricFingerprintConstants;
+
+/**
+ * Checks if the fingerprint HAL has sent a re-enrollment request.
+ */
+public interface FingerprintReEnrollNotification {
+    //TODO: Remove this class and add a constant in the HAL API instead (b/281841852)
+    /** Returns true if msgId corresponds to FINGERPRINT_ACQUIRED_RE_ENROLL. */
+    boolean isFingerprintReEnrollRequired(
+            @BiometricFingerprintConstants.FingerprintAcquired int msgId);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintReEnrollNotificationImpl.java b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintReEnrollNotificationImpl.java
new file mode 100644
index 000000000000..1f86bc6ae298
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintReEnrollNotificationImpl.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2023 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.biometrics;
+
+import android.hardware.biometrics.BiometricFingerprintConstants;
+
+/**
+ * Checks if the fingerprint HAL has sent a re-enrollment request.
+ */
+public class FingerprintReEnrollNotificationImpl implements FingerprintReEnrollNotification{
+    @Override
+    public boolean isFingerprintReEnrollRequired(int msgId) {
+        return msgId == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_RE_ENROLL;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 3a942bd8203f..a0ecb3defc36 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -35,6 +35,7 @@ import com.android.systemui.assist.AssistModule;
 import com.android.systemui.authentication.AuthenticationModule;
 import com.android.systemui.biometrics.AlternateUdfpsTouchProvider;
 import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider;
+import com.android.systemui.biometrics.FingerprintReEnrollNotification;
 import com.android.systemui.biometrics.UdfpsDisplayModeProvider;
 import com.android.systemui.biometrics.dagger.BiometricsModule;
 import com.android.systemui.bouncer.ui.BouncerViewModule;
@@ -297,6 +298,9 @@ public abstract class SystemUIModule {
     @BindsOptionalOf
     abstract SystemStatusAnimationScheduler optionalSystemStatusAnimationScheduler();
 
+    @BindsOptionalOf
+    abstract FingerprintReEnrollNotification optionalFingerprintReEnrollNotification();
+
     @SysUISingleton
     @Binds
     abstract SystemClock bindSystemClock(SystemClockImpl systemClock);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationServiceTest.java
index b0d006353a98..8d596da96a3d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationServiceTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationServiceTest.java
@@ -52,6 +52,8 @@ import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 
+import java.util.Optional;
+
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
@@ -65,11 +67,16 @@ public class BiometricNotificationServiceTest extends SysuiTestCase {
     KeyguardStateController mKeyguardStateController;
     @Mock
     NotificationManager mNotificationManager;
+    @Mock
+    Optional<FingerprintReEnrollNotification> mFingerprintReEnrollNotificationOptional;
+    @Mock
+    FingerprintReEnrollNotification mFingerprintReEnrollNotification;
 
     private static final String TAG = "BiometricNotificationService";
     private static final int FACE_NOTIFICATION_ID = 1;
     private static final int FINGERPRINT_NOTIFICATION_ID = 2;
     private static final long SHOW_NOTIFICATION_DELAY_MS = 5_000L; // 5 seconds
+    private static final int FINGERPRINT_ACQUIRED_RE_ENROLL = 0;
 
     private final ArgumentCaptor<Notification> mNotificationArgumentCaptor =
             ArgumentCaptor.forClass(Notification.class);
@@ -80,14 +87,22 @@ public class BiometricNotificationServiceTest extends SysuiTestCase {
 
     @Before
     public void setUp() {
+        when(mFingerprintReEnrollNotificationOptional.orElse(any()))
+                .thenReturn(mFingerprintReEnrollNotification);
+        when(mFingerprintReEnrollNotification.isFingerprintReEnrollRequired(
+                FINGERPRINT_ACQUIRED_RE_ENROLL)).thenReturn(true);
+
         mLooper = TestableLooper.get(this);
         Handler handler = new Handler(mLooper.getLooper());
         BiometricNotificationDialogFactory dialogFactory = new BiometricNotificationDialogFactory();
         BiometricNotificationBroadcastReceiver broadcastReceiver =
                 new BiometricNotificationBroadcastReceiver(mContext, dialogFactory);
-        mBiometricNotificationService = new BiometricNotificationService(mContext,
-                mKeyguardUpdateMonitor, mKeyguardStateController, handler,
-                mNotificationManager, broadcastReceiver);
+        mBiometricNotificationService =
+                new BiometricNotificationService(mContext,
+                        mKeyguardUpdateMonitor, mKeyguardStateController, handler,
+                        mNotificationManager,
+                        broadcastReceiver,
+                        mFingerprintReEnrollNotificationOptional);
         mBiometricNotificationService.start();
 
         ArgumentCaptor<KeyguardUpdateMonitorCallback> updateMonitorCallbackArgumentCaptor =
@@ -108,8 +123,8 @@ public class BiometricNotificationServiceTest extends SysuiTestCase {
     public void testShowFingerprintReEnrollNotification() {
         when(mKeyguardStateController.isShowing()).thenReturn(false);
 
-        mKeyguardUpdateMonitorCallback.onBiometricError(
-                BiometricFingerprintConstants.BIOMETRIC_ERROR_RE_ENROLL,
+        mKeyguardUpdateMonitorCallback.onBiometricHelp(
+                FINGERPRINT_ACQUIRED_RE_ENROLL,
                 "Testing Fingerprint Re-enrollment" /* errString */,
                 BiometricSourceType.FINGERPRINT
         );
-- 
GitLab


From a02b386d679d26201ce6624daf6fb0cbd1680f77 Mon Sep 17 00:00:00 2001
From: Diya Bera <diyab@google.com>
Date: Thu, 15 Jun 2023 15:42:17 -0700
Subject: [PATCH 23/95] Remove duplicate face re-enroll notification

Cancel re-enroll notification when face is removed.

Test: atest BiometricsNotificationService
Fixes: 286759227
Change-Id: I27d6bb843b01a844e44d9445bef4e24c38a2df56
---
 .../BiometricNotificationService.java         | 45 +++++++++--
 .../BiometricNotificationServiceTest.java     | 77 ++++++++++++++++++-
 .../face/aidl/FaceAuthenticationClient.java   |  4 -
 3 files changed, 111 insertions(+), 15 deletions(-)

diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java
index 436da7cadf2f..c2b9102cbcb2 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java
@@ -21,6 +21,8 @@ import static android.app.PendingIntent.FLAG_IMMUTABLE;
 import static com.android.systemui.biometrics.BiometricNotificationBroadcastReceiver.ACTION_SHOW_FACE_REENROLL_DIALOG;
 import static com.android.systemui.biometrics.BiometricNotificationBroadcastReceiver.ACTION_SHOW_FINGERPRINT_REENROLL_DIALOG;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
@@ -30,6 +32,9 @@ import android.content.Intent;
 import android.content.IntentFilter;
 import android.hardware.biometrics.BiometricFaceConstants;
 import android.hardware.biometrics.BiometricSourceType;
+import android.hardware.biometrics.BiometricStateListener;
+import android.hardware.face.FaceManager;
+import android.hardware.fingerprint.FingerprintManager;
 import android.os.Handler;
 import android.os.UserHandle;
 import android.provider.Settings;
@@ -42,7 +47,6 @@ import com.android.systemui.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
-
 import java.util.Optional;
 
 import javax.inject.Inject;
@@ -69,6 +73,8 @@ public class BiometricNotificationService implements CoreStartable {
     private final NotificationManager mNotificationManager;
     private final BiometricNotificationBroadcastReceiver mBroadcastReceiver;
     private final FingerprintReEnrollNotification mFingerprintReEnrollNotification;
+    private final FingerprintManager mFingerprintManager;
+    private final FaceManager mFaceManager;
     private NotificationChannel mNotificationChannel;
     private boolean mFaceNotificationQueued;
     private boolean mFingerprintNotificationQueued;
@@ -119,14 +125,29 @@ public class BiometricNotificationService implements CoreStartable {
                 }
             };
 
+    private final BiometricStateListener mFaceStateListener = new BiometricStateListener() {
+        @Override
+        public void onEnrollmentsChanged(int userId, int sensorId, boolean hasEnrollments) {
+            mNotificationManager.cancelAsUser(TAG, FACE_NOTIFICATION_ID, UserHandle.CURRENT);
+        }
+    };
+
+    private final BiometricStateListener mFingerprintStateListener = new BiometricStateListener() {
+        @Override
+        public void onEnrollmentsChanged(int userId, int sensorId, boolean hasEnrollments) {
+            mNotificationManager.cancelAsUser(TAG, FINGERPRINT_NOTIFICATION_ID, UserHandle.CURRENT);
+        }
+    };
 
     @Inject
-    public BiometricNotificationService(Context context,
-            KeyguardUpdateMonitor keyguardUpdateMonitor,
-            KeyguardStateController keyguardStateController,
-            Handler handler, NotificationManager notificationManager,
-            BiometricNotificationBroadcastReceiver biometricNotificationBroadcastReceiver,
-            Optional<FingerprintReEnrollNotification> fingerprintReEnrollNotification) {
+    public BiometricNotificationService(@NonNull Context context,
+            @NonNull KeyguardUpdateMonitor keyguardUpdateMonitor,
+            @NonNull KeyguardStateController keyguardStateController,
+            @NonNull Handler handler, @NonNull NotificationManager notificationManager,
+            @NonNull BiometricNotificationBroadcastReceiver biometricNotificationBroadcastReceiver,
+            @NonNull Optional<FingerprintReEnrollNotification> fingerprintReEnrollNotification,
+            @Nullable FingerprintManager fingerprintManager,
+            @Nullable FaceManager faceManager) {
         mContext = context;
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mKeyguardStateController = keyguardStateController;
@@ -135,6 +156,8 @@ public class BiometricNotificationService implements CoreStartable {
         mBroadcastReceiver = biometricNotificationBroadcastReceiver;
         mFingerprintReEnrollNotification = fingerprintReEnrollNotification.orElse(
                 new FingerprintReEnrollNotificationImpl());
+        mFingerprintManager = fingerprintManager;
+        mFaceManager = faceManager;
     }
 
     @Override
@@ -148,12 +171,19 @@ public class BiometricNotificationService implements CoreStartable {
         intentFilter.addAction(ACTION_SHOW_FACE_REENROLL_DIALOG);
         mContext.registerReceiver(mBroadcastReceiver, intentFilter,
                 Context.RECEIVER_EXPORTED_UNAUDITED);
+        if (mFingerprintManager != null) {
+            mFingerprintManager.registerBiometricStateListener(mFingerprintStateListener);
+        }
+        if (mFaceManager != null) {
+            mFaceManager.registerBiometricStateListener(mFaceStateListener);
+        }
         Settings.Secure.putIntForUser(mContext.getContentResolver(),
                 Settings.Secure.FACE_UNLOCK_RE_ENROLL, REENROLL_NOT_REQUIRED,
                 UserHandle.USER_CURRENT);
     }
 
     private void queueFaceReenrollNotification() {
+        Log.d(TAG, "Face re-enroll notification queued.");
         mFaceNotificationQueued = true;
         final String title = mContext.getString(R.string.face_re_enroll_notification_title);
         final String content = mContext.getString(
@@ -166,6 +196,7 @@ public class BiometricNotificationService implements CoreStartable {
     }
 
     private void queueFingerprintReenrollNotification() {
+        Log.d(TAG, "Fingerprint re-enroll notification queued.");
         mFingerprintNotificationQueued = true;
         final String title = mContext.getString(R.string.fingerprint_re_enroll_notification_title);
         final String content = mContext.getString(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationServiceTest.java
index 8d596da96a3d..3c106789290d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationServiceTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationServiceTest.java
@@ -30,9 +30,12 @@ import static org.mockito.Mockito.when;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.hardware.biometrics.BiometricFaceConstants;
-import android.hardware.biometrics.BiometricFingerprintConstants;
 import android.hardware.biometrics.BiometricSourceType;
+import android.hardware.biometrics.BiometricStateListener;
+import android.hardware.face.FaceManager;
+import android.hardware.fingerprint.FingerprintManager;
 import android.os.Handler;
+import android.os.UserHandle;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
@@ -71,6 +74,10 @@ public class BiometricNotificationServiceTest extends SysuiTestCase {
     Optional<FingerprintReEnrollNotification> mFingerprintReEnrollNotificationOptional;
     @Mock
     FingerprintReEnrollNotification mFingerprintReEnrollNotification;
+    @Mock
+    FingerprintManager mFingerprintManager;
+    @Mock
+    FaceManager mFaceManager;
 
     private static final String TAG = "BiometricNotificationService";
     private static final int FACE_NOTIFICATION_ID = 1;
@@ -84,6 +91,8 @@ public class BiometricNotificationServiceTest extends SysuiTestCase {
     private KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback;
     private KeyguardStateController.Callback mKeyguardStateControllerCallback;
     private BiometricNotificationService mBiometricNotificationService;
+    private BiometricStateListener mFaceStateListener;
+    private BiometricStateListener mFingerprintStateListener;
 
     @Before
     public void setUp() {
@@ -102,25 +111,37 @@ public class BiometricNotificationServiceTest extends SysuiTestCase {
                         mKeyguardUpdateMonitor, mKeyguardStateController, handler,
                         mNotificationManager,
                         broadcastReceiver,
-                        mFingerprintReEnrollNotificationOptional);
+                        mFingerprintReEnrollNotificationOptional,
+                        mFingerprintManager,
+                        mFaceManager);
         mBiometricNotificationService.start();
 
         ArgumentCaptor<KeyguardUpdateMonitorCallback> updateMonitorCallbackArgumentCaptor =
                 ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback.class);
         ArgumentCaptor<KeyguardStateController.Callback> stateControllerCallbackArgumentCaptor =
                 ArgumentCaptor.forClass(KeyguardStateController.Callback.class);
+        ArgumentCaptor<BiometricStateListener> faceStateListenerArgumentCaptor =
+                ArgumentCaptor.forClass(BiometricStateListener.class);
+        ArgumentCaptor<BiometricStateListener> fingerprintStateListenerArgumentCaptor =
+                ArgumentCaptor.forClass(BiometricStateListener.class);
 
         verify(mKeyguardUpdateMonitor).registerCallback(
                 updateMonitorCallbackArgumentCaptor.capture());
         verify(mKeyguardStateController).addCallback(
                 stateControllerCallbackArgumentCaptor.capture());
+        verify(mFaceManager).registerBiometricStateListener(
+                faceStateListenerArgumentCaptor.capture());
+        verify(mFingerprintManager).registerBiometricStateListener(
+                fingerprintStateListenerArgumentCaptor.capture());
 
+        mFaceStateListener = faceStateListenerArgumentCaptor.getValue();
+        mFingerprintStateListener = fingerprintStateListenerArgumentCaptor.getValue();
         mKeyguardUpdateMonitorCallback = updateMonitorCallbackArgumentCaptor.getValue();
         mKeyguardStateControllerCallback = stateControllerCallbackArgumentCaptor.getValue();
     }
 
     @Test
-    public void testShowFingerprintReEnrollNotification() {
+    public void testShowFingerprintReEnrollNotification_onAcquiredReEnroll() {
         when(mKeyguardStateController.isShowing()).thenReturn(false);
 
         mKeyguardUpdateMonitorCallback.onBiometricHelp(
@@ -142,7 +163,7 @@ public class BiometricNotificationServiceTest extends SysuiTestCase {
                 .isEqualTo(ACTION_SHOW_FINGERPRINT_REENROLL_DIALOG);
     }
     @Test
-    public void testShowFaceReEnrollNotification() {
+    public void testShowFaceReEnrollNotification_onErrorReEnroll() {
         when(mKeyguardStateController.isShowing()).thenReturn(false);
 
         mKeyguardUpdateMonitorCallback.onBiometricError(
@@ -164,6 +185,54 @@ public class BiometricNotificationServiceTest extends SysuiTestCase {
                 .isEqualTo(ACTION_SHOW_FACE_REENROLL_DIALOG);
     }
 
+    @Test
+    public void testCancelReEnrollmentNotification_onFaceEnrollmentStateChange() {
+        when(mKeyguardStateController.isShowing()).thenReturn(false);
+
+        mKeyguardUpdateMonitorCallback.onBiometricError(
+                BiometricFaceConstants.BIOMETRIC_ERROR_RE_ENROLL,
+                "Testing Face Re-enrollment" /* errString */,
+                BiometricSourceType.FACE
+        );
+        mKeyguardStateControllerCallback.onKeyguardShowingChanged();
+
+        mLooper.moveTimeForward(SHOW_NOTIFICATION_DELAY_MS);
+        mLooper.processAllMessages();
+
+        verify(mNotificationManager).notifyAsUser(eq(TAG), eq(FACE_NOTIFICATION_ID),
+                mNotificationArgumentCaptor.capture(), any());
+
+        mFaceStateListener.onEnrollmentsChanged(0 /* userId */, 0 /* sensorId */,
+                false /* hasEnrollments */);
+
+        verify(mNotificationManager).cancelAsUser(eq(TAG), eq(FACE_NOTIFICATION_ID),
+                eq(UserHandle.CURRENT));
+    }
+
+    @Test
+    public void testCancelReEnrollmentNotification_onFingerprintEnrollmentStateChange() {
+        when(mKeyguardStateController.isShowing()).thenReturn(false);
+
+        mKeyguardUpdateMonitorCallback.onBiometricHelp(
+                FINGERPRINT_ACQUIRED_RE_ENROLL,
+                "Testing Fingerprint Re-enrollment" /* errString */,
+                BiometricSourceType.FINGERPRINT
+        );
+        mKeyguardStateControllerCallback.onKeyguardShowingChanged();
+
+        mLooper.moveTimeForward(SHOW_NOTIFICATION_DELAY_MS);
+        mLooper.processAllMessages();
+
+        verify(mNotificationManager).notifyAsUser(eq(TAG), eq(FINGERPRINT_NOTIFICATION_ID),
+                mNotificationArgumentCaptor.capture(), any());
+
+        mFingerprintStateListener.onEnrollmentsChanged(0 /* userId */, 0 /* sensorId */,
+                false /* hasEnrollments */);
+
+        verify(mNotificationManager).cancelAsUser(eq(TAG), eq(FINGERPRINT_NOTIFICATION_ID),
+                eq(UserHandle.CURRENT));
+    }
+
     @Test
     public void testResetFaceUnlockReEnroll_onStart() {
         when(mKeyguardStateController.isShowing()).thenReturn(false);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
index 50d375c56f4a..35fc43ae5f74 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
@@ -43,7 +43,6 @@ import com.android.server.biometrics.log.BiometricLogger;
 import com.android.server.biometrics.log.OperationContextExt;
 import com.android.server.biometrics.sensors.AuthSessionCoordinator;
 import com.android.server.biometrics.sensors.AuthenticationClient;
-import com.android.server.biometrics.sensors.BiometricNotificationUtils;
 import com.android.server.biometrics.sensors.ClientMonitorCallback;
 import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
 import com.android.server.biometrics.sensors.ClientMonitorCompositeCallback;
@@ -242,9 +241,6 @@ class FaceAuthenticationClient extends AuthenticationClient<AidlSession, FaceAut
                 vendorCode,
                 getTargetUserId()));
 
-        if (error == BiometricConstants.BIOMETRIC_ERROR_RE_ENROLL) {
-            BiometricNotificationUtils.showReEnrollmentNotification(getContext());
-        }
         super.onError(error, vendorCode);
     }
 
-- 
GitLab


From e8d8bf4d73d5f75858e93bdb4373217a7c00b9ed Mon Sep 17 00:00:00 2001
From: beatricemarch <beatricemarch@google.com>
Date: Thu, 31 Aug 2023 12:53:16 +0000
Subject: [PATCH 24/95] Add a 60 days retention period to BMM Events

Test: manual testing(set a 5 minutes retention period, factory reset the test device, go trough SUW, confirm that the logs show in backup dumpsys, confirm that logs  are deleted after 5 minutes)
atest CtsBackupHostTestCases, GtsBackupHostTestCases
atest BackupManagerMonitorDumpsysUtilsTest, BackupManagerMonitorEventSenderTest, UserBackupManagerServiceTest
Bug: 297159898

Change-Id: If8ce57c68cf9ffaa5472e5e14aee72c6bf2e5153
---
 .../backup/UserBackupManagerService.java      |  16 ++
 .../BackupManagerMonitorDumpsysUtils.java     | 166 ++++++++++++++-
 .../BackupManagerMonitorDumpsysUtilsTest.java | 201 +++++++++++++++++-
 3 files changed, 364 insertions(+), 19 deletions(-)

diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
index 4c137bce4f7b..2d80af92eea5 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
@@ -654,6 +654,13 @@ public class UserBackupManagerService {
         // the pending backup set
         mBackupHandler.postDelayed(this::parseLeftoverJournals, INITIALIZATION_DELAY_MILLIS);
 
+        // check if we are past the retention period for BMM Events,
+        // if so delete expired events and do not print them to dumpsys
+        BackupManagerMonitorDumpsysUtils backupManagerMonitorDumpsysUtils =
+                new BackupManagerMonitorDumpsysUtils();
+        mBackupHandler.postDelayed(backupManagerMonitorDumpsysUtils::deleteExpiredBMMEvents,
+                INITIALIZATION_DELAY_MILLIS);
+
         mBackupPreferences = new UserBackupPreferences(mContext, mBaseStateDir);
 
         // Power management
@@ -4181,7 +4188,16 @@ public class UserBackupManagerService {
     private void dumpBMMEvents(PrintWriter pw) {
         BackupManagerMonitorDumpsysUtils bm =
                 new BackupManagerMonitorDumpsysUtils();
+        if (bm.deleteExpiredBMMEvents()) {
+            pw.println("BACKUP MANAGER MONITOR EVENTS HAVE EXPIRED");
+            return;
+        }
         File events = bm.getBMMEventsFile();
+        if (events.length() == 0){
+            // We have not recorded BMMEvents yet.
+            pw.println("NO BACKUP MANAGER MONITOR EVENTS");
+            return;
+        }
         pw.println("START OF BACKUP MANAGER MONITOR EVENTS");
         try (BufferedReader reader = new BufferedReader(new FileReader(events))) {
             String line;
diff --git a/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtils.java b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtils.java
index 0b55ca21371b..bc2326d8241d 100644
--- a/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtils.java
@@ -23,15 +23,22 @@ import android.os.Bundle;
 import android.os.Environment;
 import android.util.Slog;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.FastPrintWriter;
 
+import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
 import java.io.PrintWriter;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.Map;
+import java.util.concurrent.TimeUnit;
 
 
 /*
@@ -46,12 +53,21 @@ public class BackupManagerMonitorDumpsysUtils {
     // Name of the subdirectory where the text file containing the BMM events will be stored.
     // Same as {@link UserBackupManagerFiles}
     private static final String BACKUP_PERSISTENT_DIR = "backup";
+    private static final String INITIAL_SETUP_TIMESTAMP_KEY = "initialSetupTimestamp";
+    // Retention period of 60 days (in millisec) for the BMM Events.
+    // After tha time has passed the text file containing the BMM events will be emptied
+    private static final long LOGS_RETENTION_PERIOD_MILLISEC = 60 * TimeUnit.DAYS.toMillis(1);
+    // We cache the value of IsAfterRetentionPeriod() to avoid unnecessary disk I/O
+    // mIsAfterRetentionPeriodCached tracks if we have cached the value of IsAfterRetentionPeriod()
+    private boolean mIsAfterRetentionPeriodCached = false;
+    // The cahched value of IsAfterRetentionPeriod()
+    private boolean mIsAfterRetentionPeriod;
 
     /**
      * Parses the BackupManagerMonitor bundle for a RESTORE event in a series of strings that
      * will be persisted in a text file and printed in the dumpsys.
      *
-     * If the evenntBundle passed is not a RESTORE event, return early
+     * If the eventBundle passed is not a RESTORE event, return early
      *
      * Key information related to the event:
      * - Timestamp (HAS TO ALWAYS BE THE FIRST LINE OF EACH EVENT)
@@ -63,16 +79,21 @@ public class BackupManagerMonitorDumpsysUtils {
      *
      * Example of formatting:
      * RESTORE Event: [2023-08-18 17:16:00.735] Agent - Agent logging results
-     *     Package name: com.android.wallpaperbackup
-     *     Agent Logs:
-     *         Data Type: wlp_img_system
-     *             Item restored: 0/1
-     *             Agent Error - Category: no_wallpaper, Count: 1
-     *         Data Type: wlp_img_lock
-     *             Item restored: 0/1
-     *             Agent Error - Category: no_wallpaper, Count: 1
+     * Package name: com.android.wallpaperbackup
+     * Agent Logs:
+     * Data Type: wlp_img_system
+     * Item restored: 0/1
+     * Agent Error - Category: no_wallpaper, Count: 1
+     * Data Type: wlp_img_lock
+     * Item restored: 0/1
+     * Agent Error - Category: no_wallpaper, Count: 1
      */
     public void parseBackupManagerMonitorRestoreEventForDumpsys(Bundle eventBundle) {
+        if (isAfterRetentionPeriod()) {
+            // We only log data for the first 60 days since setup
+            return;
+        }
+
         if (eventBundle == null) {
             return;
         }
@@ -89,8 +110,14 @@ public class BackupManagerMonitorDumpsysUtils {
         }
         File bmmEvents = getBMMEventsFile();
 
+        if (bmmEvents.length() == 0) {
+            // We are parsing the first restore event.
+            // Time to also record the setup timestamp of the device
+            recordSetUpTimestamp();
+        }
+
         try (FileOutputStream out = new FileOutputStream(bmmEvents, /*append*/ true);
-            PrintWriter pw = new FastPrintWriter(out);) {
+             PrintWriter pw = new FastPrintWriter(out);) {
 
             int eventCategory = eventBundle.getInt(BackupManagerMonitor.EXTRA_LOG_EVENT_CATEGORY);
             int eventId = eventBundle.getInt(BackupManagerMonitor.EXTRA_LOG_EVENT_ID);
@@ -257,4 +284,123 @@ public class BackupManagerMonitorDumpsysUtils {
             default -> false;
         };
     }
+
+    /**
+     * Store the timestamp when the device was set up (date when the first BMM event is parsed)
+     * in a text file.
+     */
+    @VisibleForTesting
+    void recordSetUpTimestamp() {
+        File setupDateFile = getSetUpDateFile();
+        // record setup timestamp only once
+        if (setupDateFile.length() == 0) {
+            try (FileOutputStream out = new FileOutputStream(setupDateFile, /*append*/ true);
+                 PrintWriter pw = new FastPrintWriter(out);) {
+                long currentDate = System.currentTimeMillis();
+                pw.println(currentDate);
+            } catch (IOException e) {
+                Slog.w(TAG, "An error occurred while recording the setup date: "
+                        + e.getMessage());
+            }
+        }
+
+    }
+
+    @VisibleForTesting
+    String getSetUpDate() {
+        File fname = getSetUpDateFile();
+        try (FileInputStream inputStream = new FileInputStream(fname);
+             InputStreamReader reader = new InputStreamReader(inputStream);
+             BufferedReader bufferedReader = new BufferedReader(reader);) {
+            return bufferedReader.readLine();
+        } catch (Exception e) {
+            Slog.w(TAG, "An error occurred while reading the date: " + e.getMessage());
+            return "Could not retrieve setup date";
+        }
+    }
+
+    @VisibleForTesting
+    static boolean isDateAfterNMillisec(long startTimeStamp, long endTimeStamp, long millisec) {
+        if (startTimeStamp > endTimeStamp) {
+            // Something has gone wrong, timeStamp1 should always precede timeStamp2.
+            // Out of caution return true: we would delete the logs rather than
+            // risking them being kept for longer than the retention period
+            return true;
+        }
+        long timeDifferenceMillis = endTimeStamp - startTimeStamp;
+        return (timeDifferenceMillis >= millisec);
+    }
+
+    /**
+     * Check if current date is after retention period
+     */
+    @VisibleForTesting
+    boolean isAfterRetentionPeriod() {
+        if (mIsAfterRetentionPeriodCached) {
+            return mIsAfterRetentionPeriod;
+        } else {
+            File setUpDateFile = getSetUpDateFile();
+            if (setUpDateFile.length() == 0) {
+                // We are yet to record a setup date. This means we haven't parsed the first event.
+                mIsAfterRetentionPeriod = false;
+                mIsAfterRetentionPeriodCached = true;
+                return false;
+            }
+            try {
+                long setupTimestamp = Long.parseLong(getSetUpDate());
+                long currentTimestamp = System.currentTimeMillis();
+                mIsAfterRetentionPeriod = isDateAfterNMillisec(setupTimestamp, currentTimestamp,
+                        getRetentionPeriodInMillisec());
+                mIsAfterRetentionPeriodCached = true;
+                return mIsAfterRetentionPeriod;
+            } catch (NumberFormatException e) {
+                // An error occurred when parsing the setup timestamp.
+                // Out of caution return true: we would delete the logs rather than
+                // risking them being kept for longer than the retention period
+                mIsAfterRetentionPeriod = true;
+                mIsAfterRetentionPeriodCached = true;
+                return true;
+            }
+        }
+    }
+
+    @VisibleForTesting
+    File getSetUpDateFile() {
+        File dataDir = new File(Environment.getDataDirectory(), BACKUP_PERSISTENT_DIR);
+        File setupDateFile = new File(dataDir, INITIAL_SETUP_TIMESTAMP_KEY + ".txt");
+        return setupDateFile;
+    }
+
+    @VisibleForTesting
+    long getRetentionPeriodInMillisec() {
+        return LOGS_RETENTION_PERIOD_MILLISEC;
+    }
+
+    /**
+     * Delete the BMM Events file after the retention period has passed.
+     *
+     * @return true if the retention period has passed false otherwise.
+     * we want to return true even if we were unable to delete the file, as this will prevent
+     * expired BMM events from being printed to the dumpsys
+     */
+    public boolean deleteExpiredBMMEvents() {
+        try {
+            if (isAfterRetentionPeriod()) {
+                File bmmEvents = getBMMEventsFile();
+                if (bmmEvents.exists()) {
+                    if (bmmEvents.delete()) {
+                        Slog.i(TAG, "Deleted expired BMM Events");
+                    } else {
+                        Slog.e(TAG, "Unable to delete expired BMM Events");
+                    }
+                }
+                return true;
+            }
+            return false;
+        } catch (Exception e) {
+            // Handle any unexpected exceptions
+            // To be safe we return true as we want to avoid exposing expired BMMEvents
+            return true;
+        }
+    }
 }
diff --git a/services/tests/mockingservicestests/src/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtilsTest.java b/services/tests/mockingservicestests/src/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtilsTest.java
index 8e17b3a58769..a45b17e2e3c5 100644
--- a/services/tests/mockingservicestests/src/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtilsTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtilsTest.java
@@ -17,26 +17,29 @@
 package com.android.server.backup.utils;
 
 import static org.junit.Assert.assertTrue;
-
+import static org.testng.AssertJUnit.assertFalse;
+import android.app.backup.BackupAnnotations;
 import android.app.backup.BackupManagerMonitor;
 import android.os.Bundle;
-
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
-
 import java.io.File;
 
 public class BackupManagerMonitorDumpsysUtilsTest {
-    private File mTempFile;
+    private long mRetentionPeriod;
+    private File mTempBMMEventsFile;
+    private File mTempSetUpDateFile;
     private TestBackupManagerMonitorDumpsysUtils mBackupManagerMonitorDumpsysUtils;
     @Rule
     public TemporaryFolder tmp = new TemporaryFolder();
 
     @Before
     public void setUp() throws Exception {
-        mTempFile = tmp.newFile("testbmmevents.txt");
+        mRetentionPeriod = 30 * 60 * 1000;
+        mTempBMMEventsFile = tmp.newFile("testbmmevents.txt");
+        mTempSetUpDateFile = tmp.newFile("testSetUpDate.txt");
         mBackupManagerMonitorDumpsysUtils = new TestBackupManagerMonitorDumpsysUtils();
     }
 
@@ -46,7 +49,7 @@ public class BackupManagerMonitorDumpsysUtilsTest {
             throws Exception {
         mBackupManagerMonitorDumpsysUtils.parseBackupManagerMonitorRestoreEventForDumpsys(null);
 
-        assertTrue(mTempFile.length() == 0);
+        assertTrue(mTempBMMEventsFile.length() == 0);
 
     }
 
@@ -57,7 +60,7 @@ public class BackupManagerMonitorDumpsysUtilsTest {
         event.putInt(BackupManagerMonitor.EXTRA_LOG_EVENT_CATEGORY, 1);
         mBackupManagerMonitorDumpsysUtils.parseBackupManagerMonitorRestoreEventForDumpsys(event);
 
-        assertTrue(mTempFile.length() == 0);
+        assertTrue(mTempBMMEventsFile.length() == 0);
     }
 
     @Test
@@ -67,18 +70,198 @@ public class BackupManagerMonitorDumpsysUtilsTest {
         event.putInt(BackupManagerMonitor.EXTRA_LOG_EVENT_ID, 1);
         mBackupManagerMonitorDumpsysUtils.parseBackupManagerMonitorRestoreEventForDumpsys(event);
 
-        assertTrue(mTempFile.length() == 0);
+        assertTrue(mTempBMMEventsFile.length() == 0);
+    }
+
+    @Test
+    public void parseBackupManagerMonitorEventForDumpsys_eventWithCategoryAndId_eventIsWrittenToFile()
+            throws Exception {
+        Bundle event = createRestoreBMMEvent();
+        mBackupManagerMonitorDumpsysUtils.parseBackupManagerMonitorRestoreEventForDumpsys(event);
+
+        assertTrue(mTempBMMEventsFile.length() != 0);
+    }
+
+    @Test
+    public void parseBackupManagerMonitorEventForDumpsys_firstEvent_recordSetUpTimestamp()
+            throws Exception {
+        assertTrue(mTempBMMEventsFile.length()==0);
+        assertTrue(mTempSetUpDateFile.length()==0);
+
+        Bundle event = createRestoreBMMEvent();
+        mBackupManagerMonitorDumpsysUtils.parseBackupManagerMonitorRestoreEventForDumpsys(event);
+
+        assertTrue(mTempBMMEventsFile.length() != 0);
+        assertTrue(mTempSetUpDateFile.length()!=0);
+    }
+
+    @Test
+    public void parseBackupManagerMonitorEventForDumpsys_notFirstEvent_doNotChangeSetUpTimestamp()
+            throws Exception {
+        Bundle event1 = createRestoreBMMEvent();
+        mBackupManagerMonitorDumpsysUtils.parseBackupManagerMonitorRestoreEventForDumpsys(event1);
+        String setUpTimestampBefore = mBackupManagerMonitorDumpsysUtils.getSetUpDate();
+
+        Bundle event2 = createRestoreBMMEvent();
+        mBackupManagerMonitorDumpsysUtils.parseBackupManagerMonitorRestoreEventForDumpsys(event2);
+        String setUpTimestampAfter = mBackupManagerMonitorDumpsysUtils.getSetUpDate();
+
+        assertTrue(setUpTimestampBefore.equals(setUpTimestampAfter));
+    }
+
+
+    @Test
+    public void deleteExpiredBackupManagerMonitorEvent_eventsAreExpired_deleteEventsAndReturnTrue()
+            throws Exception {
+        Bundle event = createRestoreBMMEvent();
+        mBackupManagerMonitorDumpsysUtils.parseBackupManagerMonitorRestoreEventForDumpsys(event);
+        assertTrue(mTempBMMEventsFile.length() != 0);
+        // Re-initialise the test BackupManagerMonitorDumpsysUtils to
+        // clear the cached value of isAfterRetentionPeriod
+        mBackupManagerMonitorDumpsysUtils = new TestBackupManagerMonitorDumpsysUtils();
+
+        // set a retention period of 0 second
+        mBackupManagerMonitorDumpsysUtils.setTestRetentionPeriod(0);
+
+        assertTrue(mBackupManagerMonitorDumpsysUtils.deleteExpiredBMMEvents());
+        assertFalse(mTempBMMEventsFile.exists());
+    }
+
+    @Test
+    public void deleteExpiredBackupManagerMonitorEvent_eventsAreNotExpired_returnFalse() throws
+            Exception {
+        Bundle event = createRestoreBMMEvent();
+        mBackupManagerMonitorDumpsysUtils.parseBackupManagerMonitorRestoreEventForDumpsys(event);
+        assertTrue(mTempBMMEventsFile.length() != 0);
+
+        // set a retention period of 30 minutes
+        mBackupManagerMonitorDumpsysUtils.setTestRetentionPeriod(30 * 60 * 1000);
+
+        assertFalse(mBackupManagerMonitorDumpsysUtils.deleteExpiredBMMEvents());
+        assertTrue(mTempBMMEventsFile.length() != 0);
+    }
+
+    @Test
+    public void isAfterRetentionPeriod_afterRetentionPeriod_returnTrue() throws
+            Exception {
+        mBackupManagerMonitorDumpsysUtils.recordSetUpTimestamp();
+
+        // set a retention period of 0 second
+        mBackupManagerMonitorDumpsysUtils.setTestRetentionPeriod(0);
+
+        assertTrue(mBackupManagerMonitorDumpsysUtils.isAfterRetentionPeriod());
+    }
+
+    @Test
+    public void isAfterRetentionPeriod_beforeRetentionPeriod_returnFalse() throws
+            Exception {
+        mBackupManagerMonitorDumpsysUtils.recordSetUpTimestamp();
+
+        // set a retention period of 30 minutes
+        mBackupManagerMonitorDumpsysUtils.setTestRetentionPeriod(30 * 60 * 1000);
+
+        assertFalse(mBackupManagerMonitorDumpsysUtils.isAfterRetentionPeriod());
+    }
+
+    @Test
+    public void isAfterRetentionPeriod_noSetupDate_returnFalse() throws
+            Exception {
+        assertTrue(mTempSetUpDateFile.length() == 0);
+
+        assertFalse(mBackupManagerMonitorDumpsysUtils.isAfterRetentionPeriod());
+    }
+
+    @Test
+    public void isDateAfterNMillisec_date1IsAfterThanDate2_returnTrue() throws
+            Exception {
+        long timestamp1 = System.currentTimeMillis();
+        long timestamp2 = timestamp1 - 1;
+
+        assertTrue(mBackupManagerMonitorDumpsysUtils.isDateAfterNMillisec(timestamp1, timestamp2,
+                0));
+    }
+
+    @Test
+    public void isDateAfterNMillisec_date1IsAfterNMillisecFromDate2_returnTrue() throws
+            Exception {
+        long timestamp1 = System.currentTimeMillis();
+        long timestamp2 = timestamp1 + 10;
+
+        assertTrue(mBackupManagerMonitorDumpsysUtils.isDateAfterNMillisec(timestamp1, timestamp2,
+                10));
+    }
+
+    @Test
+    public void isDateAfterNMillisec_date1IsLessThanNMillisecFromDate2_returnFalse() throws
+            Exception {
+        long timestamp1 = System.currentTimeMillis();
+        long timestamp2 = timestamp1 + 10;
+
+        assertFalse(mBackupManagerMonitorDumpsysUtils.isDateAfterNMillisec(timestamp1, timestamp2,
+                11));
+    }
+
+    @Test
+    public void recordSetUpTimestamp_timestampNotSetBefore_setTimestamp() throws
+            Exception {
+        assertTrue(mTempSetUpDateFile.length() == 0);
+
+        mBackupManagerMonitorDumpsysUtils.recordSetUpTimestamp();
+
+        assertTrue(mTempSetUpDateFile.length() != 0);
+    }
+
+    @Test
+    public void recordSetUpTimestamp_timestampSetBefore_doNothing() throws
+            Exception {
+        mBackupManagerMonitorDumpsysUtils.recordSetUpTimestamp();
+        assertTrue(mTempSetUpDateFile.length() != 0);
+        String timestampBefore = mBackupManagerMonitorDumpsysUtils.getSetUpDate();
+
+        mBackupManagerMonitorDumpsysUtils.recordSetUpTimestamp();
+
+        assertTrue(mTempSetUpDateFile.length() != 0);
+        String timestampAfter = mBackupManagerMonitorDumpsysUtils.getSetUpDate();
+        assertTrue(timestampAfter.equals(timestampBefore));
+    }
+
+    private Bundle createRestoreBMMEvent() {
+        Bundle event = new Bundle();
+        event.putInt(BackupManagerMonitor.EXTRA_LOG_EVENT_ID, 1);
+        event.putInt(BackupManagerMonitor.EXTRA_LOG_EVENT_CATEGORY, 1);
+        event.putInt(BackupManagerMonitor.EXTRA_LOG_OPERATION_TYPE,
+                BackupAnnotations.OperationType.RESTORE);
+        return event;
     }
 
     private class TestBackupManagerMonitorDumpsysUtils
             extends BackupManagerMonitorDumpsysUtils {
+
+        private long testRetentionPeriod;
+
         TestBackupManagerMonitorDumpsysUtils() {
             super();
+            this.testRetentionPeriod = mRetentionPeriod;
+        }
+
+        public void setTestRetentionPeriod(long testRetentionPeriod) {
+            this.testRetentionPeriod = testRetentionPeriod;
         }
 
         @Override
         public File getBMMEventsFile() {
-            return mTempFile;
+            return mTempBMMEventsFile;
         }
+
+        @Override
+        File getSetUpDateFile() {
+            return mTempSetUpDateFile;
+        }
+
+        @Override
+        long getRetentionPeriodInMillisec() {
+            return testRetentionPeriod;
+        }
+
     }
 }
-- 
GitLab


From 3748d0e3144313b5cbba6215feb0b8789d67c296 Mon Sep 17 00:00:00 2001
From: Justin Chung <justinkchung@google.com>
Date: Mon, 4 Sep 2023 16:35:51 +0900
Subject: [PATCH 25/95] Do not generate WTF for the SearchManager query

1. getSystemService() can generate WTF error, if service is not available
   from the device. But since search service is not available from the
   watch device, the query to the service should not print the WTF.
2. Still WTF was reported from the phone side too, due to the race of
   init order. To handle this, make PhoneWindowManager to not to call
   getSystemService for SearchService from init, but call in on demand.

Bug: 297928943
Test: Manual test from SearchManager non-available device
Change-Id: I7e3f7060f436aac28da8442773ca957c2e4cc172
---
 core/java/android/app/SystemServiceRegistry.java           | 6 ++++++
 .../java/com/android/server/policy/PhoneWindowManager.java | 7 +++----
 .../com/android/server/policy/TestPhoneWindowManager.java  | 2 +-
 3 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index cbbf4e0f9adc..fa52968e4554 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -1647,6 +1647,12 @@ public final class SystemServiceRegistry {
                 case Context.VIRTUALIZATION_SERVICE:
                 case Context.VIRTUAL_DEVICE_SERVICE:
                     return null;
+                case Context.SEARCH_SERVICE:
+                    // Wear device does not support SEARCH_SERVICE so we do not print WTF here
+                    PackageManager manager = ctx.getPackageManager();
+                    if (manager != null && manager.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+                        return null;
+                    }
             }
             Slog.wtf(TAG, "Manager wrapper not available: " + name);
             return null;
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index b420acdc0850..b001c6aa95ef 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -438,7 +438,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
     boolean mPreloadedRecentApps;
     final Object mServiceAcquireLock = new Object();
     Vibrator mVibrator; // Vibrator for giving feedback of orientation changes
-    SearchManager mSearchManager;
     AccessibilityManager mAccessibilityManager;
     AccessibilityManagerInternal mAccessibilityManagerInternal;
     BurnInProtectionHelper mBurnInProtectionHelper;
@@ -2217,7 +2216,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
         mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
         mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
         mSensorPrivacyManager = mContext.getSystemService(SensorPrivacyManager.class);
-        mSearchManager = mContext.getSystemService(SearchManager.class);
         mDisplayManager = mContext.getSystemService(DisplayManager.class);
         mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
         mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
@@ -4009,8 +4007,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
         args.putLong(Intent.EXTRA_TIME, eventTime);
         args.putInt(AssistUtils.INVOCATION_TYPE_KEY, invocationType);
 
-        if (mSearchManager != null) {
-            mSearchManager.launchAssist(args);
+        SearchManager searchManager = mContext.getSystemService(SearchManager.class);
+        if (searchManager != null) {
+            searchManager.launchAssist(args);
         } else {
             // Fallback to status bar if search manager doesn't exist (e.g. on wear).
             StatusBarManagerInternal statusBar = getStatusBarManagerInternal();
diff --git a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
index 6d46d9ccf02e..35d7f01a5e64 100644
--- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
+++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
@@ -447,7 +447,7 @@ class TestPhoneWindowManager {
     }
 
     void overrideSearchManager(SearchManager searchManager) {
-        mPhoneWindowManager.mSearchManager = searchManager;
+        doReturn(searchManager).when(mContext).getSystemService(eq(SearchManager.class));
     }
 
     void assumeResolveActivityNotNull() {
-- 
GitLab


From df830e17f80b4d1e1f9d2334aa164baa31c49f85 Mon Sep 17 00:00:00 2001
From: Jordan Demeulenaere <jdemeulenaere@google.com>
Date: Tue, 19 Sep 2023 17:35:41 +0200
Subject: [PATCH 26/95] Post ActivityLaunchAnimator timeout on
 Looper.mainLooper()

This CL fixes weird shade state bugs that can happen during Activity
launches animated by the ActivityLaunchAnimator.

Before this CL, if a WindowManager timeout happened (i.e. WM never
starts or cancels the remote animation) *and* that the launchContainer
(the ViewRootImpl where the launch started) was detached, then the
timeout would never be triggered, leaving our UI in an invalid state.
This bug is currently easily reproducible using the steps from
b/300056100#comment4, where we incorrectly animate an activity launch
from a dialog then instantly dismiss that dialog.

This CL fixes this bug by posting the timeout on Looper.getMainLooper()
instead of using launchContainer.postDelayed(). That way, the timeout is
always called after 1s if WM didn't start or cancel the remote
animation.

I suspect that this is somehow what is also happening with b/288507023,
but I was not able to confirm this theory yet.

Bug: b/300056100
Bug: b/288507023
Test: Manual, made sure that b/300056100#comment4 is not reproducible
 with this CL. Unfortunately ActivityLaunchAnimator is in a separate
 library so it can't use our DelayableExecutor (that is testable), so
 I don't think there is a good way to write a unit test for this.
Change-Id: Iaa019d6d0aabdf97af0cb6995ad81270f275f3e7
---
 .../animation/ActivityLaunchAnimator.kt       | 34 +++++++++++++++----
 .../animation/ActivityLaunchAnimatorTest.kt   |  3 +-
 2 files changed, 30 insertions(+), 7 deletions(-)

diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
index a95ab5565ab9..288b842d947a 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
@@ -25,6 +25,7 @@ import android.graphics.Path
 import android.graphics.Rect
 import android.graphics.RectF
 import android.os.Build
+import android.os.Handler
 import android.os.Looper
 import android.os.RemoteException
 import android.util.Log
@@ -58,7 +59,14 @@ class ActivityLaunchAnimator(
     /** The animator used when animating a Dialog into an app. */
     // TODO(b/218989950): Remove this animator and instead set the duration of the dim fade out to
     // TIMINGS.contentBeforeFadeOutDuration.
-    private val dialogToAppAnimator: LaunchAnimator = DEFAULT_DIALOG_TO_APP_ANIMATOR
+    private val dialogToAppAnimator: LaunchAnimator = DEFAULT_DIALOG_TO_APP_ANIMATOR,
+
+    /**
+     * Whether we should disable the WindowManager timeout. This should be set to true in tests
+     * only.
+     */
+    // TODO(b/301385865): Remove this flag.
+    private val disableWmTimeout: Boolean = false,
 ) {
     companion object {
         /** The timings when animating a View into an app. */
@@ -252,7 +260,7 @@ class ActivityLaunchAnimator(
                 Log.d(
                     TAG,
                     "Calling controller.onIntentStarted(willAnimate=$willAnimate) " +
-                            "[controller=$this]"
+                        "[controller=$this]"
                 )
             }
             this.onIntentStarted(willAnimate)
@@ -432,7 +440,8 @@ class ActivityLaunchAnimator(
         internal val delegate: AnimationDelegate
 
         init {
-            delegate = AnimationDelegate(controller, callback, listener, launchAnimator)
+            delegate =
+                AnimationDelegate(controller, callback, listener, launchAnimator, disableWmTimeout)
         }
 
         @BinderThread
@@ -462,13 +471,26 @@ class ActivityLaunchAnimator(
         /** Listener for animation lifecycle events. */
         private val listener: Listener? = null,
         /** The animator to use to animate the window launch. */
-        private val launchAnimator: LaunchAnimator = DEFAULT_LAUNCH_ANIMATOR
+        private val launchAnimator: LaunchAnimator = DEFAULT_LAUNCH_ANIMATOR,
+
+        /**
+         * Whether we should disable the WindowManager timeout. This should be set to true in tests
+         * only.
+         */
+        // TODO(b/301385865): Remove this flag.
+        disableWmTimeout: Boolean = false,
     ) : RemoteAnimationDelegate<IRemoteAnimationFinishedCallback> {
         private val launchContainer = controller.launchContainer
         private val context = launchContainer.context
         private val transactionApplierView =
             controller.openingWindowSyncView ?: controller.launchContainer
         private val transactionApplier = SyncRtSurfaceTransactionApplier(transactionApplierView)
+        private val timeoutHandler =
+            if (!disableWmTimeout) {
+                Handler(Looper.getMainLooper())
+            } else {
+                null
+            }
 
         private val matrix = Matrix()
         private val invertMatrix = Matrix()
@@ -488,11 +510,11 @@ class ActivityLaunchAnimator(
 
         @UiThread
         internal fun postTimeout() {
-            launchContainer.postDelayed(onTimeout, LAUNCH_TIMEOUT)
+            timeoutHandler?.postDelayed(onTimeout, LAUNCH_TIMEOUT)
         }
 
         private fun removeTimeout() {
-            launchContainer.removeCallbacks(onTimeout)
+            timeoutHandler?.removeCallbacks(onTimeout)
         }
 
         @UiThread
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt
index cc004363a049..59c7e7669b63 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt
@@ -57,7 +57,8 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() {
 
     @Before
     fun setup() {
-        activityLaunchAnimator = ActivityLaunchAnimator(testLaunchAnimator, testLaunchAnimator)
+        activityLaunchAnimator =
+            ActivityLaunchAnimator(testLaunchAnimator, testLaunchAnimator, disableWmTimeout = true)
         activityLaunchAnimator.callback = callback
         activityLaunchAnimator.addListener(listener)
     }
-- 
GitLab


From 37e0fd63c3928c076b93a9b19fd76972b01a6c60 Mon Sep 17 00:00:00 2001
From: Riddle Hsu <riddlehsu@google.com>
Date: Wed, 20 Sep 2023 23:13:43 +0800
Subject: [PATCH 27/95] Only increase pending relaunch count if schedule is
 success

Otherwise the client won't report finishRelaunching to decrease
mPendingRelaunchCount and cause ActivityRecord#isSyncFinished
to return false.

Also skip pre-loading recents(home) if its process is still cached
(e.g. intermediate state when switching user). Otherwise the
transaction may be failed by frozen state.

Bug: 301034389
Test: atest RecentsAnimationTest#testPreloadRecentsActivity
Test: Create multiple users with using different font size, wallpaper,
      dark theme. Launch several apps on each users. Switch between
      the users multiple times. There won't be transition timeout when
      returning from other apps to home.
Merged-In: Ia2761e1e9fadf98ab952440ae884c12cc78697c8
Change-Id: Ia2761e1e9fadf98ab952440ae884c12cc78697c8
---
 data/etc/services.core.protolog.json                        | 6 ------
 .../core/java/com/android/server/wm/ActivityRecord.java     | 4 ++--
 .../core/java/com/android/server/wm/RecentsAnimation.java   | 6 ++++++
 .../src/com/android/server/wm/RecentsAnimationTest.java     | 6 ++++--
 4 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 7d5c06cbed1a..13cf82e51b22 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -2047,12 +2047,6 @@
       "group": "WM_DEBUG_WINDOW_TRANSITIONS_MIN",
       "at": "com\/android\/server\/wm\/TransitionController.java"
     },
-    "-262984451": {
-      "message": "Relaunch failed %s",
-      "level": "INFO",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
     "-251259736": {
       "message": "No longer freezing: %s",
       "level": "VERBOSE",
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index d231cf300806..ca3a84752fc4 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -9854,7 +9854,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
             ProtoLog.i(WM_DEBUG_STATES, "Moving to %s Relaunching %s callers=%s" ,
                     (andResume ? "RESUMED" : "PAUSED"), this, Debug.getCallers(6));
             forceNewConfig = false;
-            startRelaunching();
             final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(pendingResults,
                     pendingNewIntents, configChangeFlags,
                     new MergedConfiguration(getProcessGlobalConfiguration(),
@@ -9871,11 +9870,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
             transaction.addCallback(callbackItem);
             transaction.setLifecycleStateRequest(lifecycleItem);
             mAtmService.getLifecycleManager().scheduleTransaction(transaction);
+            startRelaunching();
             // Note: don't need to call pauseIfSleepingLocked() here, because the caller will only
             // request resume if this activity is currently resumed, which implies we aren't
             // sleeping.
         } catch (RemoteException e) {
-            ProtoLog.i(WM_DEBUG_STATES, "Relaunch failed %s", e);
+            Slog.w(TAG, "Failed to relaunch " + this + ": " + e);
         }
 
         if (andResume) {
diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java
index be9058840492..ee05e355e8ef 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimation.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimation.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
 import static android.app.ActivityManager.START_TASK_TO_FRONT;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
@@ -117,6 +118,11 @@ class RecentsAnimation implements RecentsAnimationCallbacks, OnRootTaskOrderChan
                 return;
             }
             if (targetActivity.attachedToProcess()) {
+                if (targetActivity.app.getCurrentProcState() >= PROCESS_STATE_CACHED_ACTIVITY) {
+                    Slog.v(TAG, "Skip preload recents for cached proc " + targetActivity.app);
+                    // The process may be frozen that cannot receive binder call.
+                    return;
+                }
                 // The activity may be relaunched if it cannot handle the current configuration
                 // changes. The activity will be paused state if it is relaunched, otherwise it
                 // keeps the original stopped state.
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
index de3a526573f8..491d5b56c8e2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.app.ActivityManager.PROCESS_STATE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
@@ -148,8 +149,9 @@ public class RecentsAnimationTest extends WindowTestsBase {
                 anyInt() /* startFlags */, any() /* profilerInfo */);
 
         // Assume its process is alive because the caller should be the recents service.
-        mSystemServicesTestRule.addProcess(aInfo.packageName, aInfo.processName, 12345 /* pid */,
-                aInfo.applicationInfo.uid);
+        final WindowProcessController proc = mSystemServicesTestRule.addProcess(aInfo.packageName,
+                aInfo.processName, 12345 /* pid */, aInfo.applicationInfo.uid);
+        proc.setCurrentProcState(PROCESS_STATE_HOME);
 
         Intent recentsIntent = new Intent().setComponent(mRecentsComponent);
         // Null animation indicates to preload.
-- 
GitLab


From 568961726dbe0b081fbbc25aa461891c2f8ff7ba Mon Sep 17 00:00:00 2001
From: Liz Kammer <eakammer@google.com>
Date: Wed, 20 Sep 2023 15:15:43 +0000
Subject: [PATCH 28/95] Expand @FlaggedApi(FLAG) constants in API signature
 files

The auto-generated Flags.FLAG_NAME constants are difficult to review in
API tracking files. metalava will expand annotation arguments if

  (1) the field declaration is known to metalava, and
  (2) the constant is not part of the API surface.

The auto-generated constants are hidden, so not part of any API surface.
This satisfies (1).

This CL adds the auto-generated sources to metalava's input. This
satisfies (2).

(cherry picked from commit 01544b94d3b7b90dcac6f62d9528ede9e6ef2838)

Bug: 297881670
Test: m checkapi
Test: m <partition>/etc/aconfig_flags.textproto & diff against a clean build
Merged-In: I757c6e87d81768ef6095a4bea67c74c3ae6028a7
Change-Id: I757c6e87d81768ef6095a4bea67c74c3ae6028a7
---
 AconfigFlags.bp      | 23 +++++++++++++++--------
 api/StubLibraries.bp |  3 +++
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 55f5436eed90..8670b4db2a5a 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -12,20 +12,27 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+aconfig_srcjars = [
+    ":android.os.flags-aconfig-java{.generated_srcjars}",
+    ":android.security.flags-aconfig-java{.generated_srcjars}",
+    ":com.android.hardware.camera2-aconfig-java{.generated_srcjars}",
+    ":com.android.window.flags.window-aconfig-java{.generated_srcjars}",
+    ":com.android.hardware.input-aconfig-java{.generated_srcjars}",
+    ":com.android.text.flags-aconfig-java{.generated_srcjars}",
+]
+
+filegroup {
+    name: "framework-minus-apex-aconfig-srcjars",
+    srcs: aconfig_srcjars,
+}
+
 // Aconfig declarations and libraries for the core framework
 java_defaults {
     name: "framework-minus-apex-aconfig-libraries",
 
     // Add java_aconfig_libraries to here to add them to the core framework
-    srcs: [
-        ":android.os.flags-aconfig-java{.generated_srcjars}",
-        ":android.security.flags-aconfig-java{.generated_srcjars}",
-        ":com.android.hardware.camera2-aconfig-java{.generated_srcjars}",
-        ":com.android.window.flags.window-aconfig-java{.generated_srcjars}",
-        ":com.android.hardware.input-aconfig-java{.generated_srcjars}",
-        ":com.android.text.flags-aconfig-java{.generated_srcjars}",
-    ],
     // Add aconfig-annotations-lib as a dependency for the optimization
+    srcs: aconfig_srcjars,
     libs: ["aconfig-annotations-lib"],
 }
 
diff --git a/api/StubLibraries.bp b/api/StubLibraries.bp
index dc17a78a1cd9..c05d300fddb8 100644
--- a/api/StubLibraries.bp
+++ b/api/StubLibraries.bp
@@ -29,6 +29,9 @@
 
 droidstubs {
     name: "api-stubs-docs-non-updatable",
+    srcs: [
+        ":framework-minus-apex-aconfig-srcjars",
+    ],
     defaults: [
         "android-non-updatable-stubs-defaults",
         "module-classpath-stubs-defaults",
-- 
GitLab


From 42592cc89868349bb59bdf0c32cfb64b4b995584 Mon Sep 17 00:00:00 2001
From: Joanne Chung <joannechung@google.com>
Date: Thu, 21 Sep 2023 12:54:27 +0000
Subject: [PATCH 29/95] Catch NPE when reportInstallationToSecurityLog

The scan result is null for installExistingPackageAsUser(), becuse
it is installing a package that already exists, there is no scanning
or parsing involved.

Like reportInstallationStats, we also catch the exception temporary
here. There is a follow up bug to handle it correctly.

Bug: 301397206
Test: manual.
Change-Id: Ie846264d2bc1cd300d67d5cf69e41b710716fa54
---
 .../com/android/server/pm/PackageMetrics.java | 31 ++++++++++++-------
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/services/core/java/com/android/server/pm/PackageMetrics.java b/services/core/java/com/android/server/pm/PackageMetrics.java
index c1580c4b1cb9..3a00dc7f8aeb 100644
--- a/services/core/java/com/android/server/pm/PackageMetrics.java
+++ b/services/core/java/com/android/server/pm/PackageMetrics.java
@@ -310,18 +310,25 @@ final class PackageMetrics {
         if (!SecurityLog.isLoggingEnabled()) {
             return;
         }
-        final PackageSetting ps = mInstallRequest.getScannedPackageSetting();
-        if (ps == null) {
-            return;
-        }
-        final String packageName = ps.getPackageName();
-        final long versionCode = ps.getVersionCode();
-        if (!mInstallRequest.isInstallReplace()) {
-            SecurityLog.writeEvent(SecurityLog.TAG_PACKAGE_INSTALLED, packageName, versionCode,
-                    userId);
-        } else {
-            SecurityLog.writeEvent(SecurityLog.TAG_PACKAGE_UPDATED, packageName, versionCode,
-                    userId);
+        // TODO: Remove temp try-catch to avoid IllegalStateException. The reason is because
+        //  the scan result is null for installExistingPackageAsUser(). Because it's installing
+        //  a package that's already existing, there's no scanning or parsing involved
+        try {
+            final PackageSetting ps = mInstallRequest.getScannedPackageSetting();
+            if (ps == null) {
+                return;
+            }
+            final String packageName = ps.getPackageName();
+            final long versionCode = ps.getVersionCode();
+            if (!mInstallRequest.isInstallReplace()) {
+                SecurityLog.writeEvent(SecurityLog.TAG_PACKAGE_INSTALLED, packageName, versionCode,
+                        userId);
+            } else {
+                SecurityLog.writeEvent(SecurityLog.TAG_PACKAGE_UPDATED, packageName, versionCode,
+                        userId);
+            }
+        } catch (IllegalStateException | NullPointerException e) {
+            // no-op
         }
     }
 
-- 
GitLab


From e3fd8d48bb81ea195d117bec8f4154302bb01f9c Mon Sep 17 00:00:00 2001
From: Ibrahim Yilmaz <iyz@google.com>
Date: Wed, 20 Sep 2023 17:37:46 +0000
Subject: [PATCH 30/95] Team Food qs_container_graph_optimizer

This CL opens  qs_container_graph_optimizer change to the team food.

Bug: 287205379,298975758
Test: SystemUITests
Change-Id: I6dd86e2ff3d2c910c5d4d07087376024124a5577
---
 packages/SystemUI/src/com/android/systemui/flags/Flags.kt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 02575eb8adf4..07381bcd164e 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -795,7 +795,8 @@ object Flags {
 
     // TODO(b/287205379): Tracking bug
     @JvmField
-    val QS_CONTAINER_GRAPH_OPTIMIZER = unreleasedFlag( "qs_container_graph_optimizer")
+    val QS_CONTAINER_GRAPH_OPTIMIZER = unreleasedFlag( "qs_container_graph_optimizer",
+            teamfood = true)
 
     /** Enable showing a dialog when clicking on Quick Settings bluetooth tile. */
     @JvmField
-- 
GitLab


From cc4e7ccceb662083d3c2731df03ae30eab9a422b Mon Sep 17 00:00:00 2001
From: Ibrahim Yilmaz <iyz@google.com>
Date: Wed, 20 Sep 2023 17:55:20 +0000
Subject: [PATCH 31/95] Team Food precomputed_text This CL opens 
 precomputed_text change to the team food.

Bug: 289250881, 289573946
Test: SystemUITests
Change-Id: I6e389554fc6b2d2dfe36081b284c3e7447500579
---
 packages/SystemUI/src/com/android/systemui/flags/Flags.kt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 02575eb8adf4..60c492888f59 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -757,7 +757,7 @@ object Flags {
         unreleasedFlag("enable_new_privacy_dialog", teamfood = true)
 
     // TODO(b/289573946): Tracking Bug
-    @JvmField val PRECOMPUTED_TEXT = unreleasedFlag("precomputed_text")
+    @JvmField val PRECOMPUTED_TEXT = unreleasedFlag("precomputed_text", teamfood = true)
 
     // 2900 - CentralSurfaces-related flags
 
-- 
GitLab


From 98d050666d4f1d2adb19b77f27985f1e0156fef8 Mon Sep 17 00:00:00 2001
From: Riddle Hsu <riddlehsu@google.com>
Date: Thu, 21 Sep 2023 12:58:50 +0000
Subject: [PATCH 32/95] Adjust to next focusable task if top task is died

Since shell transition is enabled, there will also have a transition
animation to handle app died. Then the died activity and task won't be
removed immediately until the animation is finished.

To be more specific, TaskDisplayArea#mPreferredTopFocusableRootTask
is not changed to next task, so updateTopResumedActivityIfNeeded
will early return without calling setLastResumedActivityUncheckLocked.

Note that this will also change the animation style of the died task.
Because previously the root task of home is not collected, the
animation style is the default sliding out. Now the animation will
match the remote animation rule of launcher so it will animate scaling
to the icon on home.

Bug: 301265227
Test: Launch Settings from home.
      adb shell am force-stop com.android.settings
      adb shell dumpsys window | grep mFocusedApp
      The output will show home activity.
Change-Id: I8c99964df9e1f2d52779d41c23c6195fe3c87af3
---
 .../com/android/server/wm/ActivityTaskManagerService.java    | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index f38f6b0e4fa0..237bc9203415 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -6420,6 +6420,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
                 if (!restarting && hasVisibleActivities) {
                     deferWindowLayout();
                     try {
+                        final Task topTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
+                        if (topTask != null
+                                && topTask.topRunningActivity(true /* focusableOnly */) == null) {
+                            topTask.adjustFocusToNextFocusableTask("handleAppDied");
+                        }
                         if (!mRootWindowContainer.resumeFocusedTasksTopActivities()) {
                             // If there was nothing to resume, and we are not already restarting
                             // this process, but there is a visible activity that is hosted by the
-- 
GitLab


From 6fb5384ade3e9550479b6b2c23f3a6a86f7d9f98 Mon Sep 17 00:00:00 2001
From: Eghosa Ewansiha-Vlachavas <eevlachavas@google.com>
Date: Wed, 13 Sep 2023 13:09:54 +0000
Subject: [PATCH 33/95] [1/n] Optimize user aspect ratio button heuristic

Don't allow the user aspect ratio settings button to be shown more than
once for the current application visible to the user.

Test: `atest WMShellUnitTests:UserAspectRatioSettingsWindowManagerTest`
      `atest WMShellUnitTests:UserAspectRatioSettingsLayoutTest`
      `atest WMShellUnitTests:CompatUIControllerTest`
Fix: 300226988
Bug: 299078364
Bug: 289356588
Change-Id: Ib32df6b2ac6aaf7a7446f7b5be5cd684b9f7ebde
---
 core/java/android/app/TaskInfo.java           |   1 +
 .../wm/shell/compatui/CompatUIController.java |  59 ++++++++-
 .../UserAspectRatioSettingsWindowManager.java |  18 ++-
 .../compatui/CompatUIControllerTest.java      | 119 ++++++++++++++++++
 .../UserAspectRatioSettingsLayoutTest.java    |   3 +-
 ...rAspectRatioSettingsWindowManagerTest.java |   3 +-
 6 files changed, 198 insertions(+), 5 deletions(-)

diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java
index 634089b73618..4957c3e2b81d 100644
--- a/core/java/android/app/TaskInfo.java
+++ b/core/java/android/app/TaskInfo.java
@@ -583,6 +583,7 @@ public class TaskInfo {
                     == that.configuration.getLayoutDirection())
                 && (!hasCompatUI() || configuration.uiMode == that.configuration.uiMode)
                 && (!hasCompatUI() || isVisible == that.isVisible)
+                && isFocused == that.isFocused
                 && isUserFullscreenOverrideEnabled == that.isUserFullscreenOverrideEnabled;
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
index c111ce623c1a..e0031b4db419 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
@@ -173,6 +173,18 @@ public class CompatUIController implements OnDisplaysChangedListener,
     // be shown.
     private boolean mKeyguardShowing;
 
+    /**
+     * The id of the task for the application we're currently attempting to show the user aspect
+     * ratio settings button for, or have most recently shown the button for.
+     */
+    private int mTopActivityTaskId;
+
+    /**
+     * Whether the user aspect ratio settings button has been shown for the current application
+     * associated with the task id stored in {@link CompatUIController#mTopActivityTaskId}.
+     */
+    private boolean mHasShownUserAspectRatioSettingsButton = false;
+
     public CompatUIController(@NonNull Context context,
             @NonNull ShellInit shellInit,
             @NonNull ShellController shellController,
@@ -227,6 +239,11 @@ public class CompatUIController implements OnDisplaysChangedListener,
         if (taskInfo != null && !taskInfo.topActivityInSizeCompat) {
             mSetOfTaskIdsShowingRestartDialog.remove(taskInfo.taskId);
         }
+
+        if (taskInfo != null && taskListener != null) {
+            updateActiveTaskInfo(taskInfo);
+        }
+
         if (taskInfo.configuration == null || taskListener == null) {
             // Null token means the current foreground activity is not in compatibility mode.
             removeLayouts(taskInfo.taskId);
@@ -319,6 +336,45 @@ public class CompatUIController implements OnDisplaysChangedListener,
         forAllLayouts(layout -> layout.updateVisibility(showOnDisplay(layout.getDisplayId())));
     }
 
+    /**
+     * Invoked when a new task is created or the info of an existing task has changed. Updates the
+     * shown status of the user aspect ratio settings button and the task id it relates to.
+     */
+    void updateActiveTaskInfo(@NonNull TaskInfo taskInfo) {
+        // If the activity belongs to the task we are currently tracking, don't update any variables
+        // as they are still relevant. Else, if the activity is visible and focused (the one the
+        // user can see and is using), the user aspect ratio button can potentially be displayed so
+        // start tracking the buttons visibility for this task.
+        if (mTopActivityTaskId != taskInfo.taskId && taskInfo.isVisible && taskInfo.isFocused) {
+            mTopActivityTaskId = taskInfo.taskId;
+            setHasShownUserAspectRatioSettingsButton(false);
+        }
+    }
+
+    /**
+     * Informs the system that the user aspect ratio button has been displayed for the application
+     * associated with the task id in {@link CompatUIController#mTopActivityTaskId}.
+     */
+    void setHasShownUserAspectRatioSettingsButton(boolean state) {
+        mHasShownUserAspectRatioSettingsButton = state;
+    }
+
+    /**
+     * Returns whether the user aspect ratio settings button has been show for the application
+     * associated with the task id in {@link CompatUIController#mTopActivityTaskId}.
+     */
+    boolean hasShownUserAspectRatioSettingsButton() {
+        return mHasShownUserAspectRatioSettingsButton;
+    }
+
+    /**
+     * Returns the task id of the application we are currently attempting to show, of have most
+     * recently shown, the user aspect ratio settings button for.
+     */
+    int getTopActivityTaskId() {
+        return mTopActivityTaskId;
+    }
+
     private boolean showOnDisplay(int displayId) {
         return !mKeyguardShowing && !isImeShowingOnDisplay(displayId);
     }
@@ -569,7 +625,8 @@ public class CompatUIController implements OnDisplaysChangedListener,
         return new UserAspectRatioSettingsWindowManager(context, taskInfo, mSyncQueue,
                 taskListener, mDisplayController.getDisplayLayout(taskInfo.displayId),
                 mCompatUIHintsState, this::launchUserAspectRatioSettings, mMainExecutor,
-                mDisappearTimeSupplier);
+                mDisappearTimeSupplier, this::hasShownUserAspectRatioSettingsButton,
+                this::setHasShownUserAspectRatioSettingsButton);
     }
 
     private void launchUserAspectRatioSettings(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManager.java
index 77aefc8f7e4a..96470012af03 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManager.java
@@ -37,7 +37,9 @@ import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.compatui.CompatUIController.CompatUIHintsState;
 
 import java.util.function.BiConsumer;
+import java.util.function.Consumer;
 import java.util.function.Function;
+import java.util.function.Supplier;
 
 /**
  * Window manager for the user aspect ratio settings button which allows users to go to
@@ -55,6 +57,12 @@ class UserAspectRatioSettingsWindowManager extends CompatUIWindowManagerAbstract
 
     private final ShellExecutor mShellExecutor;
 
+    @NonNull
+    private final Supplier<Boolean> mUserAspectRatioButtonShownChecker;
+
+    @NonNull
+    private final Consumer<Boolean> mUserAspectRatioButtonStateConsumer;
+
     @VisibleForTesting
     @NonNull
     final CompatUIHintsState mCompatUIHintsState;
@@ -72,9 +80,13 @@ class UserAspectRatioSettingsWindowManager extends CompatUIWindowManagerAbstract
             @NonNull DisplayLayout displayLayout, @NonNull CompatUIHintsState compatUIHintsState,
             @NonNull BiConsumer<TaskInfo, ShellTaskOrganizer.TaskListener> onButtonClicked,
             @NonNull ShellExecutor shellExecutor,
-            @NonNull Function<Integer, Integer> disappearTimeSupplier) {
+            @NonNull Function<Integer, Integer> disappearTimeSupplier,
+            @NonNull Supplier<Boolean> userAspectRatioButtonStateChecker,
+            @NonNull Consumer<Boolean> userAspectRatioButtonShownConsumer) {
         super(context, taskInfo, syncQueue, taskListener, displayLayout);
         mShellExecutor = shellExecutor;
+        mUserAspectRatioButtonShownChecker = userAspectRatioButtonStateChecker;
+        mUserAspectRatioButtonStateConsumer = userAspectRatioButtonShownConsumer;
         mHasUserAspectRatioSettingsButton = getHasUserAspectRatioSettingsButton(taskInfo);
         mCompatUIHintsState = compatUIHintsState;
         mOnButtonClicked = onButtonClicked;
@@ -185,6 +197,7 @@ class UserAspectRatioSettingsWindowManager extends CompatUIWindowManagerAbstract
             return;
         }
         mLayout.setUserAspectRatioButtonVisibility(true);
+        mUserAspectRatioButtonStateConsumer.accept(true);
         // Only show by default for the first time.
         if (!mCompatUIHintsState.mHasShownUserAspectRatioSettingsButtonHint) {
             mLayout.setUserAspectRatioSettingsHintVisibility(/* show= */ true);
@@ -210,7 +223,8 @@ class UserAspectRatioSettingsWindowManager extends CompatUIWindowManagerAbstract
     private boolean getHasUserAspectRatioSettingsButton(@NonNull TaskInfo taskInfo) {
         return taskInfo.topActivityEligibleForUserAspectRatioButton
                 && (taskInfo.topActivityBoundsLetterboxed
-                    || taskInfo.isUserFullscreenOverrideEnabled);
+                    || taskInfo.isUserFullscreenOverrideEnabled)
+                && !mUserAspectRatioButtonShownChecker.get();
     }
 
     private long getDisappearTimeMs() {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
index 9b9600e4a51e..3e0c853cf7dd 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
@@ -61,6 +61,7 @@ import com.android.wm.shell.transition.Transitions;
 
 import dagger.Lazy;
 
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -523,13 +524,131 @@ public class CompatUIControllerTest extends ShellTestCase {
                 .createLayout(anyBoolean());
     }
 
+    @Test
+    public void testUpdateActiveTaskInfo_newTask_visibleAndFocused_updated() {
+        // Simulate user aspect ratio button being shown for previous task
+        mController.setHasShownUserAspectRatioSettingsButton(true);
+        Assert.assertTrue(mController.hasShownUserAspectRatioSettingsButton());
+
+        // Create new task
+        final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID,
+                /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN, /* isVisible */ true,
+                /* isFocused */ true);
+
+        // Simulate new task being shown
+        mController.updateActiveTaskInfo(taskInfo);
+
+        // Check topActivityTaskId is updated to the taskId of the new task and
+        // hasShownUserAspectRatioSettingsButton has been reset to false
+        Assert.assertEquals(TASK_ID, mController.getTopActivityTaskId());
+        Assert.assertFalse(mController.hasShownUserAspectRatioSettingsButton());
+    }
+
+    @Test
+    public void testUpdateActiveTaskInfo_newTask_notVisibleOrFocused_notUpdated() {
+        // Create new task
+        final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID,
+                /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN, /* isVisible */ true,
+                /* isFocused */ true);
+
+        // Simulate task being shown
+        mController.updateActiveTaskInfo(taskInfo);
+
+        // Check topActivityTaskId is updated to the taskId of the new task and
+        // hasShownUserAspectRatioSettingsButton has been reset to false
+        Assert.assertEquals(TASK_ID, mController.getTopActivityTaskId());
+        Assert.assertFalse(mController.hasShownUserAspectRatioSettingsButton());
+
+        // Simulate user aspect ratio button being shown
+        mController.setHasShownUserAspectRatioSettingsButton(true);
+        Assert.assertTrue(mController.hasShownUserAspectRatioSettingsButton());
+
+        final int newTaskId = TASK_ID + 1;
+
+        // Create visible but NOT focused task
+        final TaskInfo taskInfo1 = createTaskInfo(DISPLAY_ID, newTaskId,
+                /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN, /* isVisible */ true,
+                /* isFocused */ false);
+
+        // Simulate new task being shown
+        mController.updateActiveTaskInfo(taskInfo1);
+
+        // Check topActivityTaskId is NOT updated and hasShownUserAspectRatioSettingsButton
+        // remains true
+        Assert.assertEquals(TASK_ID, mController.getTopActivityTaskId());
+        Assert.assertTrue(mController.hasShownUserAspectRatioSettingsButton());
+
+        // Create focused but NOT visible task
+        final TaskInfo taskInfo2 = createTaskInfo(DISPLAY_ID, newTaskId,
+                /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN, /* isVisible */ false,
+                /* isFocused */ true);
+
+        // Simulate new task being shown
+        mController.updateActiveTaskInfo(taskInfo2);
+
+        // Check topActivityTaskId is NOT updated and hasShownUserAspectRatioSettingsButton
+        // remains true
+        Assert.assertEquals(TASK_ID, mController.getTopActivityTaskId());
+        Assert.assertTrue(mController.hasShownUserAspectRatioSettingsButton());
+
+        // Create NOT focused but NOT visible task
+        final TaskInfo taskInfo3 = createTaskInfo(DISPLAY_ID, newTaskId,
+                /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN, /* isVisible */ false,
+                /* isFocused */ false);
+
+        // Simulate new task being shown
+        mController.updateActiveTaskInfo(taskInfo3);
+
+        // Check topActivityTaskId is NOT updated and hasShownUserAspectRatioSettingsButton
+        // remains true
+        Assert.assertEquals(TASK_ID, mController.getTopActivityTaskId());
+        Assert.assertTrue(mController.hasShownUserAspectRatioSettingsButton());
+    }
+
+    @Test
+    public void testUpdateActiveTaskInfo_sameTask_notUpdated() {
+        // Create new task
+        final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID,
+                /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN, /* isVisible */ true,
+                /* isFocused */ true);
+
+        // Simulate new task being shown
+        mController.updateActiveTaskInfo(taskInfo);
+
+        // Check topActivityTaskId is updated to the taskId of the new task and
+        // hasShownUserAspectRatioSettingsButton has been reset to false
+        Assert.assertEquals(TASK_ID, mController.getTopActivityTaskId());
+        Assert.assertFalse(mController.hasShownUserAspectRatioSettingsButton());
+
+        // Simulate user aspect ratio button being shown
+        mController.setHasShownUserAspectRatioSettingsButton(true);
+        Assert.assertTrue(mController.hasShownUserAspectRatioSettingsButton());
+
+        // Simulate same task being re-shown
+        mController.updateActiveTaskInfo(taskInfo);
+
+        // Check topActivityTaskId is NOT updated and hasShownUserAspectRatioSettingsButton
+        // remains true
+        Assert.assertEquals(TASK_ID, mController.getTopActivityTaskId());
+        Assert.assertTrue(mController.hasShownUserAspectRatioSettingsButton());
+    }
+
     private static TaskInfo createTaskInfo(int displayId, int taskId, boolean hasSizeCompat,
             @CameraCompatControlState int cameraCompatControlState) {
+        return createTaskInfo(displayId, taskId, hasSizeCompat, cameraCompatControlState,
+                /* isVisible */ false, /* isFocused */ false);
+    }
+
+    private static TaskInfo createTaskInfo(int displayId, int taskId, boolean hasSizeCompat,
+            @CameraCompatControlState int cameraCompatControlState, boolean isVisible,
+            boolean isFocused) {
         RunningTaskInfo taskInfo = new RunningTaskInfo();
         taskInfo.taskId = taskId;
         taskInfo.displayId = displayId;
         taskInfo.topActivityInSizeCompat = hasSizeCompat;
         taskInfo.cameraCompatControlState = cameraCompatControlState;
+        taskInfo.isVisible = isVisible;
+        taskInfo.isFocused = isFocused;
         return taskInfo;
     }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayoutTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayoutTest.java
index ce1290b38830..f460d1b09e34 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayoutTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayoutTest.java
@@ -93,7 +93,8 @@ public class UserAspectRatioSettingsLayoutTest extends ShellTestCase {
         mWindowManager = new UserAspectRatioSettingsWindowManager(mContext, mTaskInfo,
                 mSyncTransactionQueue, mTaskListener, new DisplayLayout(),
                 new CompatUIController.CompatUIHintsState(),
-                mOnUserAspectRatioSettingsButtonClicked, new TestShellExecutor(), flags -> 0);
+                mOnUserAspectRatioSettingsButtonClicked, new TestShellExecutor(), flags -> 0,
+                () -> false, s -> {});
 
         mLayout = (UserAspectRatioSettingsLayout) LayoutInflater.from(mContext).inflate(
                 R.layout.user_aspect_ratio_settings_layout, null);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java
index 08cc2f763135..2a9b72a0bc49 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java
@@ -106,7 +106,8 @@ public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase {
                 false, /* topActivityBoundsLetterboxed */ true);
         mWindowManager = new UserAspectRatioSettingsWindowManager(mContext, mTaskInfo,
                 mSyncTransactionQueue, mTaskListener, new DisplayLayout(), new CompatUIHintsState(),
-                mOnUserAspectRatioSettingsButtonClicked, mExecutor, flags -> 0);
+                mOnUserAspectRatioSettingsButtonClicked, mExecutor, flags -> 0, () -> false,
+                s -> {});
         spyOn(mWindowManager);
         doReturn(mLayout).when(mWindowManager).inflateLayout();
         doReturn(mViewHost).when(mWindowManager).createSurfaceViewHost();
-- 
GitLab


From 92210febda7b47c044870034daf1faa3f33935f9 Mon Sep 17 00:00:00 2001
From: Eghosa Ewansiha-Vlachavas <eevlachavas@google.com>
Date: Fri, 15 Sep 2023 11:14:38 +0000
Subject: [PATCH 34/95] [2/n] Optimize user aspect ratio button heuristic

Don't show the user aspect ratio settings button after a transparent
activity has been dismissed if it was previously shown for the previous
activity.

Test: atest WMShellUnitTests:CompatUIControllerTest
Fix: 299080123
Bug: 289356588
Change-Id: Iab00c25cb0c105696bdd40dd4ebc35c5f34ed1b0
---
 core/java/android/app/TaskInfo.java           | 15 +++++-
 .../wm/shell/compatui/CompatUIController.java |  3 +-
 .../compatui/CompatUIControllerTest.java      | 46 ++++++++++++++++++-
 .../core/java/com/android/server/wm/Task.java |  1 +
 4 files changed, 61 insertions(+), 4 deletions(-)

diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java
index 4957c3e2b81d..5f8b76508ef3 100644
--- a/core/java/android/app/TaskInfo.java
+++ b/core/java/android/app/TaskInfo.java
@@ -254,6 +254,12 @@ public class TaskInfo {
      */
     public boolean isUserFullscreenOverrideEnabled;
 
+    /**
+     * Whether the top activity fillsParent() is false
+     * @hide
+     */
+    public boolean isTopActivityTransparent;
+
     /**
      * Hint about the letterbox state of the top activity.
      * @hide
@@ -551,7 +557,8 @@ public class TaskInfo {
                 && Objects.equals(mTopActivityLocusId, that.mTopActivityLocusId)
                 && parentTaskId == that.parentTaskId
                 && Objects.equals(topActivity, that.topActivity)
-                && isUserFullscreenOverrideEnabled == that.isUserFullscreenOverrideEnabled;
+                && isUserFullscreenOverrideEnabled == that.isUserFullscreenOverrideEnabled
+                && isTopActivityTransparent == that.isTopActivityTransparent;
     }
 
     /**
@@ -584,7 +591,8 @@ public class TaskInfo {
                 && (!hasCompatUI() || configuration.uiMode == that.configuration.uiMode)
                 && (!hasCompatUI() || isVisible == that.isVisible)
                 && isFocused == that.isFocused
-                && isUserFullscreenOverrideEnabled == that.isUserFullscreenOverrideEnabled;
+                && isUserFullscreenOverrideEnabled == that.isUserFullscreenOverrideEnabled
+                && isTopActivityTransparent == that.isTopActivityTransparent;
     }
 
     /**
@@ -641,6 +649,7 @@ public class TaskInfo {
         topActivityLetterboxWidth = source.readInt();
         topActivityLetterboxHeight = source.readInt();
         isUserFullscreenOverrideEnabled = source.readBoolean();
+        isTopActivityTransparent = source.readBoolean();
     }
 
     /**
@@ -698,6 +707,7 @@ public class TaskInfo {
         dest.writeInt(topActivityLetterboxWidth);
         dest.writeInt(topActivityLetterboxHeight);
         dest.writeBoolean(isUserFullscreenOverrideEnabled);
+        dest.writeBoolean(isTopActivityTransparent);
     }
 
     @Override
@@ -745,6 +755,7 @@ public class TaskInfo {
                 + " topActivityLetterboxWidth=" + topActivityLetterboxWidth
                 + " topActivityLetterboxHeight=" + topActivityLetterboxHeight
                 + " isUserFullscreenOverrideEnabled=" + isUserFullscreenOverrideEnabled
+                + " isTopActivityTransparent=" + isTopActivityTransparent
                 + " locusId=" + mTopActivityLocusId
                 + " displayAreaFeatureId=" + displayAreaFeatureId
                 + " cameraCompatControlState="
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
index e0031b4db419..96f22c0bc97b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
@@ -345,7 +345,8 @@ public class CompatUIController implements OnDisplaysChangedListener,
         // as they are still relevant. Else, if the activity is visible and focused (the one the
         // user can see and is using), the user aspect ratio button can potentially be displayed so
         // start tracking the buttons visibility for this task.
-        if (mTopActivityTaskId != taskInfo.taskId && taskInfo.isVisible && taskInfo.isFocused) {
+        if (mTopActivityTaskId != taskInfo.taskId && !taskInfo.isTopActivityTransparent
+                && taskInfo.isVisible && taskInfo.isFocused) {
             mTopActivityTaskId = taskInfo.taskId;
             setHasShownUserAspectRatioSettingsButton(false);
         }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
index 3e0c853cf7dd..f85d707d55f9 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
@@ -633,15 +633,58 @@ public class CompatUIControllerTest extends ShellTestCase {
         Assert.assertTrue(mController.hasShownUserAspectRatioSettingsButton());
     }
 
+    @Test
+    public void testUpdateActiveTaskInfo_transparentTask_notUpdated() {
+        // Create new task
+        final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID,
+                /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN, /* isVisible */ true,
+                /* isFocused */ true);
+
+        // Simulate new task being shown
+        mController.updateActiveTaskInfo(taskInfo);
+
+        // Check topActivityTaskId is updated to the taskId of the new task and
+        // hasShownUserAspectRatioSettingsButton has been reset to false
+        Assert.assertEquals(TASK_ID, mController.getTopActivityTaskId());
+        Assert.assertFalse(mController.hasShownUserAspectRatioSettingsButton());
+
+        // Simulate user aspect ratio button being shown
+        mController.setHasShownUserAspectRatioSettingsButton(true);
+        Assert.assertTrue(mController.hasShownUserAspectRatioSettingsButton());
+
+        final int newTaskId = TASK_ID + 1;
+
+        // Create transparent task
+        final TaskInfo taskInfo1 = createTaskInfo(DISPLAY_ID, newTaskId,
+                /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN, /* isVisible */ true,
+                /* isFocused */ true, /* isTopActivityTransparent */ true);
+
+        // Simulate new task being shown
+        mController.updateActiveTaskInfo(taskInfo1);
+
+        // Check topActivityTaskId is NOT updated and hasShownUserAspectRatioSettingsButton
+        // remains true
+        Assert.assertEquals(TASK_ID, mController.getTopActivityTaskId());
+        Assert.assertTrue(mController.hasShownUserAspectRatioSettingsButton());
+    }
+
     private static TaskInfo createTaskInfo(int displayId, int taskId, boolean hasSizeCompat,
             @CameraCompatControlState int cameraCompatControlState) {
         return createTaskInfo(displayId, taskId, hasSizeCompat, cameraCompatControlState,
-                /* isVisible */ false, /* isFocused */ false);
+                /* isVisible */ false, /* isFocused */ false,
+                /* isTopActivityTransparent */ false);
     }
 
     private static TaskInfo createTaskInfo(int displayId, int taskId, boolean hasSizeCompat,
             @CameraCompatControlState int cameraCompatControlState, boolean isVisible,
             boolean isFocused) {
+        return createTaskInfo(displayId, taskId, hasSizeCompat, cameraCompatControlState,
+                isVisible, isFocused, /* isTopActivityTransparent */ false);
+    }
+
+    private static TaskInfo createTaskInfo(int displayId, int taskId, boolean hasSizeCompat,
+            @CameraCompatControlState int cameraCompatControlState, boolean isVisible,
+            boolean isFocused, boolean isTopActivityTransparent) {
         RunningTaskInfo taskInfo = new RunningTaskInfo();
         taskInfo.taskId = taskId;
         taskInfo.displayId = displayId;
@@ -649,6 +692,7 @@ public class CompatUIControllerTest extends ShellTestCase {
         taskInfo.cameraCompatControlState = cameraCompatControlState;
         taskInfo.isVisible = isVisible;
         taskInfo.isFocused = isFocused;
+        taskInfo.isTopActivityTransparent = isTopActivityTransparent;
         return taskInfo;
     }
 }
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 9f2aff28cb11..a6eace7ff8d1 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -3461,6 +3461,7 @@ class Task extends TaskFragment {
         info.topActivityLetterboxHeight = TaskInfo.PROPERTY_VALUE_UNSET;
         info.isUserFullscreenOverrideEnabled = top != null
                 && top.mLetterboxUiController.shouldApplyUserFullscreenOverride();
+        info.isTopActivityTransparent = top != null && !top.fillsParent();
         info.isFromLetterboxDoubleTap = top != null && top.mLetterboxUiController.isFromDoubleTap();
         if (info.isLetterboxDoubleTapEnabled) {
             info.topActivityLetterboxWidth = top.getBounds().width();
-- 
GitLab


From 309a61bd1cb9f3341e2fcdb6f7db55b611f1380f Mon Sep 17 00:00:00 2001
From: Santiago Seifert <aquilescanta@google.com>
Date: Thu, 21 Sep 2023 13:43:34 +0000
Subject: [PATCH 35/95] Converge documentation around media session key

As a collateral effect, this change also fixes some javadocs.

Bug: 237533067
Test: N/A. Javadoc only change.
Change-Id: I960e719cba66056c0ae6db3a265550ac9c17c905
---
 core/java/android/view/KeyEvent.java          | 19 +++++++++-
 media/java/android/media/AudioManager.java    | 26 ++++---------
 .../java/android/media/RemoteController.java  | 38 +++++++------------
 .../server/media/MediaKeyDispatcher.java      | 21 ++--------
 4 files changed, 41 insertions(+), 63 deletions(-)

diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index bb4cc8fc8d45..b17d2d1800e5 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -1990,8 +1990,23 @@ public class KeyEvent extends InputEvent implements Parcelable {
     }
 
     /**
-     * Returns whether this key will be sent to the
-     * {@link android.media.session.MediaSession.Callback} if not handled.
+     * Returns whether this key will be sent to the {@link
+     * android.media.session.MediaSession.Callback} if not handled.
+     *
+     * <p>The following key codes are considered {@link android.media.session.MediaSession} keys:
+     *
+     * <ul>
+     *   <li>{@link #KEYCODE_MEDIA_PLAY}
+     *   <li>{@link #KEYCODE_MEDIA_PAUSE}
+     *   <li>{@link #KEYCODE_MEDIA_PLAY_PAUSE}
+     *   <li>{@link #KEYCODE_HEADSETHOOK}
+     *   <li>{@link #KEYCODE_MEDIA_STOP}
+     *   <li>{@link #KEYCODE_MEDIA_NEXT}
+     *   <li>{@link #KEYCODE_MEDIA_PREVIOUS}
+     *   <li>{@link #KEYCODE_MEDIA_REWIND}
+     *   <li>{@link #KEYCODE_MEDIA_RECORD}
+     *   <li>{@link #KEYCODE_MEDIA_FAST_FORWARD}
+     * </ul>
      */
     public static final boolean isMediaSessionKey(int keyCode) {
         switch (keyCode) {
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 842542f4f43b..adc0e16448ee 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -941,27 +941,15 @@ public class AudioManager {
     }
 
     /**
-     * Sends a simulated key event for a media button.
-     * To simulate a key press, you must first send a KeyEvent built with a
-     * {@link KeyEvent#ACTION_DOWN} action, then another event with the {@link KeyEvent#ACTION_UP}
-     * action.
+     * Sends a simulated key event for a media button. To simulate a key press, you must first send
+     * a KeyEvent built with a {@link KeyEvent#ACTION_DOWN} action, then another event with the
+     * {@link KeyEvent#ACTION_UP} action.
+     *
      * <p>The key event will be sent to the current media key event consumer which registered with
      * {@link AudioManager#registerMediaButtonEventReceiver(PendingIntent)}.
-     * @param keyEvent a {@link KeyEvent} instance whose key code is one of
-     *     {@link KeyEvent#KEYCODE_MUTE},
-     *     {@link KeyEvent#KEYCODE_HEADSETHOOK},
-     *     {@link KeyEvent#KEYCODE_MEDIA_PLAY},
-     *     {@link KeyEvent#KEYCODE_MEDIA_PAUSE},
-     *     {@link KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE},
-     *     {@link KeyEvent#KEYCODE_MEDIA_STOP},
-     *     {@link KeyEvent#KEYCODE_MEDIA_NEXT},
-     *     {@link KeyEvent#KEYCODE_MEDIA_PREVIOUS},
-     *     {@link KeyEvent#KEYCODE_MEDIA_REWIND},
-     *     {@link KeyEvent#KEYCODE_MEDIA_RECORD},
-     *     {@link KeyEvent#KEYCODE_MEDIA_FAST_FORWARD},
-     *     {@link KeyEvent#KEYCODE_MEDIA_CLOSE},
-     *     {@link KeyEvent#KEYCODE_MEDIA_EJECT},
-     *     or {@link KeyEvent#KEYCODE_MEDIA_AUDIO_TRACK}.
+     *
+     * @param keyEvent a media session {@link KeyEvent}, as defined by {@link
+     *     KeyEvent#isMediaSessionKey}.
      */
     public void dispatchMediaKeyEvent(KeyEvent keyEvent) {
         MediaSessionLegacyHelper helper = MediaSessionLegacyHelper.getHelper(getContext());
diff --git a/media/java/android/media/RemoteController.java b/media/java/android/media/RemoteController.java
index a6e8fa0644df..aaaf25f008c7 100644
--- a/media/java/android/media/RemoteController.java
+++ b/media/java/android/media/RemoteController.java
@@ -220,33 +220,21 @@ import java.util.List;
         return -1;
     }
 
-
     /**
-     * Send a simulated key event for a media button to be received by the current client.
-     * To simulate a key press, you must first send a KeyEvent built with
-     * a {@link KeyEvent#ACTION_DOWN} action, then another event with the {@link KeyEvent#ACTION_UP}
-     * action.
-     * <p>The key event will be sent to the registered receiver
-     * (see {@link AudioManager#registerMediaButtonEventReceiver(PendingIntent)}) whose associated
-     * {@link RemoteControlClient}'s metadata and playback state is published (there may be
-     * none under some circumstances).
-     * @param keyEvent a {@link KeyEvent} instance whose key code is one of
-     *     {@link KeyEvent#KEYCODE_MUTE},
-     *     {@link KeyEvent#KEYCODE_HEADSETHOOK},
-     *     {@link KeyEvent#KEYCODE_MEDIA_PLAY},
-     *     {@link KeyEvent#KEYCODE_MEDIA_PAUSE},
-     *     {@link KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE},
-     *     {@link KeyEvent#KEYCODE_MEDIA_STOP},
-     *     {@link KeyEvent#KEYCODE_MEDIA_NEXT},
-     *     {@link KeyEvent#KEYCODE_MEDIA_PREVIOUS},
-     *     {@link KeyEvent#KEYCODE_MEDIA_REWIND},
-     *     {@link KeyEvent#KEYCODE_MEDIA_RECORD},
-     *     {@link KeyEvent#KEYCODE_MEDIA_FAST_FORWARD},
-     *     {@link KeyEvent#KEYCODE_MEDIA_CLOSE},
-     *     {@link KeyEvent#KEYCODE_MEDIA_EJECT},
-     *     or {@link KeyEvent#KEYCODE_MEDIA_AUDIO_TRACK}.
+     * Send a simulated key event for a media button to be received by the current client. To
+     * simulate a key press, you must first send a KeyEvent built with a {@link
+     * KeyEvent#ACTION_DOWN} action, then another event with the {@link KeyEvent#ACTION_UP} action.
+     *
+     * <p>The key event will be sent to the registered receiver (see {@link
+     * AudioManager#registerMediaButtonEventReceiver(PendingIntent)}) whose associated {@link
+     * RemoteControlClient}'s metadata and playback state is published (there may be none under some
+     * circumstances).
+     *
+     * @param keyEvent a media session {@link KeyEvent}, as defined by {@link
+     *     KeyEvent#isMediaSessionKey}.
      * @return true if the event was successfully sent, false otherwise.
-     * @throws IllegalArgumentException
+     * @throws IllegalArgumentException If the provided {@link KeyEvent} is not a media session key,
+     *     as defined by {@link KeyEvent#isMediaSessionKey}.
      */
     public boolean sendMediaKeyEvent(KeyEvent keyEvent) throws IllegalArgumentException {
         if (!KeyEvent.isMediaSessionKey(keyEvent.getKeyCode())) {
diff --git a/services/core/java/com/android/server/media/MediaKeyDispatcher.java b/services/core/java/com/android/server/media/MediaKeyDispatcher.java
index 55511ad637ac..66cafabb1e6e 100644
--- a/services/core/java/com/android/server/media/MediaKeyDispatcher.java
+++ b/services/core/java/com/android/server/media/MediaKeyDispatcher.java
@@ -117,24 +117,11 @@ public abstract class MediaKeyDispatcher {
 
     /**
      * Gets the map of key code -> {@link KeyEventType} that have been overridden.
-     * <p>
-     * The list of valid key codes are the following:
-     * <ul>
-     * <li> {@link KeyEvent#KEYCODE_MEDIA_PLAY}
-     * <li> {@link KeyEvent#KEYCODE_MEDIA_PAUSE}
-     * <li> {@link KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE}
-     * <li> {@link KeyEvent#KEYCODE_MUTE}
-     * <li> {@link KeyEvent#KEYCODE_HEADSETHOOK}
-     * <li> {@link KeyEvent#KEYCODE_MEDIA_STOP}
-     * <li> {@link KeyEvent#KEYCODE_MEDIA_NEXT}
-     * <li> {@link KeyEvent#KEYCODE_MEDIA_PREVIOUS}
-     * <li> {@link KeyEvent#KEYCODE_VOLUME_UP}
-     * <li> {@link KeyEvent#KEYCODE_VOLUME_DOWN}
-     * <li> {@link KeyEvent#KEYCODE_VOLUME_MUTE}
-     * </ul>
-     * @see {@link KeyEvent#isMediaSessionKey(int)}
+     *
+     * <p>For the list of relevant key codes, see {@link KeyEvent#isMediaSessionKey(int)}.
      */
-    @KeyEventType Map<Integer, Integer> getOverriddenKeyEvents() {
+    @KeyEventType
+    Map<Integer, Integer> getOverriddenKeyEvents() {
         return mOverriddenKeyEvents;
     }
 
-- 
GitLab


From 91171a4bfcc1ec937c4a3221270a47d3083ca46b Mon Sep 17 00:00:00 2001
From: Justin Chung <justinkchung@google.com>
Date: Thu, 21 Sep 2023 14:20:18 +0000
Subject: [PATCH 36/95] Inject mock VibratorInfo from TestPhoneWinowManager

Bug: 300967518
Test: atest PowerKeyGestureTests#testPowerLongPress
Change-Id: I6244d01c2d50bde753775073741bec3649fc322a
---
 .../src/com/android/server/policy/TestPhoneWindowManager.java  | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
index e301da7c58fc..0e0f64ddecd6 100644
--- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
+++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
@@ -77,6 +77,7 @@ import android.os.PowerManagerInternal;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.Vibrator;
+import android.os.VibratorInfo;
 import android.service.dreams.DreamManagerInternal;
 import android.telecom.TelecomManager;
 import android.util.FeatureFlagUtils;
@@ -138,6 +139,7 @@ class TestPhoneWindowManager {
     @Mock private TelecomManager mTelecomManager;
     @Mock private NotificationManager mNotificationManager;
     @Mock private Vibrator mVibrator;
+    @Mock private VibratorInfo mVibratorInfo;
     @Mock private PowerManager mPowerManager;
     @Mock private WindowManagerPolicy.WindowManagerFuncs mWindowManagerFuncsImpl;
     @Mock private InputMethodManagerInternal mInputMethodManagerInternal;
@@ -246,6 +248,7 @@ class TestPhoneWindowManager {
         doReturn(mTelecomManager).when(mPhoneWindowManager).getTelecommService();
         doNothing().when(mNotificationManager).silenceNotificationSound();
         doReturn(mNotificationManager).when(mPhoneWindowManager).getNotificationService();
+        doReturn(mVibratorInfo).when(mVibrator).getInfo();
         doReturn(mVibrator).when(mContext).getSystemService(eq(Context.VIBRATOR_SERVICE));
 
         final PowerManager.WakeLock wakeLock = mock(PowerManager.WakeLock.class);
-- 
GitLab


From 1c9ae2000596be1dda69a48666feca40c98d7680 Mon Sep 17 00:00:00 2001
From: Evan Laird <evanlaird@google.com>
Date: Thu, 21 Sep 2023 10:35:22 -0400
Subject: [PATCH 37/95] [Status bar] Reduce length of BatteryController log

We don't need 300 lines anymore. 30 Seems reasonable since we have about
3 log lines per event, so this is effectively a 10-event buffer

Test: manually check dumpsys
Fixes: 300147438
Change-Id: I0ff8f5130b04d6f91318c7405bc2260519f69489
---
 .../statusbar/policy/dagger/StatusBarPolicyModule.java       | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java
index 927024fbdd34..a77c69236946 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java
@@ -213,12 +213,11 @@ public interface StatusBarPolicyModule {
         return networkController.getDataSaverController();
     }
 
-    /** Provides a log bufffer for BatteryControllerImpl */
+    /** Provides a log buffer for BatteryControllerImpl */
     @Provides
     @SysUISingleton
     @BatteryControllerLog
-    //TODO(b/300147438): reduce the size of this log buffer
     static LogBuffer provideBatteryControllerLog(LogBufferFactory factory) {
-        return factory.create(BatteryControllerLogger.TAG, 300);
+        return factory.create(BatteryControllerLogger.TAG, 30);
     }
 }
-- 
GitLab


From 501eeee21a5fb200b88b42eb8ed53be67bd16e56 Mon Sep 17 00:00:00 2001
From: beatricemarch <beatricemarch@google.com>
Date: Thu, 31 Aug 2023 12:53:16 +0000
Subject: [PATCH 38/95] Add more BackupManagerMonitor events to
 PerformUnifiedRestoreTask.

In particular
add events to cover
-If this is KV or Full restore
-For each package, when the restore started and when it ended
-When a restore operation starts, if it is system restore or restore at install
-Any errors

Test: manual testing. Run `adb shell bmgr restore 1` and verify that the
new restore events are added to the dumpsys
atest CtsBackupHostTestCases, GtsBackupHostTestCases
atest BackupManagerMonitorDumpsysUtilsTest,
BackupManagerMonitorEventSenderTest, UserBackupManagerServiceTest,
PerformUnifiedRestoreTaskTest, BmgrTest
Bug: 290747920

Change-Id: I0d221f10932fea3e8fb90a1827c7f1b5bf21d25d
---
 .../src/com/android/commands/bmgr/Bmgr.java   |  34 +++++
 .../app/backup/BackupManagerMonitor.java      |  51 ++++++++
 .../restore/PerformUnifiedRestoreTask.java    | 117 ++++++++++++++++++
 .../BackupManagerMonitorDumpsysUtils.java     |  26 ++++
 4 files changed, 228 insertions(+)

diff --git a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
index b6dc32a29f04..088372702ebc 100644
--- a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
+++ b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
@@ -1246,6 +1246,40 @@ public class Bmgr {
                 return "TRANSPORT_IS_NULL";
             case BackupManagerMonitor.LOG_EVENT_ID_AGENT_LOGGING_RESULTS:
                 return "AGENT_LOGGING_RESULTS";
+            case BackupManagerMonitor.LOG_EVENT_ID_START_SYSTEM_RESTORE:
+                return "START_SYSTEM_RESTORE";
+            case BackupManagerMonitor.LOG_EVENT_ID_START_RESTORE_AT_INSTALL:
+                return "START_RESTORE_AT_INSTALL";
+            case BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_ERROR_DURING_START_RESTORE:
+                return "TRANSPORT_ERROR_DURING_START_RESTORE";
+            case BackupManagerMonitor.LOG_EVENT_ID_CANNOT_GET_NEXT_PKG_NAME:
+                return "CANNOT_GET_NEXT_PKG_NAME";
+            case BackupManagerMonitor.LOG_EVENT_ID_UNKNOWN_RESTORE_TYPE:
+                return "UNKNOWN_RESTORE_TYPE";
+            case BackupManagerMonitor.LOG_EVENT_ID_KV_RESTORE:
+                return "KV_RESTORE";
+            case BackupManagerMonitor.LOG_EVENT_ID_FULL_RESTORE:
+                return "FULL_RESTORE";
+            case BackupManagerMonitor.LOG_EVENT_ID_NO_NEXT_RESTORE_TARGET:
+                return "NO_NEXT_RESTORE_TARGET";
+            case BackupManagerMonitor.LOG_EVENT_ID_KV_AGENT_ERROR:
+                return "KV_AGENT_ERROR";
+            case BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_RESTORE_FINISHED:
+                return "PACKAGE_RESTORE_FINISHED";
+            case BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_ERROR_KV_RESTORE:
+                return "TRANSPORT_ERROR_KV_RESTORE";
+            case BackupManagerMonitor.LOG_EVENT_ID_NO_FEEDER_THREAD:
+                return "NO_FEEDER_THREAD";
+            case BackupManagerMonitor.LOG_EVENT_ID_FULL_AGENT_ERROR:
+                return "FULL_AGENT_ERROR";
+            case BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_ERROR_FULL_RESTORE:
+                return "TRANSPORT_ERROR_FULL_RESTORE";
+            case BackupManagerMonitor.LOG_EVENT_ID_RESTORE_COMPLETE:
+                return "RESTORE_COMPLETE";
+            case BackupManagerMonitor.LOG_EVENT_ID_START_PACKAGE_RESTORE:
+                return "START_PACKAGE_RESTORE";
+            case BackupManagerMonitor.LOG_EVENT_ID_AGENT_FAILURE:
+                return "AGENT_FAILURE";
             default:
                 return "UNKNOWN_ID";
         }
diff --git a/core/java/android/app/backup/BackupManagerMonitor.java b/core/java/android/app/backup/BackupManagerMonitor.java
index f73366b6af0c..812bf8e6be6a 100644
--- a/core/java/android/app/backup/BackupManagerMonitor.java
+++ b/core/java/android/app/backup/BackupManagerMonitor.java
@@ -18,6 +18,7 @@ package android.app.backup;
 
 import android.annotation.SystemApi;
 import android.app.backup.BackupAnnotations.OperationType;
+import android.content.pm.PackageInfo;
 import android.os.Bundle;
 
 /**
@@ -190,6 +191,56 @@ public class BackupManagerMonitor {
   public static final int LOG_EVENT_ID_TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED = 51;
 
   public static final int LOG_EVENT_ID_AGENT_LOGGING_RESULTS = 52;
+  /** @hide */
+  public static final int LOG_EVENT_ID_START_SYSTEM_RESTORE = 53;
+  /** @hide */
+  public static final int LOG_EVENT_ID_START_RESTORE_AT_INSTALL = 54;
+  /** A transport error happened during {@link PerformUnifiedRestoreTask#startRestore()}
+  @hide */
+  public static final int LOG_EVENT_ID_TRANSPORT_ERROR_DURING_START_RESTORE = 55;
+  /** Unable to get the name of the next package in the queue during a restore operation
+  @hide */
+  public static final int LOG_EVENT_ID_CANNOT_GET_NEXT_PKG_NAME = 56;
+  /** Attempting a restore operation that is neither KV nor full
+  @hide */
+  public static final int LOG_EVENT_ID_UNKNOWN_RESTORE_TYPE = 57;
+  /** The package is part of KeyValue restore
+  @hide */
+  public static final int LOG_EVENT_ID_KV_RESTORE = 58;
+  /** The package is part of Full restore
+  @hide */
+  public static final int LOG_EVENT_ID_FULL_RESTORE = 59;
+  /** Unable to fetch the nest restore target in the queue
+  @hide */
+  public static final int LOG_EVENT_ID_NO_NEXT_RESTORE_TARGET = 60;
+  /** An error occurred while attempting KeyValueRestore
+  @hide */
+  public static final int LOG_EVENT_ID_KV_AGENT_ERROR = 61;
+  /** Restore operation finished for the given package
+  @hide */
+  public static final int LOG_EVENT_ID_PACKAGE_RESTORE_FINISHED= 62;
+  /** A transport error happened during
+   * {@link PerformUnifiedRestoreTask#initiateOneRestore(PackageInfo, long)}
+  @hide */
+  public static final int LOG_EVENT_ID_TRANSPORT_ERROR_KV_RESTORE = 63;
+  /** Unable to instantiate the feeder thread in full restore
+  @hide */
+  public static final int LOG_EVENT_ID_NO_FEEDER_THREAD = 64;
+  /** An error occurred while attempting Full restore
+  @hide */
+  public static final int LOG_EVENT_ID_FULL_AGENT_ERROR = 65;
+  /** A transport error happened during a full restore
+  @hide */
+  public static final int LOG_EVENT_ID_TRANSPORT_ERROR_FULL_RESTORE = 66;
+  /** Start restore operation for a given package
+  @hide */
+  public static final int LOG_EVENT_ID_START_PACKAGE_RESTORE = 67;
+  /** Whole restore operation is complete
+  @hide */
+  public static final int LOG_EVENT_ID_RESTORE_COMPLETE = 68;
+  /** Agent error during {@link PerformUnifiedRestoreTask#restoreFinished()}
+   @hide */
+  public static final int LOG_EVENT_ID_AGENT_FAILURE = 69;
 
   /**
    * This method will be called each time something important happens on BackupManager.
diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
index e04bf11dad9f..bbec79d6cd47 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
@@ -394,6 +394,20 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
         // If we're starting a full-system restore, set up to begin widget ID remapping
         if (mIsSystemRestore) {
             AppWidgetBackupBridge.systemRestoreStarting(mUserId);
+            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+            mBackupManagerMonitorEventSender.monitorEvent(
+                    BackupManagerMonitor.LOG_EVENT_ID_START_SYSTEM_RESTORE,
+                    null,
+                    BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                    monitoringExtras);
+        } else {
+            //We are either performing RestoreAtInstall or Bmgr.
+            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+            mBackupManagerMonitorEventSender.monitorEvent(
+                    BackupManagerMonitor.LOG_EVENT_ID_START_RESTORE_AT_INSTALL,
+                    null,
+                    BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                    monitoringExtras);
         }
 
         try {
@@ -421,6 +435,12 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
             mStatus = transport.startRestore(mToken, packages);
             if (mStatus != BackupTransport.TRANSPORT_OK) {
                 Slog.e(TAG, "Transport error " + mStatus + "; no restore possible");
+                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+                mBackupManagerMonitorEventSender.monitorEvent(
+                        BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_ERROR_DURING_START_RESTORE,
+                        mCurrentPackage,
+                        BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT,
+                        monitoringExtras);
                 mStatus = BackupTransport.TRANSPORT_ERROR;
                 executeNextState(UnifiedRestoreState.FINAL);
                 return;
@@ -528,6 +548,12 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
             final String pkgName = (mRestoreDescription != null)
                     ? mRestoreDescription.getPackageName() : null;
             if (pkgName == null) {
+                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+                mBackupManagerMonitorEventSender.monitorEvent(
+                        BackupManagerMonitor.LOG_EVENT_ID_CANNOT_GET_NEXT_PKG_NAME,
+                        null,
+                        BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT,
+                        monitoringExtras);
                 Slog.e(TAG, "Failure getting next package name");
                 EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
                 nextState = UnifiedRestoreState.FINAL;
@@ -550,6 +576,14 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
 
             Metadata metaInfo = mPmAgent.getRestoredMetadata(pkgName);
             if (metaInfo == null) {
+                PackageInfo pkgInfo = new PackageInfo();
+                pkgInfo.packageName = pkgName;
+                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+                mBackupManagerMonitorEventSender.monitorEvent(
+                        BackupManagerMonitor.LOG_EVENT_ID_PM_AGENT_HAS_NO_METADATA,
+                        pkgInfo,
+                        BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                        monitoringExtras);
                 Slog.e(TAG, "No metadata for " + pkgName);
                 EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, pkgName,
                         "Package metadata missing");
@@ -560,6 +594,13 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
             try {
                 mCurrentPackage = backupManagerService.getPackageManager().getPackageInfoAsUser(
                         pkgName, PackageManager.GET_SIGNING_CERTIFICATES, mUserId);
+                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+                mBackupManagerMonitorEventSender.monitorEvent(
+                        BackupManagerMonitor.LOG_EVENT_ID_START_PACKAGE_RESTORE,
+                        mCurrentPackage,
+                        BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                        monitoringExtras);
+
             } catch (NameNotFoundException e) {
                 // Whoops, we thought we could restore this package but it
                 // turns out not to be present.  Skip it.
@@ -641,12 +682,24 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
             } else {
                 // Unknown restore type; ignore this package and move on
                 Slog.e(TAG, "Unrecognized restore type " + type);
+                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);;
+                mBackupManagerMonitorEventSender.monitorEvent(
+                        BackupManagerMonitor.LOG_EVENT_ID_UNKNOWN_RESTORE_TYPE,
+                        mCurrentPackage,
+                        BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                        monitoringExtras);
                 nextState = UnifiedRestoreState.RUNNING_QUEUE;
                 return;
             }
         } catch (Exception e) {
             Slog.e(TAG, "Can't get next restore target from transport; halting: "
                     + e.getMessage());
+            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);;
+            mBackupManagerMonitorEventSender.monitorEvent(
+                    BackupManagerMonitor.LOG_EVENT_ID_NO_NEXT_RESTORE_TARGET,
+                    mCurrentPackage,
+                    BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                    monitoringExtras);
             EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
             nextState = UnifiedRestoreState.FINAL;
             return;
@@ -663,6 +716,10 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
         final String packageName = mCurrentPackage.packageName;
         // Validate some semantic requirements that apply in this way
         // only to the key/value restore API flow
+        mBackupManagerMonitorEventSender.monitorEvent(
+                BackupManagerMonitor.LOG_EVENT_ID_KV_RESTORE, mCurrentPackage,
+                BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                /*monitoringExtras*/ addRestoreOperationTypeToEvent(/*extras*/null));
         if (mCurrentPackage.applicationInfo.backupAgentName == null
                 || "".equals(mCurrentPackage.applicationInfo.backupAgentName)) {
             if (MORE_DEBUG) {
@@ -721,6 +778,11 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
             ++mCount;
         } catch (Exception e) {
             Slog.e(TAG, "Error when attempting restore: " + e.toString());
+            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+            mBackupManagerMonitorEventSender.monitorEvent(
+                    BackupManagerMonitor.LOG_EVENT_ID_KV_AGENT_ERROR, mCurrentPackage,
+                    BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT,
+                    monitoringExtras);
             keyValueAgentErrorCleanup(false);
             executeNextState(UnifiedRestoreState.RUNNING_QUEUE);
         }
@@ -759,6 +821,12 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
                 // Transport-level failure. This failure could be specific to package currently in
                 // restore.
                 Slog.e(TAG, "Error getting restore data for " + packageName);
+                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+                mBackupManagerMonitorEventSender.monitorEvent(
+                        BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_ERROR_KV_RESTORE,
+                        mCurrentPackage,
+                        BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT,
+                        monitoringExtras);
                 EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
                 stage.close();
                 downloadFile.delete();
@@ -815,6 +883,11 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
                     new ArrayList<>(getExcludedKeysForPackage(packageName)));
         } catch (Exception e) {
             Slog.e(TAG, "Unable to call app for restore: " + packageName, e);
+            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+            mBackupManagerMonitorEventSender.monitorEvent(
+                    BackupManagerMonitor.LOG_EVENT_ID_KV_AGENT_ERROR, mCurrentPackage,
+                    BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT,
+                    monitoringExtras);
             EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
                     packageName, e.toString());
             // Clears any pending timeout messages as well.
@@ -888,6 +961,10 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
         //
         // When finished, StreamFeederThread executes next state as appropriate on the
         // backup looper, and the overall unified restore task resumes
+        mBackupManagerMonitorEventSender.monitorEvent(
+                BackupManagerMonitor.LOG_EVENT_ID_FULL_RESTORE, mCurrentPackage,
+                BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                /*monitoringExtras*/ addRestoreOperationTypeToEvent(/*extras*/null));
         try {
             StreamFeederThread feeder = new StreamFeederThread();
             if (MORE_DEBUG) {
@@ -903,6 +980,11 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
             // current target.  We haven't asked the transport for data yet, though,
             // so we can do that simply by going back to running the restore queue.
             Slog.e(TAG, "Unable to construct pipes for stream restore!");
+            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+            mBackupManagerMonitorEventSender.monitorEvent(
+                    BackupManagerMonitor.LOG_EVENT_ID_NO_FEEDER_THREAD, mCurrentPackage,
+                    BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                    monitoringExtras);
             executeNextState(UnifiedRestoreState.RUNNING_QUEUE);
         }
     }
@@ -927,6 +1009,10 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
         } catch (Exception e) {
             final String packageName = mCurrentPackage.packageName;
             Slog.e(TAG, "Unable to finalize restore of " + packageName);
+            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+            mBackupManagerMonitorEventSender.monitorEvent(
+                    BackupManagerMonitor.LOG_EVENT_ID_AGENT_FAILURE, mCurrentPackage,
+                    BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT, monitoringExtras);
             EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
                     packageName, e.toString());
             keyValueAgentErrorCleanup(true);
@@ -1020,6 +1106,12 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
                         // handling will deal properly with that.
                         Slog.e(TAG, "Error " + result + " streaming restore for "
                                 + mCurrentPackage.packageName);
+                        Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+                        mBackupManagerMonitorEventSender.monitorEvent(
+                                BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_ERROR_FULL_RESTORE,
+                                mCurrentPackage,
+                                BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT,
+                                monitoringExtras);
                         EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
                         status = result;
                     }
@@ -1032,6 +1124,12 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
                 // but potentially recoverable; abandon this package's restore but
                 // carry on with the next restore target.
                 Slog.e(TAG, "Unable to route data for restore");
+                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+                mBackupManagerMonitorEventSender.monitorEvent(
+                        BackupManagerMonitor.LOG_EVENT_ID_FULL_AGENT_ERROR,
+                        mCurrentPackage,
+                        BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT,
+                        monitoringExtras);
                 EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
                         mCurrentPackage.packageName, "I/O error on pipes");
                 status = BackupTransport.AGENT_ERROR;
@@ -1040,6 +1138,12 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
                 // the sockets will wake up the engine and it will then tidy up the
                 // remote end.
                 Slog.e(TAG, "Transport failed during restore: " + e.getMessage());
+                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+                mBackupManagerMonitorEventSender.monitorEvent(
+                        BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_ERROR_FULL_RESTORE,
+                        mCurrentPackage,
+                        BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT,
+                        monitoringExtras);
                 EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
                 status = BackupTransport.TRANSPORT_ERROR;
             } finally {
@@ -1213,6 +1317,13 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
         }
 
         Slog.i(TAG, "Restore complete.");
+        Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+        mBackupManagerMonitorEventSender.monitorEvent(
+                BackupManagerMonitor.LOG_EVENT_ID_RESTORE_COMPLETE,
+                null,
+                BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                monitoringExtras);
+
         mListener.onFinished(callerLogString);
     }
 
@@ -1313,6 +1424,7 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
     @Override
     public void operationComplete(long unusedResult) {
         mOperationStorage.removeOperation(mEphemeralOpToken);
+
         if (MORE_DEBUG) {
             Slog.i(TAG, "operationComplete() during restore: target="
                     + mCurrentPackage.packageName
@@ -1341,6 +1453,11 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
                 // Okay, we're done with this package.  Tidy up and go on to the next
                 // app in the queue.
                 int size = (int) mBackupDataName.length();
+                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+                mBackupManagerMonitorEventSender.monitorEvent(
+                        BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_RESTORE_FINISHED, mCurrentPackage,
+                        BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                        monitoringExtras);
                 EventLog.writeEvent(EventLogTags.RESTORE_PACKAGE,
                         mCurrentPackage.packageName, size);
 
diff --git a/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtils.java b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtils.java
index bc2326d8241d..16da846a093a 100644
--- a/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtils.java
@@ -272,6 +272,32 @@ public class BackupManagerMonitorDumpsysUtils {
             case BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED ->
                     "Transport non-incremental backup required";
             case BackupManagerMonitor.LOG_EVENT_ID_AGENT_LOGGING_RESULTS -> "Agent logging results";
+            case BackupManagerMonitor.LOG_EVENT_ID_START_SYSTEM_RESTORE -> "Start system restore";
+            case BackupManagerMonitor.LOG_EVENT_ID_START_RESTORE_AT_INSTALL ->
+                    "Start restore at install";
+            case BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_ERROR_DURING_START_RESTORE ->
+                    "Transport error during start restore";
+            case BackupManagerMonitor.LOG_EVENT_ID_CANNOT_GET_NEXT_PKG_NAME ->
+                    "Cannot get next package name";
+            case BackupManagerMonitor.LOG_EVENT_ID_UNKNOWN_RESTORE_TYPE -> "Unknown restore type";
+            case BackupManagerMonitor.LOG_EVENT_ID_KV_RESTORE -> "KV restore";
+            case BackupManagerMonitor.LOG_EVENT_ID_FULL_RESTORE -> "Full restore";
+            case BackupManagerMonitor.LOG_EVENT_ID_NO_NEXT_RESTORE_TARGET ->
+                    "No next restore target";
+            case BackupManagerMonitor.LOG_EVENT_ID_KV_AGENT_ERROR -> "KV agent error";
+            case BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_RESTORE_FINISHED ->
+                    "Package restore finished";
+            case BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_ERROR_KV_RESTORE ->
+                    "Transport error KV restore";
+            case BackupManagerMonitor.LOG_EVENT_ID_NO_FEEDER_THREAD -> "No feeder thread";
+            case BackupManagerMonitor.LOG_EVENT_ID_FULL_AGENT_ERROR -> "Full agent error";
+            case BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_ERROR_FULL_RESTORE ->
+                    "Transport error full restore";
+            case BackupManagerMonitor.LOG_EVENT_ID_RESTORE_COMPLETE -> "Restore complete";
+            case BackupManagerMonitor.LOG_EVENT_ID_START_PACKAGE_RESTORE ->
+                    "Start package restore";
+            case BackupManagerMonitor.LOG_EVENT_ID_AGENT_FAILURE ->
+                    "Agent failure";
             default -> "Unknown log event ID: " + code;
         };
         return id;
-- 
GitLab


From 3f8ff83497f421bef686a71b65c4afcf28ee9695 Mon Sep 17 00:00:00 2001
From: beatricemarch <beatricemarch@google.com>
Date: Thu, 31 Aug 2023 12:53:16 +0000
Subject: [PATCH 39/95] Add a 2.5 MB size limit to the text file storing BMM
 Events.

Test: atest CtsBackupHostTestCases, GtsBackupHostTestCases
atest BackupManagerMonitorDumpsysUtilsTest, UserBackupManagerServiceTest
Bug: 297163567

Change-Id: Ia1fdc0b465b960337f5e5c626460e305d96f4eb2
---
 .../backup/UserBackupManagerService.java      | 10 +++++
 .../BackupManagerMonitorDumpsysUtils.java     | 25 ++++++++++-
 .../BackupManagerMonitorDumpsysUtilsTest.java | 42 +++++++++++++++++++
 3 files changed, 76 insertions(+), 1 deletion(-)

diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
index 2d80af92eea5..38af61b16ef3 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
@@ -486,6 +486,13 @@ public class UserBackupManagerService {
             File baseStateDir,
             File dataDir,
             TransportManager transportManager) {
+        // check if we are past the retention period for BMM Events,
+        // if so delete expired events and do not print them to dumpsys
+        BackupManagerMonitorDumpsysUtils backupManagerMonitorDumpsysUtils =
+                new BackupManagerMonitorDumpsysUtils();
+        if (backupManagerMonitorDumpsysUtils.deleteExpiredBMMEvents() && DEBUG){
+            Slog.d(TAG, "BMM Events recorded for dumpsys have expired");
+        }
         return new UserBackupManagerService(
                 userId,
                 context,
@@ -4197,6 +4204,9 @@ public class UserBackupManagerService {
             // We have not recorded BMMEvents yet.
             pw.println("NO BACKUP MANAGER MONITOR EVENTS");
             return;
+        } else if (bm.isFileLargerThanSizeLimit(events)){
+            pw.println("BACKUP MANAGER MONITOR EVENTS FILE OVER SIZE LIMIT - "
+                    + "future events will not be recorded");
         }
         pw.println("START OF BACKUP MANAGER MONITOR EVENTS");
         try (BufferedReader reader = new BufferedReader(new FileReader(events))) {
diff --git a/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtils.java b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtils.java
index 16da846a093a..4b0d5a4928b6 100644
--- a/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtils.java
@@ -57,11 +57,17 @@ public class BackupManagerMonitorDumpsysUtils {
     // Retention period of 60 days (in millisec) for the BMM Events.
     // After tha time has passed the text file containing the BMM events will be emptied
     private static final long LOGS_RETENTION_PERIOD_MILLISEC = 60 * TimeUnit.DAYS.toMillis(1);
+    // Size limit for the text file containing the BMM events
+    private static final long BMM_FILE_SIZE_LIMIT_BYTES = 25 * 1024 * 1000; // 2.5 MB
+
     // We cache the value of IsAfterRetentionPeriod() to avoid unnecessary disk I/O
     // mIsAfterRetentionPeriodCached tracks if we have cached the value of IsAfterRetentionPeriod()
     private boolean mIsAfterRetentionPeriodCached = false;
-    // The cahched value of IsAfterRetentionPeriod()
+    // The cached value of IsAfterRetentionPeriod()
     private boolean mIsAfterRetentionPeriod;
+    // If isFileLargerThanSizeLimit(bmmEvents)  returns true we cache the value to avoid
+    // unnecessary disk I/O
+   private boolean mIsFileLargerThanSizeLimit = false;
 
     /**
      * Parses the BackupManagerMonitor bundle for a RESTORE event in a series of strings that
@@ -116,6 +122,11 @@ public class BackupManagerMonitorDumpsysUtils {
             recordSetUpTimestamp();
         }
 
+        if(isFileLargerThanSizeLimit(bmmEvents)){
+            // Do not write more events if the file is over size limit
+            return;
+        }
+
         try (FileOutputStream out = new FileOutputStream(bmmEvents, /*append*/ true);
              PrintWriter pw = new FastPrintWriter(out);) {
 
@@ -192,6 +203,13 @@ public class BackupManagerMonitorDumpsysUtils {
         return fname;
     }
 
+    public boolean isFileLargerThanSizeLimit(File events){
+        if (!mIsFileLargerThanSizeLimit) {
+            mIsFileLargerThanSizeLimit = events.length() > getBMMEventsFileSizeLimit();
+        }
+        return mIsFileLargerThanSizeLimit;
+    }
+
     private String timestamp() {
         long currentTime = System.currentTimeMillis();
         Date date = new Date(currentTime);
@@ -402,6 +420,11 @@ public class BackupManagerMonitorDumpsysUtils {
         return LOGS_RETENTION_PERIOD_MILLISEC;
     }
 
+    @VisibleForTesting
+    long getBMMEventsFileSizeLimit(){
+        return BMM_FILE_SIZE_LIMIT_BYTES;
+    }
+
     /**
      * Delete the BMM Events file after the retention period has passed.
      *
diff --git a/services/tests/mockingservicestests/src/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtilsTest.java b/services/tests/mockingservicestests/src/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtilsTest.java
index a45b17e2e3c5..dcd531751cd7 100644
--- a/services/tests/mockingservicestests/src/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtilsTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtilsTest.java
@@ -26,11 +26,14 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 import java.io.File;
+import java.io.FileWriter;
 
 public class BackupManagerMonitorDumpsysUtilsTest {
     private long mRetentionPeriod;
     private File mTempBMMEventsFile;
     private File mTempSetUpDateFile;
+
+    private long mSizeLimit;
     private TestBackupManagerMonitorDumpsysUtils mBackupManagerMonitorDumpsysUtils;
     @Rule
     public TemporaryFolder tmp = new TemporaryFolder();
@@ -38,6 +41,7 @@ public class BackupManagerMonitorDumpsysUtilsTest {
     @Before
     public void setUp() throws Exception {
         mRetentionPeriod = 30 * 60 * 1000;
+        mSizeLimit = 25 * 1024 * 1000;
         mTempBMMEventsFile = tmp.newFile("testbmmevents.txt");
         mTempSetUpDateFile = tmp.newFile("testSetUpDate.txt");
         mBackupManagerMonitorDumpsysUtils = new TestBackupManagerMonitorDumpsysUtils();
@@ -110,6 +114,33 @@ public class BackupManagerMonitorDumpsysUtilsTest {
     }
 
 
+    @Test
+    public void parseBackupManagerMonitorEventForDumpsys_fileOverSizeLimit_doNotRecordEvents()
+            throws Exception {
+        assertTrue(mTempBMMEventsFile.length() == 0);
+        Bundle event = createRestoreBMMEvent();
+        mBackupManagerMonitorDumpsysUtils.parseBackupManagerMonitorRestoreEventForDumpsys(event);
+        long fileSizeBefore = mTempBMMEventsFile.length();
+
+        mBackupManagerMonitorDumpsysUtils.setTestSizeLimit(0);
+        mBackupManagerMonitorDumpsysUtils.parseBackupManagerMonitorRestoreEventForDumpsys(event);
+        long fileSizeAfter = mTempBMMEventsFile.length();
+        assertTrue(mBackupManagerMonitorDumpsysUtils.isFileLargerThanSizeLimit(mTempBMMEventsFile));
+        assertTrue(fileSizeBefore == fileSizeAfter);
+    }
+
+    @Test
+    public void parseBackupManagerMonitorEventForDumpsys_fileUnderSizeLimit_recordEvents()
+            throws Exception {
+        assertTrue(mTempBMMEventsFile.length() == 0);
+        Bundle event = createRestoreBMMEvent();
+
+        mBackupManagerMonitorDumpsysUtils.setTestSizeLimit(25 * 1024 * 1000);
+        mBackupManagerMonitorDumpsysUtils.parseBackupManagerMonitorRestoreEventForDumpsys(event);
+        assertFalse(mBackupManagerMonitorDumpsysUtils.isFileLargerThanSizeLimit(mTempBMMEventsFile));
+        assertTrue(mTempBMMEventsFile.length() != 0);
+    }
+
     @Test
     public void deleteExpiredBackupManagerMonitorEvent_eventsAreExpired_deleteEventsAndReturnTrue()
             throws Exception {
@@ -238,15 +269,20 @@ public class BackupManagerMonitorDumpsysUtilsTest {
             extends BackupManagerMonitorDumpsysUtils {
 
         private long testRetentionPeriod;
+        private long testSizeLimit;
 
         TestBackupManagerMonitorDumpsysUtils() {
             super();
             this.testRetentionPeriod = mRetentionPeriod;
+            this.testSizeLimit = mSizeLimit;
         }
 
         public void setTestRetentionPeriod(long testRetentionPeriod) {
             this.testRetentionPeriod = testRetentionPeriod;
         }
+        public void setTestSizeLimit(long testSizeLimit) {
+            this.testSizeLimit = testSizeLimit;
+        }
 
         @Override
         public File getBMMEventsFile() {
@@ -263,5 +299,11 @@ public class BackupManagerMonitorDumpsysUtilsTest {
             return testRetentionPeriod;
         }
 
+        @Override
+        long getBMMEventsFileSizeLimit(){
+            return testSizeLimit;
+        }
+
+
     }
 }
-- 
GitLab


From 0322c45426d574e24bc852b7da2b76506d7f4e54 Mon Sep 17 00:00:00 2001
From: dakinola <dakinola@google.com>
Date: Tue, 19 Sep 2023 16:08:19 +0000
Subject: [PATCH 40/95] Remove record_task_content feature flag check in
 ContentRecorder

Feature flag check is no longer needed and leads to scenarios where partial screen sharing fails despite the device being capable of it, so its better to remove this extra point of failure.

Bug: 301273469
Test: manually built & smoke test
Test: atest WmTests:ContentRecorderTests
Change-Id: Iad8926c377a2cae7c1b08f874926d09cc46274a4
---
 data/etc/services.core.protolog.json          |  6 ---
 .../android/server/wm/ContentRecorder.java    | 14 ------
 .../server/wm/ContentRecorderTests.java       | 47 -------------------
 3 files changed, 67 deletions(-)

diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index e46ba9abc9a6..ad0ead78f492 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -3973,12 +3973,6 @@
       "group": "WM_ERROR",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
-    "1563836923": {
-      "message": "Content Recording: Unable to record task since feature is disabled %d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecorder.java"
-    },
     "1577579529": {
       "message": "win=%s destroySurfaces: appStopped=%b win.mWindowRemovalAllowed=%b win.mRemoveOnExit=%b",
       "level": "ERROR",
diff --git a/services/core/java/com/android/server/wm/ContentRecorder.java b/services/core/java/com/android/server/wm/ContentRecorder.java
index b499dad53326..06448d0c1e84 100644
--- a/services/core/java/com/android/server/wm/ContentRecorder.java
+++ b/services/core/java/com/android/server/wm/ContentRecorder.java
@@ -33,7 +33,6 @@ import android.media.projection.IMediaProjectionManager;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.provider.DeviceConfig;
 import android.view.ContentRecordingSession;
 import android.view.ContentRecordingSession.RecordContent;
 import android.view.Display;
@@ -47,11 +46,6 @@ import com.android.internal.protolog.common.ProtoLog;
  */
 final class ContentRecorder implements WindowContainerListener {
 
-    /**
-     * The key for accessing the device config that controls if task recording is supported.
-     */
-    @VisibleForTesting static final String KEY_RECORD_TASK_FEATURE = "record_task_content";
-
     /**
      * The display content this class is handling recording for.
      */
@@ -411,14 +405,6 @@ final class ContentRecorder implements WindowContainerListener {
                 // TODO(206461622) Migrate to using the RootDisplayArea
                 return dc;
             case RECORD_CONTENT_TASK:
-                if (!DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
-                        KEY_RECORD_TASK_FEATURE, false)) {
-                    handleStartRecordingFailed();
-                    ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
-                            "Content Recording: Unable to record task since feature is disabled %d",
-                            mDisplayContent.getDisplayId());
-                    return null;
-                }
                 // Given the WindowToken of the region to record, retrieve the associated
                 // SurfaceControl.
                 if (tokenToRecord == null) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
index 3d3531e92abe..d2eb1cc0222b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
@@ -31,7 +31,6 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
-import static com.android.server.wm.ContentRecorder.KEY_RECORD_TASK_FEATURE;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -51,25 +50,21 @@ import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.IBinder;
 import android.platform.test.annotations.Presubmit;
-import android.provider.DeviceConfig;
 import android.view.ContentRecordingSession;
 import android.view.DisplayInfo;
 import android.view.Gravity;
 import android.view.SurfaceControl;
 
-import androidx.annotation.NonNull;
 import androidx.test.filters.SmallTest;
 
 import com.android.server.wm.ContentRecorder.MediaProjectionManagerWrapper;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-import java.util.concurrent.CountDownLatch;
 
 /**
  * Tests for the {@link ContentRecorder} class.
@@ -93,9 +88,6 @@ public class ContentRecorderTests extends WindowTestsBase {
     private ContentRecorder mContentRecorder;
     @Mock private MediaProjectionManagerWrapper mMediaProjectionManagerWrapper;
     private SurfaceControl mRecordedSurface;
-    // Handle feature flag.
-    private ConfigListener mConfigListener;
-    private CountDownLatch mLatch;
 
     @Before public void setUp() {
         MockitoAnnotations.initMocks(this);
@@ -133,23 +125,11 @@ public class ContentRecorderTests extends WindowTestsBase {
         mWaitingDisplaySession.setVirtualDisplayId(displayId);
         mWaitingDisplaySession.setWaitingForConsent(true);
 
-        mConfigListener = new ConfigListener();
-        DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
-                mContext.getMainExecutor(), mConfigListener);
-        mLatch = new CountDownLatch(1);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER, KEY_RECORD_TASK_FEATURE,
-                "true", true);
-
         // Skip unnecessary operations of relayout.
         spyOn(mWm.mWindowPlacerLocked);
         doNothing().when(mWm.mWindowPlacerLocked).performSurfacePlacement(anyBoolean());
     }
 
-    @After
-    public void teardown() {
-        DeviceConfig.removeOnPropertiesChangedListener(mConfigListener);
-    }
-
     @Test
     public void testIsCurrentlyRecording() {
         assertThat(mContentRecorder.isCurrentlyRecording()).isFalse();
@@ -183,24 +163,6 @@ public class ContentRecorderTests extends WindowTestsBase {
         assertThat(mContentRecorder.isCurrentlyRecording()).isFalse();
     }
 
-    @Test
-    public void testUpdateRecording_task_featureDisabled() {
-        mLatch = new CountDownLatch(1);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER, KEY_RECORD_TASK_FEATURE,
-                "false", false);
-        mContentRecorder.setContentRecordingSession(mTaskSession);
-        mContentRecorder.updateRecording();
-        assertThat(mContentRecorder.isCurrentlyRecording()).isFalse();
-    }
-
-    @Test
-    public void testUpdateRecording_task_featureEnabled() {
-        // Feature already enabled; don't need to again.
-        mContentRecorder.setContentRecordingSession(mTaskSession);
-        mContentRecorder.updateRecording();
-        assertThat(mContentRecorder.isCurrentlyRecording()).isTrue();
-    }
-
     @Test
     public void testUpdateRecording_task_nullToken() {
         ContentRecordingSession session = mTaskSession;
@@ -703,13 +665,4 @@ public class ContentRecorderTests extends WindowTestsBase {
                 anyInt());
         return mirroredSurface;
     }
-
-    private class ConfigListener implements DeviceConfig.OnPropertiesChangedListener {
-        @Override
-        public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) {
-            if (mLatch != null && properties.getKeyset().contains(KEY_RECORD_TASK_FEATURE)) {
-                mLatch.countDown();
-            }
-        }
-    }
 }
-- 
GitLab


From 08718c4e74e36d26051da65c80f4d61707d943c1 Mon Sep 17 00:00:00 2001
From: lpeter <lpeter@google.com>
Date: Thu, 21 Sep 2023 10:47:58 +0000
Subject: [PATCH 41/95] Fix the command problem "adb shell pm list permissions
 -f"

After using the command adb shell pm list permissions -f,
it will break the list when dealing with a malformed APEX.

We think that we should not break the list. We should print
the error and continue to list all permissions.

Bug: 300268371
Bug: 301211657
Test: Manual by using adb shell pm list permissions -f
Change-Id: I8322900989385d360e3d0a7be66a334ffc1091cf
---
 .../com/android/server/pm/PackageManagerShellCommand.java     | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index e1f010f62232..b6f4aeea3704 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -4126,6 +4126,10 @@ class PackageManagerShellCommand extends ShellCommand {
                 PackageManager.MATCH_DISABLED_COMPONENTS
                         | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS
                         | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, 0);
+        if (ai == null) {
+            Slog.e(TAG, "Failed to get ApplicationInfo for package name(" + pii.packageName + ").");
+            return null;
+        }
         AssetManager am = new AssetManager();
         am.addAssetPath(ai.publicSourceDir);
         res = new Resources(am, null, null);
-- 
GitLab


From 5f101dcfef687891672834b61067387b4545e5d7 Mon Sep 17 00:00:00 2001
From: Pablo Gamito <pablogamito@google.com>
Date: Thu, 21 Sep 2023 16:15:59 +0000
Subject: [PATCH 42/95] Disable rotation check to enter overview

If we are on the launcher on a phone we are likely to be in portrait which will fail the switchToOverview action.

Bug: 300065764
Test: atest com.android.wm.shell.flicker.service.splitscreen.flicker.EnterSplitScreenFromOverviewGesturalNavLandscape
Change-Id: I9542409f2c28b1996ad958d8c572e53ca7ea2537
---
 .../src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt
index d53adc08d2ff..6b3cfaf33c05 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt
@@ -151,8 +151,11 @@ object SplitScreenUtils {
             }
             snapshots[0].click()
         } else {
+            val rotationCheckEnabled = tapl.getExpectedRotationCheckEnabled()
+            tapl.setExpectedRotationCheckEnabled(false) // disable rotation check to enter overview
             val home = tapl.workspace
                 .switchToOverview()
+            tapl.setExpectedRotationCheckEnabled(rotationCheckEnabled) // restore rotation checks
             ChangeDisplayOrientationRule.setRotation(rotation)
             home.currentTask
                 .tapMenu()
-- 
GitLab


From 45f79af128335d1fb77cf37e3e1b1ab46b4282f6 Mon Sep 17 00:00:00 2001
From: Pablo Gamito <pablogamito@google.com>
Date: Thu, 21 Sep 2023 16:27:12 +0000
Subject: [PATCH 43/95] Update expected scenario for
 DismissSplitScreenByDivider

In this case we don't seem to tag the SPLIT_SCREEN_EXIT cuj

Bug: 300260196
Test: atest com.android.wm.shell.flicker.service.splitscreen.flicker.DismissSplitScreenByDividerGesturalNavLandscape
Change-Id: I3b507f5cab638376c170255df9e93d0ca496bb06
---
 .../flicker/DismissSplitScreenByDividerGesturalNavLandscape.kt | 3 ++-
 .../flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt  | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavLandscape.kt
index 8cb25fe531b8..69499b9b488b 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavLandscape.kt
@@ -31,7 +31,8 @@ import org.junit.runner.RunWith
 class DismissSplitScreenByDividerGesturalNavLandscape :
     DismissSplitScreenByDivider(Rotation.ROTATION_90) {
 
-    @ExpectedScenarios(["SPLIT_SCREEN_EXIT"])
+    // TODO(b/300260196): Not detecting SPLIT_SCREEN_EXIT right now
+    @ExpectedScenarios(["ENTIRE_TRACE"])
     @Test
     override fun dismissSplitScreenByDivider() = super.dismissSplitScreenByDivider()
 
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt
index 2539fd50d742..bd627f4babaa 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt
@@ -31,7 +31,7 @@ import org.junit.runner.RunWith
 class DismissSplitScreenByDividerGesturalNavPortrait :
     DismissSplitScreenByDivider(Rotation.ROTATION_0) {
 
-    // TODO(b/300260196): Not detecting this scenario right now
+    // TODO(b/300260196): Not detecting SPLIT_SCREEN_EXIT right now
     @ExpectedScenarios(["ENTIRE_TRACE"])
     @Test
     override fun dismissSplitScreenByDivider() = super.dismissSplitScreenByDivider()
-- 
GitLab


From 9cd12c2a131c7cb2328f88dc8398bd1743b00672 Mon Sep 17 00:00:00 2001
From: Winson Chung <winsonc@google.com>
Date: Wed, 20 Sep 2023 05:13:56 +0000
Subject: [PATCH 44/95] Preemptively reset split reparenting flag when entering
 split

- Currently, this flag is not reset until we start the animation or when
  the stage visibilities officially change, but following a drop to
  initiate split and Shell actually receiving the transition,
  the app may launch a trampoline activity (ie. esp during create)
  which will trigger the task to be reparented back out of the
  split root (preventing split from succeeding).  Instead we preemptively
  reset this state when we know that we are about to enter split, and
  rely on the existing paths to update the flag when the split is next
  fully shown or hidden.

Bug: 292454704
Test: Drag app that launches a trampoline into split
Change-Id: I17c8b7e92dfbf18a1bd1a9ca64b7ee7f3097f233
---
 .../com/android/wm/shell/splitscreen/StageCoordinator.java   | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index 94fa485efd5c..8efdfd6ca1e1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -1551,6 +1551,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
             @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition,
             boolean resizeAnim) {
         onSplitScreenEnter();
+        // Preemptively reset the reparenting behavior if we know that we are entering, as starting
+        // split tasks with activity trampolines can inadvertently trigger the task to be
+        // reparented out of the split root mid-launch
+        wct.setReparentLeafTaskIfRelaunch(mRootTaskInfo.token,
+                false /* setReparentLeafTaskIfRelaunch */);
         if (isSplitActive()) {
             prepareBringSplit(wct, taskInfo, startPosition, resizeAnim);
         } else {
-- 
GitLab


From 1c60dd442598c234a4c49c8f95888c962afdb6e2 Mon Sep 17 00:00:00 2001
From: Xin Guan <guanxin@google.com>
Date: Wed, 13 Sep 2023 13:40:22 -0500
Subject: [PATCH 45/95] Add trace support to usagestats

Adding a few tracing point to the code paths related to
the user unlocking.

Bug: 300285947
Test: verify it's available in the trace
Change-Id: I2a1368c4022f174c115f0269ad6c100caa5e5817
---
 .../server/usage/UsageStatsService.java       | 25 ++++++++++++++++---
 .../server/usage/UserUsageStatsService.java   |  2 +-
 2 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 7db32a9f1ad9..f93c70388129 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -85,6 +85,7 @@ import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.SystemProperties;
+import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
@@ -452,7 +453,9 @@ public class UsageStatsService extends SystemService implements
 
             // Read pending reported events from disk and merge them with those stored in memory
             final LinkedList<Event> pendingEvents = new LinkedList<>();
+            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "loadPendingEvents");
             loadPendingEventsLocked(userId, pendingEvents);
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
             final LinkedList<Event> eventsInMem = mReportedEvents.get(userId);
             if (eventsInMem != null) {
                 pendingEvents.addAll(eventsInMem);
@@ -967,6 +970,12 @@ public class UsageStatsService extends SystemService implements
             mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget();
             return;
         }
+
+        if (Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
+            final String traceTag = "usageStatsQueueEvent(" + userId + ") #"
+                    + UserUsageStatsService.eventToString(event.mEventType);
+            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, traceTag);
+        }
         synchronized (mLock) {
             LinkedList<Event> events = mReportedEvents.get(userId);
             if (events == null) {
@@ -980,6 +989,7 @@ public class UsageStatsService extends SystemService implements
                 mHandler.sendEmptyMessageDelayed(MSG_FLUSH_TO_DISK, FLUSH_INTERVAL);
             }
         }
+        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
     }
 
     /**
@@ -1944,17 +1954,23 @@ public class UsageStatsService extends SystemService implements
                 case MSG_FLUSH_TO_DISK:
                     flushToDisk();
                     break;
-                case MSG_UNLOCKED_USER:
+                case MSG_UNLOCKED_USER: {
+                    final int userId = msg.arg1;
                     try {
-                        onUserUnlocked(msg.arg1);
+                        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER,
+                                "usageStatsHandleUserUnlocked(" + userId + ")");
+                        onUserUnlocked(userId);
                     } catch (Exception e) {
-                        if (mUserManager.isUserUnlocked(msg.arg1)) {
+                        if (mUserManager.isUserUnlocked(userId)) {
                             throw e; // rethrow exception - user is unlocked
                         } else {
                             Slog.w(TAG, "Attempted to unlock stopped or removed user " + msg.arg1);
                         }
+                    } finally {
+                        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
                     }
                     break;
+                }
                 case MSG_REMOVE_USER:
                     onUserRemoved(msg.arg1);
                     break;
@@ -1986,7 +2002,10 @@ public class UsageStatsService extends SystemService implements
                     break;
                 case MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK: {
                     final int userId = msg.arg1;
+                    Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER,
+                            "usageStatsHandleEstimatedLaunchTimesOnUser(" + userId + ")");
                     handleEstimatedLaunchTimesOnUserUnlock(userId);
+                    Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
                 }
                 break;
                 case MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED: {
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index 7d2e1a4ed86a..b5d8096deac0 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -1306,7 +1306,7 @@ class UserUsageStatsService {
         }
     }
 
-    private static String eventToString(int eventType) {
+    static String eventToString(int eventType) {
         switch (eventType) {
             case Event.NONE:
                 return "NONE";
-- 
GitLab


From bfbbe9fab73cccc37743c2f45ad547839fc836f2 Mon Sep 17 00:00:00 2001
From: Mady Mellor <madym@google.com>
Date: Wed, 20 Sep 2023 15:10:53 -0700
Subject: [PATCH 46/95] Add some tests for BubbleViewInfoTask

- Test that populating icons & inflating views work
- Test that exception loading shortcut icon doesn't doesn't crash

Test: atest BubbleViewInfoTest
Bug: 300073572
Change-Id: I0c67cf78d344334b3968f9bc03df0d72e34a1082
---
 .../wm/shell/bubbles/BubbleViewInfoTask.java  |   8 +-
 .../wm/shell/bubbles/BubbleViewInfoTest.kt    | 201 ++++++++++++++++++
 2 files changed, 205 insertions(+), 4 deletions(-)
 create mode 100644 libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleViewInfoTest.kt

diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java
index 66e69300f45f..03a63f5c8d6f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java
@@ -155,14 +155,14 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
         Bitmap rawBadgeBitmap;
 
         // Only populated when showing in taskbar
-        BubbleBarExpandedView bubbleBarExpandedView;
+        @Nullable BubbleBarExpandedView bubbleBarExpandedView;
 
         // These are only populated when not showing in taskbar
-        BadgedImageView imageView;
-        BubbleExpandedView expandedView;
+        @Nullable BadgedImageView imageView;
+        @Nullable BubbleExpandedView expandedView;
         int dotColor;
         Path dotPath;
-        Bubble.FlyoutMessage flyoutMessage;
+        @Nullable Bubble.FlyoutMessage flyoutMessage;
         Bitmap bubbleBitmap;
         Bitmap badgeBitmap;
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleViewInfoTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleViewInfoTest.kt
new file mode 100644
index 000000000000..f58332198696
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleViewInfoTest.kt
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2023 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.wm.shell.bubbles
+
+import android.content.pm.LauncherApps
+import android.content.pm.ShortcutInfo
+import android.content.res.Resources
+import android.graphics.Color
+import android.os.Handler
+import android.os.UserManager
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
+import android.view.IWindowManager
+import android.view.WindowManager
+import androidx.test.filters.SmallTest
+import com.android.internal.R
+import com.android.internal.statusbar.IStatusBarService
+import com.android.launcher3.icons.BubbleIconFactory
+import com.android.wm.shell.ShellTaskOrganizer
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.TestShellExecutor
+import com.android.wm.shell.WindowManagerShellWrapper
+import com.android.wm.shell.bubbles.bar.BubbleBarLayerView
+import com.android.wm.shell.bubbles.properties.BubbleProperties
+import com.android.wm.shell.common.DisplayController
+import com.android.wm.shell.common.FloatingContentCoordinator
+import com.android.wm.shell.common.ShellExecutor
+import com.android.wm.shell.common.SyncTransactionQueue
+import com.android.wm.shell.common.TaskStackListenerImpl
+import com.android.wm.shell.sysui.ShellCommandHandler
+import com.android.wm.shell.sysui.ShellController
+import com.android.wm.shell.sysui.ShellInit
+import com.android.wm.shell.taskview.TaskViewTransitions
+import com.android.wm.shell.transition.Transitions
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doThrow
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
+
+/**
+ * Tests for loading / inflating views & icons for a bubble.
+ */
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@RunWithLooper(setAsMainLooper = true)
+class BubbleViewInfoTest : ShellTestCase() {
+
+    private lateinit var metadataFlagListener: Bubbles.BubbleMetadataFlagListener
+    private lateinit var iconFactory: BubbleIconFactory
+    private lateinit var bubble: Bubble
+
+    private lateinit var bubbleController: BubbleController
+    private lateinit var mainExecutor: ShellExecutor
+    private lateinit var bubbleStackView: BubbleStackView
+    private lateinit var bubbleBarLayerView: BubbleBarLayerView
+
+    @Before
+    fun setup() {
+        metadataFlagListener = Bubbles.BubbleMetadataFlagListener {}
+        iconFactory = BubbleIconFactory(context,
+                60,
+                30,
+                Color.RED,
+                mContext.resources.getDimensionPixelSize(
+                        R.dimen.importance_ring_stroke_width))
+
+        mainExecutor = TestShellExecutor()
+        val windowManager = context.getSystemService(WindowManager::class.java)
+        val shellInit = ShellInit(mainExecutor)
+        val shellCommandHandler = ShellCommandHandler()
+        val shellController = ShellController(context, shellInit, shellCommandHandler,
+                mainExecutor)
+        val bubblePositioner = BubblePositioner(context, windowManager)
+        val bubbleData = BubbleData(context, mock<BubbleLogger>(), bubblePositioner,
+                BubbleEducationController(context), mainExecutor)
+        val surfaceSynchronizer = { obj: Runnable -> obj.run() }
+
+        bubbleController = BubbleController(
+                context,
+                shellInit,
+                shellCommandHandler,
+                shellController,
+                bubbleData,
+                surfaceSynchronizer,
+                FloatingContentCoordinator(),
+                mock<BubbleDataRepository>(),
+                mock<IStatusBarService>(),
+                windowManager,
+                WindowManagerShellWrapper(mainExecutor),
+                mock<UserManager>(),
+                mock<LauncherApps>(),
+                mock<BubbleLogger>(),
+                mock<TaskStackListenerImpl>(),
+                ShellTaskOrganizer(mainExecutor),
+                bubblePositioner,
+                mock<DisplayController>(),
+                null,
+                null,
+                mainExecutor,
+                mock<Handler>(),
+                mock<ShellExecutor>(),
+                mock<TaskViewTransitions>(),
+                mock<Transitions>(),
+                mock<SyncTransactionQueue>(),
+                mock<IWindowManager>(),
+                mock<BubbleProperties>())
+
+        bubbleStackView = BubbleStackView(context, bubbleController, bubbleData,
+                surfaceSynchronizer, FloatingContentCoordinator(), mainExecutor)
+        bubbleBarLayerView = BubbleBarLayerView(context, bubbleController)
+    }
+
+    @Test
+    fun testPopulate() {
+        bubble = createBubbleWithShortcut()
+        val info = BubbleViewInfoTask.BubbleViewInfo.populate(context,
+                bubbleController, bubbleStackView, iconFactory, bubble, false /* skipInflation */)
+        assertThat(info!!).isNotNull()
+
+        assertThat(info.imageView).isNotNull()
+        assertThat(info.expandedView).isNotNull()
+        assertThat(info.bubbleBarExpandedView).isNull()
+
+        assertThat(info.shortcutInfo).isNotNull()
+        assertThat(info.appName).isNotEmpty()
+        assertThat(info.rawBadgeBitmap).isNotNull()
+        assertThat(info.dotPath).isNotNull()
+        assertThat(info.bubbleBitmap).isNotNull()
+        assertThat(info.badgeBitmap).isNotNull()
+    }
+
+    @Test
+    fun testPopulateForBubbleBar() {
+        bubble = createBubbleWithShortcut()
+        val info = BubbleViewInfoTask.BubbleViewInfo.populateForBubbleBar(context,
+                bubbleController, bubbleBarLayerView, iconFactory, bubble,
+                false /* skipInflation */)
+        assertThat(info!!).isNotNull()
+
+        assertThat(info.imageView).isNull()
+        assertThat(info.expandedView).isNull()
+        assertThat(info.bubbleBarExpandedView).isNotNull()
+
+        assertThat(info.shortcutInfo).isNotNull()
+        assertThat(info.appName).isNotEmpty()
+        assertThat(info.rawBadgeBitmap).isNotNull()
+        assertThat(info.dotPath).isNotNull()
+        assertThat(info.bubbleBitmap).isNotNull()
+        assertThat(info.badgeBitmap).isNotNull()
+    }
+
+    @Test
+    fun testPopulate_invalidShortcutIcon() {
+        bubble = createBubbleWithShortcut()
+
+        // This eventually calls down to load the shortcut icon from the app, simulate an
+        // exception here if the app has an issue loading the shortcut icon; we default to
+        // the app icon in that case / none of the icons will be null.
+        val mockIconFactory = mock<BubbleIconFactory>()
+        whenever(mockIconFactory.getBubbleDrawable(eq(context), eq(bubble.shortcutInfo),
+                any())).doThrow(RuntimeException())
+
+        val info = BubbleViewInfoTask.BubbleViewInfo.populateForBubbleBar(context,
+                bubbleController, bubbleBarLayerView, iconFactory, bubble,
+                true /* skipInflation */)
+        assertThat(info).isNotNull()
+
+        assertThat(info?.shortcutInfo).isNotNull()
+        assertThat(info?.appName).isNotEmpty()
+        assertThat(info?.rawBadgeBitmap).isNotNull()
+        assertThat(info?.dotPath).isNotNull()
+        assertThat(info?.bubbleBitmap).isNotNull()
+        assertThat(info?.badgeBitmap).isNotNull()
+    }
+
+    private fun createBubbleWithShortcut(): Bubble {
+        val shortcutInfo = ShortcutInfo.Builder(mContext, "mockShortcutId").build()
+        return Bubble("mockKey", shortcutInfo, 1000, Resources.ID_NULL,
+                "mockTitle", 0 /* taskId */, "mockLocus", true /* isDismissible */,
+                mainExecutor, metadataFlagListener)
+    }
+}
\ No newline at end of file
-- 
GitLab


From b3e07d83c8f533fe5efc956f7eca34d8bc3b164a Mon Sep 17 00:00:00 2001
From: Andy Yu <chingtangyu@google.com>
Date: Wed, 20 Sep 2023 16:13:59 -0700
Subject: [PATCH 47/95] Remove FrameRate Enum to allow all possible frame rate
 values

Previously we restricted the frame rate override of game intervention to
a certain set of values, which is now not scalable and not compatible to
all devices.

In addition, SurfaceFlinger is able to choose the proper
frame rate to run at, there is no longer a need to impose such
restriction to available frame rates.

Bug: 296988493
Bug: 253178812

Tested on Pixel 7 Pro userdebug
Test: atest GameManagerServiceTests
Test: atest GameManagerTests
Test: atest CtsFrameRateOverrideTestCases

Change-Id: I2e2e18a9ec0d1a2fd505464a1297e9b7f9874d1c
---
 .../src/android/app/GameManagerTests.java     | 10 ---
 .../server/app/GameManagerService.java        | 67 ++++---------------
 .../server/app/GameManagerShellCommand.java   | 10 +--
 3 files changed, 18 insertions(+), 69 deletions(-)

diff --git a/core/tests/GameManagerTests/src/android/app/GameManagerTests.java b/core/tests/GameManagerTests/src/android/app/GameManagerTests.java
index fac3a0ecdec2..d34c91ee48ba 100644
--- a/core/tests/GameManagerTests/src/android/app/GameManagerTests.java
+++ b/core/tests/GameManagerTests/src/android/app/GameManagerTests.java
@@ -86,16 +86,6 @@ public final class GameManagerTests {
         GameModeInfo gameModeInfo = mGameManager.getGameModeInfo(mPackageName);
         assertNotNull(gameModeInfo);
         assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_CUSTOM));
-        GameModeConfiguration unsupportedFpsConfig =
-                new GameModeConfiguration.Builder().setFpsOverride(
-                        70).setScalingFactor(0.5f).build();
-        mGameManager.updateCustomGameModeConfiguration(mPackageName, unsupportedFpsConfig);
-        gameModeInfo = mGameManager.getGameModeInfo(mPackageName);
-        assertNotNull(gameModeInfo);
-        // TODO(b/243448953): update to non-zero FPS when matching is implemented
-        assertEquals(new GameModeConfiguration.Builder().setFpsOverride(
-                        GameModeConfiguration.FPS_OVERRIDE_NONE).setScalingFactor(0.5f).build(),
-                gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_CUSTOM));
 
         GameModeConfiguration supportedFpsConfig =
                 new GameModeConfiguration.Builder().setFpsOverride(
diff --git a/services/core/java/com/android/server/app/GameManagerService.java b/services/core/java/com/android/server/app/GameManagerService.java
index 80d14a21cc7e..5dd86e7abfc0 100644
--- a/services/core/java/com/android/server/app/GameManagerService.java
+++ b/services/core/java/com/android/server/app/GameManagerService.java
@@ -417,59 +417,6 @@ public final class GameManagerService extends IGameManagerService.Stub {
         }
     }
 
-    public enum FrameRate {
-        FPS_DEFAULT(0),
-        FPS_30(30),
-        FPS_36(36),
-        FPS_40(40),
-        FPS_45(45),
-        FPS_48(48),
-        FPS_60(60),
-        FPS_72(72),
-        FPS_90(90),
-        FPS_120(120),
-        FPS_144(144),
-        FPS_INVALID(-1);
-
-        public final int fps;
-
-        FrameRate(int fps) {
-            this.fps = fps;
-        }
-    }
-
-    // Turn the raw string to the corresponding fps int.
-    // Return 0 when disabling, -1 for invalid fps.
-    static int getFpsInt(String raw) {
-        // TODO(b/243448953): make sure this translates to proper values based on current display
-        switch (raw) {
-            case "30":
-                return FrameRate.FPS_30.fps;
-            case "36":
-                return FrameRate.FPS_36.fps;
-            case "40":
-                return FrameRate.FPS_40.fps;
-            case "45":
-                return FrameRate.FPS_45.fps;
-            case "48":
-                return FrameRate.FPS_48.fps;
-            case "60":
-                return FrameRate.FPS_60.fps;
-            case "72":
-                return FrameRate.FPS_72.fps;
-            case "90":
-                return FrameRate.FPS_90.fps;
-            case "120":
-                return FrameRate.FPS_120.fps;
-            case "144":
-                return FrameRate.FPS_144.fps;
-            case "disable":
-            case "":
-                return FrameRate.FPS_DEFAULT.fps;
-        }
-        return FrameRate.FPS_INVALID.fps;
-    }
-
     /**
      * Called by games to communicate the current state to the platform.
      *
@@ -717,7 +664,12 @@ public final class GameManagerService extends IGameManagerService.Stub {
             }
 
             public synchronized int getFps() {
-                return GameManagerService.getFpsInt(mFps);
+                try {
+                    final int fpsInt = Integer.parseInt(mFps);
+                    return fpsInt;
+                } catch (NumberFormatException e) {
+                    return 0;
+                }
             }
 
             synchronized String getFpsStr() {
@@ -757,7 +709,12 @@ public final class GameManagerService extends IGameManagerService.Stub {
             }
 
             android.app.GameModeConfiguration toPublicGameModeConfig() {
-                int fpsOverride = getFpsInt(mFps);
+                int fpsOverride;
+                try {
+                    fpsOverride = Integer.parseInt(mFps);
+                } catch (NumberFormatException e) {
+                    fpsOverride = 0;
+                }
                 // TODO(b/243448953): match to proper value in case of display change?
                 fpsOverride = fpsOverride > 0 ? fpsOverride
                         : android.app.GameModeConfiguration.FPS_OVERRIDE_NONE;
diff --git a/services/core/java/com/android/server/app/GameManagerShellCommand.java b/services/core/java/com/android/server/app/GameManagerShellCommand.java
index 00ff489ee0ff..ab57c4fe837e 100644
--- a/services/core/java/com/android/server/app/GameManagerShellCommand.java
+++ b/services/core/java/com/android/server/app/GameManagerShellCommand.java
@@ -241,8 +241,10 @@ public class GameManagerShellCommand extends ShellCommand {
                 case "--fps":
                     if (fpsStr == null) {
                         fpsStr = getNextArgRequired();
-                        if (fpsStr != null && GameManagerService.getFpsInt(fpsStr) == -1) {
-                            pw.println("Invalid frame rate '" + fpsStr + "'");
+                        try {
+                            Integer.parseInt(fpsStr);
+                        } catch (NumberFormatException e) {
+                            pw.println("Invalid frame rate: '" + fpsStr + "'");
                             return -1;
                         }
                     } else {
@@ -375,8 +377,8 @@ public class GameManagerShellCommand extends ShellCommand {
         pw.println("      --downscale [0.3|0.35|0.4|0.45|0.5|0.55|0.6|0.65");
         pw.println("                  |0.7|0.75|0.8|0.85|0.9|disable]: Set app to run at the");
         pw.println("                                                   specified scaling ratio.");
-        pw.println("      --fps [30|45|60|90|120|disable]: Set app to run at the specified fps,");
-        pw.println("                                       if supported.");
+        pw.println("      --fps: Integer value to set app to run at the specified fps,");
+        pw.println("             if supported. 0 to disable.");
         pw.println("  reset [--mode [2|3|performance|battery] --user <USER_ID>] <PACKAGE_NAME>");
         pw.println("      Resets the game mode of the app to device configuration.");
         pw.println("      This should only be used to reset any override to non custom game mode");
-- 
GitLab


From e3eb9a1a51a1eceb046cfd808f23b4d72b86270c Mon Sep 17 00:00:00 2001
From: Gustavo Pagani <gustavopagani@google.com>
Date: Thu, 21 Sep 2023 18:08:22 +0000
Subject: [PATCH 48/95] Add single provider and single account screens

Bug: 301206470
Test: N/A - feature not fully implemented yet

Change-Id: I25f54e2bcb8228b46a8ca7a89f63753c639a26ef
---
 .../CredentialManager/horologist/Android.bp   |   1 +
 .../compose/layout/BelowTimeTextPreview.kt    |  26 ++++
 .../horologist/compose/material/Button.kt     | 143 ++++++++++++++++++
 .../horologist/compose/material/Icon.kt       | 129 ++++++++++++++++
 .../horologist/compose/material/util/A11y.kt  |  28 ++++
 .../horologist/compose/tools/WearPreview.kt   |  25 +++
 packages/CredentialManager/shared/Android.bp  |   1 +
 .../credentialmanager/ui/IntentParser.kt      |  20 ++-
 .../ui/factory/CredentialEntryFactory.kt      |  25 +++
 .../credentialmanager/ui/ktx/IntentKtx.kt     |  17 ++-
 .../credentialmanager/ui/model/Request.kt     |  10 +-
 packages/CredentialManager/wear/Android.bp    |   1 +
 .../wear/res/drawable/passkey_icon.xml        |  21 +++
 .../wear/res/values/strings.xml               |  10 ++
 .../ui/CredentialSelectorActivity.kt          |   2 +-
 .../ui/CredentialSelectorViewModel.kt         |  21 ++-
 .../ui/components/AccountRow.kt               |  63 ++++++++
 .../ui/components/DialogButtonsRow.kt         |  71 +++++++++
 .../ui/components/PasswordRow.kt              |  62 ++++++++
 .../ui/components/SignInHeader.kt             |  83 ++++++++++
 .../CredentialSelectorUiStateGetMapper.kt     |  51 +++++++
 .../ui/model/PasskeyUiModel.kt                |  22 +++
 .../ui/model/PasswordUiModel.kt               |  19 +++
 .../ui/screens/SingleAccountScreen.kt         |  83 ++++++++++
 .../ui/screens/SinglePasskeyScreen.kt         |  82 ++++++++++
 .../ui/screens/SinglePasswordScreen.kt        |  79 ++++++++++
 26 files changed, 1085 insertions(+), 10 deletions(-)
 create mode 100644 packages/CredentialManager/horologist/src/com/google/android/horologist/compose/layout/BelowTimeTextPreview.kt
 create mode 100644 packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/Button.kt
 create mode 100644 packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/Icon.kt
 create mode 100644 packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/util/A11y.kt
 create mode 100644 packages/CredentialManager/horologist/src/com/google/android/horologist/compose/tools/WearPreview.kt
 create mode 100644 packages/CredentialManager/shared/src/com/android/credentialmanager/ui/factory/CredentialEntryFactory.kt
 create mode 100644 packages/CredentialManager/wear/res/drawable/passkey_icon.xml
 create mode 100644 packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/AccountRow.kt
 create mode 100644 packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/DialogButtonsRow.kt
 create mode 100644 packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/PasswordRow.kt
 create mode 100644 packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/SignInHeader.kt
 create mode 100644 packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mapper/CredentialSelectorUiStateGetMapper.kt
 create mode 100644 packages/CredentialManager/wear/src/com/android/credentialmanager/ui/model/PasskeyUiModel.kt
 create mode 100644 packages/CredentialManager/wear/src/com/android/credentialmanager/ui/model/PasswordUiModel.kt
 create mode 100644 packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/SingleAccountScreen.kt
 create mode 100644 packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/SinglePasskeyScreen.kt
 create mode 100644 packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/SinglePasswordScreen.kt

diff --git a/packages/CredentialManager/horologist/Android.bp b/packages/CredentialManager/horologist/Android.bp
index bb324bb8350d..bb255bdb1306 100644
--- a/packages/CredentialManager/horologist/Android.bp
+++ b/packages/CredentialManager/horologist/Android.bp
@@ -16,6 +16,7 @@ android_library {
         "androidx.compose.foundation_foundation",
         "androidx.compose.runtime_runtime",
         "androidx.compose.ui_ui",
+        "androidx.compose.ui_ui-tooling",
         "androidx.navigation_navigation-compose",
         "androidx.lifecycle_lifecycle-extensions",
         "androidx.lifecycle_lifecycle-runtime-ktx",
diff --git a/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/layout/BelowTimeTextPreview.kt b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/layout/BelowTimeTextPreview.kt
new file mode 100644
index 000000000000..e6025fc0911f
--- /dev/null
+++ b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/layout/BelowTimeTextPreview.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright 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
+ *
+ *      https://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.horologist.compose.layout
+
+import androidx.compose.runtime.Composable
+import com.google.android.horologist.annotations.ExperimentalHorologistApi
+
+@OptIn(ExperimentalHorologistApi::class)
+@Composable
+public fun belowTimeTextPreview(): ScalingLazyColumnState {
+    return ScalingLazyColumnDefaults.belowTimeText().create()
+}
diff --git a/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/Button.kt b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/Button.kt
new file mode 100644
index 000000000000..57e0c106b5f0
--- /dev/null
+++ b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/Button.kt
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2023 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
+ *
+ *      https://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.horologist.compose.material
+
+import androidx.annotation.DrawableRes
+import androidx.compose.foundation.layout.size
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.unit.Dp
+import androidx.wear.compose.material.Button
+import androidx.wear.compose.material.ButtonColors
+import androidx.wear.compose.material.ButtonDefaults
+import androidx.wear.compose.material.ButtonDefaults.DefaultButtonSize
+import androidx.wear.compose.material.ButtonDefaults.DefaultIconSize
+import androidx.wear.compose.material.ButtonDefaults.LargeButtonSize
+import androidx.wear.compose.material.ButtonDefaults.LargeIconSize
+import androidx.wear.compose.material.ButtonDefaults.SmallButtonSize
+import androidx.wear.compose.material.ButtonDefaults.SmallIconSize
+import com.google.android.horologist.annotations.ExperimentalHorologistApi
+
+/**
+ * This component is an alternative to [Button], providing the following:
+ * - a convenient way of providing an icon and choosing its size from a range of sizes recommended
+ * by the Wear guidelines;
+ */
+@ExperimentalHorologistApi
+@Composable
+public fun Button(
+    imageVector: ImageVector,
+    contentDescription: String,
+    onClick: () -> Unit,
+    modifier: Modifier = Modifier,
+    colors: ButtonColors = ButtonDefaults.primaryButtonColors(),
+    buttonSize: ButtonSize = ButtonSize.Default,
+    iconRtlMode: IconRtlMode = IconRtlMode.Default,
+    enabled: Boolean = true,
+) {
+    Button(
+        icon = imageVector,
+        contentDescription = contentDescription,
+        onClick = onClick,
+        modifier = modifier,
+        colors = colors,
+        buttonSize = buttonSize,
+        iconRtlMode = iconRtlMode,
+        enabled = enabled,
+    )
+}
+
+/**
+ * This component is an alternative to [Button], providing the following:
+ * - a convenient way of providing an icon and choosing its size from a range of sizes recommended
+ * by the Wear guidelines;
+ */
+@ExperimentalHorologistApi
+@Composable
+public fun Button(
+    @DrawableRes id: Int,
+    contentDescription: String,
+    onClick: () -> Unit,
+    modifier: Modifier = Modifier,
+    colors: ButtonColors = ButtonDefaults.primaryButtonColors(),
+    buttonSize: ButtonSize = ButtonSize.Default,
+    iconRtlMode: IconRtlMode = IconRtlMode.Default,
+    enabled: Boolean = true,
+) {
+    Button(
+        icon = id,
+        contentDescription = contentDescription,
+        onClick = onClick,
+        modifier = modifier,
+        colors = colors,
+        buttonSize = buttonSize,
+        iconRtlMode = iconRtlMode,
+        enabled = enabled,
+    )
+}
+
+@OptIn(ExperimentalHorologistApi::class)
+@Composable
+internal fun Button(
+    icon: Any,
+    contentDescription: String,
+    onClick: () -> Unit,
+    modifier: Modifier = Modifier,
+    colors: ButtonColors = ButtonDefaults.primaryButtonColors(),
+    buttonSize: ButtonSize = ButtonSize.Default,
+    iconRtlMode: IconRtlMode = IconRtlMode.Default,
+    enabled: Boolean = true,
+) {
+    Button(
+        onClick = onClick,
+        modifier = modifier.size(buttonSize.tapTargetSize),
+        enabled = enabled,
+        colors = colors,
+    ) {
+        val iconModifier = Modifier
+            .size(buttonSize.iconSize)
+            .align(Alignment.Center)
+
+        Icon(
+            icon = icon,
+            contentDescription = contentDescription,
+            modifier = iconModifier,
+            rtlMode = iconRtlMode,
+        )
+    }
+}
+
+@ExperimentalHorologistApi
+public sealed class ButtonSize(
+    public val iconSize: Dp,
+    public val tapTargetSize: Dp,
+) {
+    public object Default :
+        ButtonSize(iconSize = DefaultIconSize, tapTargetSize = DefaultButtonSize)
+
+    public object Large : ButtonSize(iconSize = LargeIconSize, tapTargetSize = LargeButtonSize)
+    public object Small : ButtonSize(iconSize = SmallIconSize, tapTargetSize = SmallButtonSize)
+
+    /**
+     * Custom sizes should follow the [accessibility principles and guidance for touch targets](https://developer.android.com/training/wearables/accessibility#set-minimum).
+     */
+    public data class Custom(val customIconSize: Dp, val customTapTargetSize: Dp) :
+        ButtonSize(iconSize = customIconSize, tapTargetSize = customTapTargetSize)
+}
+
diff --git a/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/Icon.kt b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/Icon.kt
new file mode 100644
index 000000000000..74e54c0ba479
--- /dev/null
+++ b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/Icon.kt
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2023 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
+ *
+ *      https://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.horologist.compose.material
+
+import androidx.annotation.DrawableRes
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.scale
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.platform.LocalLayoutDirection
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.unit.LayoutDirection
+import androidx.wear.compose.material.Icon
+import androidx.wear.compose.material.LocalContentAlpha
+import androidx.wear.compose.material.LocalContentColor
+import com.google.android.horologist.annotations.ExperimentalHorologistApi
+
+/**
+ * This component is an alternative to [Icon], providing the following:
+ * - a convenient way of setting the icon to be mirrored in RTL mode;
+ */
+@ExperimentalHorologistApi
+@Composable
+public fun Icon(
+    imageVector: ImageVector,
+    contentDescription: String?,
+    modifier: Modifier = Modifier,
+    tint: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current),
+    rtlMode: IconRtlMode = IconRtlMode.Default,
+) {
+    val shouldMirror =
+        rtlMode == IconRtlMode.Mirrored && LocalLayoutDirection.current == LayoutDirection.Rtl
+    Icon(
+        modifier = modifier.scale(
+            scaleX = if (shouldMirror) -1f else 1f,
+            scaleY = 1f,
+        ),
+        imageVector = imageVector,
+        contentDescription = contentDescription,
+        tint = tint,
+    )
+}
+
+/**
+ * This component is an alternative to [Icon], providing the following:
+ * - a convenient way of setting the icon to be mirrored in RTL mode;
+ */
+@ExperimentalHorologistApi
+@Composable
+public fun Icon(
+    @DrawableRes id: Int,
+    contentDescription: String?,
+    modifier: Modifier = Modifier,
+    tint: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current),
+    rtlMode: IconRtlMode = IconRtlMode.Default,
+) {
+    val shouldMirror =
+        rtlMode == IconRtlMode.Mirrored && LocalLayoutDirection.current == LayoutDirection.Rtl
+
+    Icon(
+        painter = painterResource(id = id),
+        contentDescription = contentDescription,
+        modifier = modifier.scale(
+            scaleX = if (shouldMirror) -1f else 1f,
+            scaleY = 1f,
+        ),
+        tint = tint,
+    )
+}
+
+@OptIn(ExperimentalHorologistApi::class)
+@Composable
+internal fun Icon(
+    icon: Any,
+    contentDescription: String?,
+    modifier: Modifier = Modifier,
+    tint: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current),
+    rtlMode: IconRtlMode = IconRtlMode.Default,
+) {
+    val shouldMirror =
+        rtlMode == IconRtlMode.Mirrored && LocalLayoutDirection.current == LayoutDirection.Rtl
+
+    val iconModifier = modifier.scale(
+        scaleX = if (shouldMirror) -1f else 1f,
+        scaleY = 1f,
+    )
+    when (icon) {
+        is ImageVector -> {
+            Icon(
+                imageVector = icon,
+                modifier = iconModifier,
+                contentDescription = contentDescription,
+                tint = tint,
+            )
+        }
+
+        is Int -> {
+            Icon(
+                painter = painterResource(id = icon),
+                contentDescription = contentDescription,
+                modifier = iconModifier,
+                tint = tint,
+            )
+        }
+
+        else -> throw IllegalArgumentException("Type not supported.")
+    }
+}
+
+@ExperimentalHorologistApi
+public enum class IconRtlMode {
+    Default,
+    Mirrored,
+}
diff --git a/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/util/A11y.kt b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/util/A11y.kt
new file mode 100644
index 000000000000..39de2e142edc
--- /dev/null
+++ b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/util/A11y.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright 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
+ *
+ *      https://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.horologist.compose.material.util
+
+import com.google.android.horologist.annotations.ExperimentalHorologistApi
+
+/**
+ * Make explicit that a conscious decision was made to mark an element as decorative, so it does not
+ * have associated actions or state.
+ *
+ * https://developer.android.com/jetpack/compose/accessibility#describe-visual
+ */
+@ExperimentalHorologistApi
+public val DECORATIVE_ELEMENT_CONTENT_DESCRIPTION: String? = null
diff --git a/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/tools/WearPreview.kt b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/tools/WearPreview.kt
new file mode 100644
index 000000000000..0bfceeea916c
--- /dev/null
+++ b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/tools/WearPreview.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright 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
+ *
+ *      https://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.horologist.compose.tools
+
+import androidx.compose.ui.tooling.preview.Preview
+
+@Preview(
+    backgroundColor = 0xff000000,
+    showBackground = true,
+)
+public annotation class WearPreview
diff --git a/packages/CredentialManager/shared/Android.bp b/packages/CredentialManager/shared/Android.bp
index ae4281e5561c..38d98a9d47f7 100644
--- a/packages/CredentialManager/shared/Android.bp
+++ b/packages/CredentialManager/shared/Android.bp
@@ -14,5 +14,6 @@ android_library {
     static_libs: [
         "androidx.core_core-ktx",
         "androidx.credentials_credentials",
+        "guava",
     ],
 }
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/IntentParser.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/IntentParser.kt
index 6627af526dee..43d8fb3228d5 100644
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/IntentParser.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/IntentParser.kt
@@ -17,11 +17,15 @@
 package com.android.credentialmanager.ui
 
 import android.content.Intent
+import android.credentials.ui.GetCredentialProviderData
 import android.credentials.ui.RequestInfo
 import com.android.credentialmanager.ui.ktx.cancelUiRequest
+import com.android.credentialmanager.ui.ktx.getCredentialProviderDataList
 import com.android.credentialmanager.ui.ktx.requestInfo
 import com.android.credentialmanager.ui.mapper.toCancel
 import com.android.credentialmanager.ui.model.Request
+import com.google.common.collect.ImmutableList
+import com.google.common.collect.ImmutableMap
 
 fun Intent.parse(): Request {
     cancelUiRequest?.let {
@@ -32,9 +36,23 @@ fun Intent.parse(): Request {
         RequestInfo.TYPE_CREATE -> {
             Request.Create
         }
+
         RequestInfo.TYPE_GET -> {
-            Request.Get
+            Request.Get(
+                providers = ImmutableMap.copyOf(
+                    getCredentialProviderDataList.associateBy { it.providerFlattenedComponentName }
+                ),
+                entries = ImmutableList.copyOf(
+                    getCredentialProviderDataList.map { providerData ->
+                        check(providerData is GetCredentialProviderData) {
+                            "Invalid provider data type for GetCredentialRequest"
+                        }
+                        providerData
+                    }.flatMap { it.credentialEntries }
+                )
+            )
         }
+
         else -> {
             throw IllegalStateException("Unrecognized request type: ${requestInfo?.type}")
         }
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/factory/CredentialEntryFactory.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/factory/CredentialEntryFactory.kt
new file mode 100644
index 000000000000..f01fdedc9137
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/factory/CredentialEntryFactory.kt
@@ -0,0 +1,25 @@
+package com.android.credentialmanager.ui.factory
+
+import android.app.slice.Slice
+import android.credentials.Credential
+import androidx.credentials.PublicKeyCredential
+import androidx.credentials.provider.CredentialEntry
+import androidx.credentials.provider.CustomCredentialEntry
+import androidx.credentials.provider.PasswordCredentialEntry
+import androidx.credentials.provider.PublicKeyCredentialEntry
+
+fun fromSlice(slice: Slice): CredentialEntry? =
+    try {
+        when (slice.spec?.type) {
+            Credential.TYPE_PASSWORD_CREDENTIAL -> PasswordCredentialEntry.fromSlice(slice)!!
+
+            PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL ->
+                PublicKeyCredentialEntry.fromSlice(slice)!!
+
+            else -> CustomCredentialEntry.fromSlice(slice)!!
+        }
+    } catch (e: Exception) {
+        // Try CustomCredentialEntry.fromSlice one last time in case the cause was a failed
+        // password / passkey parsing attempt.
+        CustomCredentialEntry.fromSlice(slice)
+    }
\ No newline at end of file
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/ktx/IntentKtx.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/ktx/IntentKtx.kt
index a646851bf570..b9895a0ab52a 100644
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/ktx/IntentKtx.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/ktx/IntentKtx.kt
@@ -18,6 +18,9 @@ package com.android.credentialmanager.ui.ktx
 
 import android.content.Intent
 import android.credentials.ui.CancelUiRequest
+import android.credentials.ui.CreateCredentialProviderData
+import android.credentials.ui.GetCredentialProviderData
+import android.credentials.ui.ProviderData
 import android.credentials.ui.RequestInfo
 
 val Intent.cancelUiRequest: CancelUiRequest?
@@ -30,4 +33,16 @@ val Intent.requestInfo: RequestInfo?
     get() = this.extras?.getParcelable(
         RequestInfo.EXTRA_REQUEST_INFO,
         RequestInfo::class.java
-    )
\ No newline at end of file
+    )
+
+val Intent.getCredentialProviderDataList: List<ProviderData>
+    get() = this.extras?.getParcelableArrayList(
+        ProviderData.EXTRA_ENABLED_PROVIDER_DATA_LIST,
+        GetCredentialProviderData::class.java
+    ) ?: emptyList()
+
+val Intent.createCredentialProviderDataList: List<ProviderData>
+    get() = this.extras?.getParcelableArrayList(
+        ProviderData.EXTRA_ENABLED_PROVIDER_DATA_LIST,
+        CreateCredentialProviderData::class.java
+    ) ?: emptyList()
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/model/Request.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/model/Request.kt
index 3d835bebc06b..cffa2b2586b1 100644
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/model/Request.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/model/Request.kt
@@ -16,6 +16,11 @@
 
 package com.android.credentialmanager.ui.model
 
+import android.credentials.ui.Entry
+import android.credentials.ui.ProviderData
+import com.google.common.collect.ImmutableList
+import com.google.common.collect.ImmutableMap
+
 /**
  * Represents the request made by the CredentialManager API.
  */
@@ -25,7 +30,10 @@ sealed class Request {
         val appPackageName: String?
     ) : Request()
 
-    data object Get : Request()
+    data class Get(
+        val providers: ImmutableMap<String, ProviderData>,
+        val entries: ImmutableList<Entry>,
+    ) : Request()
 
     data object Create : Request()
 }
diff --git a/packages/CredentialManager/wear/Android.bp b/packages/CredentialManager/wear/Android.bp
index 36340fac1760..c0dff168969d 100644
--- a/packages/CredentialManager/wear/Android.bp
+++ b/packages/CredentialManager/wear/Android.bp
@@ -32,6 +32,7 @@ android_app {
         "androidx.compose.material_material-icons-extended",
         "androidx.compose.runtime_runtime",
         "androidx.compose.ui_ui",
+        "androidx.compose.ui_ui-tooling",
         "androidx.core_core-ktx",
         "androidx.lifecycle_lifecycle-extensions",
         "androidx.lifecycle_lifecycle-livedata",
diff --git a/packages/CredentialManager/wear/res/drawable/passkey_icon.xml b/packages/CredentialManager/wear/res/drawable/passkey_icon.xml
new file mode 100644
index 000000000000..be366bf2a255
--- /dev/null
+++ b/packages/CredentialManager/wear/res/drawable/passkey_icon.xml
@@ -0,0 +1,21 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:pathData="M23,10.5H17V13.5H23V10.5Z"
+        android:fillColor="#188038"/>
+    <path
+        android:pathData="M6.5,17.5C3.5,17.5 1,15 1,12C1,9 3.5,6.5 6.5,6.5C9.5,6.5 12,9 12,12C12,15 9.5,17.5 6.5,17.5ZM6.5,9.5C5.1,9.5 4,10.6 4,12C4,13.4 5.1,14.5 6.5,14.5C7.9,14.5 9,13.4 9,12C9,10.6 7.9,9.5 6.5,9.5Z"
+        android:fillColor="#4285F4"/>
+    <path
+        android:pathData="M21,13.5H19H17V16.5H19V15.5C19,14.9 19.4,14.5 20,14.5C20.6,14.5 21,14.9 21,15.5V16.5H23V13.5H21Z"
+        android:fillColor="#34A853"/>
+    <path
+        android:pathData="M11.8,10.5H8.5C8.8,10.9 9,11.4 9,12C9,12.6 8.8,13.1 8.5,13.5H11.8C11.9,13 12,12.5 12,12C12,11.5 11.9,11 11.8,10.5Z"
+        android:fillColor="#EA4335"/>
+    <path
+        android:pathData="M17,10.5H11.8C11.9,11 12,11.5 12,12C12,12.5 11.9,13 11.8,13.5H17V10.5Z"
+        android:fillColor="#FBBC04"/>
+</vector>
diff --git a/packages/CredentialManager/wear/res/values/strings.xml b/packages/CredentialManager/wear/res/values/strings.xml
index 10ea9186ca85..109644f46b10 100644
--- a/packages/CredentialManager/wear/res/values/strings.xml
+++ b/packages/CredentialManager/wear/res/values/strings.xml
@@ -18,4 +18,14 @@
   <!-- The name of this application. Credential Manager is a service that centralizes and provides
   access to a user's credentials used to sign in to various apps. [CHAR LIMIT=80] -->
   <string name="app_name">Credential Manager</string>
+  <!-- Title of a screen prompting if the user would like to use their saved passkey.
+  [CHAR LIMIT=80] -->
+  <string name="use_passkey_title">Use passkey?</string>
+  <!-- Title of a screen prompting if the user would like to use their saved password.
+  [CHAR LIMIT=80] -->
+  <string name="use_password_title">Use password?</string>
+  <!-- Content description for the cancel button of a screen. [CHAR LIMIT=NONE] -->
+  <string name="dialog_cancel_button_cd">Cancel</string>
+  <!-- Content description for the OK button of a screen. [CHAR LIMIT=NONE] -->
+  <string name="dialog_ok_button_cd">OK</string>
 </resources>
\ No newline at end of file
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorActivity.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorActivity.kt
index 2c0575547162..a93fa81bb85b 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorActivity.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorActivity.kt
@@ -47,7 +47,7 @@ class CredentialSelectorActivity : ComponentActivity() {
                             // to the user.
                         }
 
-                        CredentialSelectorUiState.Get -> {
+                        is CredentialSelectorUiState.Get -> {
                             // TODO: b/301206470 - Implement get flow
                             setContent {
                                 MaterialTheme {
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorViewModel.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorViewModel.kt
index e46fcae78f6a..c61bb2e0f949 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorViewModel.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorViewModel.kt
@@ -23,6 +23,9 @@ import androidx.lifecycle.AndroidViewModel
 import androidx.lifecycle.viewModelScope
 import com.android.credentialmanager.ui.ktx.appLabel
 import com.android.credentialmanager.ui.ktx.requestInfo
+import com.android.credentialmanager.ui.mapper.toGet
+import com.android.credentialmanager.ui.model.PasskeyUiModel
+import com.android.credentialmanager.ui.model.PasswordUiModel
 import com.android.credentialmanager.ui.model.Request
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
@@ -62,8 +65,8 @@ class CredentialSelectorViewModel(
                         _uiState.value = CredentialSelectorUiState.Create
                     }
 
-                    Request.Get -> {
-                        _uiState.value = CredentialSelectorUiState.Get
+                    is Request.Get -> {
+                        _uiState.value = request.toGet()
                     }
                 }
             }
@@ -103,9 +106,15 @@ class CredentialSelectorViewModel(
 }
 
 sealed class CredentialSelectorUiState {
-    object Idle : CredentialSelectorUiState()
-    object Get : CredentialSelectorUiState()
-    object Create : CredentialSelectorUiState()
+    data object Idle : CredentialSelectorUiState()
+    sealed class Get : CredentialSelectorUiState() {
+        data class SingleProviderSinglePasskey(val passkeyUiModel: PasskeyUiModel) : Get()
+        data class SingleProviderSinglePassword(val passwordUiModel: PasswordUiModel) : Get()
+
+        // TODO: b/301206470 add the remaining states
+    }
+
+    data object Create : CredentialSelectorUiState()
     data class Cancel(val appName: String) : CredentialSelectorUiState()
-    object Finish : CredentialSelectorUiState()
+    data object Finish : CredentialSelectorUiState()
 }
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/AccountRow.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/AccountRow.kt
new file mode 100644
index 000000000000..c20ee0c22ad6
--- /dev/null
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/AccountRow.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2023 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
+ *
+ *      https://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.credentialmanager.ui.components
+
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.padding
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.unit.dp
+import androidx.wear.compose.material.MaterialTheme
+import androidx.wear.compose.material.Text
+import com.google.android.horologist.compose.tools.WearPreview
+
+@Composable
+fun AccountRow(
+    name: String,
+    email: String,
+    modifier: Modifier = Modifier,
+) {
+    Column(modifier = modifier, horizontalAlignment = Alignment.CenterHorizontally) {
+        Text(
+            text = name,
+            color = Color(0xFFE6FF7B),
+            overflow = TextOverflow.Ellipsis,
+            maxLines = 1,
+            style = MaterialTheme.typography.title2
+        )
+        Text(
+            text = email,
+            modifier = Modifier.padding(top = 7.dp),
+            color = Color(0xFFCAC5BC),
+            overflow = TextOverflow.Ellipsis,
+            maxLines = 2,
+            style = MaterialTheme.typography.body1,
+        )
+    }
+}
+
+@WearPreview
+@Composable
+fun AccountRowPreview() {
+    AccountRow(
+        name = "Elisa Beckett",
+        email = "beckett_bakery@gmail.com",
+    )
+}
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/DialogButtonsRow.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/DialogButtonsRow.kt
new file mode 100644
index 000000000000..5cb3c1590dfd
--- /dev/null
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/DialogButtonsRow.kt
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2023 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
+ *
+ *      https://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.credentialmanager.ui.components
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Check
+import androidx.compose.material.icons.filled.Close
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import androidx.wear.compose.material.ButtonDefaults
+import com.google.android.horologist.compose.material.Button
+import com.google.android.horologist.compose.tools.WearPreview
+import com.android.credentialmanager.R
+import com.google.android.horologist.annotations.ExperimentalHorologistApi
+
+@OptIn(ExperimentalHorologistApi::class)
+@Composable
+fun DialogButtonsRow(
+    onCancelClick: () -> Unit,
+    onOKClick: () -> Unit,
+    modifier: Modifier = Modifier,
+    cancelButtonIcon: ImageVector = Icons.Default.Close,
+    okButtonIcon: ImageVector = Icons.Default.Check,
+    cancelButtonContentDescription: String = stringResource(R.string.dialog_cancel_button_cd),
+    okButtonContentDescription: String = stringResource(R.string.dialog_ok_button_cd),
+) {
+    Row(
+        modifier = modifier,
+        horizontalArrangement = Arrangement.Center,
+    ) {
+        Button(
+            imageVector = cancelButtonIcon,
+            contentDescription = cancelButtonContentDescription,
+            onClick = onCancelClick,
+            colors = ButtonDefaults.secondaryButtonColors(),
+        )
+        Button(
+            imageVector = okButtonIcon,
+            contentDescription = okButtonContentDescription,
+            onClick = onOKClick,
+            modifier = Modifier.padding(start = 20.dp)
+        )
+    }
+}
+
+@WearPreview
+@Composable
+fun DialogButtonsRowPreview() {
+    DialogButtonsRow(onCancelClick = {}, onOKClick = {})
+}
+
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/PasswordRow.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/PasswordRow.kt
new file mode 100644
index 000000000000..97900b723bc3
--- /dev/null
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/PasswordRow.kt
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2023 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
+ *
+ *      https://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.credentialmanager.ui.components
+
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.padding
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.unit.dp
+import androidx.wear.compose.material.MaterialTheme
+import androidx.wear.compose.material.Text
+import com.google.android.horologist.compose.tools.WearPreview
+
+@Composable
+fun PasswordRow(
+    email: String,
+    modifier: Modifier = Modifier,
+) {
+    Column(modifier = modifier, horizontalAlignment = Alignment.CenterHorizontally) {
+        Text(
+            text = email,
+            color = Color(0xFFE6FF7B),
+            overflow = TextOverflow.Ellipsis,
+            maxLines = 2,
+            style = MaterialTheme.typography.title2
+        )
+        Text(
+            text = "••••••••••••••",
+            modifier = Modifier.padding(top = 7.dp),
+            color = Color(0xFFCAC5BC),
+            overflow = TextOverflow.Ellipsis,
+            maxLines = 1,
+            style = MaterialTheme.typography.body1,
+        )
+    }
+}
+
+@WearPreview
+@Composable
+fun PasswordRowPreview() {
+    PasswordRow(
+        email = "beckett_bakery@gmail.com",
+    )
+}
+
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/SignInHeader.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/SignInHeader.kt
new file mode 100644
index 000000000000..956c56b2c7b1
--- /dev/null
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/SignInHeader.kt
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2023 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
+ *
+ *      https://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.credentialmanager.ui.components
+
+import androidx.annotation.DrawableRes
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.ColumnScope
+import androidx.compose.foundation.layout.padding
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import androidx.wear.compose.material.MaterialTheme
+import androidx.wear.compose.material.Text
+import com.android.credentialmanager.R
+import com.google.android.horologist.annotations.ExperimentalHorologistApi
+import com.google.android.horologist.compose.material.Icon
+import com.google.android.horologist.compose.material.util.DECORATIVE_ELEMENT_CONTENT_DESCRIPTION
+import com.google.android.horologist.compose.tools.WearPreview
+
+@OptIn(ExperimentalHorologistApi::class)
+@Composable
+fun SignInHeader(
+    @DrawableRes icon: Int,
+    title: String,
+    modifier: Modifier = Modifier,
+) {
+    SignInHeader(
+        iconContent = {
+            Icon(
+                id = icon,
+                contentDescription = DECORATIVE_ELEMENT_CONTENT_DESCRIPTION
+            )
+        },
+        title = title,
+        modifier = modifier,
+    )
+}
+
+@Composable
+fun SignInHeader(
+    iconContent: @Composable ColumnScope.() -> Unit,
+    title: String,
+    modifier: Modifier = Modifier,
+) {
+    Column(
+        modifier = modifier,
+        horizontalAlignment = Alignment.CenterHorizontally
+    ) {
+        iconContent()
+        Text(
+            text = title,
+            modifier = Modifier
+                .padding(top = 6.dp)
+                .padding(horizontal = 10.dp),
+            style = MaterialTheme.typography.title3
+        )
+    }
+}
+
+@WearPreview
+@Composable
+fun SignInHeaderPreview() {
+    SignInHeader(
+        icon = R.drawable.passkey_icon,
+        title = stringResource(R.string.use_passkey_title)
+    )
+}
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mapper/CredentialSelectorUiStateGetMapper.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mapper/CredentialSelectorUiStateGetMapper.kt
new file mode 100644
index 000000000000..1fe1e5596805
--- /dev/null
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mapper/CredentialSelectorUiStateGetMapper.kt
@@ -0,0 +1,51 @@
+package com.android.credentialmanager.ui.mapper
+
+import androidx.credentials.provider.CustomCredentialEntry
+import androidx.credentials.provider.PasswordCredentialEntry
+import androidx.credentials.provider.PublicKeyCredentialEntry
+import com.android.credentialmanager.ui.CredentialSelectorUiState
+import com.android.credentialmanager.ui.factory.fromSlice
+import com.android.credentialmanager.ui.model.PasswordUiModel
+import com.android.credentialmanager.ui.model.Request
+
+fun Request.Get.toGet(): CredentialSelectorUiState.Get {
+    if (this.providers.isEmpty()) {
+        throw IllegalStateException("Invalid GetCredential request with empty list of providers.")
+    }
+
+    if (this.entries.isEmpty()) {
+        throw IllegalStateException("Invalid GetCredential request with empty list of entries.")
+    }
+
+    if (this.providers.size == 1) {
+        if (this.entries.size == 1) {
+            val slice = this.entries.first().slice
+            when (val credentialEntry = fromSlice(slice)) {
+                is PasswordCredentialEntry -> {
+                    return CredentialSelectorUiState.Get.SingleProviderSinglePassword(
+                        PasswordUiModel(credentialEntry.displayName.toString())
+                    )
+                }
+
+                is PublicKeyCredentialEntry -> {
+                    TODO("b/301206470 - to be implemented")
+                }
+
+                is CustomCredentialEntry -> {
+                    TODO("b/301206470 - to be implemented")
+                }
+
+                else -> {
+                    throw IllegalStateException(
+                        "Encountered unrecognized credential entry (${slice.spec?.type}) for " +
+                            "GetCredential request with single account"
+                    )
+                }
+            }
+        } else {
+            TODO("b/301206470 - to be implemented")
+        }
+    } else {
+        TODO("b/301206470 - to be implemented")
+    }
+}
\ No newline at end of file
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/model/PasskeyUiModel.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/model/PasskeyUiModel.kt
new file mode 100644
index 000000000000..a368de27867a
--- /dev/null
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/model/PasskeyUiModel.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2023 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.0N
+ *
+ * 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.credentialmanager.ui.model
+
+data class PasskeyUiModel(
+    val name: String,
+    val email: String,
+)
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/model/PasswordUiModel.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/model/PasswordUiModel.kt
new file mode 100644
index 000000000000..514dca8244f1
--- /dev/null
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/model/PasswordUiModel.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2023 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.0N
+ *
+ * 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.credentialmanager.ui.model
+
+data class PasswordUiModel(val name: String)
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/SingleAccountScreen.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/SingleAccountScreen.kt
new file mode 100644
index 000000000000..f344ad0bd22d
--- /dev/null
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/SingleAccountScreen.kt
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2023 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
+ *
+ *      https://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.
+ */
+
+@file:OptIn(ExperimentalHorologistApi::class)
+
+package com.android.credentialmanager.ui.screens
+
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import androidx.wear.compose.foundation.lazy.ScalingLazyListScope
+import com.android.credentialmanager.R
+import com.android.credentialmanager.ui.components.AccountRow
+import com.android.credentialmanager.ui.components.DialogButtonsRow
+import com.android.credentialmanager.ui.components.SignInHeader
+import com.google.android.horologist.annotations.ExperimentalHorologistApi
+import com.google.android.horologist.compose.layout.ScalingLazyColumn
+import com.google.android.horologist.compose.layout.ScalingLazyColumnState
+import com.google.android.horologist.compose.layout.belowTimeTextPreview
+import com.google.android.horologist.compose.tools.WearPreview
+
+@Composable
+fun SingleAccountScreen(
+    headerContent: @Composable () -> Unit,
+    accountContent: @Composable () -> Unit,
+    columnState: ScalingLazyColumnState,
+    modifier: Modifier = Modifier,
+    content: ScalingLazyListScope.() -> Unit,
+) {
+    ScalingLazyColumn(
+        columnState = columnState,
+        modifier = modifier.fillMaxSize(),
+    ) {
+        item { headerContent() }
+        item { accountContent() }
+        content()
+    }
+}
+
+@WearPreview
+@Composable
+fun SingleAccountScreenPreview() {
+    SingleAccountScreen(
+        headerContent = {
+            SignInHeader(
+                icon = R.drawable.passkey_icon,
+                title = stringResource(R.string.use_passkey_title),
+            )
+        },
+        accountContent = {
+            AccountRow(
+                name = "Elisa Beckett",
+                email = "beckett_bakery@gmail.com",
+                modifier = Modifier.padding(top = 10.dp)
+            )
+        },
+        columnState = belowTimeTextPreview(),
+    ) {
+        item {
+            DialogButtonsRow(
+                onCancelClick = {},
+                onOKClick = {},
+                modifier = Modifier.padding(top = 10.dp)
+            )
+        }
+    }
+}
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/SinglePasskeyScreen.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/SinglePasskeyScreen.kt
new file mode 100644
index 000000000000..c8f871e46c83
--- /dev/null
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/SinglePasskeyScreen.kt
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2023 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
+ *
+ *      https://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.
+ */
+
+@file:OptIn(ExperimentalHorologistApi::class)
+
+package com.android.credentialmanager.ui.screens
+
+import androidx.compose.foundation.layout.padding
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import com.android.credentialmanager.R
+import com.android.credentialmanager.ui.components.AccountRow
+import com.android.credentialmanager.ui.components.DialogButtonsRow
+import com.android.credentialmanager.ui.components.SignInHeader
+import com.google.android.horologist.annotations.ExperimentalHorologistApi
+import com.google.android.horologist.compose.layout.ScalingLazyColumnState
+import com.google.android.horologist.compose.layout.belowTimeTextPreview
+import com.google.android.horologist.compose.tools.WearPreview
+
+@Composable
+fun SinglePasskeyScreen(
+    name: String,
+    email: String,
+    onCancelClick: () -> Unit,
+    onOKClick: () -> Unit,
+    columnState: ScalingLazyColumnState,
+    modifier: Modifier = Modifier,
+) {
+    SingleAccountScreen(
+        headerContent = {
+            SignInHeader(
+                icon = R.drawable.passkey_icon,
+                title = stringResource(R.string.use_passkey_title),
+            )
+        },
+        accountContent = {
+            AccountRow(
+                name = name,
+                email = email,
+                modifier = Modifier.padding(top = 10.dp),
+            )
+        },
+        columnState = columnState,
+        modifier = modifier.padding(horizontal = 10.dp)
+    ) {
+        item {
+            DialogButtonsRow(
+                onCancelClick = onCancelClick,
+                onOKClick = onOKClick,
+                modifier = Modifier.padding(top = 10.dp)
+            )
+        }
+    }
+}
+
+@WearPreview
+@Composable
+fun SinglePasskeyScreenPreview() {
+    SinglePasskeyScreen(
+        name = "Elisa Beckett",
+        email = "beckett_bakery@gmail.com",
+        onCancelClick = {},
+        onOKClick = {},
+        columnState = belowTimeTextPreview(),
+    )
+}
+
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/SinglePasswordScreen.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/SinglePasswordScreen.kt
new file mode 100644
index 000000000000..d863d3c68ceb
--- /dev/null
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/SinglePasswordScreen.kt
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2023 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
+ *
+ *      https://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.
+ */
+
+@file:OptIn(ExperimentalHorologistApi::class)
+
+package com.android.credentialmanager.ui.screens
+
+import androidx.compose.foundation.layout.padding
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import com.android.credentialmanager.R
+import com.android.credentialmanager.ui.components.DialogButtonsRow
+import com.android.credentialmanager.ui.components.PasswordRow
+import com.android.credentialmanager.ui.components.SignInHeader
+import com.google.android.horologist.annotations.ExperimentalHorologistApi
+import com.google.android.horologist.compose.layout.ScalingLazyColumnState
+import com.google.android.horologist.compose.layout.belowTimeTextPreview
+import com.google.android.horologist.compose.tools.WearPreview
+
+@Composable
+fun SinglePasswordScreen(
+    email: String,
+    onCancelClick: () -> Unit,
+    onOKClick: () -> Unit,
+    columnState: ScalingLazyColumnState,
+    modifier: Modifier = Modifier,
+) {
+    SingleAccountScreen(
+        headerContent = {
+            SignInHeader(
+                icon = R.drawable.passkey_icon,
+                title = stringResource(R.string.use_password_title),
+            )
+        },
+        accountContent = {
+            PasswordRow(
+                email = email,
+                modifier = Modifier.padding(top = 10.dp),
+            )
+        },
+        columnState = columnState,
+        modifier = modifier.padding(horizontal = 10.dp)
+    ) {
+        item {
+            DialogButtonsRow(
+                onCancelClick = onCancelClick,
+                onOKClick = onOKClick,
+                modifier = Modifier.padding(top = 10.dp)
+            )
+        }
+    }
+}
+
+@WearPreview
+@Composable
+fun SinglePasswordScreenPreview() {
+    SinglePasswordScreen(
+        email = "beckett_bakery@gmail.com",
+        onCancelClick = {},
+        onOKClick = {},
+        columnState = belowTimeTextPreview(),
+    )
+}
+
-- 
GitLab


From 301e3ae60c9a587e74187e12908c843335ba6443 Mon Sep 17 00:00:00 2001
From: Chandru S <chandruis@google.com>
Date: Wed, 20 Sep 2023 14:19:31 -0700
Subject: [PATCH 49/95] Ignore aod/dozing/off -> lockscreen transitions if the
 power manager wake up reason is not allowlisted

Fixes: 301271023
Test: atest KeyguardFaceAuthInteractorTest
Test: manually,
   1. Disable AOD
   2. Put device to sleep
   3. Plug in device without moving it or touching the screen
   4. Device should wake up and show the lockscreen
   5. Face auth should not be triggered
Change-Id: Ia9b65b4dab87afd19e233d46ee3511a8bbf4eef9
---
 .../keyguard/FaceWakeUpTriggersConfig.kt      | 13 ++++
 .../DeviceEntryFaceAuthRepository.kt          | 16 ++--
 .../SystemUIKeyguardFaceAuthInteractor.kt     | 19 +++++
 .../keyguard/shared/model/WakeSleepReason.kt  | 33 +++++++-
 .../systemui/log/FaceAuthenticationLogger.kt  | 21 ++++-
 .../DeviceEntryFaceAuthRepositoryTest.kt      | 19 +++--
 .../KeyguardFaceAuthInteractorTest.kt         | 76 +++++++++++++++++++
 7 files changed, 179 insertions(+), 18 deletions(-)

diff --git a/packages/SystemUI/src/com/android/keyguard/FaceWakeUpTriggersConfig.kt b/packages/SystemUI/src/com/android/keyguard/FaceWakeUpTriggersConfig.kt
index 788a66dcf281..5c57d4eaf7ca 100644
--- a/packages/SystemUI/src/com/android/keyguard/FaceWakeUpTriggersConfig.kt
+++ b/packages/SystemUI/src/com/android/keyguard/FaceWakeUpTriggersConfig.kt
@@ -24,6 +24,7 @@ import com.android.systemui.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.dump.DumpManager
+import com.android.systemui.keyguard.shared.model.WakeSleepReason
 import com.android.systemui.util.settings.GlobalSettings
 import java.io.PrintWriter
 import java.util.stream.Collectors
@@ -38,6 +39,7 @@ constructor(@Main resources: Resources, globalSettings: GlobalSettings, dumpMana
     private val defaultTriggerFaceAuthOnWakeUpFrom: Set<Int> =
         resources.getIntArray(R.array.config_face_auth_wake_up_triggers).toSet()
     private val triggerFaceAuthOnWakeUpFrom: Set<Int>
+    private val wakeSleepReasonsToTriggerFaceAuth: Set<WakeSleepReason>
 
     init {
         triggerFaceAuthOnWakeUpFrom =
@@ -52,6 +54,14 @@ constructor(@Main resources: Resources, globalSettings: GlobalSettings, dumpMana
             } else {
                 defaultTriggerFaceAuthOnWakeUpFrom
             }
+        wakeSleepReasonsToTriggerFaceAuth =
+            triggerFaceAuthOnWakeUpFrom
+                .map {
+                    val enumVal = WakeSleepReason.fromPowerManagerWakeReason(it)
+                    assert(enumVal != WakeSleepReason.OTHER)
+                    enumVal
+                }
+                .toSet()
         dumpManager.registerDumpable(this)
     }
 
@@ -59,6 +69,9 @@ constructor(@Main resources: Resources, globalSettings: GlobalSettings, dumpMana
         return triggerFaceAuthOnWakeUpFrom.contains(pmWakeReason)
     }
 
+    fun shouldTriggerFaceAuthOnWakeUpFrom(wakeReason: WakeSleepReason): Boolean =
+        wakeSleepReasonsToTriggerFaceAuth.contains(wakeReason)
+
     override fun dump(pw: PrintWriter, args: Array<out String>) {
         pw.println("FaceWakeUpTriggers:")
         for (pmWakeReason in triggerFaceAuthOnWakeUpFrom) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt
index 233acd90aee3..65cf0c9597d9 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt
@@ -18,7 +18,6 @@ package com.android.systemui.keyguard.data.repository
 
 import android.app.StatusBarManager
 import android.content.Context
-import android.hardware.face.FaceAuthenticateOptions
 import android.hardware.face.FaceManager
 import android.os.CancellationSignal
 import com.android.internal.logging.InstanceId
@@ -47,6 +46,7 @@ import com.android.systemui.keyguard.shared.model.FailedFaceAuthenticationStatus
 import com.android.systemui.keyguard.shared.model.HelpFaceAuthenticationStatus
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.SuccessFaceAuthenticationStatus
+import com.android.systemui.keyguard.shared.model.SysUiFaceAuthenticateOptions
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.log.FaceAuthenticationLogger
 import com.android.systemui.log.SessionTracker
@@ -578,7 +578,12 @@ constructor(
                     authCancellationSignal,
                     faceAuthCallback,
                     null,
-                    FaceAuthenticateOptions.Builder().setUserId(currentUserId).build()
+                    SysUiFaceAuthenticateOptions(
+                            currentUserId,
+                            uiEvent,
+                            wakeReason = uiEvent.extraInfo
+                        )
+                        .toFaceAuthenticateOptions()
                 )
             }
         } else if (canRunDetection.value) {
@@ -587,7 +592,7 @@ constructor(
                     uiEvent,
                     "face auth gating check is false, falling back to detection."
                 )
-                detect()
+                detect(uiEvent)
             } else {
                 faceAuthLogger.ignoredFaceAuthTrigger(
                     uiEvent = uiEvent,
@@ -602,7 +607,7 @@ constructor(
         }
     }
 
-    suspend fun detect() {
+    suspend fun detect(uiEvent: FaceAuthUiEvent) {
         if (!isDetectionSupported) {
             faceAuthLogger.detectionNotSupported(faceManager, faceManager?.sensorPropertiesInternal)
             return
@@ -619,7 +624,8 @@ constructor(
             faceManager?.detectFace(
                 checkNotNull(detectCancellationSignal),
                 detectionCallback,
-                FaceAuthenticateOptions.Builder().setUserId(currentUserId).build()
+                SysUiFaceAuthenticateOptions(currentUserId, uiEvent, uiEvent.extraInfo)
+                    .toFaceAuthenticateOptions()
             )
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt
index f0df3a2e6a6f..665e16db8abb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt
@@ -19,6 +19,7 @@ package com.android.systemui.keyguard.domain.interactor
 import android.content.Context
 import android.hardware.biometrics.BiometricFaceConstants
 import com.android.keyguard.FaceAuthUiEvent
+import com.android.keyguard.FaceWakeUpTriggersConfig
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.CoreStartable
 import com.android.systemui.R
@@ -31,8 +32,10 @@ import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository
 import com.android.systemui.keyguard.data.repository.DeviceEntryFaceAuthRepository
 import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository
+import com.android.systemui.keyguard.data.repository.KeyguardRepository
 import com.android.systemui.keyguard.shared.model.ErrorFaceAuthenticationStatus
 import com.android.systemui.keyguard.shared.model.FaceAuthenticationStatus
 import com.android.systemui.keyguard.shared.model.TransitionState
@@ -40,6 +43,7 @@ import com.android.systemui.log.FaceAuthenticationLogger
 import com.android.systemui.user.data.model.SelectionStatus
 import com.android.systemui.user.data.repository.UserRepository
 import com.android.systemui.util.kotlin.pairwise
+import com.android.systemui.util.kotlin.sample
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
@@ -75,6 +79,8 @@ constructor(
     private val deviceEntryFingerprintAuthRepository: DeviceEntryFingerprintAuthRepository,
     private val userRepository: UserRepository,
     private val facePropertyRepository: FacePropertyRepository,
+    private val keyguardRepository: KeyguardRepository,
+    private val faceWakeUpTriggersConfig: FaceWakeUpTriggersConfig,
 ) : CoreStartable, KeyguardFaceAuthInteractor {
 
     private val listeners: MutableList<FaceAuthenticationListener> = mutableListOf()
@@ -117,8 +123,21 @@ constructor(
                 keyguardTransitionInteractor.dozingToLockscreenTransition
             )
             .filter { it.transitionState == TransitionState.STARTED }
+            .sample(keyguardRepository.wakefulness)
+            .filter { wakefulnessModel ->
+                val validWakeupReason =
+                    faceWakeUpTriggersConfig.shouldTriggerFaceAuthOnWakeUpFrom(
+                        wakefulnessModel.lastWakeReason
+                    )
+                if (!validWakeupReason) {
+                    faceAuthenticationLogger.ignoredWakeupReason(wakefulnessModel.lastWakeReason)
+                }
+                validWakeupReason
+            }
             .onEach {
                 faceAuthenticationLogger.lockscreenBecameVisible(it)
+                FaceAuthUiEvent.FACE_AUTH_UPDATED_KEYGUARD_VISIBILITY_CHANGED.extraInfo =
+                    it.lastWakeReason.powerManagerWakeReason
                 runFaceAuth(
                     FaceAuthUiEvent.FACE_AUTH_UPDATED_KEYGUARD_VISIBILITY_CHANGED,
                     fallbackToDetect = true
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/WakeSleepReason.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/WakeSleepReason.kt
index c8a04fdbca52..3602be8e62a4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/WakeSleepReason.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/WakeSleepReason.kt
@@ -21,18 +21,37 @@ import android.os.PowerManager
 /** The reason we're waking up or going to sleep, such as pressing the power button. */
 enum class WakeSleepReason(
     val isTouch: Boolean,
+    @PowerManager.WakeReason val powerManagerWakeReason: Int,
 ) {
     /** The physical power button was pressed to wake up or sleep the device. */
-    POWER_BUTTON(isTouch = false),
+    POWER_BUTTON(isTouch = false, PowerManager.WAKE_REASON_POWER_BUTTON),
 
     /** The user has tapped or double tapped to wake the screen. */
-    TAP(isTouch = true),
+    TAP(isTouch = true, PowerManager.WAKE_REASON_TAP),
 
     /** The user performed some sort of gesture to wake the screen. */
-    GESTURE(isTouch = true),
+    GESTURE(isTouch = true, PowerManager.WAKE_REASON_GESTURE),
+
+    /** Waking up because a wake key other than power was pressed. */
+    KEY(isTouch = false, PowerManager.WAKE_REASON_WAKE_KEY),
+
+    /** Waking up because a wake motion was performed */
+    MOTION(isTouch = false, PowerManager.WAKE_REASON_WAKE_MOTION),
+
+    /** Waking due to the lid being opened. */
+    LID(isTouch = false, PowerManager.WAKE_REASON_LID),
+
+    /** Waking the device due to unfolding of a foldable device. */
+    UNFOLD(isTouch = false, PowerManager.WAKE_REASON_UNFOLD_DEVICE),
+
+    /** Waking up due to a user performed lift gesture. */
+    LIFT(isTouch = false, PowerManager.WAKE_REASON_LIFT),
+
+    /** Waking up due to a user interacting with a biometric. */
+    BIOMETRIC(isTouch = false, PowerManager.WAKE_REASON_BIOMETRIC),
 
     /** Something else happened to wake up or sleep the device. */
-    OTHER(isTouch = false);
+    OTHER(isTouch = false, PowerManager.WAKE_REASON_UNKNOWN);
 
     companion object {
         fun fromPowerManagerWakeReason(reason: Int): WakeSleepReason {
@@ -40,6 +59,12 @@ enum class WakeSleepReason(
                 PowerManager.WAKE_REASON_POWER_BUTTON -> POWER_BUTTON
                 PowerManager.WAKE_REASON_TAP -> TAP
                 PowerManager.WAKE_REASON_GESTURE -> GESTURE
+                PowerManager.WAKE_REASON_WAKE_KEY -> KEY
+                PowerManager.WAKE_REASON_WAKE_MOTION -> MOTION
+                PowerManager.WAKE_REASON_LID -> LID
+                PowerManager.WAKE_REASON_UNFOLD_DEVICE -> UNFOLD
+                PowerManager.WAKE_REASON_LIFT -> LIFT
+                PowerManager.WAKE_REASON_BIOMETRIC -> BIOMETRIC
                 else -> OTHER
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt b/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt
index 8143f99c4d0a..66af36a71d38 100644
--- a/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt
@@ -5,7 +5,8 @@ import android.hardware.face.FaceSensorPropertiesInternal
 import com.android.keyguard.FaceAuthUiEvent
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.keyguard.shared.model.ErrorFaceAuthenticationStatus
-import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.keyguard.shared.model.WakeSleepReason
+import com.android.systemui.keyguard.shared.model.WakefulnessModel
 import com.android.systemui.log.core.LogLevel.DEBUG
 import com.android.systemui.log.dagger.FaceAuthLog
 import com.google.errorprone.annotations.CompileTimeConstant
@@ -29,6 +30,18 @@ class FaceAuthenticationLogger
 constructor(
     @FaceAuthLog private val logBuffer: LogBuffer,
 ) {
+
+    fun ignoredWakeupReason(lastWakeReason: WakeSleepReason) {
+        logBuffer.log(
+            TAG,
+            DEBUG,
+            { str1 = "$lastWakeReason" },
+            {
+                "Ignoring off/aod/dozing -> Lockscreen transition " +
+                    "because the last wake up reason is not allow-listed: $str1"
+            }
+        )
+    }
     fun ignoredFaceAuthTrigger(uiEvent: FaceAuthUiEvent?, ignoredReason: String) {
         logBuffer.log(
             TAG,
@@ -175,12 +188,12 @@ constructor(
         logBuffer.log(TAG, DEBUG, "Triggering face auth because alternate bouncer is visible")
     }
 
-    fun lockscreenBecameVisible(transitionStep: TransitionStep?) {
+    fun lockscreenBecameVisible(wake: WakefulnessModel?) {
         logBuffer.log(
             TAG,
             DEBUG,
-            { str1 = "$transitionStep" },
-            { "Triggering face auth because lockscreen became visible due to transition: $str1" }
+            { str1 = "${wake?.lastWakeReason}" },
+            { "Triggering face auth because lockscreen became visible due to wake reason: $str1" }
         )
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
index 6b194f243b2c..3f87ee2b272a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
@@ -25,6 +25,9 @@ import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_HW_UNAVAILA
 import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT
 import android.hardware.biometrics.ComponentInfoInternal
 import android.hardware.face.FaceAuthenticateOptions
+import android.hardware.face.FaceAuthenticateOptions.AUTHENTICATE_REASON_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN
+import android.hardware.face.FaceAuthenticateOptions.AUTHENTICATE_REASON_NOTIFICATION_PANEL_CLICKED
+import android.hardware.face.FaceAuthenticateOptions.AUTHENTICATE_REASON_SWIPE_UP_ON_BOUNCER
 import android.hardware.face.FaceManager
 import android.hardware.face.FaceSensorProperties
 import android.hardware.face.FaceSensorPropertiesInternal
@@ -102,7 +105,6 @@ import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentCaptor
 import org.mockito.ArgumentMatchers.any
-import org.mockito.ArgumentMatchers.eq
 import org.mockito.Captor
 import org.mockito.Mock
 import org.mockito.Mockito.atLeastOnce
@@ -133,6 +135,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
 
     @Captor
     private lateinit var detectionCallback: ArgumentCaptor<FaceManager.FaceDetectionCallback>
+    @Captor private lateinit var faceAuthenticateOptions: ArgumentCaptor<FaceAuthenticateOptions>
     @Captor private lateinit var cancellationSignal: ArgumentCaptor<CancellationSignal>
 
     private lateinit var bypassStateChangedListener:
@@ -412,7 +415,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
             underTest = createDeviceEntryFaceAuthRepositoryImpl()
             initCollectors()
 
-            underTest.detect()
+            underTest.detect(FACE_AUTH_TRIGGERED_NOTIFICATION_PANEL_CLICKED)
             faceDetectIsCalled()
 
             detectionCallback.value.onFaceDetected(1, 1, true)
@@ -421,6 +424,8 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
             assertThat(status.sensorId).isEqualTo(1)
             assertThat(status.userId).isEqualTo(1)
             assertThat(status.isStrongBiometric).isEqualTo(true)
+            assertThat(faceAuthenticateOptions.value.authenticateReason)
+                .isEqualTo(AUTHENTICATE_REASON_NOTIFICATION_PANEL_CLICKED)
         }
 
     @Test
@@ -432,7 +437,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
             initCollectors()
             clearInvocations(faceManager)
 
-            underTest.detect()
+            underTest.detect(FACE_AUTH_TRIGGERED_NOTIFICATION_PANEL_CLICKED)
 
             verify(faceManager, never())
                 .detectFace(any(), any(), any(FaceAuthenticateOptions::class.java))
@@ -467,6 +472,8 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
 
             faceAuthenticateIsCalled()
             uiEventIsLogged(FACE_AUTH_TRIGGERED_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN)
+            assertThat(faceAuthenticateOptions.value.authenticateReason)
+                .isEqualTo(AUTHENTICATE_REASON_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN)
         }
 
     @Test
@@ -484,6 +491,8 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
 
             underTest.requestAuthenticate(FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER)
             faceAuthenticateIsCalled()
+            assertThat(faceAuthenticateOptions.value.authenticateReason)
+                .isEqualTo(AUTHENTICATE_REASON_SWIPE_UP_ON_BOUNCER)
         }
 
     @Test
@@ -1238,7 +1247,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
             .detectFace(
                 cancellationSignal.capture(),
                 detectionCallback.capture(),
-                eq(FaceAuthenticateOptions.Builder().setUserId(primaryUserId).build())
+                faceAuthenticateOptions.capture(),
             )
     }
 
@@ -1251,7 +1260,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
                 cancellationSignal.capture(),
                 authenticationCallback.capture(),
                 isNull(),
-                eq(FaceAuthenticateOptions.Builder().setUserId(primaryUserId).build())
+                faceAuthenticateOptions.capture(),
             )
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt
index 2ed9de26dfa3..0f9e4887fd78 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt
@@ -23,6 +23,7 @@ import android.os.Handler
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.keyguard.FaceAuthUiEvent
+import com.android.keyguard.FaceWakeUpTriggersConfig
 import com.android.keyguard.KeyguardSecurityModel
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.SysuiTestCase
@@ -42,17 +43,22 @@ import com.android.systemui.keyguard.DismissCallbackRegistry
 import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository
 import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFaceAuthRepository
 import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository
+import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.data.repository.FakeTrustRepository
 import com.android.systemui.keyguard.shared.model.ErrorFaceAuthenticationStatus
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.keyguard.shared.model.WakeSleepReason
+import com.android.systemui.keyguard.shared.model.WakefulnessModel
+import com.android.systemui.keyguard.shared.model.WakefulnessState
 import com.android.systemui.log.FaceAuthenticationLogger
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.user.data.model.SelectionStatus
 import com.android.systemui.user.data.repository.FakeUserRepository
+import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -83,8 +89,10 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() {
     private lateinit var facePropertyRepository: FakeFacePropertyRepository
     private lateinit var fakeDeviceEntryFingerprintAuthRepository:
         FakeDeviceEntryFingerprintAuthRepository
+    private lateinit var fakeKeyguardRepository: FakeKeyguardRepository
 
     @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
+    @Mock private lateinit var faceWakeUpTriggersConfig: FaceWakeUpTriggersConfig
 
     @Before
     fun setup() {
@@ -108,6 +116,7 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() {
         fakeUserRepository = FakeUserRepository()
         fakeUserRepository.setUserInfos(listOf(primaryUser, secondaryUser))
         facePropertyRepository = FakeFacePropertyRepository()
+        fakeKeyguardRepository = FakeKeyguardRepository()
         underTest =
             SystemUIKeyguardFaceAuthInteractor(
                 mContext,
@@ -144,6 +153,8 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() {
                 fakeDeviceEntryFingerprintAuthRepository,
                 fakeUserRepository,
                 facePropertyRepository,
+                fakeKeyguardRepository,
+                faceWakeUpTriggersConfig,
             )
     }
 
@@ -152,6 +163,18 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() {
         testScope.runTest {
             underTest.start()
 
+            fakeKeyguardRepository.setWakefulnessModel(
+                WakefulnessModel(
+                    WakefulnessState.STARTING_TO_WAKE,
+                    WakeSleepReason.LID,
+                    WakeSleepReason.LID
+                )
+            )
+            whenever(
+                    faceWakeUpTriggersConfig.shouldTriggerFaceAuthOnWakeUpFrom(WakeSleepReason.LID)
+                )
+                .thenReturn(true)
+
             keyguardTransitionRepository.sendTransitionStep(
                 TransitionStep(
                     KeyguardState.OFF,
@@ -188,6 +211,18 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() {
         testScope.runTest {
             underTest.start()
 
+            fakeKeyguardRepository.setWakefulnessModel(
+                WakefulnessModel(
+                    WakefulnessState.STARTING_TO_WAKE,
+                    WakeSleepReason.LID,
+                    WakeSleepReason.LID
+                )
+            )
+            whenever(
+                    faceWakeUpTriggersConfig.shouldTriggerFaceAuthOnWakeUpFrom(WakeSleepReason.LID)
+                )
+                .thenReturn(true)
+
             keyguardTransitionRepository.sendTransitionStep(
                 TransitionStep(
                     KeyguardState.AOD,
@@ -203,11 +238,52 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() {
                 )
         }
 
+    @Test
+    fun faceAuthIsNotRequestedWhenLockscreenBecomesVisibleDueToIgnoredWakeReasons() =
+        testScope.runTest {
+            underTest.start()
+
+            fakeKeyguardRepository.setWakefulnessModel(
+                WakefulnessModel(
+                    WakefulnessState.STARTING_TO_WAKE,
+                    WakeSleepReason.LIFT,
+                    WakeSleepReason.POWER_BUTTON
+                )
+            )
+            whenever(
+                    faceWakeUpTriggersConfig.shouldTriggerFaceAuthOnWakeUpFrom(WakeSleepReason.LIFT)
+                )
+                .thenReturn(false)
+
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(
+                    KeyguardState.DOZING,
+                    KeyguardState.LOCKSCREEN,
+                    transitionState = TransitionState.STARTED
+                )
+            )
+
+            runCurrent()
+            assertThat(faceAuthRepository.runningAuthRequest.value).isNull()
+        }
+
     @Test
     fun faceAuthIsRequestedWhenLockscreenBecomesVisibleFromDozingState() =
         testScope.runTest {
             underTest.start()
 
+            fakeKeyguardRepository.setWakefulnessModel(
+                WakefulnessModel(
+                    WakefulnessState.STARTING_TO_WAKE,
+                    WakeSleepReason.LID,
+                    WakeSleepReason.LID
+                )
+            )
+            whenever(
+                    faceWakeUpTriggersConfig.shouldTriggerFaceAuthOnWakeUpFrom(WakeSleepReason.LID)
+                )
+                .thenReturn(true)
+
             keyguardTransitionRepository.sendTransitionStep(
                 TransitionStep(
                     KeyguardState.DOZING,
-- 
GitLab


From ccfdf94b931250a90e993207b9c000f2d55b7b67 Mon Sep 17 00:00:00 2001
From: Beverly <beverlyt@google.com>
Date: Thu, 21 Sep 2023 18:20:09 +0000
Subject: [PATCH 50/95] Always allow UDFPS touches if alt bouncer is visible

QS can be mid-expansion but validly require UDFPS auth when
notifications are not allowed to be shown on the lockscreen.
When QS is in mid-expansion, we request/show the AlternateBouncer
so the user has an opportunity to use UDFPS to see their notifications.

Test: atest UdfpsControllerTest
Test: manual (don't show notifications on LS,
can still use UDFPS when requested to auth
when pulling down the shade on LS)
Fixes: 301037136

Change-Id: I5c91c4df394f8c6788077dd1ba60fe3123993d54
---
 .../systemui/biometrics/UdfpsController.java  |  4 +-
 .../biometrics/UdfpsControllerTest.java       | 47 +++++++++++++++++++
 2 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index c29f884c848d..3472a859ac82 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -562,7 +562,9 @@ public class UdfpsController implements DozeReceiver, Dumpable {
                     + mOverlay.getRequestId());
             return false;
         }
-        if (mLockscreenShadeTransitionController.getQSDragProgress() != 0f
+
+        if ((mLockscreenShadeTransitionController.getQSDragProgress() != 0f
+                && !mAlternateBouncerInteractor.isVisibleState())
                 || mPrimaryBouncerInteractor.isInTransit()) {
             return false;
         }
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 7dd88b437f17..e7fc870fab33 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -1597,6 +1597,53 @@ public class UdfpsControllerTest extends SysuiTestCase {
                 anyBoolean());
     }
 
+
+    @Test
+    public void onTouch_withNewTouchDetection_qsDrag_processesTouchWhenAlternateBouncerVisible()
+            throws RemoteException {
+        final NormalizedTouchData touchData = new NormalizedTouchData(0, 0f, 0f, 0f, 0f, 0f, 0L,
+                0L);
+        final TouchProcessorResult processorResultMove =
+                new TouchProcessorResult.ProcessedTouch(InteractionEvent.DOWN,
+                        1 /* pointerId */, touchData);
+
+        // Enable new touch detection.
+        when(mFeatureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION)).thenReturn(true);
+
+        // Configure UdfpsController to use FingerprintManager as opposed to AlternateTouchProvider.
+        initUdfpsController(mOpticalProps, false /* hasAlternateTouchProvider */);
+
+        // Configure UdfpsView to accept the ACTION_MOVE event
+        when(mUdfpsView.isDisplayConfigured()).thenReturn(false);
+        when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
+
+        // GIVEN that the alternate bouncer is showing and a11y touch exploration NOT enabled
+        when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false);
+        when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
+        mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId,
+                BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
+        mFgExecutor.runAllReady();
+
+        verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
+
+        // GIVEN swipe down for QS
+        when(mPrimaryBouncerInteractor.isInTransit()).thenReturn(false);
+        when(mLockscreenShadeTransitionController.getQSDragProgress()).thenReturn(1f);
+
+        // WHEN ACTION_MOVE is received and touch is within sensor
+        when(mSinglePointerTouchProcessor.processTouch(any(), anyInt(), any())).thenReturn(
+                processorResultMove);
+        MotionEvent moveEvent = MotionEvent.obtain(0, 0, ACTION_MOVE, 0, 0, 0);
+        mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
+        mBiometricExecutor.runAllReady();
+        moveEvent.recycle();
+
+        // THEN the touch is still processed
+        verify(mFingerprintManager).onPointerDown(anyLong(), anyInt(), anyInt(),
+                anyFloat(), anyFloat(), anyFloat(), anyFloat(), anyFloat(), anyLong(), anyLong(),
+                anyBoolean());
+    }
+
     @Test
     public void onAodInterrupt_onAcquiredGood_fingerNoLongerDown() throws RemoteException {
         // GIVEN UDFPS overlay is showing
-- 
GitLab


From 2d8d591b3b9f5fb14c9d2270a8b8bb1eac9328e4 Mon Sep 17 00:00:00 2001
From: Hai Zhang <zhanghai@google.com>
Date: Thu, 21 Sep 2023 19:36:17 +0000
Subject: [PATCH 51/95] Use non-null assertion instead of checkNotNull().

For consistency in code style, and always avoiding a method call
regardless of optimizations.

Change-Id: I2c041c8ef2e5cb8e3ca6c9d3eaaec36ebb01779b
---
 .../server/permission/access/permission/PermissionService.kt    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt b/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
index 1e052c037b3c..cee2524657dc 100644
--- a/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
@@ -985,7 +985,7 @@ class PermissionService(
     ) {
         val appOpPolicy = service.getSchemePolicy(UidUri.SCHEME, AppOpUri.SCHEME) as
             AppIdAppOpPolicy
-        val appOpName = checkNotNull(AppOpsManager.permissionToOp(permissionName))
+        val appOpName = AppOpsManager.permissionToOp(permissionName)!!
         val mode = if (isGranted) AppOpsManager.MODE_ALLOWED else AppOpsManager.MODE_ERRORED
         with(appOpPolicy) { setAppOpMode(packageState.appId, userId, appOpName, mode) }
     }
-- 
GitLab


From 749e083d84ca159e99d2e2c73c2bfa8d3c63bf11 Mon Sep 17 00:00:00 2001
From: Josh Tsuji <tsuji@google.com>
Date: Mon, 18 Sep 2023 19:07:16 -0400
Subject: [PATCH 52/95] Initialize isLockscreenShowing as null rather than
 true.

We were short-circuiting after boot since we thought
we'd already called setLockScreenShown(true).

Fixes: 300990985
Test: reboot device with refactor flag enabled
Change-Id: Icc25bd750bb5205c59813c68139c7193c5f00553
---
 ...indowManagerLockscreenVisibilityManager.kt | 29 +++++++++++++++----
 ...wManagerLockscreenVisibilityManagerTest.kt | 10 +++++++
 2 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WindowManagerLockscreenVisibilityManager.kt b/packages/SystemUI/src/com/android/systemui/keyguard/WindowManagerLockscreenVisibilityManager.kt
index 75677f2d9e9a..8ebcece940c2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/WindowManagerLockscreenVisibilityManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/WindowManagerLockscreenVisibilityManager.kt
@@ -45,8 +45,13 @@ constructor(
     /**
      * Whether the lockscreen is showing, which we pass to [IActivityTaskManager.setLockScreenShown]
      * in order to show the lockscreen and hide the surface behind the keyguard (or the inverse).
+     *
+     * This value is null if we have not yet called setLockScreenShown with any value. This will
+     * happen during the boot sequence, but we can't default to true here since otherwise we'll
+     * short-circuit on the first call to setLockScreenShown since we'll think we're already
+     * showing.
      */
-    private var isLockscreenShowing = true
+    private var isLockscreenShowing: Boolean? = null
 
     /**
      * Whether AOD is showing, which we pass to [IActivityTaskManager.setLockScreenShown] in order
@@ -102,7 +107,7 @@ constructor(
 
         // The surface behind is always visible if the lockscreen is not showing, so we're already
         // visible.
-        if (visible && !isLockscreenShowing) {
+        if (visible && isLockscreenShowing != true) {
             Log.d(TAG, "#setVisibility -> already visible since the lockscreen isn't showing")
             return
         }
@@ -159,9 +164,23 @@ constructor(
         }
     }
 
+    /**
+     * Sets the lockscreen state WM-side by calling ATMS#setLockScreenShown.
+     *
+     * [lockscreenShowing] defaults to true, since it's only ever null during the boot sequence,
+     * when we haven't yet called ATMS#setLockScreenShown. Typically,
+     * setWmLockscreenState(lockscreenShowing = true) is called early in the boot sequence, before
+     * setWmLockscreenState(aodVisible = true), so we don't expect to need to use this default, but
+     * if so, true should be the right choice.
+     */
     private fun setWmLockscreenState(
-        lockscreenShowing: Boolean = this.isLockscreenShowing,
-        aodVisible: Boolean = this.isAodVisible
+            lockscreenShowing: Boolean = this.isLockscreenShowing ?: true.also {
+                Log.d(TAG, "Using isLockscreenShowing=true default in setWmLockscreenState, " +
+                        "because setAodVisible was called before the first setLockscreenShown " +
+                        "call during boot. This is not typical, but is theoretically possible. " +
+                        "If you're investigating the lockscreen showing unexpectedly, start here.")
+            },
+            aodVisible: Boolean = this.isAodVisible
     ) {
         Log.d(
             TAG,
@@ -201,6 +220,6 @@ constructor(
     }
 
     companion object {
-        private val TAG = this::class.java.simpleName
+        private val TAG = WindowManagerLockscreenVisibilityManager::class.java.simpleName
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt
index 623c8771b3d2..7a17435b9165 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt
@@ -67,6 +67,7 @@ class WindowManagerLockscreenVisibilityManagerTest : SysuiTestCase() {
         underTest.setLockscreenShown(true)
         underTest.setAodVisible(true)
 
+        verify(activityTaskManagerService).setLockScreenShown(true, false)
         verify(activityTaskManagerService).setLockScreenShown(true, true)
         verifyNoMoreInteractions(activityTaskManagerService)
     }
@@ -76,6 +77,7 @@ class WindowManagerLockscreenVisibilityManagerTest : SysuiTestCase() {
         underTest.setLockscreenShown(true)
         underTest.setAodVisible(true)
 
+        verify(activityTaskManagerService).setLockScreenShown(true, false)
         verify(activityTaskManagerService).setLockScreenShown(true, true)
         verifyNoMoreInteractions(activityTaskManagerService)
 
@@ -97,4 +99,12 @@ class WindowManagerLockscreenVisibilityManagerTest : SysuiTestCase() {
 
         verifyNoMoreInteractions(activityTaskManagerService)
     }
+
+    @Test
+    fun testAodVisible_noLockscreenShownCallYet_defaultsToShowLockscreen() {
+        underTest.setAodVisible(false)
+
+        verify(activityTaskManagerService).setLockScreenShown(true, false)
+        verifyNoMoreInteractions(activityTaskManagerService)
+    }
 }
-- 
GitLab


From ac3368dd225dff58337039d4ccd1636e79719ebb Mon Sep 17 00:00:00 2001
From: Evan Laird <evanlaird@google.com>
Date: Wed, 20 Sep 2023 18:37:34 -0400
Subject: [PATCH 53/95] [QS] Add contentDescription and stateDescription to
 tile

These values were missing from the initial implementation. Since the
states are broken out from the way the old tile defined them, they're
generally simpler to see here. Mostly the content description is the
same as the underlying flow's description prepended by "Internet,".

Note that ethernet didn't have a content description defined in the old
tile impl. It's been added here.

Test: InternetTileViewModelTest
Test: manually testing different connections

Fixes: 299292270
Change-Id: Ieb16b594d235f8144014bc88dc3c565153661a07
---
 .../shared/ui/model/InternetTileModel.kt      | 11 +++++
 .../ui/viewmodel/InternetTileViewModel.kt     | 42 ++++++++++++++-----
 .../ui/viewmodel/InternetTileViewModelTest.kt | 26 ++++++++++++
 3 files changed, 69 insertions(+), 10 deletions(-)

diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/model/InternetTileModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/model/InternetTileModel.kt
index 1f076ed30f8a..18865900eef6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/model/InternetTileModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/model/InternetTileModel.kt
@@ -20,6 +20,8 @@ import android.content.Context
 import android.graphics.drawable.Drawable
 import android.service.quicksettings.Tile
 import com.android.settingslib.graph.SignalDrawable
+import com.android.systemui.common.shared.model.ContentDescription
+import com.android.systemui.common.shared.model.ContentDescription.Companion.loadContentDescription
 import com.android.systemui.common.shared.model.Text
 import com.android.systemui.common.shared.model.Text.Companion.loadText
 import com.android.systemui.plugins.qs.QSTile
@@ -31,6 +33,8 @@ sealed interface InternetTileModel {
     val secondaryLabel: Text?
     val iconId: Int?
     val icon: QSTile.Icon?
+    val stateDescription: ContentDescription?
+    val contentDescription: ContentDescription?
 
     fun applyTo(state: QSTile.BooleanState, context: Context) {
         if (secondaryLabel != null) {
@@ -39,6 +43,9 @@ sealed interface InternetTileModel {
             state.secondaryLabel = secondaryTitle
         }
 
+        state.stateDescription = stateDescription.loadContentDescription(context)
+        state.contentDescription = contentDescription.loadContentDescription(context)
+
         // To support both SignalDrawable and other icons, give priority to icons over IDs
         if (icon != null) {
             state.icon = icon
@@ -59,6 +66,8 @@ sealed interface InternetTileModel {
         override val secondaryLabel: Text? = null,
         override val iconId: Int? = null,
         override val icon: QSTile.Icon? = null,
+        override val stateDescription: ContentDescription? = null,
+        override val contentDescription: ContentDescription? = null,
     ) : InternetTileModel
 
     data class Inactive(
@@ -66,6 +75,8 @@ sealed interface InternetTileModel {
         override val secondaryLabel: Text? = null,
         override val iconId: Int? = null,
         override val icon: QSTile.Icon? = null,
+        override val stateDescription: ContentDescription? = null,
+        override val contentDescription: ContentDescription? = null,
     ) : InternetTileModel
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModel.kt
index b6f167704cd7..3f82c5bfc33c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModel.kt
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.pipeline.shared.ui.viewmodel
 
 import android.content.Context
 import com.android.systemui.R
+import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Text
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
@@ -61,16 +62,21 @@ constructor(
     private val context: Context,
     @Application scope: CoroutineScope,
 ) {
+    private val internetLabel: String = context.getString(R.string.quick_settings_internet_label)
+
     // Three symmetrical Flows that can be switched upon based on the value of
     // [DefaultConnectionModel]
     private val wifiIconFlow: Flow<InternetTileModel> =
         wifiInteractor.wifiNetwork.flatMapLatest {
             val wifiIcon = WifiIcon.fromModel(it, context, showHotspotInfo = true)
             if (it is WifiNetworkModel.Active && wifiIcon is WifiIcon.Visible) {
+                val secondary = removeDoubleQuotes(it.ssid)
                 flowOf(
                     InternetTileModel.Active(
-                        secondaryTitle = removeDoubleQuotes(it.ssid),
-                        icon = ResourceIcon.get(wifiIcon.icon.res)
+                        secondaryTitle = secondary,
+                        icon = ResourceIcon.get(wifiIcon.icon.res),
+                        stateDescription = wifiIcon.contentDescription,
+                        contentDescription = ContentDescription.Loaded("$internetLabel,$secondary"),
                     )
                 )
             } else {
@@ -109,10 +115,13 @@ constructor(
                     it.signalLevelIcon,
                     mobileDataContentName,
                 ) { networkNameModel, signalIcon, dataContentDescription ->
+                    val secondary =
+                        mobileDataContentConcat(networkNameModel.name, dataContentDescription)
                     InternetTileModel.Active(
-                        secondaryTitle =
-                            mobileDataContentConcat(networkNameModel.name, dataContentDescription),
+                        secondaryTitle = secondary,
                         icon = SignalIcon(signalIcon.toSignalDrawableState()),
+                        stateDescription = ContentDescription.Loaded(secondary),
+                        contentDescription = ContentDescription.Loaded(internetLabel),
                     )
                 }
             }
@@ -148,10 +157,13 @@ constructor(
             if (it == null) {
                 notConnectedFlow
             } else {
+                val secondary = it.contentDescription.toString()
                 flowOf(
                     InternetTileModel.Active(
-                        secondaryTitle = it.contentDescription.toString(),
-                        iconId = it.res
+                        secondaryTitle = secondary,
+                        iconId = it.res,
+                        stateDescription = null,
+                        contentDescription = ContentDescription.Loaded(secondary),
                     )
                 )
             }
@@ -164,16 +176,23 @@ constructor(
             ) { networksAvailable, isAirplaneMode ->
                 when {
                     isAirplaneMode -> {
+                        val secondary = context.getString(R.string.status_bar_airplane)
                         InternetTileModel.Inactive(
-                            secondaryTitle = context.getString(R.string.status_bar_airplane),
-                            icon = ResourceIcon.get(R.drawable.ic_qs_no_internet_unavailable)
+                            secondaryTitle = secondary,
+                            icon = ResourceIcon.get(R.drawable.ic_qs_no_internet_unavailable),
+                            stateDescription = null,
+                            contentDescription = ContentDescription.Loaded(secondary),
                         )
                     }
                     networksAvailable -> {
+                        val secondary =
+                            context.getString(R.string.quick_settings_networks_available)
                         InternetTileModel.Inactive(
-                            secondaryTitle =
-                                context.getString(R.string.quick_settings_networks_available),
+                            secondaryTitle = secondary,
                             iconId = R.drawable.ic_qs_no_internet_available,
+                            stateDescription = null,
+                            contentDescription =
+                                ContentDescription.Loaded("$internetLabel,$secondary")
                         )
                     }
                     else -> {
@@ -206,6 +225,9 @@ constructor(
             InternetTileModel.Inactive(
                 secondaryLabel = Text.Resource(R.string.quick_settings_networks_unavailable),
                 iconId = R.drawable.ic_qs_no_internet_unavailable,
+                stateDescription = null,
+                contentDescription =
+                    ContentDescription.Resource(R.string.quick_settings_networks_unavailable),
             )
 
         private fun removeDoubleQuotes(string: String?): String? {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt
index 6624ec2ece77..87163d24bae2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.pipeline.shared.ui.viewmodel
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.common.shared.model.ContentDescription.Companion.loadContentDescription
 import com.android.systemui.common.shared.model.Text
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.log.table.TableLogBuffer
@@ -42,6 +43,7 @@ import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepo
 import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractorImpl
 import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
 import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiScanEntry
+import com.android.systemui.statusbar.pipeline.wifi.ui.model.WifiIcon
 import com.android.systemui.util.CarrierConfigTracker
 import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth.assertThat
@@ -72,6 +74,8 @@ class InternetTileViewModelTest : SysuiTestCase() {
     private val mobileConnectionRepository =
         FakeMobileConnectionRepository(SUB_1_ID, tableLogBuffer)
 
+    private val internet = context.getString(R.string.quick_settings_internet_label)
+
     @Before
     fun setUp() {
         mobileConnectionRepository.apply {
@@ -139,6 +143,9 @@ class InternetTileViewModelTest : SysuiTestCase() {
                     level = 4,
                     ssid = "test ssid",
                 )
+            val wifiIcon =
+                WifiIcon.fromModel(model = networkModel, context = context, showHotspotInfo = false)
+                    as WifiIcon.Visible
 
             connectivityRepository.setWifiConnected()
             wifiRepository.setIsWifiDefault(true)
@@ -149,6 +156,10 @@ class InternetTileViewModelTest : SysuiTestCase() {
             assertThat(latest?.icon)
                 .isEqualTo(ResourceIcon.get(WifiIcons.WIFI_NO_INTERNET_ICONS[4]))
             assertThat(latest?.iconId).isNull()
+            assertThat(latest?.contentDescription.loadContentDescription(context))
+                .isEqualTo("$internet,test ssid")
+            val expectedSd = wifiIcon.contentDescription
+            assertThat(latest?.stateDescription).isEqualTo(expectedSd)
         }
 
     @Test
@@ -281,6 +292,11 @@ class InternetTileViewModelTest : SysuiTestCase() {
                 .isEqualTo(context.getString(R.string.quick_settings_networks_available))
             assertThat(latest?.icon).isNull()
             assertThat(latest?.iconId).isEqualTo(R.drawable.ic_qs_no_internet_available)
+            assertThat(latest?.stateDescription).isNull()
+            val expectedCd =
+                "$internet,${context.getString(R.string.quick_settings_networks_available)}"
+            assertThat(latest?.contentDescription.loadContentDescription(context))
+                .isEqualTo(expectedCd)
         }
 
     @Test
@@ -300,6 +316,10 @@ class InternetTileViewModelTest : SysuiTestCase() {
             assertThat(latest?.secondaryLabel).isNull()
             assertThat(latest?.icon).isInstanceOf(SignalIcon::class.java)
             assertThat(latest?.iconId).isNull()
+            assertThat(latest?.stateDescription.loadContentDescription(context))
+                .isEqualTo(latest?.secondaryTitle)
+            assertThat(latest?.contentDescription.loadContentDescription(context))
+                .isEqualTo(internet)
         }
 
     @Test
@@ -315,6 +335,9 @@ class InternetTileViewModelTest : SysuiTestCase() {
                 .isEqualTo(ethernetIcon!!.contentDescription.toString())
             assertThat(latest?.iconId).isEqualTo(R.drawable.stat_sys_ethernet_fully)
             assertThat(latest?.icon).isNull()
+            assertThat(latest?.stateDescription).isNull()
+            assertThat(latest?.contentDescription.loadContentDescription(context))
+                .isEqualTo(latest?.secondaryTitle)
         }
 
     @Test
@@ -330,6 +353,9 @@ class InternetTileViewModelTest : SysuiTestCase() {
                 .isEqualTo(ethernetIcon!!.contentDescription.toString())
             assertThat(latest?.iconId).isEqualTo(R.drawable.stat_sys_ethernet)
             assertThat(latest?.icon).isNull()
+            assertThat(latest?.stateDescription).isNull()
+            assertThat(latest?.contentDescription.loadContentDescription(context))
+                .isEqualTo(latest?.secondaryTitle)
         }
 
     private fun setWifiNetworkWithHotspot(hotspot: WifiNetworkModel.HotspotDeviceType) {
-- 
GitLab


From 5d66f1d15d5590f23f3f3d6b4b2c56b3f34adbdc Mon Sep 17 00:00:00 2001
From: Gustavo Pagani <gustavopagani@google.com>
Date: Thu, 21 Sep 2023 21:07:58 +0000
Subject: [PATCH 54/95] Remove "ui" from package name from shared project.

Bug: 301206470
Test: N/A - package name refactoring

Change-Id: I05392c3fefcae340e898fbb40eb52a11b79e75ac
---
 .../android/credentialmanager/IntentParser.kt | 42 +++++++++++++
 .../{ui => }/LogConstants.kt                  |  2 +-
 .../factory/CredentialEntryFactory.kt         |  2 +-
 .../{ui => }/ktx/IntentKtx.kt                 |  2 +-
 .../{ui => }/ktx/PackageManagerKtx.kt         |  4 +-
 .../RequestCancelMapper.kt}                   | 18 +++---
 .../mapper/RequestGetMapper.kt                | 22 +++++++
 .../{ui => }/model/Request.kt                 |  2 +-
 .../credentialmanager/ui/IntentParser.kt      | 60 -------------------
 .../ui/CredentialSelectorActivity.kt          |  1 -
 .../ui/CredentialSelectorViewModel.kt         | 11 ++--
 .../android/credentialmanager/ui/Screen.kt    |  2 +-
 .../CredentialSelectorUiStateGetMapper.kt     |  4 +-
 .../ui/model/PasswordUiModel.kt               |  2 +-
 .../ui/screens/MainScreen.kt                  |  4 +-
 15 files changed, 95 insertions(+), 83 deletions(-)
 create mode 100644 packages/CredentialManager/shared/src/com/android/credentialmanager/IntentParser.kt
 rename packages/CredentialManager/shared/src/com/android/credentialmanager/{ui => }/LogConstants.kt (94%)
 rename packages/CredentialManager/shared/src/com/android/credentialmanager/{ui => }/factory/CredentialEntryFactory.kt (95%)
 rename packages/CredentialManager/shared/src/com/android/credentialmanager/{ui => }/ktx/IntentKtx.kt (97%)
 rename packages/CredentialManager/shared/src/com/android/credentialmanager/{ui => }/ktx/PackageManagerKtx.kt (93%)
 rename packages/CredentialManager/shared/src/com/android/credentialmanager/{ui/mapper/RequestMapper.kt => mapper/RequestCancelMapper.kt} (57%)
 create mode 100644 packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestGetMapper.kt
 rename packages/CredentialManager/shared/src/com/android/credentialmanager/{ui => }/model/Request.kt (96%)
 delete mode 100644 packages/CredentialManager/shared/src/com/android/credentialmanager/ui/IntentParser.kt

diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/IntentParser.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/IntentParser.kt
new file mode 100644
index 000000000000..defba8dacb7b
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/IntentParser.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 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.0N
+ *
+ * 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.credentialmanager
+
+import android.content.Intent
+import android.credentials.ui.RequestInfo
+import com.android.credentialmanager.ktx.requestInfo
+import com.android.credentialmanager.mapper.toGet
+import com.android.credentialmanager.mapper.toRequestCancel
+import com.android.credentialmanager.model.Request
+
+fun Intent.parse(): Request {
+    this.toRequestCancel()?.let { return it }
+
+    return when (requestInfo?.type) {
+        RequestInfo.TYPE_CREATE -> {
+            Request.Create
+        }
+
+        RequestInfo.TYPE_GET -> {
+            this.toGet()
+        }
+
+        else -> {
+            throw IllegalStateException("Unrecognized request type: ${requestInfo?.type}")
+        }
+    }
+}
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/LogConstants.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/LogConstants.kt
similarity index 94%
rename from packages/CredentialManager/shared/src/com/android/credentialmanager/ui/LogConstants.kt
rename to packages/CredentialManager/shared/src/com/android/credentialmanager/LogConstants.kt
index f49bb33d2e8a..44d33ff7084a 100644
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/LogConstants.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/LogConstants.kt
@@ -14,6 +14,6 @@
  * limitations under the License.
  */
 
-package com.android.credentialmanager.ui
+package com.android.credentialmanager
 
 const val TAG = "CredentialSelector"
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/factory/CredentialEntryFactory.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/factory/CredentialEntryFactory.kt
similarity index 95%
rename from packages/CredentialManager/shared/src/com/android/credentialmanager/ui/factory/CredentialEntryFactory.kt
rename to packages/CredentialManager/shared/src/com/android/credentialmanager/factory/CredentialEntryFactory.kt
index f01fdedc9137..a2c1f0388807 100644
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/factory/CredentialEntryFactory.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/factory/CredentialEntryFactory.kt
@@ -1,4 +1,4 @@
-package com.android.credentialmanager.ui.factory
+package com.android.credentialmanager.factory
 
 import android.app.slice.Slice
 import android.credentials.Credential
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/ktx/IntentKtx.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/IntentKtx.kt
similarity index 97%
rename from packages/CredentialManager/shared/src/com/android/credentialmanager/ui/ktx/IntentKtx.kt
rename to packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/IntentKtx.kt
index b9895a0ab52a..a4c20bfabb35 100644
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/ktx/IntentKtx.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/IntentKtx.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.credentialmanager.ui.ktx
+package com.android.credentialmanager.ktx
 
 import android.content.Intent
 import android.credentials.ui.CancelUiRequest
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/ktx/PackageManagerKtx.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/PackageManagerKtx.kt
similarity index 93%
rename from packages/CredentialManager/shared/src/com/android/credentialmanager/ui/ktx/PackageManagerKtx.kt
rename to packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/PackageManagerKtx.kt
index 7fa0ca918e21..5f4f298241a1 100644
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/ktx/PackageManagerKtx.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/PackageManagerKtx.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.credentialmanager.ui.ktx
+package com.android.credentialmanager.ktx
 
 import android.content.pm.PackageManager
 import android.text.TextUtils
 import android.util.Log
-import com.android.credentialmanager.ui.TAG
+import com.android.credentialmanager.TAG
 
 fun PackageManager.appLabel(appPackageName: String): String? =
     try {
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/mapper/RequestMapper.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestCancelMapper.kt
similarity index 57%
rename from packages/CredentialManager/shared/src/com/android/credentialmanager/ui/mapper/RequestMapper.kt
rename to packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestCancelMapper.kt
index 89766c2ec61b..86a6d23a76a9 100644
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/mapper/RequestMapper.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestCancelMapper.kt
@@ -14,12 +14,16 @@
  * limitations under the License.
  */
 
-package com.android.credentialmanager.ui.mapper
+package com.android.credentialmanager.mapper
 
-import android.credentials.ui.CancelUiRequest
-import com.android.credentialmanager.ui.model.Request
+import android.content.Intent
+import com.android.credentialmanager.ktx.cancelUiRequest
+import com.android.credentialmanager.model.Request
 
-fun CancelUiRequest.toCancel() = Request.Cancel(
-    showCancellationUi = this.shouldShowCancellationUi(),
-    appPackageName = this.appPackageName
-)
+fun Intent.toRequestCancel(): Request.Cancel? =
+    this.cancelUiRequest?.let { cancelUiRequest ->
+        Request.Cancel(
+            showCancellationUi = cancelUiRequest.shouldShowCancellationUi(),
+            appPackageName = cancelUiRequest.appPackageName
+        )
+    }
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestGetMapper.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestGetMapper.kt
new file mode 100644
index 000000000000..ed9d56344853
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestGetMapper.kt
@@ -0,0 +1,22 @@
+package com.android.credentialmanager.mapper
+
+import android.content.Intent
+import android.credentials.ui.GetCredentialProviderData
+import com.android.credentialmanager.ktx.getCredentialProviderDataList
+import com.android.credentialmanager.model.Request
+import com.google.common.collect.ImmutableList
+import com.google.common.collect.ImmutableMap
+
+fun Intent.toGet() = Request.Get(
+    providers = ImmutableMap.copyOf(
+        getCredentialProviderDataList.associateBy { it.providerFlattenedComponentName }
+    ),
+    entries = ImmutableList.copyOf(
+        getCredentialProviderDataList.map { providerData ->
+            check(providerData is GetCredentialProviderData) {
+                "Invalid provider data type for GetCredentialRequest"
+            }
+            providerData
+        }.flatMap { it.credentialEntries }
+    )
+)
\ No newline at end of file
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/model/Request.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/Request.kt
similarity index 96%
rename from packages/CredentialManager/shared/src/com/android/credentialmanager/ui/model/Request.kt
rename to packages/CredentialManager/shared/src/com/android/credentialmanager/model/Request.kt
index cffa2b2586b1..bc073105efe1 100644
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/model/Request.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/Request.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.credentialmanager.ui.model
+package com.android.credentialmanager.model
 
 import android.credentials.ui.Entry
 import android.credentials.ui.ProviderData
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/IntentParser.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/IntentParser.kt
deleted file mode 100644
index 43d8fb3228d5..000000000000
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/IntentParser.kt
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2023 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.0N
- *
- * 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.credentialmanager.ui
-
-import android.content.Intent
-import android.credentials.ui.GetCredentialProviderData
-import android.credentials.ui.RequestInfo
-import com.android.credentialmanager.ui.ktx.cancelUiRequest
-import com.android.credentialmanager.ui.ktx.getCredentialProviderDataList
-import com.android.credentialmanager.ui.ktx.requestInfo
-import com.android.credentialmanager.ui.mapper.toCancel
-import com.android.credentialmanager.ui.model.Request
-import com.google.common.collect.ImmutableList
-import com.google.common.collect.ImmutableMap
-
-fun Intent.parse(): Request {
-    cancelUiRequest?.let {
-        return it.toCancel()
-    }
-
-    return when (requestInfo?.type) {
-        RequestInfo.TYPE_CREATE -> {
-            Request.Create
-        }
-
-        RequestInfo.TYPE_GET -> {
-            Request.Get(
-                providers = ImmutableMap.copyOf(
-                    getCredentialProviderDataList.associateBy { it.providerFlattenedComponentName }
-                ),
-                entries = ImmutableList.copyOf(
-                    getCredentialProviderDataList.map { providerData ->
-                        check(providerData is GetCredentialProviderData) {
-                            "Invalid provider data type for GetCredentialRequest"
-                        }
-                        providerData
-                    }.flatMap { it.credentialEntries }
-                )
-            )
-        }
-
-        else -> {
-            throw IllegalStateException("Unrecognized request type: ${requestInfo?.type}")
-        }
-    }
-}
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorActivity.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorActivity.kt
index a93fa81bb85b..53122ba7ccdc 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorActivity.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorActivity.kt
@@ -48,7 +48,6 @@ class CredentialSelectorActivity : ComponentActivity() {
                         }
 
                         is CredentialSelectorUiState.Get -> {
-                            // TODO: b/301206470 - Implement get flow
                             setContent {
                                 MaterialTheme {
                                     WearApp()
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorViewModel.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorViewModel.kt
index c61bb2e0f949..d22d5d1a28a3 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorViewModel.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorViewModel.kt
@@ -21,12 +21,15 @@ import android.content.Intent
 import android.util.Log
 import androidx.lifecycle.AndroidViewModel
 import androidx.lifecycle.viewModelScope
-import com.android.credentialmanager.ui.ktx.appLabel
-import com.android.credentialmanager.ui.ktx.requestInfo
-import com.android.credentialmanager.ui.mapper.toGet
+import com.android.credentialmanager.TAG
+import com.android.credentialmanager.parse
+import com.android.credentialmanager.ktx.appLabel
+import com.android.credentialmanager.ktx.requestInfo
+import com.android.credentialmanager.mapper.toGet
 import com.android.credentialmanager.ui.model.PasskeyUiModel
 import com.android.credentialmanager.ui.model.PasswordUiModel
-import com.android.credentialmanager.ui.model.Request
+import com.android.credentialmanager.model.Request
+import com.android.credentialmanager.ui.mapper.toGet
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.launch
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/Screen.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/Screen.kt
index ee6ea5e57c19..7d1a49b07718 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/Screen.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/Screen.kt
@@ -19,5 +19,5 @@ package com.android.credentialmanager.ui
 sealed class Screen(
     val route: String,
 ) {
-    object Main : Screen("main")
+    data object Main : Screen("main")
 }
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mapper/CredentialSelectorUiStateGetMapper.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mapper/CredentialSelectorUiStateGetMapper.kt
index 1fe1e5596805..5ceec1783c84 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mapper/CredentialSelectorUiStateGetMapper.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mapper/CredentialSelectorUiStateGetMapper.kt
@@ -4,9 +4,9 @@ import androidx.credentials.provider.CustomCredentialEntry
 import androidx.credentials.provider.PasswordCredentialEntry
 import androidx.credentials.provider.PublicKeyCredentialEntry
 import com.android.credentialmanager.ui.CredentialSelectorUiState
-import com.android.credentialmanager.ui.factory.fromSlice
+import com.android.credentialmanager.factory.fromSlice
 import com.android.credentialmanager.ui.model.PasswordUiModel
-import com.android.credentialmanager.ui.model.Request
+import com.android.credentialmanager.model.Request
 
 fun Request.Get.toGet(): CredentialSelectorUiState.Get {
     if (this.providers.isEmpty()) {
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/model/PasswordUiModel.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/model/PasswordUiModel.kt
index 514dca8244f1..52bbfaa818ed 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/model/PasswordUiModel.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/model/PasswordUiModel.kt
@@ -16,4 +16,4 @@
 
 package com.android.credentialmanager.ui.model
 
-data class PasswordUiModel(val name: String)
+data class PasswordUiModel(val email: String)
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/MainScreen.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/MainScreen.kt
index 662d7108ab90..94a671efc393 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/MainScreen.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/MainScreen.kt
@@ -23,7 +23,9 @@ import androidx.compose.ui.Modifier
 import androidx.wear.compose.material.Text
 
 @Composable
-fun MainScreen(modifier: Modifier = Modifier) {
+fun MainScreen(
+    modifier: Modifier = Modifier
+) {
     Box(modifier = modifier, contentAlignment = Alignment.Center) {
         Text("This is a placeholder for the main screen.")
     }
-- 
GitLab


From 1d50590d1a86464321fbd40062ee7edf008d0d92 Mon Sep 17 00:00:00 2001
From: Caitlin Shkuratov <caitlinshk@google.com>
Date: Thu, 21 Sep 2023 21:17:59 +0000
Subject: [PATCH 55/95] [Status Bar][Wifi] Unlaunch
 WIFI_TRACKER_LIB_FOR_WIFI_ICON to droidfood.

Bug: 300829104
Bug: 292533677

Change-Id: Ia76938f44ddd9c8e031afef34035c570aa6cad89
---
 packages/SystemUI/src/com/android/systemui/flags/Flags.kt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index cfab00125e8c..8b549956b397 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -368,7 +368,8 @@ object Flags {
     @JvmField val NEW_BLUETOOTH_REPOSITORY = releasedFlag("new_bluetooth_repository")
 
     // TODO(b/292533677): Tracking Bug
-    val WIFI_TRACKER_LIB_FOR_WIFI_ICON = releasedFlag("wifi_tracker_lib_for_wifi_icon")
+    val WIFI_TRACKER_LIB_FOR_WIFI_ICON =
+        unreleasedFlag("wifi_tracker_lib_for_wifi_icon", teamfood = true)
 
     // TODO(b/293863612): Tracking Bug
     @JvmField val INCOMPATIBLE_CHARGING_BATTERY_ICON =
-- 
GitLab


From 668e17494cd1847bdca32b11edb5adb149028295 Mon Sep 17 00:00:00 2001
From: Yeabkal Wubshit <yeabkal@google.com>
Date: Thu, 14 Sep 2023 20:44:16 -0700
Subject: [PATCH 56/95] Add ViewConfigurationPerfTest

Created two simple benchmark tests to measure performance of
ViewConfiguration#get.

Bug: 299587011
Test: atest ViewConfigurationPerfTest

Change-Id: If502a4acb6bc6080af134675e610a76df59c538a
---
 .../view/ViewConfigurationPerfTest.java       | 61 +++++++++++++++++++
 core/java/android/view/ViewConfiguration.java | 14 +++++
 2 files changed, 75 insertions(+)
 create mode 100644 apct-tests/perftests/core/src/android/view/ViewConfigurationPerfTest.java

diff --git a/apct-tests/perftests/core/src/android/view/ViewConfigurationPerfTest.java b/apct-tests/perftests/core/src/android/view/ViewConfigurationPerfTest.java
new file mode 100644
index 000000000000..7a7250b9e910
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/view/ViewConfigurationPerfTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2023 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.view;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import android.content.Context;
+
+import androidx.benchmark.BenchmarkState;
+import androidx.benchmark.junit4.BenchmarkRule;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+@SmallTest
+public class ViewConfigurationPerfTest {
+    @Rule
+    public final BenchmarkRule mBenchmarkRule = new BenchmarkRule();
+
+    private final Context mContext = getInstrumentation().getTargetContext();
+
+    @Test
+    public void testGet_newViewConfiguration() {
+        final BenchmarkState state = mBenchmarkRule.getState();
+
+        while (state.keepRunning()) {
+            state.pauseTiming();
+            // Reset cache so that `ViewConfiguration#get` creates a new instance.
+            ViewConfiguration.resetCacheForTesting();
+            state.resumeTiming();
+
+            ViewConfiguration.get(mContext);
+        }
+    }
+
+    @Test
+    public void testGet_cachedViewConfiguration() {
+        final BenchmarkState state = mBenchmarkRule.getState();
+        // Do `get` once to make sure there's something cached.
+        ViewConfiguration.get(mContext);
+
+        while (state.keepRunning()) {
+            ViewConfiguration.get(mContext);
+        }
+    }
+}
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index a3ae6cf20725..6ee674ab4ab3 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -40,6 +40,8 @@ import android.util.SparseArray;
 import android.util.TypedValue;
 import android.view.flags.Flags;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 /**
  * Contains methods to standard constants used in the UI for timeouts, sizes, and distances.
  */
@@ -602,6 +604,18 @@ public class ViewConfiguration {
         return configuration;
     }
 
+    /**
+     * Removes cached ViewConfiguration instances, so that we can ensure `get` constructs a new
+     * ViewConfiguration instance. This is useful for testing the behavior and performance of
+     * creating ViewConfiguration the first time.
+     *
+     * @hide
+     */
+    @VisibleForTesting
+    public static void resetCacheForTesting() {
+        sConfigurations.clear();
+    }
+
     /**
      * @return The width of the horizontal scrollbar and the height of the vertical
      *         scrollbar in dips
-- 
GitLab


From 616806e510dc3f2b9553a00b8e3b1f4b0df71c97 Mon Sep 17 00:00:00 2001
From: Yeabkal Wubshit <yeabkal@google.com>
Date: Wed, 6 Sep 2023 23:08:04 -0700
Subject: [PATCH 57/95] Rotary encoder scroll haptics in View class

This change implements scroll haptics in View class for rotary encoders.
The View class implementation allows to avoid regression for devices
which have had rotary scroll haptics in forks of previous Android
releases.
The long term plan for scroll haptics is to use the
ScrollFeedbackProvider in widgets. As such, this implementation will
eventually be removed in future Android releases once the
ScrollFeedbackProvider has been well integrated with major widgets.

We have also fixed a bug in HapticScrollFeedbackProvider, which was
necessary in using it for View-based rotary haptics. The bug was that it
was allowing scroll-limit haptics without any non-limit scroll events.
Tests have accordingly been adjusted.

Bug: 299587011
Test: manual, unit tests

Change-Id: Ifaeb89bd5bdc8c806c718d4aa8087cc0d2bf3ae5
---
 .../view/HapticScrollFeedbackProvider.java    |  25 +-
 core/java/android/view/View.java              |  94 ++++++-
 core/java/android/view/ViewConfiguration.java |  37 ++-
 .../view/flags/scroll_feedback_flags.aconfig  |   7 +
 core/res/res/values/config.xml                |   3 +
 core/res/res/values/symbols.xml               |   1 +
 .../HapticScrollFeedbackProviderTest.java     | 107 ++++++--
 .../android/view/RotaryScrollHapticsTest.java | 259 ++++++++++++++++++
 8 files changed, 506 insertions(+), 27 deletions(-)
 create mode 100644 core/tests/coretests/src/android/view/RotaryScrollHapticsTest.java

diff --git a/core/java/android/view/HapticScrollFeedbackProvider.java b/core/java/android/view/HapticScrollFeedbackProvider.java
index a2f1d37c2c11..1310b0ccd3a9 100644
--- a/core/java/android/view/HapticScrollFeedbackProvider.java
+++ b/core/java/android/view/HapticScrollFeedbackProvider.java
@@ -47,9 +47,17 @@ public class HapticScrollFeedbackProvider implements ScrollFeedbackProvider {
     public @interface HapticScrollFeedbackAxis {}
 
     private static final int TICK_INTERVAL_NO_TICK = 0;
+    private static final boolean INITIAL_END_OF_LIST_HAPTICS_ENABLED = false;
 
     private final View mView;
     private final ViewConfiguration mViewConfig;
+    /**
+     * Flag to disable the logic in this class if the View-based scroll haptics implementation is
+     * enabled. If {@code false}, this class will continue to run despite the View's scroll
+     * haptics implementation being enabled. This value should be set to {@code true} when this
+     * class is directly used by the View class.
+     */
+    private final boolean mDisabledIfViewPlaysScrollHaptics;
 
 
     // Info about the cause of the latest scroll event.
@@ -63,18 +71,21 @@ public class HapticScrollFeedbackProvider implements ScrollFeedbackProvider {
     /** The tick interval corresponding to the current InputDevice/source/axis. */
     private int mTickIntervalPixels = TICK_INTERVAL_NO_TICK;
     private int mTotalScrollPixels = 0;
-    private boolean mCanPlayLimitFeedback = true;
+    private boolean mCanPlayLimitFeedback = INITIAL_END_OF_LIST_HAPTICS_ENABLED;
     private boolean mHapticScrollFeedbackEnabled = false;
 
     public HapticScrollFeedbackProvider(@NonNull View view) {
-        this(view, ViewConfiguration.get(view.getContext()));
+        this(view, ViewConfiguration.get(view.getContext()),
+                /* disabledIfViewPlaysScrollHaptics= */ true);
     }
 
     /** @hide */
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
-    public HapticScrollFeedbackProvider(View view, ViewConfiguration viewConfig) {
+    public HapticScrollFeedbackProvider(
+            View view, ViewConfiguration viewConfig, boolean disabledIfViewPlaysScrollHaptics) {
         mView = view;
         mViewConfig = viewConfig;
+        mDisabledIfViewPlaysScrollHaptics = disabledIfViewPlaysScrollHaptics;
     }
 
     @Override
@@ -136,13 +147,19 @@ public class HapticScrollFeedbackProvider implements ScrollFeedbackProvider {
 
     private void maybeUpdateCurrentConfig(int deviceId, int source, int axis) {
         if (mAxis != axis || mSource != source || mDeviceId != deviceId) {
+            if (mDisabledIfViewPlaysScrollHaptics
+                    && (source == InputDevice.SOURCE_ROTARY_ENCODER)
+                    && mViewConfig.isViewBasedRotaryEncoderHapticScrollFeedbackEnabled()) {
+                mHapticScrollFeedbackEnabled = false;
+                return;
+            }
             mSource = source;
             mAxis = axis;
             mDeviceId = deviceId;
 
             mHapticScrollFeedbackEnabled =
                     mViewConfig.isHapticScrollFeedbackEnabled(deviceId, axis, source);
-            mCanPlayLimitFeedback = true;
+            mCanPlayLimitFeedback = INITIAL_END_OF_LIST_HAPTICS_ENABLED;
             mTotalScrollPixels = 0;
             updateTickIntervals(deviceId, source, axis);
         }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 4d53b2c6b821..55374b994cd4 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -919,6 +919,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
      */
     private static boolean sCompatibilityDone = false;
 
+    /** @hide */
+    public HapticScrollFeedbackProvider mScrollFeedbackProvider = null;
+
     /**
      * Use the old (broken) way of building MeasureSpecs.
      */
@@ -3605,6 +3608,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
      *               1                  PFLAG4_IMPORTANT_FOR_CREDENTIAL_MANAGER
      *              1                   PFLAG4_TRAVERSAL_TRACING_ENABLED
      *             1                    PFLAG4_RELAYOUT_TRACING_ENABLED
+     *            1                     PFLAG4_ROTARY_HAPTICS_DETERMINED
+     *           1                      PFLAG4_ROTARY_HAPTICS_ENABLED
+     *          1                       PFLAG4_ROTARY_HAPTICS_SCROLL_SINCE_LAST_ROTARY_INPUT
+     *         1                        PFLAG4_ROTARY_HAPTICS_WAITING_FOR_SCROLL_EVENT
      * |-------|-------|-------|-------|
      */
 
@@ -3703,6 +3710,24 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
      */
     private static final int PFLAG4_RELAYOUT_TRACING_ENABLED = 0x000080000;
 
+    /** Indicates if rotary scroll haptics support for the view has been determined. */
+    private static final int PFLAG4_ROTARY_HAPTICS_DETERMINED = 0x100000;
+
+    /**
+     * Indicates if rotary scroll haptics is enabled for this view.
+     * The source of truth for this info is a ViewConfiguration API; this bit only caches the value.
+     */
+    private static final int PFLAG4_ROTARY_HAPTICS_ENABLED = 0x200000;
+
+    /** Indicates if there has been a scroll event since the last rotary input. */
+    private static final int PFLAG4_ROTARY_HAPTICS_SCROLL_SINCE_LAST_ROTARY_INPUT = 0x400000;
+
+    /**
+     * Indicates if there has been a rotary input that may generate a scroll event.
+     * This flag is important so that a scroll event can be properly attributed to a rotary input.
+     */
+    private static final int PFLAG4_ROTARY_HAPTICS_WAITING_FOR_SCROLL_EVENT = 0x800000;
+
     /* End of masks for mPrivateFlags4 */
 
     /** @hide */
@@ -15894,6 +15919,28 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     }
 
     private boolean dispatchGenericMotionEventInternal(MotionEvent event) {
+        final boolean isRotaryEncoderEvent = event.isFromSource(InputDevice.SOURCE_ROTARY_ENCODER);
+        if (isRotaryEncoderEvent) {
+            // Determine and cache rotary scroll haptics support if it's not yet determined.
+            // Caching the support is important for two reasons:
+            // 1) Limits call to `ViewConfiguration#get`, which we should avoid if possible.
+            // 2) Limits latency from the `ViewConfiguration` API, which may be slow due to feature
+            //    flag querying.
+            if ((mPrivateFlags4 & PFLAG4_ROTARY_HAPTICS_DETERMINED) == 0) {
+                if (ViewConfiguration.get(mContext)
+                        .isViewBasedRotaryEncoderHapticScrollFeedbackEnabled()) {
+                    mPrivateFlags4 |= PFLAG4_ROTARY_HAPTICS_ENABLED;
+                }
+                mPrivateFlags4 |= PFLAG4_ROTARY_HAPTICS_DETERMINED;
+            }
+        }
+        final boolean processForRotaryScrollHaptics =
+                isRotaryEncoderEvent && ((mPrivateFlags4 & PFLAG4_ROTARY_HAPTICS_ENABLED) != 0);
+        if (processForRotaryScrollHaptics) {
+            mPrivateFlags4 &= ~PFLAG4_ROTARY_HAPTICS_SCROLL_SINCE_LAST_ROTARY_INPUT;
+            mPrivateFlags4 |= PFLAG4_ROTARY_HAPTICS_WAITING_FOR_SCROLL_EVENT;
+        }
+
         //noinspection SimplifiableIfStatement
         ListenerInfo li = mListenerInfo;
         if (li != null && li.mOnGenericMotionListener != null
@@ -15902,7 +15949,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
             return true;
         }
 
-        if (onGenericMotionEvent(event)) {
+        final boolean onGenericMotionEventResult = onGenericMotionEvent(event);
+        // Process scroll haptics after `onGenericMotionEvent`, since that's where scrolling usually
+        // happens. Some views may return false from `onGenericMotionEvent` even if they have done
+        // scrolling, so disregard the return value when processing for scroll haptics.
+        if (processForRotaryScrollHaptics) {
+            if ((mPrivateFlags4 & PFLAG4_ROTARY_HAPTICS_SCROLL_SINCE_LAST_ROTARY_INPUT) != 0) {
+                doRotaryProgressForScrollHaptics(event);
+            } else {
+                doRotaryLimitForScrollHaptics(event);
+            }
+        }
+        if (onGenericMotionEventResult) {
             return true;
         }
 
@@ -17783,6 +17841,38 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
         }
     }
 
+    private HapticScrollFeedbackProvider getScrollFeedbackProvider() {
+        if (mScrollFeedbackProvider == null) {
+            mScrollFeedbackProvider = new HapticScrollFeedbackProvider(this,
+                    ViewConfiguration.get(mContext), /* disabledIfViewPlaysScrollHaptics= */ false);
+        }
+        return mScrollFeedbackProvider;
+    }
+
+    private void doRotaryProgressForScrollHaptics(MotionEvent rotaryEvent) {
+        final float axisScrollValue = rotaryEvent.getAxisValue(MotionEvent.AXIS_SCROLL);
+        final float verticalScrollFactor =
+                ViewConfiguration.get(mContext).getScaledVerticalScrollFactor();
+        final int scrollAmount = -Math.round(axisScrollValue * verticalScrollFactor);
+        getScrollFeedbackProvider().onScrollProgress(
+                rotaryEvent.getDeviceId(), InputDevice.SOURCE_ROTARY_ENCODER,
+                MotionEvent.AXIS_SCROLL, scrollAmount);
+    }
+
+    private void doRotaryLimitForScrollHaptics(MotionEvent rotaryEvent) {
+        final boolean isStart = rotaryEvent.getAxisValue(MotionEvent.AXIS_SCROLL) > 0;
+        getScrollFeedbackProvider().onScrollLimit(
+                rotaryEvent.getDeviceId(), InputDevice.SOURCE_ROTARY_ENCODER,
+                MotionEvent.AXIS_SCROLL, isStart);
+    }
+
+    private void processScrollEventForRotaryEncoderHaptics() {
+        if ((mPrivateFlags4 |= PFLAG4_ROTARY_HAPTICS_WAITING_FOR_SCROLL_EVENT) != 0) {
+            mPrivateFlags4 |= PFLAG4_ROTARY_HAPTICS_SCROLL_SINCE_LAST_ROTARY_INPUT;
+            mPrivateFlags4 &= ~PFLAG4_ROTARY_HAPTICS_WAITING_FOR_SCROLL_EVENT;
+        }
+    }
+
     /**
      * This is called in response to an internal scroll in this view (i.e., the
      * view scrolled its own contents). This is typically as a result of
@@ -17798,6 +17888,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
         notifySubtreeAccessibilityStateChangedIfNeeded();
         postSendViewScrolledAccessibilityEventCallback(l - oldl, t - oldt);
 
+        processScrollEventForRotaryEncoderHaptics();
+
         mBackgroundSizeChanged = true;
         mDefaultFocusHighlightSizeChanged = true;
         if (mForegroundInfo != null) {
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index 6ee674ab4ab3..2cf5d5d63596 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -377,6 +377,7 @@ public class ViewConfiguration {
     private final int mSmartSelectionInitializedTimeout;
     private final int mSmartSelectionInitializingTimeout;
     private final boolean mPreferKeepClearForFocusEnabled;
+    private final boolean mViewBasedRotaryEncoderScrollHapticsEnabledConfig;
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768915)
     private boolean sHasPermanentMenuKey;
@@ -401,6 +402,7 @@ public class ViewConfiguration {
         mMaximumRotaryEncoderFlingVelocity = MAXIMUM_FLING_VELOCITY;
         mRotaryEncoderHapticScrollFeedbackEnabled = false;
         mRotaryEncoderHapticScrollFeedbackTickIntervalPixels = NO_HAPTIC_SCROLL_TICK_INTERVAL;
+        mViewBasedRotaryEncoderScrollHapticsEnabledConfig = false;
         mScrollbarSize = SCROLL_BAR_SIZE;
         mTouchSlop = TOUCH_SLOP;
         mHandwritingSlop = HANDWRITING_SLOP;
@@ -577,6 +579,9 @@ public class ViewConfiguration {
                 com.android.internal.R.integer.config_smartSelectionInitializingTimeoutMillis);
         mPreferKeepClearForFocusEnabled = res.getBoolean(
                 com.android.internal.R.bool.config_preferKeepClearForFocus);
+        mViewBasedRotaryEncoderScrollHapticsEnabledConfig =
+                res.getBoolean(
+                        com.android.internal.R.bool.config_viewBasedRotaryEncoderHapticsEnabled);
     }
 
     /**
@@ -592,8 +597,7 @@ public class ViewConfiguration {
     public static ViewConfiguration get(@NonNull @UiContext Context context) {
         StrictMode.assertConfigurationContext(context, "ViewConfiguration");
 
-        final DisplayMetrics metrics = context.getResources().getDisplayMetrics();
-        final int density = (int) (100.0f * metrics.density);
+        final int density = getDisplayDensity(context);
 
         ViewConfiguration configuration = sConfigurations.get(density);
         if (configuration == null) {
@@ -616,6 +620,16 @@ public class ViewConfiguration {
         sConfigurations.clear();
     }
 
+    /**
+     * Sets the ViewConfiguration cached instanc for a given Context for testing.
+     *
+     * @hide
+     */
+    @VisibleForTesting
+    public static void setInstanceForTesting(Context context, ViewConfiguration instance) {
+        sConfigurations.put(getDisplayDensity(context), instance);
+    }
+
     /**
      * @return The width of the horizontal scrollbar and the height of the vertical
      *         scrollbar in dips
@@ -1325,6 +1339,20 @@ public class ViewConfiguration {
         return NO_HAPTIC_SCROLL_TICK_INTERVAL;
     }
 
+    /**
+     * Checks if the View-based haptic scroll feedback implementation is enabled for
+     * {@link InputDevice#SOURCE_ROTARY_ENCODER}s.
+     *
+     * <p>If this method returns {@code true}, the {@link HapticScrollFeedbackProvider} will be
+     * muted for rotary encoders in favor of View's scroll haptics implementation.
+     *
+     * @hide
+     */
+    public boolean isViewBasedRotaryEncoderHapticScrollFeedbackEnabled() {
+        return mViewBasedRotaryEncoderScrollHapticsEnabledConfig
+                && Flags.useViewBasedRotaryEncoderScrollHaptics();
+    }
+
     private static boolean isInputDeviceInfoValid(int id, int axis, int source) {
         InputDevice device = InputManagerGlobal.getInstance().getInputDevice(id);
         return device != null && device.getMotionRange(axis, source) != null;
@@ -1434,4 +1462,9 @@ public class ViewConfiguration {
     public static int getHoverTooltipHideShortTimeout() {
         return HOVER_TOOLTIP_HIDE_SHORT_TIMEOUT;
     }
+
+    private static final int getDisplayDensity(Context context) {
+        final DisplayMetrics metrics = context.getResources().getDisplayMetrics();
+        return (int) (100.0f * metrics.density);
+    }
 }
diff --git a/core/java/android/view/flags/scroll_feedback_flags.aconfig b/core/java/android/view/flags/scroll_feedback_flags.aconfig
index 62c569152ee9..d1d871c2dbda 100644
--- a/core/java/android/view/flags/scroll_feedback_flags.aconfig
+++ b/core/java/android/view/flags/scroll_feedback_flags.aconfig
@@ -5,4 +5,11 @@ flag {
     name: "scroll_feedback_api"
     description: "Enable the scroll feedback APIs"
     bug: "239594271"
+}
+
+flag {
+    namespace: "toolkit"
+    name: "use_view_based_rotary_encoder_scroll_haptics"
+    description: "If enabled, the rotary encoder scroll haptic implementation in the View class will be used, and the HapticScrollFeedbackProvider logic for rotary encoder haptic will be muted."
+    bug: "299587011"
 }
\ No newline at end of file
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 2e2ec5ba52b3..3d0af3dbde3d 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -6711,4 +6711,7 @@
          {@link MotionEvent#AXIS_SCROLL} generated by {@link InputDevice#SOURCE_ROTARY_ENCODER}
          devices. -->
     <bool name="config_viewRotaryEncoderHapticScrollFedbackEnabled">false</bool>
+    <!-- Whether the View-based scroll haptic feedback implementation is enabled for
+         {@link InputDevice#SOURCE_ROTARY_ENCODER}s. -->
+    <bool name="config_viewBasedRotaryEncoderHapticsEnabled">false</bool>
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index fe1144958c52..e0f128d5d416 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -5235,4 +5235,5 @@
   <java-symbol type="array" name="config_tvExternalInputLoggingDeviceOnScreenDisplayNames" />
   <java-symbol type="array" name="config_tvExternalInputLoggingDeviceBrandNames" />
   <java-symbol type="bool" name="config_viewRotaryEncoderHapticScrollFedbackEnabled" />
+  <java-symbol type="bool" name="config_viewBasedRotaryEncoderHapticsEnabled" />
 </resources>
diff --git a/core/tests/coretests/src/android/view/HapticScrollFeedbackProviderTest.java b/core/tests/coretests/src/android/view/HapticScrollFeedbackProviderTest.java
index d2af2a734330..3dfeb7f0fc05 100644
--- a/core/tests/coretests/src/android/view/HapticScrollFeedbackProviderTest.java
+++ b/core/tests/coretests/src/android/view/HapticScrollFeedbackProviderTest.java
@@ -26,6 +26,7 @@ import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.platform.test.annotations.Presubmit;
+import android.view.flags.FeatureFlags;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -49,6 +50,7 @@ public final class HapticScrollFeedbackProviderTest {
     private TestView mView;
 
     @Mock ViewConfiguration mMockViewConfig;
+    @Mock FeatureFlags mMockFeatureFlags;
 
     private HapticScrollFeedbackProvider mProvider;
 
@@ -56,9 +58,52 @@ public final class HapticScrollFeedbackProviderTest {
     public void setUp() {
         mMockViewConfig = mock(ViewConfiguration.class);
         setHapticScrollFeedbackEnabled(true);
+        when(mMockViewConfig.isViewBasedRotaryEncoderHapticScrollFeedbackEnabled())
+                .thenReturn(false);
 
         mView = new TestView(InstrumentationRegistry.getContext());
-        mProvider = new HapticScrollFeedbackProvider(mView, mMockViewConfig);
+        mProvider = new HapticScrollFeedbackProvider(mView, mMockViewConfig,
+                /* disabledIfViewPlaysScrollHaptics= */ true);
+    }
+
+    @Test
+    public void testRotaryEncoder_noFeedbackWhenViewBasedFeedbackIsEnabled() {
+        when(mMockViewConfig.isViewBasedRotaryEncoderHapticScrollFeedbackEnabled())
+                .thenReturn(true);
+        setHapticScrollTickInterval(5);
+
+        mProvider.onScrollProgress(
+                INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
+                /* deltaInPixels= */ 10);
+        mProvider.onSnapToItem(
+                INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL);
+        mProvider.onScrollLimit(
+                INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
+                /* isStart= */ true);
+
+        assertNoFeedback(mView);
+    }
+
+    @Test
+    public void testRotaryEncoder_feedbackWhenDisregardingViewBasedScrollHaptics() {
+        mProvider = new HapticScrollFeedbackProvider(mView, mMockViewConfig,
+                /* disabledIfViewPlaysScrollHaptics= */ false);
+        when(mMockViewConfig.isViewBasedRotaryEncoderHapticScrollFeedbackEnabled())
+                .thenReturn(true);
+        setHapticScrollTickInterval(5);
+
+        mProvider.onScrollProgress(
+                INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
+                /* deltaInPixels= */ 10);
+        mProvider.onSnapToItem(
+                INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL);
+        mProvider.onScrollLimit(
+                INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
+                /* isStart= */ true);
+
+        assertFeedbackCount(mView, SCROLL_TICK, 1);
+        assertFeedbackCount(mView, SCROLL_ITEM_FOCUS, 1);
+        assertFeedbackCount(mView, SCROLL_LIMIT, 1);
     }
 
     @Test
@@ -94,20 +139,26 @@ public final class HapticScrollFeedbackProviderTest {
 
     @Test
     public void testScrollLimit_start() {
+        mProvider.onSnapToItem(
+                INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL);
+
         mProvider.onScrollLimit(
                 INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
                 /* isStart= */ true);
 
-        assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT);
+        assertFeedbackCount(mView, HapticFeedbackConstants.SCROLL_LIMIT, 1);
     }
 
     @Test
     public void testScrollLimit_stop() {
+        mProvider.onSnapToItem(
+                INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL);
+
         mProvider.onScrollLimit(
                 INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
                 /* isStart= */ false);
 
-        assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT);
+        assertFeedbackCount(mView, HapticFeedbackConstants.SCROLL_LIMIT, 1);
     }
 
     @Test
@@ -207,8 +258,6 @@ public final class HapticScrollFeedbackProviderTest {
                 INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
                 /* deltaInPixels= */ 60);
 
-
-
         assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_TICK, 2);
     }
 
@@ -225,6 +274,9 @@ public final class HapticScrollFeedbackProviderTest {
 
     @Test
     public void testScrollLimit_startAndEndLimit_playsOnlyOneFeedback() {
+        mProvider.onSnapToItem(
+                INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL);
+
         mProvider.onScrollLimit(
                 INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
                 /* isStart= */ false);
@@ -232,11 +284,14 @@ public final class HapticScrollFeedbackProviderTest {
                 INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
                 /* isStart= */ true);
 
-        assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT);
+        assertFeedbackCount(mView, HapticFeedbackConstants.SCROLL_LIMIT, 1);
     }
 
     @Test
     public void testScrollLimit_doubleStartLimit_playsOnlyOneFeedback() {
+        mProvider.onSnapToItem(
+                INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL);
+
         mProvider.onScrollLimit(
                 INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
                 /* isStart= */ true);
@@ -244,11 +299,14 @@ public final class HapticScrollFeedbackProviderTest {
                 INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
                 /* isStart= */ true);
 
-        assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT);
+        assertFeedbackCount(mView, HapticFeedbackConstants.SCROLL_LIMIT, 1);
     }
 
     @Test
     public void testScrollLimit_doubleEndLimit_playsOnlyOneFeedback() {
+        mProvider.onSnapToItem(
+                INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL);
+
         mProvider.onScrollLimit(
                 INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
                 /* isStart= */ false);
@@ -256,11 +314,13 @@ public final class HapticScrollFeedbackProviderTest {
                 INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
                 /* isStart= */ false);
 
-        assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT);
+        assertFeedbackCount(mView, HapticFeedbackConstants.SCROLL_LIMIT, 1);
     }
 
     @Test
     public void testScrollLimit_notEnabledWithZeroProgress() {
+        mProvider.onSnapToItem(
+                INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL);
         mProvider.onScrollLimit(
                 INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
                 /* isStart= */ false);
@@ -275,11 +335,13 @@ public final class HapticScrollFeedbackProviderTest {
                 INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
                 /* isStart= */ false);
 
-        assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT, 1);
+        assertFeedbackCount(mView, HapticFeedbackConstants.SCROLL_LIMIT, 1);
     }
 
     @Test
     public void testScrollLimit_enabledWithProgress() {
+        mProvider.onSnapToItem(
+                INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL);
         mProvider.onScrollLimit(
                 INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
                 /* isStart= */ false);
@@ -291,11 +353,13 @@ public final class HapticScrollFeedbackProviderTest {
                 INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
                 /* isStart= */ false);
 
-        assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT, 2);
+        assertFeedbackCount(mView, HapticFeedbackConstants.SCROLL_LIMIT, 2);
     }
 
     @Test
     public void testScrollLimit_enabledWithSnap() {
+        mProvider.onSnapToItem(
+                INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL);
         mProvider.onScrollLimit(
                 INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
                 /* isStart= */ false);
@@ -310,7 +374,9 @@ public final class HapticScrollFeedbackProviderTest {
     }
 
     @Test
-    public void testScrollLimit_enabledWithDissimilarSnap() {
+    public void testScrollLimit_notEnabledWithDissimilarSnap() {
+        mProvider.onSnapToItem(
+                INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL);
         mProvider.onScrollLimit(
                 INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
                 /* isStart= */ false);
@@ -321,11 +387,13 @@ public final class HapticScrollFeedbackProviderTest {
                 INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
                 /* isStart= */ false);
 
-        assertFeedbackCount(mView, HapticFeedbackConstants.SCROLL_LIMIT, 2);
+        assertFeedbackCount(mView, HapticFeedbackConstants.SCROLL_LIMIT, 1);
     }
 
     @Test
     public void testScrollLimit_enabledWithDissimilarProgress() {
+        mProvider.onSnapToItem(
+                INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL);
         mProvider.onScrollLimit(
                 INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
                 /* isStart= */ false);
@@ -337,28 +405,27 @@ public final class HapticScrollFeedbackProviderTest {
                 INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
                 /* isStart= */ false);
 
-        assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT, 2);
+        assertFeedbackCount(mView, HapticFeedbackConstants.SCROLL_LIMIT, 2);
     }
 
 
     @Test
-    public void testScrollLimit_enabledWithMotionFromDifferentDeviceId() {
+    public void testScrollLimit_doesNotEnabledWithMotionFromDifferentDeviceId() {
+        mProvider.onSnapToItem(
+                INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL);
         mProvider.onScrollLimit(
                 INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
                 /* isStart= */ false);
 
-        mProvider.onScrollLimit(
-                INPUT_DEVICE_2,
-                InputDevice.SOURCE_ROTARY_ENCODER,
-                MotionEvent.AXIS_SCROLL,
-                /* isStart= */ false);
+        mProvider.onSnapToItem(
+                INPUT_DEVICE_2, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL);
         mProvider.onScrollLimit(
                 INPUT_DEVICE_1,
                 InputDevice.SOURCE_ROTARY_ENCODER,
                 MotionEvent.AXIS_SCROLL,
                 /* isStart= */ false);
 
-        assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT, 3);
+        assertFeedbackCount(mView, HapticFeedbackConstants.SCROLL_LIMIT, 1);
     }
 
 
diff --git a/core/tests/coretests/src/android/view/RotaryScrollHapticsTest.java b/core/tests/coretests/src/android/view/RotaryScrollHapticsTest.java
new file mode 100644
index 000000000000..9a5c1c5112e6
--- /dev/null
+++ b/core/tests/coretests/src/android/view/RotaryScrollHapticsTest.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2023 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.view;
+
+import static android.view.InputDevice.SOURCE_CLASS_POINTER;
+import static android.view.InputDevice.SOURCE_ROTARY_ENCODER;
+import static android.view.MotionEvent.ACTION_SCROLL;
+import static android.view.MotionEvent.AXIS_HSCROLL;
+import static android.view.MotionEvent.AXIS_SCROLL;
+import static android.view.MotionEvent.AXIS_VSCROLL;
+
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+
+/** Test for the rotary scroll haptics implementation in the View class. */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+@Presubmit
+public final class RotaryScrollHapticsTest {
+    private static final int TEST_ROTARY_DEVICE_ID = 1;
+    private static final int TEST_RANDOM_DEVICE_ID = 2;
+
+    private static final float TEST_SCALED_VERTICAL_SCROLL_FACTOR = 5f;
+
+    @Mock ViewConfiguration mMockViewConfig;
+    @Mock HapticScrollFeedbackProvider mMockScrollFeedbackProvider;
+
+    private TestGenericMotionEventControllingView mView;
+
+    @Before
+    public void setUp() {
+        mMockViewConfig = mock(ViewConfiguration.class);
+        mMockScrollFeedbackProvider = mock(HapticScrollFeedbackProvider.class);
+
+        Context context = InstrumentationRegistry.getTargetContext();
+        mView = new TestGenericMotionEventControllingView(context);
+        mView.mScrollFeedbackProvider = mMockScrollFeedbackProvider;
+
+        ViewConfiguration.setInstanceForTesting(context, mMockViewConfig);
+        when(mMockViewConfig.getScaledVerticalScrollFactor())
+                .thenReturn(TEST_SCALED_VERTICAL_SCROLL_FACTOR);
+        mockRotaryScrollHapticsEnabled(true);
+    }
+
+    @After
+    public void tearDown() {
+        ViewConfiguration.resetCacheForTesting();
+    }
+
+    @Test
+    public void testRotaryScrollHapticsDisabled_producesNoHapticEvent() {
+        mockRotaryScrollHapticsEnabled(false);
+
+        mView.configureGenericMotion(/* result= */ false, /* scroll= */ false);
+        mView.dispatchGenericMotionEvent(createRotaryEvent(-20));
+
+        mView.configureGenericMotion(/* result= */ false, /* scroll= */ true);
+        mView.dispatchGenericMotionEvent(createRotaryEvent(20));
+
+        mView.configureGenericMotion(/* result= */ true, /* scroll= */ true);
+        mView.dispatchGenericMotionEvent(createRotaryEvent(10));
+
+        mView.configureGenericMotion(/* result= */ true, /* scroll= */ false);
+        mView.dispatchGenericMotionEvent(createRotaryEvent(-10));
+
+        verifyNoScrollLimit();
+        verifyNoScrollProgress();
+    }
+
+    @Test
+    public void testNonRotaryEncoderMotion_producesNoHapticEvent() {
+        mView.configureGenericMotion(/* result= */ false, /* scroll= */ false);
+        mView.dispatchGenericMotionEvent(createGenericPointerEvent(1, 2));
+
+        mView.configureGenericMotion(/* result= */ false, /* scroll= */ true);
+        mView.dispatchGenericMotionEvent(createGenericPointerEvent(2, 2));
+
+        mView.configureGenericMotion(/* result= */ true, /* scroll= */ true);
+        mView.dispatchGenericMotionEvent(createGenericPointerEvent(1, 3));
+
+        mView.configureGenericMotion(/* result= */ true, /* scroll= */ false);
+        mView.dispatchGenericMotionEvent(createGenericPointerEvent(-1, -2));
+
+        verifyNoScrollLimit();
+        verifyNoScrollProgress();
+    }
+
+    @Test
+    public void testScrollLimit_start_genericMotionEventCallbackReturningFalse_doesScrollLimit() {
+        mView.configureGenericMotion(/* result= */ false, /* scroll= */ false);
+
+        mView.dispatchGenericMotionEvent(createRotaryEvent(20));
+
+        verifyScrollLimit(/* isStart= */ true);
+        verifyNoScrollProgress();
+    }
+
+    @Test
+    public void testScrollLimit_start_genericMotionEventCallbackReturningTrue_doesScrollLimit() {
+        mView.configureGenericMotion(/* result= */ true, /* scroll= */ false);
+
+        mView.dispatchGenericMotionEvent(createRotaryEvent(20));
+
+        verifyScrollLimit(/* isStart= */ true);
+        verifyNoScrollProgress();
+    }
+
+    @Test
+    public void testScrollLimit_end_genericMotionEventCallbackReturningFalse_doesScrollLimit() {
+        mView.configureGenericMotion(/* result= */ false, /* scroll= */ false);
+
+        mView.dispatchGenericMotionEvent(createRotaryEvent(-20));
+
+        verifyScrollLimit(/* isStart= */ false);
+        verifyNoScrollProgress();
+    }
+
+    @Test
+    public void testScrollLimit_end_genericMotionEventCallbackReturningTrue_doesScrollLimit() {
+        mView.configureGenericMotion(/* result= */ true, /* scroll= */ false);
+
+        mView.dispatchGenericMotionEvent(createRotaryEvent(-20));
+
+        verifyScrollLimit(/* isStart= */ false);
+        verifyNoScrollProgress();
+    }
+
+    @Test
+    public void testScrollProgress_genericMotionEventCallbackReturningFalse_doesScrollProgress() {
+        mView.configureGenericMotion(/* result= */ false, /* scroll= */ true);
+
+        mView.dispatchGenericMotionEvent(createRotaryEvent(20));
+
+        verifyScrollProgress(-1 * 20 * (int) TEST_SCALED_VERTICAL_SCROLL_FACTOR);
+        verifyNoScrollLimit();
+    }
+
+    @Test
+    public void testScrollProgress_genericMotionEventCallbackReturningTrue_doesScrollProgress() {
+        mView.configureGenericMotion(/* result= */ true, /* scroll= */ true);
+
+        mView.dispatchGenericMotionEvent(createRotaryEvent(-20));
+
+        verifyScrollProgress(-1 * -20 * (int) TEST_SCALED_VERTICAL_SCROLL_FACTOR);
+        verifyNoScrollLimit();
+    }
+
+    private void verifyScrollProgress(int scrollPixels) {
+        verify(mMockScrollFeedbackProvider).onScrollProgress(
+                TEST_ROTARY_DEVICE_ID, SOURCE_ROTARY_ENCODER, AXIS_SCROLL, scrollPixels);
+    }
+
+    private void verifyNoScrollProgress() {
+        verify(mMockScrollFeedbackProvider, never()).onScrollProgress(
+                anyInt(), anyInt(), anyInt(), anyInt());
+    }
+
+    private void verifyScrollLimit(boolean isStart) {
+        verify(mMockScrollFeedbackProvider).onScrollLimit(
+                TEST_ROTARY_DEVICE_ID, SOURCE_ROTARY_ENCODER, AXIS_SCROLL, isStart);
+    }
+
+    private void verifyNoScrollLimit() {
+        verify(mMockScrollFeedbackProvider, never()).onScrollLimit(
+                anyInt(), anyInt(), anyInt(), anyBoolean());
+    }
+
+    private void mockRotaryScrollHapticsEnabled(boolean enabled) {
+        when(mMockViewConfig.isViewBasedRotaryEncoderHapticScrollFeedbackEnabled())
+                .thenReturn(enabled);
+    }
+
+    /**
+     * Test implementation for View giving control on behavior of
+     * {@link View#onGenericMotionEvent(MotionEvent)}.
+     */
+    private static final class TestGenericMotionEventControllingView extends View {
+        private boolean mGenericMotionResult;
+        private boolean mScrollOnGenericMotion;
+
+        TestGenericMotionEventControllingView(Context context) {
+            super(context);
+        }
+
+        void configureGenericMotion(boolean result, boolean scroll) {
+            mGenericMotionResult = result;
+            mScrollOnGenericMotion = scroll;
+        }
+
+        @Override
+        public boolean onGenericMotionEvent(MotionEvent event) {
+            if (mScrollOnGenericMotion) {
+                scrollTo(100, 200); // scroll values random (not relevant for tests).
+            }
+            return mGenericMotionResult;
+        }
+    }
+
+    private static MotionEvent createRotaryEvent(float scroll) {
+        MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords();
+        coords.setAxisValue(AXIS_SCROLL, scroll);
+
+        return createGenericMotionEvent(
+                TEST_ROTARY_DEVICE_ID, SOURCE_ROTARY_ENCODER, ACTION_SCROLL, coords);
+    }
+
+    private static MotionEvent createGenericPointerEvent(float hScroll, float vScroll) {
+        MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords();
+        coords.setAxisValue(AXIS_HSCROLL, hScroll);
+        coords.setAxisValue(AXIS_VSCROLL, vScroll);
+
+        return createGenericMotionEvent(
+                TEST_RANDOM_DEVICE_ID, SOURCE_CLASS_POINTER, ACTION_SCROLL, coords);
+    }
+
+    private static MotionEvent createGenericMotionEvent(
+            int deviceId, int source, int action, MotionEvent.PointerCoords coords) {
+        MotionEvent.PointerProperties props = new MotionEvent.PointerProperties();
+        props.id = 0;
+
+        return MotionEvent.obtain(
+                /* downTime= */ 0, /* eventTime= */ 100, action, /* pointerCount= */ 1,
+                new MotionEvent.PointerProperties[] {props},
+                new MotionEvent.PointerCoords[] {coords},
+                /* metaState= */ 0, /* buttonState= */ 0, /* xPrecision= */ 0, /* yPrecision= */ 0,
+                deviceId, /* edgeFlags= */ 0, source, /* flags= */ 0);
+    }
+}
-- 
GitLab


From 8a1dacc004932283081ad49f2558bea074bbf5bf Mon Sep 17 00:00:00 2001
From: Valentin Iftime <valiiftime@google.com>
Date: Tue, 18 Jul 2023 13:50:09 +0200
Subject: [PATCH 58/95] Extract alert handling into NotificationAttentionHelper

  To allow more advanced handling of alerting behavior.

MUST_SLEEP

Test: atest FrameworksUiServicesTests
Bug: 270456865
Bug: 291907312
Change-Id: Ic4a2d36d9cc79b86a6040264ac7b80b68611bd9e
---
 .../sysui/SystemUiSystemPropertiesFlags.java  |    5 +
 .../NotificationAttentionHelper.java          |  951 ++++++++
 .../NotificationManagerPrivate.java           |   28 +
 .../NotificationManagerService.java           |  179 +-
 .../NotificationAttentionHelperTest.java      | 1973 +++++++++++++++++
 .../NotificationManagerServiceTest.java       |   65 +-
 6 files changed, 3141 insertions(+), 60 deletions(-)
 create mode 100644 services/core/java/com/android/server/notification/NotificationAttentionHelper.java
 create mode 100644 services/core/java/com/android/server/notification/NotificationManagerPrivate.java
 create mode 100644 services/tests/uiservicestests/src/com/android/server/notification/NotificationAttentionHelperTest.java

diff --git a/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java b/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java
index 4a848f68abab..cb2d93474971 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java
@@ -81,6 +81,11 @@ public class SystemUiSystemPropertiesFlags {
         public static final Flag PROPAGATE_CHANNEL_UPDATES_TO_CONVERSATIONS = releasedFlag(
                 "persist.sysui.notification.propagate_channel_updates_to_conversations");
 
+        // TODO: b/291907312 - remove feature flags
+        /** Gating the NMS->NotificationAttentionHelper buzzBeepBlink refactor */
+        public static final Flag ENABLE_ATTENTION_HELPER_REFACTOR = devFlag(
+                "persist.debug.sysui.notification.enable_attention_helper_refactor");
+
         /** b/301242692: Visit extra URIs used in notifications to prevent security issues. */
         public static final Flag VISIT_RISKY_URIS = devFlag(
                 "persist.sysui.notification.visit_risky_uris");
diff --git a/services/core/java/com/android/server/notification/NotificationAttentionHelper.java b/services/core/java/com/android/server/notification/NotificationAttentionHelper.java
new file mode 100644
index 000000000000..75a0cf521a1d
--- /dev/null
+++ b/services/core/java/com/android/server/notification/NotificationAttentionHelper.java
@@ -0,0 +1,951 @@
+/*
+ * Copyright (C) 2023 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.notification;
+
+import static android.app.Notification.FLAG_INSISTENT;
+import static android.app.Notification.FLAG_ONLY_ALERT_ONCE;
+import static android.app.NotificationManager.IMPORTANCE_MIN;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
+import static android.media.AudioAttributes.USAGE_NOTIFICATION_RINGTONE;
+import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_CALL_EFFECTS;
+import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_EFFECTS;
+import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_NOTIFICATION_EFFECTS;
+
+import android.annotation.IntDef;
+import android.app.ActivityManager;
+import android.app.KeyguardManager;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.StatusBarManager;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.database.ContentObserver;
+import android.media.AudioAttributes;
+import android.media.AudioManager;
+import android.media.IRingtonePlayer;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.os.VibrationEffect;
+import android.provider.Settings;
+import android.telephony.PhoneStateListener;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.Slog;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.server.EventLogTags;
+import com.android.server.lights.LightsManager;
+import com.android.server.lights.LogicalLight;
+
+import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * NotificationManagerService helper for handling notification attention effects:
+ *  make noise, vibrate, or flash the LED.
+ * @hide
+ */
+public final class NotificationAttentionHelper {
+    static final String TAG = "NotifAttentionHelper";
+    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    static final boolean DEBUG_INTERRUPTIVENESS = SystemProperties.getBoolean(
+            "debug.notification.interruptiveness", false);
+
+    private final Context mContext;
+    private final PackageManager mPackageManager;
+    private final TelephonyManager mTelephonyManager;
+    private final NotificationManagerPrivate mNMP;
+    private final SystemUiSystemPropertiesFlags.FlagResolver mFlagResolver;
+    private AccessibilityManager mAccessibilityManager;
+    private KeyguardManager mKeyguardManager;
+    private AudioManager mAudioManager;
+    private final LightsManager mLightsManager;
+    private final NotificationUsageStats mUsageStats;
+    private final ZenModeHelper mZenModeHelper;
+
+    private VibratorHelper mVibratorHelper;
+    // The last key in this list owns the hardware.
+    ArrayList<String> mLights = new ArrayList<>();
+    private LogicalLight mNotificationLight;
+    private LogicalLight mAttentionLight;
+
+    private final boolean mUseAttentionLight;
+    boolean mHasLight = true;
+
+    private final SettingsObserver mSettingsObserver;
+
+    private boolean mIsAutomotive;
+    private boolean mNotificationEffectsEnabledForAutomotive;
+    private boolean mDisableNotificationEffects;
+    private int mCallState;
+    private String mSoundNotificationKey;
+    private String mVibrateNotificationKey;
+    private boolean mSystemReady;
+    private boolean mInCallStateOffHook = false;
+    private boolean mScreenOn = true;
+    private boolean mUserPresent = false;
+    boolean mNotificationPulseEnabled;
+    private final Uri mInCallNotificationUri;
+    private final AudioAttributes mInCallNotificationAudioAttributes;
+    private final float mInCallNotificationVolume;
+    private Binder mCallNotificationToken = null;
+
+
+    public NotificationAttentionHelper(Context context, LightsManager lightsManager,
+            AccessibilityManager accessibilityManager, PackageManager packageManager,
+            NotificationUsageStats usageStats,
+            NotificationManagerPrivate notificationManagerPrivate,
+            ZenModeHelper zenModeHelper, SystemUiSystemPropertiesFlags.FlagResolver flagResolver) {
+        mContext = context;
+        mPackageManager = packageManager;
+        mTelephonyManager = context.getSystemService(TelephonyManager.class);
+        mAccessibilityManager = accessibilityManager;
+        mLightsManager = lightsManager;
+        mNMP = notificationManagerPrivate;
+        mUsageStats = usageStats;
+        mZenModeHelper = zenModeHelper;
+        mFlagResolver = flagResolver;
+
+        mVibratorHelper = new VibratorHelper(context);
+
+        mNotificationLight = mLightsManager.getLight(LightsManager.LIGHT_ID_NOTIFICATIONS);
+        mAttentionLight = mLightsManager.getLight(LightsManager.LIGHT_ID_ATTENTION);
+
+        Resources resources = context.getResources();
+        mUseAttentionLight = resources.getBoolean(R.bool.config_useAttentionLight);
+        mHasLight =
+                resources.getBoolean(com.android.internal.R.bool.config_intrusiveNotificationLed);
+
+        // Don't start allowing notifications until the setup wizard has run once.
+        // After that, including subsequent boots, init with notifications turned on.
+        // This works on the first boot because the setup wizard will toggle this
+        // flag at least once and we'll go back to 0 after that.
+        if (Settings.Global.getInt(context.getContentResolver(),
+                Settings.Global.DEVICE_PROVISIONED, 0) == 0) {
+            mDisableNotificationEffects = true;
+        }
+
+        mInCallNotificationUri = Uri.parse(
+                "file://" + resources.getString(R.string.config_inCallNotificationSound));
+        mInCallNotificationAudioAttributes = new AudioAttributes.Builder()
+                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
+                .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
+                .build();
+        mInCallNotificationVolume = resources.getFloat(R.dimen.config_inCallNotificationVolume);
+
+        mSettingsObserver = new SettingsObserver();
+    }
+
+    public void onSystemReady() {
+        mSystemReady = true;
+
+        mIsAutomotive = mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0);
+        mNotificationEffectsEnabledForAutomotive = mContext.getResources().getBoolean(
+                R.bool.config_enableServerNotificationEffectsForAutomotive);
+
+        mAudioManager = mContext.getSystemService(AudioManager.class);
+        mKeyguardManager = mContext.getSystemService(KeyguardManager.class);
+
+        registerBroadcastListeners();
+    }
+
+    private void registerBroadcastListeners() {
+        if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            mTelephonyManager.listen(new PhoneStateListener() {
+                @Override
+                public void onCallStateChanged(int state, String incomingNumber) {
+                    if (mCallState == state) return;
+                    if (DEBUG) Slog.d(TAG, "Call state changed: " + callStateToString(state));
+                    mCallState = state;
+                }
+            }, PhoneStateListener.LISTEN_CALL_STATE);
+        }
+
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_SCREEN_ON);
+        filter.addAction(Intent.ACTION_SCREEN_OFF);
+        filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
+        filter.addAction(Intent.ACTION_USER_PRESENT);
+        mContext.registerReceiverAsUser(mIntentReceiver, UserHandle.ALL, filter, null, null);
+
+        mContext.getContentResolver().registerContentObserver(
+                SettingsObserver.NOTIFICATION_LIGHT_PULSE_URI, false, mSettingsObserver,
+                UserHandle.USER_ALL);
+    }
+
+    @VisibleForTesting
+    /**
+     * Determine whether this notification should attempt to make noise, vibrate, or flash the LED
+     * @return buzzBeepBlink - bitfield (buzz ? 1 : 0) | (beep ? 2 : 0) | (blink ? 4 : 0) |
+     *  (polite_attenuated ? 8 : 0) | (polite_muted ? 16 : 0)
+     */
+    int buzzBeepBlinkLocked(NotificationRecord record, Signals signals) {
+        if (mIsAutomotive && !mNotificationEffectsEnabledForAutomotive) {
+            return 0;
+        }
+        boolean buzz = false;
+        boolean beep = false;
+        boolean blink = false;
+
+        final String key = record.getKey();
+
+        if (DEBUG) {
+            Log.d(TAG, "buzzBeepBlinkLocked " + record);
+        }
+
+        // Should this notification make noise, vibe, or use the LED?
+        final boolean aboveThreshold =
+                mIsAutomotive
+                        ? record.getImportance() > NotificationManager.IMPORTANCE_DEFAULT
+                        : record.getImportance() >= NotificationManager.IMPORTANCE_DEFAULT;
+        // Remember if this notification already owns the notification channels.
+        boolean wasBeep = key != null && key.equals(mSoundNotificationKey);
+        boolean wasBuzz = key != null && key.equals(mVibrateNotificationKey);
+        // These are set inside the conditional if the notification is allowed to make noise.
+        boolean hasValidVibrate = false;
+        boolean hasValidSound = false;
+        boolean sentAccessibilityEvent = false;
+
+        // If the notification will appear in the status bar, it should send an accessibility event
+        final boolean suppressedByDnd = record.isIntercepted()
+                && (record.getSuppressedVisualEffects() & SUPPRESSED_EFFECT_STATUS_BAR) != 0;
+        if (!record.isUpdate
+                && record.getImportance() > IMPORTANCE_MIN
+                && !suppressedByDnd
+                && isNotificationForCurrentUser(record, signals)) {
+            sendAccessibilityEvent(record);
+            sentAccessibilityEvent = true;
+        }
+
+        if (aboveThreshold && isNotificationForCurrentUser(record, signals)) {
+            if (mSystemReady && mAudioManager != null) {
+                Uri soundUri = record.getSound();
+                hasValidSound = soundUri != null && !Uri.EMPTY.equals(soundUri);
+                VibrationEffect vibration = record.getVibration();
+                // Demote sound to vibration if vibration missing & phone in vibration mode.
+                if (vibration == null
+                        && hasValidSound
+                        && (mAudioManager.getRingerModeInternal()
+                        == AudioManager.RINGER_MODE_VIBRATE)
+                        && mAudioManager.getStreamVolume(
+                        AudioAttributes.toLegacyStreamType(record.getAudioAttributes())) == 0) {
+                    boolean insistent = (record.getFlags() & Notification.FLAG_INSISTENT) != 0;
+                    vibration = mVibratorHelper.createFallbackVibration(insistent);
+                }
+                hasValidVibrate = vibration != null;
+                boolean hasAudibleAlert = hasValidSound || hasValidVibrate;
+                if (hasAudibleAlert && !shouldMuteNotificationLocked(record, signals)) {
+                    if (!sentAccessibilityEvent) {
+                        sendAccessibilityEvent(record);
+                        sentAccessibilityEvent = true;
+                    }
+                    if (DEBUG) Slog.v(TAG, "Interrupting!");
+                    boolean isInsistentUpdate = isInsistentUpdate(record);
+                    if (hasValidSound) {
+                        if (isInsistentUpdate) {
+                            // don't reset insistent sound, it's jarring
+                            beep = true;
+                        } else {
+                            if (isInCall()) {
+                                playInCallNotification();
+                                beep = true;
+                            } else {
+                                beep = playSound(record, soundUri);
+                            }
+                            if (beep) {
+                                mSoundNotificationKey = key;
+                            }
+                        }
+                    }
+
+                    final boolean ringerModeSilent =
+                            mAudioManager.getRingerModeInternal()
+                                    == AudioManager.RINGER_MODE_SILENT;
+                    if (!isInCall() && hasValidVibrate && !ringerModeSilent) {
+                        if (isInsistentUpdate) {
+                            buzz = true;
+                        } else {
+                            buzz = playVibration(record, vibration, hasValidSound);
+                            if (buzz) {
+                                mVibrateNotificationKey = key;
+                            }
+                        }
+                    }
+
+                    // Try to start flash notification event whenever an audible and non-suppressed
+                    // notification is received
+                    mAccessibilityManager.startFlashNotificationEvent(mContext,
+                            AccessibilityManager.FLASH_REASON_NOTIFICATION,
+                            record.getSbn().getPackageName());
+
+                } else if ((record.getFlags() & Notification.FLAG_INSISTENT) != 0) {
+                    hasValidSound = false;
+                }
+            }
+        }
+        // If a notification is updated to remove the actively playing sound or vibrate,
+        // cancel that feedback now
+        if (wasBeep && !hasValidSound) {
+            clearSoundLocked();
+        }
+        if (wasBuzz && !hasValidVibrate) {
+            clearVibrateLocked();
+        }
+
+        // light
+        // release the light
+        boolean wasShowLights = mLights.remove(key);
+        if (canShowLightsLocked(record, signals, aboveThreshold)) {
+            mLights.add(key);
+            updateLightsLocked();
+            if (mUseAttentionLight && mAttentionLight != null) {
+                mAttentionLight.pulse();
+            }
+            blink = true;
+        } else if (wasShowLights) {
+            updateLightsLocked();
+        }
+        final int buzzBeepBlink =
+                (buzz ? 1 : 0) | (beep ? 2 : 0) | (blink ? 4 : 0);
+        if (buzzBeepBlink > 0) {
+            // Ignore summary updates because we don't display most of the information.
+            if (record.getSbn().isGroup() && record.getSbn().getNotification().isGroupSummary()) {
+                if (DEBUG_INTERRUPTIVENESS) {
+                    Slog.v(TAG, "INTERRUPTIVENESS: "
+                            + record.getKey() + " is not interruptive: summary");
+                }
+            } else if (record.canBubble()) {
+                if (DEBUG_INTERRUPTIVENESS) {
+                    Slog.v(TAG, "INTERRUPTIVENESS: "
+                            + record.getKey() + " is not interruptive: bubble");
+                }
+            } else {
+                record.setInterruptive(true);
+                if (DEBUG_INTERRUPTIVENESS) {
+                    Slog.v(TAG, "INTERRUPTIVENESS: "
+                            + record.getKey() + " is interruptive: alerted");
+                }
+            }
+            MetricsLogger.action(record.getLogMaker()
+                    .setCategory(MetricsEvent.NOTIFICATION_ALERT)
+                    .setType(MetricsEvent.TYPE_OPEN)
+                    .setSubtype(buzzBeepBlink));
+            EventLogTags.writeNotificationAlert(key, buzz ? 1 : 0, beep ? 1 : 0, blink ? 1 : 0);
+        }
+        record.setAudiblyAlerted(buzz || beep);
+
+        return buzzBeepBlink;
+    }
+
+    boolean isInsistentUpdate(final NotificationRecord record) {
+        return (Objects.equals(record.getKey(), mSoundNotificationKey)
+                || Objects.equals(record.getKey(), mVibrateNotificationKey))
+                && isCurrentlyInsistent();
+    }
+
+    boolean isCurrentlyInsistent() {
+        return isLoopingRingtoneNotification(mNMP.getNotificationByKey(mSoundNotificationKey))
+                || isLoopingRingtoneNotification(
+                mNMP.getNotificationByKey(mVibrateNotificationKey));
+    }
+
+    boolean shouldMuteNotificationLocked(final NotificationRecord record, final Signals signals) {
+        // Suppressed because it's a silent update
+        final Notification notification = record.getNotification();
+        if (record.isUpdate && (notification.flags & FLAG_ONLY_ALERT_ONCE) != 0) {
+            return true;
+        }
+
+        // Suppressed because a user manually unsnoozed something (or similar)
+        if (record.shouldPostSilently()) {
+            return true;
+        }
+
+        // muted by listener
+        final String disableEffects = disableNotificationEffects(record, signals.listenerHints);
+        if (disableEffects != null) {
+            ZenLog.traceDisableEffects(record, disableEffects);
+            return true;
+        }
+
+        // suppressed due to DND
+        if (record.isIntercepted()) {
+            return true;
+        }
+
+        // Suppressed because another notification in its group handles alerting
+        if (record.getSbn().isGroup()) {
+            if (notification.suppressAlertingDueToGrouping()) {
+                return true;
+            }
+        }
+
+        // Suppressed for being too recently noisy
+        final String pkg = record.getSbn().getPackageName();
+        if (mUsageStats.isAlertRateLimited(pkg)) {
+            Slog.e(TAG, "Muting recently noisy " + record.getKey());
+            return true;
+        }
+
+        // A different looping ringtone, such as an incoming call is playing
+        if (isCurrentlyInsistent() && !isInsistentUpdate(record)) {
+            return true;
+        }
+
+        // Suppressed since it's a non-interruptive update to a bubble-suppressed notification
+        final boolean isBubbleOrOverflowed = record.canBubble() && (record.isFlagBubbleRemoved()
+                || record.getNotification().isBubbleNotification());
+        if (record.isUpdate && !record.isInterruptive() && isBubbleOrOverflowed
+                && record.getNotification().getBubbleMetadata() != null) {
+            if (record.getNotification().getBubbleMetadata().isNotificationSuppressed()) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    private boolean isLoopingRingtoneNotification(final NotificationRecord playingRecord) {
+        if (playingRecord != null) {
+            if (playingRecord.getAudioAttributes().getUsage() == USAGE_NOTIFICATION_RINGTONE
+                    && (playingRecord.getNotification().flags & FLAG_INSISTENT) != 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean playSound(final NotificationRecord record, Uri soundUri) {
+        boolean looping = (record.getNotification().flags & FLAG_INSISTENT) != 0;
+        // play notifications if there is no user of exclusive audio focus
+        // and the stream volume is not 0 (non-zero volume implies not silenced by SILENT or
+        //   VIBRATE ringer mode)
+        if (!mAudioManager.isAudioFocusExclusive()
+                && (mAudioManager.getStreamVolume(
+                AudioAttributes.toLegacyStreamType(record.getAudioAttributes())) != 0)) {
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                final IRingtonePlayer player = mAudioManager.getRingtonePlayer();
+                if (player != null) {
+                    if (DEBUG) {
+                        Slog.v(TAG, "Playing sound " + soundUri + " with attributes "
+                                + record.getAudioAttributes());
+                    }
+                    player.playAsync(soundUri, record.getSbn().getUser(), looping,
+                            record.getAudioAttributes());
+                    return true;
+                }
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed playSound: " + e);
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
+        return false;
+    }
+
+    private boolean playVibration(final NotificationRecord record, final VibrationEffect effect,
+            boolean delayVibForSound) {
+        // Escalate privileges so we can use the vibrator even if the
+        // notifying app does not have the VIBRATE permission.
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            if (delayVibForSound) {
+                new Thread(() -> {
+                    // delay the vibration by the same amount as the notification sound
+                    final int waitMs = mAudioManager.getFocusRampTimeMs(
+                            AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK,
+                            record.getAudioAttributes());
+                    if (DEBUG) {
+                        Slog.v(TAG, "Delaying vibration for notification "
+                                + record.getKey() + " by " + waitMs + "ms");
+                    }
+                    try {
+                        Thread.sleep(waitMs);
+                    } catch (InterruptedException e) { }
+                    // Notifications might be canceled before it actually vibrates due to waitMs,
+                    // so need to check that the notification is still valid for vibrate.
+                    if (mNMP.getNotificationByKey(record.getKey()) != null) {
+                        if (record.getKey().equals(mVibrateNotificationKey)) {
+                            vibrate(record, effect, true);
+                        } else {
+                            if (DEBUG) {
+                                Slog.v(TAG, "No vibration for notification "
+                                        + record.getKey() + ": a new notification is "
+                                        + "vibrating, or effects were cleared while waiting");
+                            }
+                        }
+                    } else {
+                        Slog.w(TAG, "No vibration for canceled notification "
+                                + record.getKey());
+                    }
+                }).start();
+            } else {
+                vibrate(record, effect, false);
+            }
+            return true;
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    private void vibrate(NotificationRecord record, VibrationEffect effect, boolean delayed) {
+        // We need to vibrate as "android" so we can breakthrough DND. VibratorManagerService
+        // doesn't have a concept of vibrating on an app's behalf, so add the app information
+        // to the reason so we can still debug from bugreports
+        String reason = "Notification (" + record.getSbn().getOpPkg() + " "
+                + record.getSbn().getUid() + ") " + (delayed ? "(Delayed)" : "");
+        mVibratorHelper.vibrate(effect, record.getAudioAttributes(), reason);
+    }
+
+    void playInCallNotification() {
+        // TODO: Should we apply politeness to mInCallNotificationVolume ?
+        final ContentResolver cr = mContext.getContentResolver();
+        if (mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_NORMAL
+                && Settings.Secure.getIntForUser(cr,
+                Settings.Secure.IN_CALL_NOTIFICATION_ENABLED, 1, cr.getUserId()) != 0) {
+            new Thread() {
+                @Override
+                public void run() {
+                    final long identity = Binder.clearCallingIdentity();
+                    try {
+                        final IRingtonePlayer player = mAudioManager.getRingtonePlayer();
+                        if (player != null) {
+                            if (mCallNotificationToken != null) {
+                                player.stop(mCallNotificationToken);
+                            }
+                            mCallNotificationToken = new Binder();
+                            player.play(mCallNotificationToken, mInCallNotificationUri,
+                                    mInCallNotificationAudioAttributes,
+                                    mInCallNotificationVolume, false);
+                        }
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "Failed playInCallNotification: " + e);
+                    } finally {
+                        Binder.restoreCallingIdentity(identity);
+                    }
+                }
+            }.start();
+        }
+    }
+
+    void clearSoundLocked() {
+        mSoundNotificationKey = null;
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            final IRingtonePlayer player = mAudioManager.getRingtonePlayer();
+            if (player != null) {
+                player.stopAsync();
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed clearSoundLocked: " + e);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    void clearVibrateLocked() {
+        mVibrateNotificationKey = null;
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            mVibratorHelper.cancelVibration();
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    private void clearLightsLocked() {
+        // light
+        mLights.clear();
+        updateLightsLocked();
+    }
+
+    public void clearEffectsLocked(String key) {
+        if (key.equals(mSoundNotificationKey)) {
+            clearSoundLocked();
+        }
+        if (key.equals(mVibrateNotificationKey)) {
+            clearVibrateLocked();
+        }
+        boolean removed = mLights.remove(key);
+        if (removed) {
+            updateLightsLocked();
+        }
+    }
+
+    public void clearAttentionEffects() {
+        clearSoundLocked();
+        clearVibrateLocked();
+        clearLightsLocked();
+    }
+
+    void updateLightsLocked() {
+        if (mNotificationLight == null) {
+            return;
+        }
+
+        // handle notification lights
+        NotificationRecord ledNotification = null;
+        while (ledNotification == null && !mLights.isEmpty()) {
+            final String owner = mLights.get(mLights.size() - 1);
+            ledNotification = mNMP.getNotificationByKey(owner);
+            if (ledNotification == null) {
+                Slog.wtfStack(TAG, "LED Notification does not exist: " + owner);
+                mLights.remove(owner);
+            }
+        }
+
+        // Don't flash while we are in a call or screen is on
+        if (ledNotification == null || isInCall() || mScreenOn) {
+            mNotificationLight.turnOff();
+        } else {
+            NotificationRecord.Light light = ledNotification.getLight();
+            if (light != null && mNotificationPulseEnabled) {
+                // pulse repeatedly
+                mNotificationLight.setFlashing(light.color, LogicalLight.LIGHT_FLASH_TIMED,
+                        light.onMs, light.offMs);
+            }
+        }
+    }
+
+    boolean canShowLightsLocked(final NotificationRecord record, final Signals signals,
+            boolean aboveThreshold) {
+        // device lacks light
+        if (!mHasLight) {
+            return false;
+        }
+        // user turned lights off globally
+        if (!mNotificationPulseEnabled) {
+            return false;
+        }
+        // the notification/channel has no light
+        if (record.getLight() == null) {
+            return false;
+        }
+        // unimportant notification
+        if (!aboveThreshold) {
+            return false;
+        }
+        // suppressed due to DND
+        if ((record.getSuppressedVisualEffects() & SUPPRESSED_EFFECT_LIGHTS) != 0) {
+            return false;
+        }
+        // Suppressed because it's a silent update
+        final Notification notification = record.getNotification();
+        if (record.isUpdate && (notification.flags & FLAG_ONLY_ALERT_ONCE) != 0) {
+            return false;
+        }
+        // Suppressed because another notification in its group handles alerting
+        if (record.getSbn().isGroup() && record.getNotification().suppressAlertingDueToGrouping()) {
+            return false;
+        }
+        // not if in call
+        if (isInCall()) {
+            return false;
+        }
+        // check current user
+        if (!isNotificationForCurrentUser(record, signals)) {
+            return false;
+        }
+        // Light, but only when the screen is off
+        return true;
+    }
+
+    private String disableNotificationEffects(NotificationRecord record, int listenerHints) {
+        if (mDisableNotificationEffects) {
+            return "booleanState";
+        }
+
+        if ((listenerHints & HINT_HOST_DISABLE_EFFECTS) != 0) {
+            return "listenerHints";
+        }
+        if (record != null && record.getAudioAttributes() != null) {
+            if ((listenerHints & HINT_HOST_DISABLE_NOTIFICATION_EFFECTS) != 0) {
+                if (record.getAudioAttributes().getUsage()
+                        != AudioAttributes.USAGE_NOTIFICATION_RINGTONE) {
+                    return "listenerNoti";
+                }
+            }
+            if ((listenerHints & HINT_HOST_DISABLE_CALL_EFFECTS) != 0) {
+                if (record.getAudioAttributes().getUsage()
+                        == AudioAttributes.USAGE_NOTIFICATION_RINGTONE) {
+                    return "listenerCall";
+                }
+            }
+        }
+        if (mCallState != TelephonyManager.CALL_STATE_IDLE && !mZenModeHelper.isCall(record)) {
+            return "callState";
+        }
+
+        return null;
+    }
+
+    public void updateDisableNotificationEffectsLocked(int status) {
+        mDisableNotificationEffects =
+                (status & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
+        //if (disableNotificationEffects(null) != null) {
+        if (mDisableNotificationEffects) {
+            // cancel whatever is going on
+            clearAttentionEffects();
+        }
+    }
+
+    private boolean isInCall() {
+        if (mInCallStateOffHook) {
+            return true;
+        }
+        int audioMode = mAudioManager.getMode();
+        if (audioMode == AudioManager.MODE_IN_CALL
+                || audioMode == AudioManager.MODE_IN_COMMUNICATION) {
+            return true;
+        }
+        return false;
+    }
+
+    private static String callStateToString(int state) {
+        switch (state) {
+            case TelephonyManager.CALL_STATE_IDLE: return "CALL_STATE_IDLE";
+            case TelephonyManager.CALL_STATE_RINGING: return "CALL_STATE_RINGING";
+            case TelephonyManager.CALL_STATE_OFFHOOK: return "CALL_STATE_OFFHOOK";
+            default: return "CALL_STATE_UNKNOWN_" + state;
+        }
+    }
+
+    private boolean isNotificationForCurrentUser(final NotificationRecord record,
+            final Signals signals) {
+        final int currentUser;
+        final long token = Binder.clearCallingIdentity();
+        try {
+            currentUser = ActivityManager.getCurrentUser();
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+        return (record.getUserId() == UserHandle.USER_ALL || record.getUserId() == currentUser
+                || signals.isCurrentProfile);
+    }
+
+    void sendAccessibilityEvent(NotificationRecord record) {
+        if (!mAccessibilityManager.isEnabled()) {
+            return;
+        }
+
+        final Notification notification = record.getNotification();
+        final CharSequence packageName = record.getSbn().getPackageName();
+        final AccessibilityEvent event =
+                AccessibilityEvent.obtain(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
+        event.setPackageName(packageName);
+        event.setClassName(Notification.class.getName());
+        final int visibilityOverride = record.getPackageVisibilityOverride();
+        final int notifVisibility = visibilityOverride == NotificationManager.VISIBILITY_NO_OVERRIDE
+                ? notification.visibility : visibilityOverride;
+        final int userId = record.getUser().getIdentifier();
+        final boolean needPublic = userId >= 0 && mKeyguardManager.isDeviceLocked(userId);
+        if (needPublic && notifVisibility != Notification.VISIBILITY_PUBLIC) {
+            // Emit the public version if we're on the lockscreen and this notification isn't
+            // publicly visible.
+            event.setParcelableData(notification.publicVersion);
+        } else {
+            event.setParcelableData(notification);
+        }
+        final CharSequence tickerText = notification.tickerText;
+        if (!TextUtils.isEmpty(tickerText)) {
+            event.getText().add(tickerText);
+        }
+
+        mAccessibilityManager.sendAccessibilityEvent(event);
+    }
+
+    public void dump(PrintWriter pw, String prefix, NotificationManagerService.DumpFilter filter) {
+        pw.println("\n  Notification attention state:");
+        pw.print(prefix);
+        pw.println("  mSoundNotificationKey=" + mSoundNotificationKey);
+        pw.print(prefix);
+        pw.println("  mVibrateNotificationKey=" + mVibrateNotificationKey);
+        pw.print(prefix);
+        pw.println("  mDisableNotificationEffects=" + mDisableNotificationEffects);
+        pw.print(prefix);
+        pw.println("  mCallState=" + callStateToString(mCallState));
+        pw.print(prefix);
+        pw.println("  mSystemReady=" + mSystemReady);
+        pw.print(prefix);
+        pw.println("  mNotificationPulseEnabled=" + mNotificationPulseEnabled);
+
+        int N = mLights.size();
+        if (N > 0) {
+            pw.print(prefix);
+            pw.println("  Lights List:");
+            for (int i=0; i<N; i++) {
+                if (i == N - 1) {
+                    pw.print("  > ");
+                } else {
+                    pw.print("    ");
+                }
+                pw.println(mLights.get(i));
+            }
+            pw.println("  ");
+        }
+
+    }
+
+    // External signals set from NMS
+    public static class Signals {
+        private final boolean isCurrentProfile;
+        private final int listenerHints;
+
+        public Signals(boolean isCurrentProfile, int listenerHints) {
+            this.isCurrentProfile = isCurrentProfile;
+            this.listenerHints = listenerHints;
+        }
+    }
+
+    //======================  Observers  =============================
+    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+
+            if (action.equals(Intent.ACTION_SCREEN_ON)) {
+                // Keep track of screen on/off state, but do not turn off the notification light
+                // until user passes through the lock screen or views the notification.
+                mScreenOn = true;
+                updateLightsLocked();
+            } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
+                mScreenOn = false;
+                mUserPresent = false;
+                updateLightsLocked();
+            } else if (action.equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
+                mInCallStateOffHook = TelephonyManager.EXTRA_STATE_OFFHOOK
+                        .equals(intent.getStringExtra(TelephonyManager.EXTRA_STATE));
+                updateLightsLocked();
+            } else if (action.equals(Intent.ACTION_USER_PRESENT)) {
+                mUserPresent = true;
+                // turn off LED when user passes through lock screen
+                if (mNotificationLight != null) {
+                    mNotificationLight.turnOff();
+                }
+            }
+        }
+    };
+
+    private final class SettingsObserver extends ContentObserver {
+
+        private static final Uri NOTIFICATION_LIGHT_PULSE_URI = Settings.System.getUriFor(
+                Settings.System.NOTIFICATION_LIGHT_PULSE);
+        public SettingsObserver() {
+            super(null);
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            if (NOTIFICATION_LIGHT_PULSE_URI.equals(uri)) {
+                boolean pulseEnabled = Settings.System.getIntForUser(
+                        mContext.getContentResolver(),
+                        Settings.System.NOTIFICATION_LIGHT_PULSE, 0,
+                        UserHandle.USER_CURRENT)
+                        != 0;
+                if (mNotificationPulseEnabled != pulseEnabled) {
+                    mNotificationPulseEnabled = pulseEnabled;
+                    updateLightsLocked();
+                }
+            }
+        }
+    }
+
+
+    //TODO: cleanup most (all?) of these
+    //======================= FOR TESTS =====================
+    @VisibleForTesting
+    void setIsAutomotive(boolean isAutomotive) {
+        mIsAutomotive = isAutomotive;
+    }
+
+    @VisibleForTesting
+    void setNotificationEffectsEnabledForAutomotive(boolean isEnabled) {
+        mNotificationEffectsEnabledForAutomotive = isEnabled;
+    }
+
+    @VisibleForTesting
+    void setSystemReady(boolean systemReady) {
+        mSystemReady = systemReady;
+    }
+
+    @VisibleForTesting
+    void setKeyguardManager(KeyguardManager keyguardManager) {
+        mKeyguardManager = keyguardManager;
+    }
+
+    @VisibleForTesting
+    void setAccessibilityManager(AccessibilityManager am) {
+        mAccessibilityManager = am;
+    }
+
+    @VisibleForTesting
+    VibratorHelper getVibratorHelper() {
+        return mVibratorHelper;
+    }
+
+    @VisibleForTesting
+    void setVibratorHelper(VibratorHelper helper) {
+        mVibratorHelper = helper;
+    }
+
+    @VisibleForTesting
+    void setScreenOn(boolean on) {
+        mScreenOn = on;
+    }
+
+    @VisibleForTesting
+    void setLights(LogicalLight light) {
+        mNotificationLight = light;
+        mAttentionLight = light;
+        mNotificationPulseEnabled = true;
+        mHasLight = true;
+    }
+
+    @VisibleForTesting
+    void setAudioManager(AudioManager audioManager) {
+        mAudioManager = audioManager;
+    }
+
+    @VisibleForTesting
+    void setInCallStateOffHook(boolean inCallStateOffHook) {
+        mInCallStateOffHook = inCallStateOffHook;
+    }
+
+}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerPrivate.java b/services/core/java/com/android/server/notification/NotificationManagerPrivate.java
new file mode 100644
index 000000000000..2cc63ebfc962
--- /dev/null
+++ b/services/core/java/com/android/server/notification/NotificationManagerPrivate.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2023 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.notification;
+
+import android.annotation.Nullable;
+
+/**
+ * Interface that allows components (helpers) to access NotificationRecords
+ * without an explicit reference to NotificationManagerService.
+ */
+interface NotificationManagerPrivate {
+    @Nullable
+    NotificationRecord getNotificationByKey(String key);
+}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index bada8165766c..802dfb182297 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -287,6 +287,7 @@ import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.compat.IPlatformCompat;
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags;
+import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags;
 import com.android.internal.logging.InstanceId;
 import com.android.internal.logging.InstanceIdSequence;
 import com.android.internal.logging.MetricsLogger;
@@ -315,6 +316,7 @@ import com.android.server.SystemService;
 import com.android.server.job.JobSchedulerInternal;
 import com.android.server.lights.LightsManager;
 import com.android.server.lights.LogicalLight;
+import com.android.server.notification.Flags;
 import com.android.server.notification.ManagedServices.ManagedServiceInfo;
 import com.android.server.notification.ManagedServices.UserProfiles;
 import com.android.server.notification.toast.CustomToastRecord;
@@ -684,6 +686,7 @@ public class NotificationManagerService extends SystemService {
     private boolean mIsAutomotive;
     private boolean mNotificationEffectsEnabledForAutomotive;
     private DeviceConfig.OnPropertiesChangedListener mDeviceConfigChangedListener;
+    protected NotificationAttentionHelper mAttentionHelper;
 
     private int mWarnRemoteViewsSizeBytes;
     private int mStripRemoteViewsSizeBytes;
@@ -1167,12 +1170,16 @@ public class NotificationManagerService extends SystemService {
         @Override
         public void onSetDisabled(int status) {
             synchronized (mNotificationLock) {
-                mDisableNotificationEffects =
-                        (status & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
-                if (disableNotificationEffects(null) != null) {
-                    // cancel whatever's going on
-                    clearSoundLocked();
-                    clearVibrateLocked();
+                if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
+                    mAttentionHelper.updateDisableNotificationEffectsLocked(status);
+                } else {
+                    mDisableNotificationEffects =
+                            (status & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
+                    if (disableNotificationEffects(null) != null) {
+                        // cancel whatever's going on
+                        clearSoundLocked();
+                        clearVibrateLocked();
+                    }
                 }
             }
         }
@@ -1309,9 +1316,13 @@ public class NotificationManagerService extends SystemService {
         public void clearEffects() {
             synchronized (mNotificationLock) {
                 if (DBG) Slog.d(TAG, "clearEffects");
-                clearSoundLocked();
-                clearVibrateLocked();
-                clearLightsLocked();
+                if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
+                    mAttentionHelper.clearAttentionEffects();
+                } else {
+                    clearSoundLocked();
+                    clearVibrateLocked();
+                    clearLightsLocked();
+                }
             }
         }
 
@@ -1534,7 +1545,12 @@ public class NotificationManagerService extends SystemService {
                         int changedFlags = data.getFlags() ^ flags;
                         if ((changedFlags & FLAG_SUPPRESS_NOTIFICATION) != 0) {
                             // Suppress notification flag changed, clear any effects
-                            clearEffectsLocked(key);
+                            if (mFlagResolver.isEnabled(
+                                    NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
+                                mAttentionHelper.clearEffectsLocked(key);
+                            } else {
+                                clearEffectsLocked(key);
+                            }
                         }
                         data.setFlags(flags);
                         // Shouldn't alert again just because of a flag change.
@@ -1626,6 +1642,12 @@ public class NotificationManagerService extends SystemService {
 
     };
 
+    NotificationManagerPrivate mNotificationManagerPrivate = key -> {
+        synchronized (mNotificationLock) {
+            return mNotificationsByKey.get(key);
+        }
+    };
+
     @VisibleForTesting
     void logSmartSuggestionsVisible(NotificationRecord r, int notificationLocation) {
         // If the newly visible notification has smart suggestions
@@ -1873,19 +1895,28 @@ public class NotificationManagerService extends SystemService {
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
 
-            if (action.equals(Intent.ACTION_SCREEN_ON)) {
-                // Keep track of screen on/off state, but do not turn off the notification light
-                // until user passes through the lock screen or views the notification.
-                mScreenOn = true;
-                updateNotificationPulse();
-            } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
-                mScreenOn = false;
-                updateNotificationPulse();
-            } else if (action.equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
-                mInCallStateOffHook = TelephonyManager.EXTRA_STATE_OFFHOOK
+            if (!mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
+                if (action.equals(Intent.ACTION_SCREEN_ON)) {
+                    // Keep track of screen on/off state, but do not turn off the notification light
+                    // until user passes through the lock screen or views the notification.
+                    mScreenOn = true;
+                    updateNotificationPulse();
+                } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
+                    mScreenOn = false;
+                    updateNotificationPulse();
+                } else if (action.equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
+                    mInCallStateOffHook = TelephonyManager.EXTRA_STATE_OFFHOOK
                         .equals(intent.getStringExtra(TelephonyManager.EXTRA_STATE));
-                updateNotificationPulse();
-            } else if (action.equals(Intent.ACTION_USER_STOPPED)) {
+                    updateNotificationPulse();
+                } else if (action.equals(Intent.ACTION_USER_PRESENT)) {
+                    // turn off LED when user passes through lock screen
+                    if (mNotificationLight != null) {
+                        mNotificationLight.turnOff();
+                    }
+                }
+            }
+
+            if (action.equals(Intent.ACTION_USER_STOPPED)) {
                 int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
                 if (userHandle >= 0) {
                     cancelAllNotificationsInt(MY_UID, MY_PID, null, null, 0, 0, userHandle,
@@ -1898,11 +1929,6 @@ public class NotificationManagerService extends SystemService {
                             REASON_PROFILE_TURNED_OFF);
                     mSnoozeHelper.clearData(userHandle);
                 }
-            } else if (action.equals(Intent.ACTION_USER_PRESENT)) {
-                // turn off LED when user passes through lock screen
-                if (mNotificationLight != null) {
-                    mNotificationLight.turnOff();
-                }
             } else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
                 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL);
                 mUserProfiles.updateCache(context);
@@ -1976,8 +2002,10 @@ public class NotificationManagerService extends SystemService {
             ContentResolver resolver = getContext().getContentResolver();
             resolver.registerContentObserver(NOTIFICATION_BADGING_URI,
                     false, this, UserHandle.USER_ALL);
-            resolver.registerContentObserver(NOTIFICATION_LIGHT_PULSE_URI,
+            if (!mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
+                resolver.registerContentObserver(NOTIFICATION_LIGHT_PULSE_URI,
                     false, this, UserHandle.USER_ALL);
+            }
             resolver.registerContentObserver(NOTIFICATION_RATE_LIMIT_URI,
                     false, this, UserHandle.USER_ALL);
             resolver.registerContentObserver(NOTIFICATION_BUBBLES_URI,
@@ -2000,13 +2028,15 @@ public class NotificationManagerService extends SystemService {
 
         public void update(Uri uri) {
             ContentResolver resolver = getContext().getContentResolver();
-            if (uri == null || NOTIFICATION_LIGHT_PULSE_URI.equals(uri)) {
-                boolean pulseEnabled = Settings.System.getIntForUser(resolver,
-                            Settings.System.NOTIFICATION_LIGHT_PULSE, 0, UserHandle.USER_CURRENT)
+            if (!mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
+                if (uri == null || NOTIFICATION_LIGHT_PULSE_URI.equals(uri)) {
+                    boolean pulseEnabled = Settings.System.getIntForUser(resolver,
+                        Settings.System.NOTIFICATION_LIGHT_PULSE, 0, UserHandle.USER_CURRENT)
                         != 0;
-                if (mNotificationPulseEnabled != pulseEnabled) {
-                    mNotificationPulseEnabled = pulseEnabled;
-                    updateNotificationPulse();
+                    if (mNotificationPulseEnabled != pulseEnabled) {
+                        mNotificationPulseEnabled = pulseEnabled;
+                        updateNotificationPulse();
+                    }
                 }
             }
             if (uri == null || NOTIFICATION_RATE_LIMIT_URI.equals(uri)) {
@@ -2491,14 +2521,22 @@ public class NotificationManagerService extends SystemService {
 
         mToastRateLimiter = toastRateLimiter;
 
+        if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
+            mAttentionHelper = new NotificationAttentionHelper(getContext(), lightsManager,
+                mAccessibilityManager, mPackageManagerClient, usageStats,
+                mNotificationManagerPrivate, mZenModeHelper, flagResolver);
+        }
+
         // register for various Intents.
         // If this is called within a test, make sure to unregister the intent receivers by
         // calling onDestroy()
         IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_SCREEN_ON);
-        filter.addAction(Intent.ACTION_SCREEN_OFF);
-        filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
-        filter.addAction(Intent.ACTION_USER_PRESENT);
+        if (!mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
+            filter.addAction(Intent.ACTION_SCREEN_ON);
+            filter.addAction(Intent.ACTION_SCREEN_OFF);
+            filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
+            filter.addAction(Intent.ACTION_USER_PRESENT);
+        }
         filter.addAction(Intent.ACTION_USER_STOPPED);
         filter.addAction(Intent.ACTION_USER_SWITCHED);
         filter.addAction(Intent.ACTION_USER_ADDED);
@@ -2818,6 +2856,9 @@ public class NotificationManagerService extends SystemService {
             }
             registerNotificationPreferencesPullers();
             new LockPatternUtils(getContext()).registerStrongAuthTracker(mStrongAuthTracker);
+            if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
+                mAttentionHelper.onSystemReady();
+            }
         } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
             // This observer will force an update when observe is called, causing us to
             // bind to listener services.
@@ -6375,6 +6416,9 @@ public class NotificationManagerService extends SystemService {
                     pw.println("  mMaxPackageEnqueueRate=" + mMaxPackageEnqueueRate);
                     pw.println("  hideSilentStatusBar="
                             + mPreferencesHelper.shouldHideSilentStatusIcons());
+                    if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
+                        mAttentionHelper.dump(pw, "    ", filter);
+                    }
                 }
                 pw.println("  mArchive=" + mArchive.toString());
                 mArchive.dumpImpl(pw, filter);
@@ -7632,7 +7676,11 @@ public class NotificationManagerService extends SystemService {
             boolean wasPosted = removeFromNotificationListsLocked(r);
             cancelNotificationLocked(r, false, REASON_SNOOZED, wasPosted, null,
                     SystemClock.elapsedRealtime());
-            updateLightsLocked();
+            if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
+                mAttentionHelper.updateLightsLocked();
+            } else {
+                updateLightsLocked();
+            }
             if (isSnoozable(r)) {
                 if (mSnoozeCriterionId != null) {
                     mAssistants.notifyAssistantSnoozedLocked(r, mSnoozeCriterionId);
@@ -7761,7 +7809,11 @@ public class NotificationManagerService extends SystemService {
                     cancelGroupChildrenLocked(r, mCallingUid, mCallingPid, listenerName,
                             mSendDelete, childrenFlagChecker, mReason,
                             mCancellationElapsedTimeMs);
-                    updateLightsLocked();
+                    if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
+                        mAttentionHelper.updateLightsLocked();
+                    } else {
+                        updateLightsLocked();
+                    }
                     if (mShortcutHelper != null) {
                         mShortcutHelper.maybeListenForShortcutChangesForBubbles(r,
                                 true /* isRemoved */,
@@ -8054,7 +8106,14 @@ public class NotificationManagerService extends SystemService {
 
                     int buzzBeepBlinkLoggingCode = 0;
                     if (!r.isHidden()) {
-                        buzzBeepBlinkLoggingCode = buzzBeepBlinkLocked(r);
+                        if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
+                            buzzBeepBlinkLoggingCode = mAttentionHelper.buzzBeepBlinkLocked(r,
+                                new NotificationAttentionHelper.Signals(
+                                    mUserProfiles.isCurrentProfile(r.getUserId()),
+                                    mListenerHints));
+                        } else {
+                            buzzBeepBlinkLoggingCode = buzzBeepBlinkLocked(r);
+                        }
                     }
 
                     if (notification.getSmallIcon() != null) {
@@ -9034,7 +9093,13 @@ public class NotificationManagerService extends SystemService {
                     || interruptiveChanged;
             if (interceptBefore && !record.isIntercepted()
                     && record.isNewEnoughForAlerting(System.currentTimeMillis())) {
-                buzzBeepBlinkLocked(record);
+                if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
+                    mAttentionHelper.buzzBeepBlinkLocked(record,
+                        new NotificationAttentionHelper.Signals(
+                            mUserProfiles.isCurrentProfile(record.getUserId()), mListenerHints));
+                } else {
+                    buzzBeepBlinkLocked(record);
+                }
 
                 // Log alert after change in intercepted state to Zen Log as well
                 ZenLog.traceAlertOnUpdatedIntercept(record);
@@ -9408,18 +9473,22 @@ public class NotificationManagerService extends SystemService {
                 });
             }
 
-            // sound
-            if (canceledKey.equals(mSoundNotificationKey)) {
-                clearSoundLocked();
-            }
+            if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
+                mAttentionHelper.clearEffectsLocked(canceledKey);
+            } else {
+                // sound
+                if (canceledKey.equals(mSoundNotificationKey)) {
+                    clearSoundLocked();
+                }
 
-            // vibrate
-            if (canceledKey.equals(mVibrateNotificationKey)) {
-                clearVibrateLocked();
-            }
+                // vibrate
+                if (canceledKey.equals(mVibrateNotificationKey)) {
+                    clearVibrateLocked();
+                }
 
-            // light
-            mLights.remove(canceledKey);
+                // light
+                mLights.remove(canceledKey);
+            }
         }
 
         // Record usage stats
@@ -9768,7 +9837,11 @@ public class NotificationManagerService extends SystemService {
                             cancellationElapsedTimeMs);
                 }
             }
-            updateLightsLocked();
+            if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
+                mAttentionHelper.updateLightsLocked();
+            } else {
+                updateLightsLocked();
+            }
         }
     }
 
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAttentionHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAttentionHelperTest.java
new file mode 100644
index 000000000000..81867df74abd
--- /dev/null
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAttentionHelperTest.java
@@ -0,0 +1,1973 @@
+/*
+ * Copyright (C) 2023 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.notification;
+
+import static android.app.Notification.FLAG_BUBBLE;
+import static android.app.Notification.GROUP_ALERT_ALL;
+import static android.app.Notification.GROUP_ALERT_CHILDREN;
+import static android.app.Notification.GROUP_ALERT_SUMMARY;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.app.NotificationManager.IMPORTANCE_MIN;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS;
+import static android.media.AudioAttributes.USAGE_NOTIFICATION;
+import static android.media.AudioAttributes.USAGE_NOTIFICATION_RINGTONE;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.mockito.ArgumentMatchers.anyFloat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyObject;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.after;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.annotation.SuppressLint;
+import android.app.ActivityManager;
+import android.app.KeyguardManager;
+import android.app.Notification;
+import android.app.Notification.Builder;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.graphics.Color;
+import android.graphics.drawable.Icon;
+import android.media.AudioAttributes;
+import android.media.AudioManager;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.VibrationAttributes;
+import android.os.VibrationEffect;
+import android.os.Vibrator;
+import android.provider.Settings;
+import android.service.notification.NotificationListenerService;
+import android.service.notification.StatusBarNotification;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.IAccessibilityManager;
+import android.view.accessibility.IAccessibilityManagerClient;
+import androidx.test.runner.AndroidJUnit4;
+import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags;
+import com.android.internal.config.sysui.TestableFlagResolver;
+import com.android.internal.logging.InstanceIdSequence;
+import com.android.internal.logging.InstanceIdSequenceFake;
+import com.android.internal.util.IntPair;
+import com.android.server.UiServiceTestCase;
+import com.android.server.lights.LightsManager;
+import com.android.server.lights.LogicalLight;
+import com.android.server.pm.PackageManagerService;
+import java.util.Objects;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.ArgumentMatcher;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.mockito.verification.VerificationMode;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+@SuppressLint("GuardedBy")
+public class NotificationAttentionHelperTest extends UiServiceTestCase {
+
+    @Mock AudioManager mAudioManager;
+    @Mock Vibrator mVibrator;
+    @Mock android.media.IRingtonePlayer mRingtonePlayer;
+    @Mock LogicalLight mLight;
+    @Mock
+    NotificationManagerService.WorkerHandler mHandler;
+    @Mock
+    NotificationUsageStats mUsageStats;
+    @Mock
+    IAccessibilityManager mAccessibilityService;
+    @Mock
+    KeyguardManager mKeyguardManager;
+    NotificationRecordLoggerFake mNotificationRecordLogger = new NotificationRecordLoggerFake();
+    private InstanceIdSequence mNotificationInstanceIdSequence = new InstanceIdSequenceFake(
+        1 << 30);
+
+    private NotificationManagerService mService;
+    private String mPkg = "com.android.server.notification";
+    private int mId = 1001;
+    private int mOtherId = 1002;
+    private String mTag = null;
+    private int mUid = 1000;
+    private int mPid = 2000;
+    private android.os.UserHandle mUser = UserHandle.of(ActivityManager.getCurrentUser());
+    private NotificationChannel mChannel;
+
+    private NotificationAttentionHelper mAttentionHelper;
+    private TestableFlagResolver mTestFlagResolver = new TestableFlagResolver();
+    private AccessibilityManager mAccessibilityManager;
+    private static final NotificationAttentionHelper.Signals DEFAULT_SIGNALS =
+        new NotificationAttentionHelper.Signals(false, 0);
+
+    private VibrateRepeatMatcher mVibrateOnceMatcher = new VibrateRepeatMatcher(-1);
+    private VibrateRepeatMatcher mVibrateLoopMatcher = new VibrateRepeatMatcher(0);
+
+    private static final long[] CUSTOM_VIBRATION = new long[] {
+        300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400,
+        300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400,
+        300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400 };
+    private static final Uri CUSTOM_SOUND = Settings.System.DEFAULT_ALARM_ALERT_URI;
+    private static final AudioAttributes CUSTOM_ATTRIBUTES = new AudioAttributes.Builder()
+        .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
+        .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
+        .build();
+    private static final int CUSTOM_LIGHT_COLOR = Color.BLACK;
+    private static final int CUSTOM_LIGHT_ON = 10000;
+    private static final int CUSTOM_LIGHT_OFF = 10000;
+    private static final int MAX_VIBRATION_DELAY = 1000;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        getContext().addMockSystemService(Vibrator.class, mVibrator);
+
+        when(mAudioManager.isAudioFocusExclusive()).thenReturn(false);
+        when(mAudioManager.getRingtonePlayer()).thenReturn(mRingtonePlayer);
+        when(mAudioManager.getStreamVolume(anyInt())).thenReturn(10);
+        when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
+        when(mAudioManager.getFocusRampTimeMs(anyInt(), any(AudioAttributes.class))).thenReturn(50);
+        when(mUsageStats.isAlertRateLimited(any())).thenReturn(false);
+        when(mVibrator.hasFrequencyControl()).thenReturn(false);
+        when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(false);
+
+        long serviceReturnValue = IntPair.of(
+            AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED,
+            AccessibilityEvent.TYPES_ALL_MASK);
+        when(mAccessibilityService.addClient(any(), anyInt())).thenReturn(serviceReturnValue);
+        mAccessibilityManager =
+            new AccessibilityManager(getContext(), Handler.getMain(), mAccessibilityService, 0,
+                true);
+        verify(mAccessibilityService).addClient(any(IAccessibilityManagerClient.class), anyInt());
+        assertTrue(mAccessibilityManager.isEnabled());
+
+        // TODO (b/291907312): remove feature flag
+        mTestFlagResolver.setFlagOverride(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR, true);
+
+        mService = spy(new NotificationManagerService(getContext(), mNotificationRecordLogger,
+            mNotificationInstanceIdSequence));
+
+        initAttentionHelper(mTestFlagResolver);
+
+        mChannel = new NotificationChannel("test", "test", IMPORTANCE_HIGH);
+    }
+
+    private void initAttentionHelper(TestableFlagResolver flagResolver) {
+        mAttentionHelper = new NotificationAttentionHelper(getContext(), mock(LightsManager.class),
+            mAccessibilityManager, getContext().getPackageManager(), mUsageStats,
+            mService.mNotificationManagerPrivate, mock(ZenModeHelper.class), flagResolver);
+        mAttentionHelper.setVibratorHelper(new VibratorHelper(getContext()));
+        mAttentionHelper.setAudioManager(mAudioManager);
+        mAttentionHelper.setSystemReady(true);
+        mAttentionHelper.setLights(mLight);
+        mAttentionHelper.setScreenOn(false);
+        mAttentionHelper.setAccessibilityManager(mAccessibilityManager);
+        mAttentionHelper.setKeyguardManager(mKeyguardManager);
+        mAttentionHelper.setScreenOn(false);
+        mAttentionHelper.setInCallStateOffHook(false);
+        mAttentionHelper.mNotificationPulseEnabled = true;
+    }
+
+    //
+    // Convenience functions for creating notification records
+    //
+
+    private NotificationRecord getNoisyOtherNotification() {
+        return getNotificationRecord(mOtherId, false /* insistent */, false /* once */,
+            true /* noisy */, true /* buzzy*/, false /* lights */);
+    }
+
+    private NotificationRecord getBeepyNotification() {
+        return getNotificationRecord(mId, false /* insistent */, false /* once */,
+            true /* noisy */, false /* buzzy*/, false /* lights */);
+    }
+
+    private NotificationRecord getBeepyOtherNotification() {
+        return getNotificationRecord(mOtherId, false /* insistent */, false /* once */,
+            true /* noisy */, false /* buzzy*/, false /* lights */);
+    }
+
+    private NotificationRecord getBeepyOnceNotification() {
+        return getNotificationRecord(mId, false /* insistent */, true /* once */,
+            true /* noisy */, false /* buzzy*/, false /* lights */);
+    }
+
+    private NotificationRecord getQuietNotification() {
+        return getNotificationRecord(mId, false /* insistent */, true /* once */,
+            false /* noisy */, false /* buzzy*/, false /* lights */);
+    }
+
+    private NotificationRecord getQuietOtherNotification() {
+        return getNotificationRecord(mOtherId, false /* insistent */, false /* once */,
+            false /* noisy */, false /* buzzy*/, false /* lights */);
+    }
+
+    private NotificationRecord getQuietOnceNotification() {
+        return getNotificationRecord(mId, false /* insistent */, true /* once */,
+            false /* noisy */, false /* buzzy*/, false /* lights */);
+    }
+
+    private NotificationRecord getInsistentBeepyNotification() {
+        return getNotificationRecord(mId, true /* insistent */, false /* once */,
+            true /* noisy */, false /* buzzy*/, false /* lights */);
+    }
+
+    private NotificationRecord getInsistentBeepyOnceNotification() {
+        return getNotificationRecord(mId, true /* insistent */, true /* once */,
+            true /* noisy */, false /* buzzy*/, false /* lights */);
+    }
+
+    private NotificationRecord getInsistentBeepyLeanbackNotification() {
+        return getLeanbackNotificationRecord(mId, true /* insistent */, false /* once */,
+            true /* noisy */, false /* buzzy*/, false /* lights */);
+    }
+
+    private NotificationRecord getBuzzyNotification() {
+        return getNotificationRecord(mId, false /* insistent */, false /* once */,
+            false /* noisy */, true /* buzzy*/, false /* lights */);
+    }
+
+    private NotificationRecord getBuzzyOtherNotification() {
+        return getNotificationRecord(mOtherId, false /* insistent */, false /* once */,
+            false /* noisy */, true /* buzzy*/, false /* lights */);
+    }
+
+    private NotificationRecord getBuzzyOnceNotification() {
+        return getNotificationRecord(mId, false /* insistent */, true /* once */,
+            false /* noisy */, true /* buzzy*/, false /* lights */);
+    }
+
+    private NotificationRecord getInsistentBuzzyNotification() {
+        return getNotificationRecord(mId, true /* insistent */, false /* once */,
+            false /* noisy */, true /* buzzy*/, false /* lights */);
+    }
+
+    private NotificationRecord getBuzzyBeepyNotification() {
+        return getNotificationRecord(mId, false /* insistent */, false /* once */,
+            true /* noisy */, true /* buzzy*/, false /* lights */);
+    }
+
+    private NotificationRecord getLightsNotification() {
+        return getNotificationRecord(mId, false /* insistent */, false /* once */,
+            false /* noisy */, false /* buzzy*/, true /* lights */);
+    }
+
+    private NotificationRecord getLightsOnceNotification() {
+        return getNotificationRecord(mId, false /* insistent */, true /* once */,
+            false /* noisy */, false /* buzzy*/, true /* lights */);
+    }
+
+    private NotificationRecord getCallRecord(int id, NotificationChannel channel, boolean looping) {
+        final Builder builder = new Builder(getContext())
+            .setContentTitle("foo")
+            .setSmallIcon(android.R.drawable.sym_def_app_icon)
+            .setPriority(Notification.PRIORITY_HIGH);
+        Notification n = builder.build();
+        if (looping) {
+            n.flags |= Notification.FLAG_INSISTENT;
+        }
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, id, mTag, mUid,
+            mPid, n, mUser, null, System.currentTimeMillis());
+        NotificationRecord r = new NotificationRecord(getContext(), sbn, channel);
+        mService.addNotification(r);
+
+        return r;
+    }
+
+    private NotificationRecord getNotificationRecord(int id, boolean insistent, boolean once,
+        boolean noisy, boolean buzzy, boolean lights) {
+        return getNotificationRecord(id, insistent, once, noisy, buzzy, lights, buzzy, noisy,
+            lights, null, Notification.GROUP_ALERT_ALL, false);
+    }
+
+    private NotificationRecord getLeanbackNotificationRecord(int id, boolean insistent,
+        boolean once,
+        boolean noisy, boolean buzzy, boolean lights) {
+        return getNotificationRecord(id, insistent, once, noisy, buzzy, lights, true, true,
+            true,
+            null, Notification.GROUP_ALERT_ALL, true);
+    }
+
+    private NotificationRecord getBeepyNotificationRecord(String groupKey, int groupAlertBehavior) {
+        return getNotificationRecord(mId, false, false, true, false, false, true, true, true,
+            groupKey, groupAlertBehavior, false);
+    }
+
+    private NotificationRecord getLightsNotificationRecord(String groupKey,
+        int groupAlertBehavior) {
+        return getNotificationRecord(mId, false, false, false, false, true /*lights*/, true,
+            true, true, groupKey, groupAlertBehavior, false);
+    }
+
+    private NotificationRecord getNotificationRecord(int id,
+        boolean insistent, boolean once,
+        boolean noisy, boolean buzzy, boolean lights, boolean defaultVibration,
+        boolean defaultSound, boolean defaultLights, String groupKey, int groupAlertBehavior,
+        boolean isLeanback) {
+
+        final Builder builder = new Builder(getContext())
+            .setContentTitle("foo")
+            .setSmallIcon(android.R.drawable.sym_def_app_icon)
+            .setPriority(Notification.PRIORITY_HIGH)
+            .setOnlyAlertOnce(once);
+
+        int defaults = 0;
+        if (noisy) {
+            if (defaultSound) {
+                defaults |= Notification.DEFAULT_SOUND;
+                mChannel.setSound(Settings.System.DEFAULT_NOTIFICATION_URI,
+                    Notification.AUDIO_ATTRIBUTES_DEFAULT);
+            } else {
+                builder.setSound(CUSTOM_SOUND);
+                mChannel.setSound(CUSTOM_SOUND, CUSTOM_ATTRIBUTES);
+            }
+        } else {
+            mChannel.setSound(null, null);
+        }
+        if (buzzy) {
+            if (defaultVibration) {
+                defaults |= Notification.DEFAULT_VIBRATE;
+            } else {
+                builder.setVibrate(CUSTOM_VIBRATION);
+                mChannel.setVibrationPattern(CUSTOM_VIBRATION);
+            }
+            mChannel.enableVibration(true);
+        } else {
+            mChannel.setVibrationPattern(null);
+            mChannel.enableVibration(false);
+        }
+
+        if (lights) {
+            if (defaultLights) {
+                defaults |= Notification.DEFAULT_LIGHTS;
+            } else {
+                builder.setLights(CUSTOM_LIGHT_COLOR, CUSTOM_LIGHT_ON, CUSTOM_LIGHT_OFF);
+            }
+            mChannel.enableLights(true);
+        } else {
+            mChannel.enableLights(false);
+        }
+        builder.setDefaults(defaults);
+
+        builder.setGroup(groupKey);
+        builder.setGroupAlertBehavior(groupAlertBehavior);
+
+        Notification n = builder.build();
+        if (insistent) {
+            n.flags |= Notification.FLAG_INSISTENT;
+        }
+
+        Context context = spy(getContext());
+        PackageManager packageManager = spy(context.getPackageManager());
+        when(context.getPackageManager()).thenReturn(packageManager);
+        when(packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK))
+            .thenReturn(isLeanback);
+
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, id, mTag, mUid,
+            mPid, n, mUser, null, System.currentTimeMillis());
+        NotificationRecord r = new NotificationRecord(context, sbn, mChannel);
+        mService.addNotification(r);
+        return r;
+    }
+
+    //
+    // Convenience functions for interacting with mocks
+    //
+
+    private void verifyNeverBeep() throws RemoteException {
+        verify(mRingtonePlayer, never()).playAsync(any(), any(), anyBoolean(), any());
+    }
+
+    private void verifyBeepUnlooped() throws RemoteException  {
+        verify(mRingtonePlayer, times(1)).playAsync(any(), any(), eq(false), any());
+    }
+
+    private void verifyBeepLooped() throws RemoteException  {
+        verify(mRingtonePlayer, times(1)).playAsync(any(), any(), eq(true), any());
+    }
+
+    private void verifyBeep(int times)  throws RemoteException  {
+        verify(mRingtonePlayer, times(times)).playAsync(any(), any(), anyBoolean(), any());
+    }
+
+    private void verifyNeverStopAudio() throws RemoteException {
+        verify(mRingtonePlayer, never()).stopAsync();
+    }
+
+    private void verifyStopAudio() throws RemoteException {
+        verify(mRingtonePlayer, times(1)).stopAsync();
+    }
+
+    private void verifyNeverVibrate() {
+        verify(mVibrator, never()).vibrate(anyInt(), anyString(), any(), anyString(),
+            any(VibrationAttributes.class));
+    }
+
+    private void verifyVibrate() {
+        verifyVibrate(/* times= */ 1);
+    }
+
+    private void verifyVibrate(int times) {
+        verifyVibrate(mVibrateOnceMatcher, times(times));
+    }
+
+    private void verifyVibrateLooped() {
+        verifyVibrate(mVibrateLoopMatcher, times(1));
+    }
+
+    private void verifyDelayedVibrateLooped() {
+        verifyVibrate(mVibrateLoopMatcher, timeout(MAX_VIBRATION_DELAY).times(1));
+    }
+
+    private void verifyDelayedVibrate(VibrationEffect effect) {
+        verifyVibrate(argument -> Objects.equals(effect, argument),
+            timeout(MAX_VIBRATION_DELAY).times(1));
+    }
+
+    private void verifyDelayedNeverVibrate() {
+        verify(mVibrator, after(MAX_VIBRATION_DELAY).never()).vibrate(anyInt(), anyString(), any(),
+            anyString(), any(VibrationAttributes.class));
+    }
+
+    private void verifyVibrate(ArgumentMatcher<VibrationEffect> effectMatcher,
+        VerificationMode verification) {
+        ArgumentCaptor<VibrationAttributes> captor =
+            ArgumentCaptor.forClass(VibrationAttributes.class);
+        verify(mVibrator, verification).vibrate(eq(Process.SYSTEM_UID),
+            eq(PackageManagerService.PLATFORM_PACKAGE_NAME), argThat(effectMatcher),
+            anyString(), captor.capture());
+        assertEquals(0, (captor.getValue().getFlags()
+            & VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY));
+    }
+
+    private void verifyStopVibrate() {
+        int alarmClassUsageFilter =
+            VibrationAttributes.USAGE_CLASS_ALARM | ~VibrationAttributes.USAGE_CLASS_MASK;
+        verify(mVibrator, times(1)).cancel(eq(alarmClassUsageFilter));
+    }
+
+    private void verifyNeverStopVibrate() {
+        verify(mVibrator, never()).cancel();
+        verify(mVibrator, never()).cancel(anyInt());
+    }
+
+    private void verifyNeverLights() {
+        verify(mLight, never()).setFlashing(anyInt(), anyInt(), anyInt(), anyInt());
+    }
+
+    private void verifyLights() {
+        verify(mLight, times(1)).setFlashing(anyInt(), anyInt(), anyInt(), anyInt());
+    }
+
+    //
+    // Tests
+    //
+
+    @Test
+    public void testLights() throws Exception {
+        NotificationRecord r = getLightsNotification();
+        r.setSystemImportance(NotificationManager.IMPORTANCE_DEFAULT);
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        verifyLights();
+        assertTrue(r.isInterruptive());
+        assertEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testBeep() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        verifyBeepUnlooped();
+        verifyNeverVibrate();
+        verify(mAccessibilityService, times(1)).sendAccessibilityEvent(any(), anyInt());
+        assertTrue(r.isInterruptive());
+        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testLockedPrivateA11yRedaction() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        r.setPackageVisibilityOverride(NotificationManager.VISIBILITY_NO_OVERRIDE);
+        r.getNotification().visibility = Notification.VISIBILITY_PRIVATE;
+        when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(true);
+        AccessibilityManager accessibilityManager = Mockito.mock(AccessibilityManager.class);
+        when(accessibilityManager.isEnabled()).thenReturn(true);
+        mAttentionHelper.setAccessibilityManager(accessibilityManager);
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        ArgumentCaptor<AccessibilityEvent> eventCaptor =
+            ArgumentCaptor.forClass(AccessibilityEvent.class);
+
+        verify(accessibilityManager, times(1))
+            .sendAccessibilityEvent(eventCaptor.capture());
+
+        AccessibilityEvent event = eventCaptor.getValue();
+        assertEquals(r.getNotification().publicVersion, event.getParcelableData());
+    }
+
+    @Test
+    public void testLockedOverridePrivateA11yRedaction() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        r.setPackageVisibilityOverride(Notification.VISIBILITY_PRIVATE);
+        r.getNotification().visibility = Notification.VISIBILITY_PUBLIC;
+        when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(true);
+        AccessibilityManager accessibilityManager = Mockito.mock(AccessibilityManager.class);
+        when(accessibilityManager.isEnabled()).thenReturn(true);
+        mAttentionHelper.setAccessibilityManager(accessibilityManager);
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        ArgumentCaptor<AccessibilityEvent> eventCaptor =
+            ArgumentCaptor.forClass(AccessibilityEvent.class);
+
+        verify(accessibilityManager, times(1))
+            .sendAccessibilityEvent(eventCaptor.capture());
+
+        AccessibilityEvent event = eventCaptor.getValue();
+        assertEquals(r.getNotification().publicVersion, event.getParcelableData());
+    }
+
+    @Test
+    public void testLockedPublicA11yNoRedaction() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        r.setPackageVisibilityOverride(NotificationManager.VISIBILITY_NO_OVERRIDE);
+        r.getNotification().visibility = Notification.VISIBILITY_PUBLIC;
+        when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(true);
+        AccessibilityManager accessibilityManager = Mockito.mock(AccessibilityManager.class);
+        when(accessibilityManager.isEnabled()).thenReturn(true);
+        mAttentionHelper.setAccessibilityManager(accessibilityManager);
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        ArgumentCaptor<AccessibilityEvent> eventCaptor =
+            ArgumentCaptor.forClass(AccessibilityEvent.class);
+
+        verify(accessibilityManager, times(1))
+            .sendAccessibilityEvent(eventCaptor.capture());
+
+        AccessibilityEvent event = eventCaptor.getValue();
+        assertEquals(r.getNotification(), event.getParcelableData());
+    }
+
+    @Test
+    public void testUnlockedPrivateA11yNoRedaction() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        r.setPackageVisibilityOverride(NotificationManager.VISIBILITY_NO_OVERRIDE);
+        r.getNotification().visibility = Notification.VISIBILITY_PRIVATE;
+        when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(false);
+        AccessibilityManager accessibilityManager = Mockito.mock(AccessibilityManager.class);
+        when(accessibilityManager.isEnabled()).thenReturn(true);
+        mAttentionHelper.setAccessibilityManager(accessibilityManager);
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        ArgumentCaptor<AccessibilityEvent> eventCaptor =
+            ArgumentCaptor.forClass(AccessibilityEvent.class);
+
+        verify(accessibilityManager, times(1))
+            .sendAccessibilityEvent(eventCaptor.capture());
+
+        AccessibilityEvent event = eventCaptor.getValue();
+        assertEquals(r.getNotification(), event.getParcelableData());
+    }
+
+    @Test
+    public void testBeepInsistently() throws Exception {
+        NotificationRecord r = getInsistentBeepyNotification();
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        verifyBeepLooped();
+        assertTrue(r.isInterruptive());
+        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testNoLeanbackBeep() throws Exception {
+        NotificationRecord r = getInsistentBeepyLeanbackNotification();
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        verifyNeverBeep();
+        assertFalse(r.isInterruptive());
+        assertEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testNoBeepForAutomotiveIfEffectsDisabled() throws Exception {
+        mAttentionHelper.setIsAutomotive(true);
+        mAttentionHelper.setNotificationEffectsEnabledForAutomotive(false);
+
+        NotificationRecord r = getBeepyNotification();
+        r.setSystemImportance(NotificationManager.IMPORTANCE_HIGH);
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        verifyNeverBeep();
+        assertFalse(r.isInterruptive());
+    }
+
+    @Test
+    public void testNoBeepForImportanceDefaultInAutomotiveIfEffectsEnabled() throws Exception {
+        mAttentionHelper.setIsAutomotive(true);
+        mAttentionHelper.setNotificationEffectsEnabledForAutomotive(true);
+
+        NotificationRecord r = getBeepyNotification();
+        r.setSystemImportance(NotificationManager.IMPORTANCE_DEFAULT);
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        verifyNeverBeep();
+        assertFalse(r.isInterruptive());
+    }
+
+    @Test
+    public void testBeepForImportanceHighInAutomotiveIfEffectsEnabled() throws Exception {
+        mAttentionHelper.setIsAutomotive(true);
+        mAttentionHelper.setNotificationEffectsEnabledForAutomotive(true);
+
+        NotificationRecord r = getBeepyNotification();
+        r.setSystemImportance(NotificationManager.IMPORTANCE_HIGH);
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        verifyBeepUnlooped();
+        assertTrue(r.isInterruptive());
+    }
+
+    @Test
+    public void testNoInterruptionForMin() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        r.setSystemImportance(NotificationManager.IMPORTANCE_MIN);
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        verifyNeverBeep();
+        verifyNeverVibrate();
+        assertFalse(r.isInterruptive());
+        assertEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testNoInterruptionForIntercepted() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        r.setIntercepted(true);
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        verifyNeverBeep();
+        verifyNeverVibrate();
+        assertFalse(r.isInterruptive());
+        assertEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testBeepTwice() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+
+        // set up internal state
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        Mockito.reset(mRingtonePlayer);
+
+        // update should beep
+        r.isUpdate = true;
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        verifyBeepUnlooped();
+        verify(mAccessibilityService, times(2)).sendAccessibilityEvent(any(), anyInt());
+        assertTrue(r.isInterruptive());
+        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testHonorAlertOnlyOnceForBeep() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        NotificationRecord s = getBeepyOnceNotification();
+        s.isUpdate = true;
+
+        // set up internal state
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        Mockito.reset(mRingtonePlayer);
+
+        // update should not beep
+        mAttentionHelper.buzzBeepBlinkLocked(s, DEFAULT_SIGNALS);
+        verifyNeverBeep();
+        verify(mAccessibilityService, times(1)).sendAccessibilityEvent(any(), anyInt());
+    }
+
+    @Test
+    public void testNoisyUpdateDoesNotCancelAudio() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        r.isUpdate = true;
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        verifyNeverStopAudio();
+        assertTrue(r.isInterruptive());
+        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testNoisyOnceUpdateDoesNotCancelAudio() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        NotificationRecord s = getBeepyOnceNotification();
+        s.isUpdate = true;
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        mAttentionHelper.buzzBeepBlinkLocked(s, DEFAULT_SIGNALS);
+
+        verifyNeverStopAudio();
+        assertTrue(r.isInterruptive());
+        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+        assertFalse(s.isInterruptive());
+        assertEquals(-1, s.getLastAudiblyAlertedMs());
+    }
+
+    /**
+     * Tests the case where the user re-posts a {@link Notification} with looping sound where
+     * {@link Notification.Builder#setOnlyAlertOnce(true)} has been called.  This should silence
+     * the sound associated with the notification.
+     * @throws Exception
+     */
+    @Test
+    public void testNoisyOnceUpdateDoesCancelAudio() throws Exception {
+        NotificationRecord r = getInsistentBeepyNotification();
+        NotificationRecord s = getInsistentBeepyOnceNotification();
+        s.isUpdate = true;
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        mAttentionHelper.buzzBeepBlinkLocked(s, DEFAULT_SIGNALS);
+
+        verifyStopAudio();
+    }
+
+    @Test
+    public void testQuietUpdateDoesNotCancelAudioFromOther() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        NotificationRecord s = getQuietNotification();
+        s.isUpdate = true;
+        NotificationRecord other = getNoisyOtherNotification();
+
+        // set up internal state
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        mAttentionHelper.buzzBeepBlinkLocked(other, DEFAULT_SIGNALS); // this takes the audio stream
+        Mockito.reset(mRingtonePlayer);
+
+        // should not stop noise, since we no longer own it
+        mAttentionHelper.buzzBeepBlinkLocked(s, DEFAULT_SIGNALS); // this no longer owns the stream
+        verifyNeverStopAudio();
+        assertTrue(other.isInterruptive());
+        assertNotEquals(-1, other.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testQuietInterloperDoesNotCancelAudio() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        NotificationRecord other = getQuietOtherNotification();
+
+        // set up internal state
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        Mockito.reset(mRingtonePlayer);
+
+        // should not stop noise, since it does not own it
+        mAttentionHelper.buzzBeepBlinkLocked(other, DEFAULT_SIGNALS);
+        verifyNeverStopAudio();
+    }
+
+    @Test
+    public void testQuietUpdateCancelsAudio() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        NotificationRecord s = getQuietNotification();
+        s.isUpdate = true;
+
+        // set up internal state
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        assertTrue(r.isInterruptive());
+        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+        Mockito.reset(mRingtonePlayer);
+
+        // quiet update should stop making noise
+        mAttentionHelper.buzzBeepBlinkLocked(s, DEFAULT_SIGNALS);
+        verifyStopAudio();
+        assertFalse(s.isInterruptive());
+        assertEquals(-1, s.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testQuietOnceUpdateCancelsAudio() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        NotificationRecord s = getQuietOnceNotification();
+        s.isUpdate = true;
+
+        // set up internal state
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        assertTrue(r.isInterruptive());
+        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+        Mockito.reset(mRingtonePlayer);
+
+        // stop making noise - this is a weird corner case, but quiet should override once
+        mAttentionHelper.buzzBeepBlinkLocked(s, DEFAULT_SIGNALS);
+        verifyStopAudio();
+        assertFalse(s.isInterruptive());
+        assertEquals(-1, s.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testInCallNotification() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+
+        mAttentionHelper = spy(mAttentionHelper);
+
+        // set up internal state
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        Mockito.reset(mRingtonePlayer);
+
+        mAttentionHelper.setInCallStateOffHook(true);
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        verify(mAttentionHelper, times(1)).playInCallNotification();
+        verifyNeverBeep(); // doesn't play normal beep
+        assertTrue(r.isInterruptive());
+        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testNoDemoteSoundToVibrateIfVibrateGiven() throws Exception {
+        NotificationRecord r = getBuzzyBeepyNotification();
+        assertTrue(r.getSound() != null);
+
+        // the phone is quiet
+        when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
+        when(mAudioManager.getStreamVolume(anyInt())).thenReturn(0);
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        verifyDelayedVibrate(r.getVibration());
+        assertTrue(r.isInterruptive());
+        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testNoDemoteSoundToVibrateIfNonNotificationStream() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        assertTrue(r.getSound() != null);
+        assertNull(r.getVibration());
+
+        // the phone is quiet
+        when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
+        when(mAudioManager.getStreamVolume(anyInt())).thenReturn(1);
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        verifyNeverVibrate();
+        verifyBeepUnlooped();
+        assertTrue(r.isInterruptive());
+        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testDemoteSoundToVibrate() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        assertTrue(r.getSound() != null);
+        assertNull(r.getVibration());
+
+        // the phone is quiet
+        when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
+        when(mAudioManager.getStreamVolume(anyInt())).thenReturn(0);
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        verifyDelayedVibrate(
+            mAttentionHelper.getVibratorHelper().createFallbackVibration(
+                /* insistent= */ false));
+        verify(mRingtonePlayer, never()).playAsync(anyObject(), anyObject(), anyBoolean(),
+            anyObject());
+        assertTrue(r.isInterruptive());
+        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testDemoteInsistentSoundToVibrate() throws Exception {
+        NotificationRecord r = getInsistentBeepyNotification();
+        assertTrue(r.getSound() != null);
+        assertNull(r.getVibration());
+
+        // the phone is quiet
+        when(mAudioManager.getStreamVolume(anyInt())).thenReturn(0);
+        when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        verifyDelayedVibrateLooped();
+        assertTrue(r.isInterruptive());
+        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testVibrate() throws Exception {
+        NotificationRecord r = getBuzzyNotification();
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        verifyNeverBeep();
+        verifyVibrate();
+        assertTrue(r.isInterruptive());
+        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testInsistentVibrate() {
+        NotificationRecord r = getInsistentBuzzyNotification();
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        verifyVibrateLooped();
+        assertTrue(r.isInterruptive());
+        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testVibrateTwice() {
+        NotificationRecord r = getBuzzyNotification();
+
+        // set up internal state
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        Mockito.reset(mVibrator);
+
+        // update should vibrate
+        r.isUpdate = true;
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        verifyVibrate();
+        assertTrue(r.isInterruptive());
+        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testPostSilently() throws Exception {
+        NotificationRecord r = getBuzzyNotification();
+        r.setPostSilently(true);
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        verifyNeverBeep();
+        assertFalse(r.isInterruptive());
+        assertEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testGroupAlertSummarySilenceChild() throws Exception {
+        NotificationRecord child = getBeepyNotificationRecord("a", GROUP_ALERT_SUMMARY);
+
+        mAttentionHelper.buzzBeepBlinkLocked(child, DEFAULT_SIGNALS);
+
+        verifyNeverBeep();
+        assertFalse(child.isInterruptive());
+        assertEquals(-1, child.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testGroupAlertSummaryNoSilenceSummary() throws Exception {
+        NotificationRecord summary = getBeepyNotificationRecord("a", GROUP_ALERT_SUMMARY);
+        summary.getNotification().flags |= Notification.FLAG_GROUP_SUMMARY;
+
+        mAttentionHelper.buzzBeepBlinkLocked(summary, DEFAULT_SIGNALS);
+
+        verifyBeepUnlooped();
+        // summaries are never interruptive for notification counts
+        assertFalse(summary.isInterruptive());
+        assertNotEquals(-1, summary.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testGroupAlertSummaryNoSilenceNonGroupChild() throws Exception {
+        NotificationRecord nonGroup = getBeepyNotificationRecord(null, GROUP_ALERT_SUMMARY);
+
+        mAttentionHelper.buzzBeepBlinkLocked(nonGroup, DEFAULT_SIGNALS);
+
+        verifyBeepUnlooped();
+        assertTrue(nonGroup.isInterruptive());
+        assertNotEquals(-1, nonGroup.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testGroupAlertChildSilenceSummary() throws Exception {
+        NotificationRecord summary = getBeepyNotificationRecord("a", GROUP_ALERT_CHILDREN);
+        summary.getNotification().flags |= Notification.FLAG_GROUP_SUMMARY;
+
+        mAttentionHelper.buzzBeepBlinkLocked(summary, DEFAULT_SIGNALS);
+
+        verifyNeverBeep();
+        assertFalse(summary.isInterruptive());
+        assertEquals(-1, summary.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testGroupAlertChildNoSilenceChild() throws Exception {
+        NotificationRecord child = getBeepyNotificationRecord("a", GROUP_ALERT_CHILDREN);
+
+        mAttentionHelper.buzzBeepBlinkLocked(child, DEFAULT_SIGNALS);
+
+        verifyBeepUnlooped();
+        assertTrue(child.isInterruptive());
+        assertNotEquals(-1, child.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testGroupAlertChildNoSilenceNonGroupSummary() throws Exception {
+        NotificationRecord nonGroup = getBeepyNotificationRecord(null, GROUP_ALERT_CHILDREN);
+
+        mAttentionHelper.buzzBeepBlinkLocked(nonGroup, DEFAULT_SIGNALS);
+
+        verifyBeepUnlooped();
+        assertTrue(nonGroup.isInterruptive());
+        assertNotEquals(-1, nonGroup.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testGroupAlertAllNoSilenceGroup() throws Exception {
+        NotificationRecord group = getBeepyNotificationRecord("a", GROUP_ALERT_ALL);
+
+        mAttentionHelper.buzzBeepBlinkLocked(group, DEFAULT_SIGNALS);
+
+        verifyBeepUnlooped();
+        assertTrue(group.isInterruptive());
+        assertNotEquals(-1, group.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testHonorAlertOnlyOnceForBuzz() throws Exception {
+        NotificationRecord r = getBuzzyNotification();
+        NotificationRecord s = getBuzzyOnceNotification();
+        s.isUpdate = true;
+
+        // set up internal state
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        Mockito.reset(mVibrator);
+        assertTrue(r.isInterruptive());
+        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+
+        // update should not beep
+        mAttentionHelper.buzzBeepBlinkLocked(s, DEFAULT_SIGNALS);
+        verifyNeverVibrate();
+        assertFalse(s.isInterruptive());
+        assertEquals(-1, s.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testNoisyUpdateDoesNotCancelVibrate() throws Exception {
+        NotificationRecord r = getBuzzyNotification();
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        r.isUpdate = true;
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        verifyNeverStopVibrate();
+        assertTrue(r.isInterruptive());
+        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testNoisyOnceUpdateDoesNotCancelVibrate() throws Exception {
+        NotificationRecord r = getBuzzyNotification();
+        NotificationRecord s = getBuzzyOnceNotification();
+        s.isUpdate = true;
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        mAttentionHelper.buzzBeepBlinkLocked(s, DEFAULT_SIGNALS);
+
+        verifyNeverStopVibrate();
+        assertTrue(r.isInterruptive());
+        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+        assertFalse(s.isInterruptive());
+        assertEquals(-1, s.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testQuietUpdateDoesNotCancelVibrateFromOther() throws Exception {
+        NotificationRecord r = getBuzzyNotification();
+        NotificationRecord s = getQuietNotification();
+        s.isUpdate = true;
+        NotificationRecord other = getNoisyOtherNotification();
+
+        // set up internal state
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        // this takes the vibrate stream
+        mAttentionHelper.buzzBeepBlinkLocked(other, DEFAULT_SIGNALS);
+        Mockito.reset(mVibrator);
+
+        // should not stop vibrate, since we no longer own it
+        mAttentionHelper.buzzBeepBlinkLocked(s, DEFAULT_SIGNALS); // this no longer owns the stream
+        verifyNeverStopVibrate();
+        assertTrue(r.isInterruptive());
+        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+        assertTrue(other.isInterruptive());
+        assertNotEquals(-1, other.getLastAudiblyAlertedMs());
+        assertFalse(s.isInterruptive());
+        assertEquals(-1, s.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testQuietInterloperDoesNotCancelVibrate() throws Exception {
+        NotificationRecord r = getBuzzyNotification();
+        NotificationRecord other = getQuietOtherNotification();
+
+        // set up internal state
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        Mockito.reset(mVibrator);
+
+        // should not stop noise, since it does not own it
+        mAttentionHelper.buzzBeepBlinkLocked(other, DEFAULT_SIGNALS);
+        verifyNeverStopVibrate();
+        assertFalse(other.isInterruptive());
+        assertEquals(-1, other.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testQuietUpdateCancelsVibrate() {
+        NotificationRecord r = getBuzzyNotification();
+        NotificationRecord s = getQuietNotification();
+        s.isUpdate = true;
+
+        // set up internal state
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        verifyVibrate();
+
+        // quiet update should stop making noise
+        mAttentionHelper.buzzBeepBlinkLocked(s, DEFAULT_SIGNALS);
+        verifyStopVibrate();
+        assertTrue(r.isInterruptive());
+        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+        assertFalse(s.isInterruptive());
+        assertEquals(-1, s.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testQuietOnceUpdateCancelVibrate() throws Exception {
+        NotificationRecord r = getBuzzyNotification();
+        NotificationRecord s = getQuietOnceNotification();
+        s.isUpdate = true;
+
+        // set up internal state
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        verifyVibrate();
+
+        // stop making noise - this is a weird corner case, but quiet should override once
+        mAttentionHelper.buzzBeepBlinkLocked(s, DEFAULT_SIGNALS);
+        verifyStopVibrate();
+        assertTrue(r.isInterruptive());
+        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+        assertFalse(s.isInterruptive());
+        assertEquals(-1, s.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testQuietUpdateCancelsDemotedVibrate() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        NotificationRecord s = getQuietNotification();
+
+        // the phone is quiet
+        when(mAudioManager.getStreamVolume(anyInt())).thenReturn(0);
+        when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        verifyDelayedVibrate(mAttentionHelper.getVibratorHelper().createFallbackVibration(false));
+
+        // quiet update should stop making noise
+        mAttentionHelper.buzzBeepBlinkLocked(s, DEFAULT_SIGNALS);
+        verifyStopVibrate();
+        assertTrue(r.isInterruptive());
+        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+        assertFalse(s.isInterruptive());
+        assertEquals(-1, s.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testEmptyUriSoundTreatedAsNoSound() throws Exception {
+        NotificationChannel channel = new NotificationChannel("test", "test", IMPORTANCE_HIGH);
+        channel.setSound(Uri.EMPTY, null);
+        final Notification n = new Builder(getContext(), "test")
+            .setSmallIcon(android.R.drawable.sym_def_app_icon).build();
+
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid,
+            mPid, n, mUser, null, System.currentTimeMillis());
+        NotificationRecord r = new NotificationRecord(getContext(), sbn, channel);
+        mService.addNotification(r);
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        verifyNeverBeep();
+        assertFalse(r.isInterruptive());
+        assertEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testRepeatedSoundOverLimitMuted() throws Exception {
+        when(mUsageStats.isAlertRateLimited(any())).thenReturn(true);
+
+        NotificationRecord r = getBeepyNotification();
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        verifyNeverBeep();
+        assertFalse(r.isInterruptive());
+        assertEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testPostingSilentNotificationDoesNotAffectRateLimiting() throws Exception {
+        NotificationRecord r = getQuietNotification();
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        verify(mUsageStats, never()).isAlertRateLimited(any());
+    }
+
+    @Test
+    public void testPostingGroupSuppressedDoesNotAffectRateLimiting() throws Exception {
+        NotificationRecord summary = getBeepyNotificationRecord("a", GROUP_ALERT_CHILDREN);
+        summary.getNotification().flags |= Notification.FLAG_GROUP_SUMMARY;
+
+        mAttentionHelper.buzzBeepBlinkLocked(summary, DEFAULT_SIGNALS);
+        verify(mUsageStats, never()).isAlertRateLimited(any());
+    }
+
+    @Test
+    public void testGroupSuppressionFailureDoesNotAffectRateLimiting() {
+        NotificationRecord summary = getBeepyNotificationRecord("a", GROUP_ALERT_SUMMARY);
+        summary.getNotification().flags |= Notification.FLAG_GROUP_SUMMARY;
+
+        mAttentionHelper.buzzBeepBlinkLocked(summary, DEFAULT_SIGNALS);
+        verify(mUsageStats, times(1)).isAlertRateLimited(any());
+    }
+
+    @Test
+    public void testCrossUserSoundMuted() throws Exception {
+        final Notification n = new Builder(getContext(), "test")
+            .setSmallIcon(android.R.drawable.sym_def_app_icon).build();
+
+        int userId = mUser.getIdentifier() + 1;
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid,
+            mPid, n, UserHandle.of(userId), null, System.currentTimeMillis());
+        NotificationRecord r = new NotificationRecord(getContext(), sbn,
+            new NotificationChannel("test", "test", IMPORTANCE_HIGH));
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        verifyNeverBeep();
+        assertFalse(r.isInterruptive());
+        assertEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testA11yMinInitialPost() throws Exception {
+        NotificationRecord r = getQuietNotification();
+        r.setSystemImportance(IMPORTANCE_MIN);
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        verify(mAccessibilityService, never()).sendAccessibilityEvent(any(), anyInt());
+    }
+
+    @Test
+    public void testA11yQuietInitialPost() throws Exception {
+        NotificationRecord r = getQuietNotification();
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        verify(mAccessibilityService, times(1)).sendAccessibilityEvent(any(), anyInt());
+    }
+
+    @Test
+    public void testA11yQuietUpdate() throws Exception {
+        NotificationRecord r = getQuietNotification();
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        r.isUpdate = true;
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        verify(mAccessibilityService, times(1)).sendAccessibilityEvent(any(), anyInt());
+    }
+
+    @Test
+    public void testA11yCrossUserEventNotSent() throws Exception {
+        final Notification n = new Builder(getContext(), "test")
+            .setSmallIcon(android.R.drawable.sym_def_app_icon).build();
+        int userId = mUser.getIdentifier() + 1;
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid,
+            mPid, n, UserHandle.of(userId), null, System.currentTimeMillis());
+        NotificationRecord r = new NotificationRecord(getContext(), sbn,
+            new NotificationChannel("test", "test", IMPORTANCE_HIGH));
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        verify(mAccessibilityService, never()).sendAccessibilityEvent(any(), anyInt());
+    }
+
+    @Test
+    public void testLightsScreenOn() {
+        mAttentionHelper.setScreenOn(true);
+        NotificationRecord r = getLightsNotification();
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        verifyNeverLights();
+        assertTrue(r.isInterruptive());
+        assertEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testLightsInCall() {
+        mAttentionHelper.setInCallStateOffHook(true);
+        NotificationRecord r = getLightsNotification();
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        verifyNeverLights();
+        assertFalse(r.isInterruptive());
+        assertEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testLightsSilentUpdate() {
+        NotificationRecord r = getLightsOnceNotification();
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        verifyLights();
+        assertTrue(r.isInterruptive());
+        assertEquals(-1, r.getLastAudiblyAlertedMs());
+
+        r = getLightsOnceNotification();
+        r.isUpdate = true;
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        // checks that lights happened once, i.e. this new call didn't trigger them again
+        verifyLights();
+        assertFalse(r.isInterruptive());
+        assertEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testLightsUnimportant() {
+        NotificationRecord r = getLightsNotification();
+        r.setSystemImportance(IMPORTANCE_LOW);
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        verifyNeverLights();
+        assertFalse(r.isInterruptive());
+        assertEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testLightsNoLights() {
+        NotificationRecord r = getQuietNotification();
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        verifyNeverLights();
+        assertFalse(r.isInterruptive());
+        assertEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testLightsNoLightOnDevice() {
+        mAttentionHelper.mHasLight = false;
+        NotificationRecord r = getLightsNotification();
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        verifyNeverLights();
+        assertFalse(r.isInterruptive());
+        assertEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testLightsLightsOffGlobally() {
+        mAttentionHelper.mNotificationPulseEnabled = false;
+        NotificationRecord r = getLightsNotification();
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        verifyNeverLights();
+        assertFalse(r.isInterruptive());
+        assertEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testLightsDndIntercepted() {
+        NotificationRecord r = getLightsNotification();
+        r.setSuppressedVisualEffects(SUPPRESSED_EFFECT_LIGHTS);
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        verifyNeverLights();
+        assertFalse(r.isInterruptive());
+        assertEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testGroupAlertSummaryNoLightsChild() {
+        NotificationRecord child = getLightsNotificationRecord("a", GROUP_ALERT_SUMMARY);
+
+        mAttentionHelper.buzzBeepBlinkLocked(child, DEFAULT_SIGNALS);
+
+        verifyNeverLights();
+        assertFalse(child.isInterruptive());
+        assertEquals(-1, child.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testGroupAlertSummaryLightsSummary() {
+        NotificationRecord summary = getLightsNotificationRecord("a", GROUP_ALERT_SUMMARY);
+        summary.getNotification().flags |= Notification.FLAG_GROUP_SUMMARY;
+
+        mAttentionHelper.buzzBeepBlinkLocked(summary, DEFAULT_SIGNALS);
+
+        verifyLights();
+        // summaries should never count for interruptiveness counts
+        assertFalse(summary.isInterruptive());
+        assertEquals(-1, summary.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testGroupAlertSummaryLightsNonGroupChild() {
+        NotificationRecord nonGroup = getLightsNotificationRecord(null, GROUP_ALERT_SUMMARY);
+
+        mAttentionHelper.buzzBeepBlinkLocked(nonGroup, DEFAULT_SIGNALS);
+
+        verifyLights();
+        assertTrue(nonGroup.isInterruptive());
+        assertEquals(-1, nonGroup.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testGroupAlertChildNoLightsSummary() {
+        NotificationRecord summary = getLightsNotificationRecord("a", GROUP_ALERT_CHILDREN);
+        summary.getNotification().flags |= Notification.FLAG_GROUP_SUMMARY;
+
+        mAttentionHelper.buzzBeepBlinkLocked(summary, DEFAULT_SIGNALS);
+
+        verifyNeverLights();
+        assertFalse(summary.isInterruptive());
+        assertEquals(-1, summary.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testGroupAlertChildLightsChild() {
+        NotificationRecord child = getLightsNotificationRecord("a", GROUP_ALERT_CHILDREN);
+
+        mAttentionHelper.buzzBeepBlinkLocked(child, DEFAULT_SIGNALS);
+
+        verifyLights();
+        assertTrue(child.isInterruptive());
+        assertEquals(-1, child.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testGroupAlertChildLightsNonGroupSummary() {
+        NotificationRecord nonGroup = getLightsNotificationRecord(null, GROUP_ALERT_CHILDREN);
+
+        mAttentionHelper.buzzBeepBlinkLocked(nonGroup, DEFAULT_SIGNALS);
+
+        verifyLights();
+        assertTrue(nonGroup.isInterruptive());
+        assertEquals(-1, nonGroup.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testGroupAlertAllLightsGroup() {
+        NotificationRecord group = getLightsNotificationRecord("a", GROUP_ALERT_ALL);
+
+        mAttentionHelper.buzzBeepBlinkLocked(group, DEFAULT_SIGNALS);
+
+        verifyLights();
+        assertTrue(group.isInterruptive());
+        assertEquals(-1, group.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testLightsCheckCurrentUser() {
+        final Notification n = new Builder(getContext(), "test")
+            .setSmallIcon(android.R.drawable.sym_def_app_icon).build();
+        int userId = mUser.getIdentifier() + 10;
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid,
+            mPid, n, UserHandle.of(userId), null, System.currentTimeMillis());
+        NotificationRecord r = new NotificationRecord(getContext(), sbn,
+            new NotificationChannel("test", "test", IMPORTANCE_HIGH));
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        verifyNeverLights();
+        assertFalse(r.isInterruptive());
+        assertEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testListenerHintCall() throws Exception {
+        NotificationChannel ringtoneChannel =
+            new NotificationChannel("ringtone", "", IMPORTANCE_HIGH);
+        ringtoneChannel.setSound(Settings.System.DEFAULT_RINGTONE_URI,
+            new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE).build());
+        NotificationRecord r = getCallRecord(1, ringtoneChannel, true);
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, new NotificationAttentionHelper.Signals(false,
+            NotificationListenerService.HINT_HOST_DISABLE_CALL_EFFECTS));
+
+        verifyNeverBeep();
+    }
+
+    @Test
+    public void testListenerHintCall_notificationSound() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, new NotificationAttentionHelper.Signals(false,
+            NotificationListenerService.HINT_HOST_DISABLE_CALL_EFFECTS));
+
+        verifyBeepUnlooped();
+    }
+
+    @Test
+    public void testListenerHintNotification() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, new NotificationAttentionHelper.Signals(false,
+            NotificationListenerService.HINT_HOST_DISABLE_NOTIFICATION_EFFECTS));
+
+        verifyNeverBeep();
+    }
+
+    @Test
+    public void testListenerHintBoth() throws Exception {
+        NotificationChannel ringtoneChannel =
+            new NotificationChannel("ringtone", "", IMPORTANCE_HIGH);
+        ringtoneChannel.setSound(Settings.System.DEFAULT_RINGTONE_URI,
+            new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE).build());
+        NotificationRecord r = getCallRecord(1, ringtoneChannel, true);
+        NotificationRecord s = getBeepyNotification();
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, new NotificationAttentionHelper.Signals(false,
+            NotificationListenerService.HINT_HOST_DISABLE_NOTIFICATION_EFFECTS
+                | NotificationListenerService.HINT_HOST_DISABLE_CALL_EFFECTS));
+        mAttentionHelper.buzzBeepBlinkLocked(s, new NotificationAttentionHelper.Signals(false,
+            NotificationListenerService.HINT_HOST_DISABLE_NOTIFICATION_EFFECTS
+                | NotificationListenerService.HINT_HOST_DISABLE_CALL_EFFECTS));
+
+        verifyNeverBeep();
+    }
+
+    @Test
+    public void testListenerHintNotification_callSound() throws Exception {
+        NotificationChannel ringtoneChannel =
+            new NotificationChannel("ringtone", "", IMPORTANCE_HIGH);
+        ringtoneChannel.setSound(Settings.System.DEFAULT_RINGTONE_URI,
+            new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE).build());
+        NotificationRecord r = getCallRecord(1, ringtoneChannel, true);
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, new NotificationAttentionHelper.Signals(false,
+            NotificationListenerService.HINT_HOST_DISABLE_NOTIFICATION_EFFECTS));
+
+        verifyBeepLooped();
+    }
+
+    @Test
+    public void testCannotInterruptRingtoneInsistentBeep() throws Exception {
+        NotificationChannel ringtoneChannel =
+            new NotificationChannel("ringtone", "", IMPORTANCE_HIGH);
+        ringtoneChannel.setSound(Settings.System.DEFAULT_RINGTONE_URI,
+            new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE).build());
+        NotificationRecord ringtoneNotification = getCallRecord(1, ringtoneChannel, true);
+        mService.addNotification(ringtoneNotification);
+
+        mAttentionHelper.buzzBeepBlinkLocked(ringtoneNotification, DEFAULT_SIGNALS);
+        verifyBeepLooped();
+
+        NotificationRecord interrupter = getBeepyOtherNotification();
+        assertTrue(mAttentionHelper.shouldMuteNotificationLocked(interrupter, DEFAULT_SIGNALS));
+        mAttentionHelper.buzzBeepBlinkLocked(interrupter, DEFAULT_SIGNALS);
+
+        verifyBeep(1);
+
+        assertFalse(interrupter.isInterruptive());
+        assertEquals(-1, interrupter.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testRingtoneInsistentBeep_canUpdate() throws Exception {
+        NotificationChannel ringtoneChannel =
+            new NotificationChannel("ringtone", "", IMPORTANCE_HIGH);
+        ringtoneChannel.setSound(Uri.fromParts("a", "b", "c"),
+            new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE).build());
+        ringtoneChannel.enableVibration(true);
+        NotificationRecord ringtoneNotification = getCallRecord(1, ringtoneChannel, true);
+        mService.addNotification(ringtoneNotification);
+        assertFalse(mAttentionHelper.shouldMuteNotificationLocked(ringtoneNotification,
+            DEFAULT_SIGNALS));
+        mAttentionHelper.buzzBeepBlinkLocked(ringtoneNotification, DEFAULT_SIGNALS);
+        verifyBeepLooped();
+        verifyDelayedVibrateLooped();
+        Mockito.reset(mVibrator);
+        Mockito.reset(mRingtonePlayer);
+
+        assertFalse(mAttentionHelper.shouldMuteNotificationLocked(ringtoneNotification,
+            DEFAULT_SIGNALS));
+        mAttentionHelper.buzzBeepBlinkLocked(ringtoneNotification, DEFAULT_SIGNALS);
+
+        // beep wasn't reset
+        verifyNeverBeep();
+        verifyNeverVibrate();
+        verifyNeverStopAudio();
+        verifyNeverStopVibrate();
+    }
+
+    @Test
+    public void testRingtoneInsistentBeep_clearEffectsStopsSoundAndVibration() throws Exception {
+        NotificationChannel ringtoneChannel =
+            new NotificationChannel("ringtone", "", IMPORTANCE_HIGH);
+        ringtoneChannel.setSound(Uri.fromParts("a", "b", "c"),
+            new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE).build());
+        ringtoneChannel.enableVibration(true);
+        NotificationRecord ringtoneNotification = getCallRecord(1, ringtoneChannel, true);
+        mService.addNotification(ringtoneNotification);
+        assertFalse(mAttentionHelper.shouldMuteNotificationLocked(ringtoneNotification,
+            DEFAULT_SIGNALS));
+        mAttentionHelper.buzzBeepBlinkLocked(ringtoneNotification, DEFAULT_SIGNALS);
+        verifyBeepLooped();
+        verifyDelayedVibrateLooped();
+
+        mAttentionHelper.clearSoundLocked();
+        mAttentionHelper.clearVibrateLocked();
+
+        verifyStopAudio();
+        verifyStopVibrate();
+    }
+
+    @Test
+    public void testRingtoneInsistentBeep_neverVibratesWhenEffectsClearedBeforeDelay()
+        throws Exception {
+        NotificationChannel ringtoneChannel =
+            new NotificationChannel("ringtone", "", IMPORTANCE_HIGH);
+        ringtoneChannel.setSound(Uri.fromParts("a", "b", "c"),
+            new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE).build());
+        ringtoneChannel.enableVibration(true);
+        NotificationRecord ringtoneNotification = getCallRecord(1, ringtoneChannel, true);
+        mService.addNotification(ringtoneNotification);
+        assertFalse(mAttentionHelper.shouldMuteNotificationLocked(ringtoneNotification,
+            DEFAULT_SIGNALS));
+        mAttentionHelper.buzzBeepBlinkLocked(ringtoneNotification, DEFAULT_SIGNALS);
+        verifyBeepLooped();
+        verifyNeverVibrate();
+
+        mAttentionHelper.clearSoundLocked();
+        mAttentionHelper.clearVibrateLocked();
+
+        verifyStopAudio();
+        verifyDelayedNeverVibrate();
+    }
+
+    @Test
+    public void testCannotInterruptRingtoneInsistentBuzz() {
+        NotificationChannel ringtoneChannel =
+            new NotificationChannel("ringtone", "", IMPORTANCE_HIGH);
+        ringtoneChannel.setSound(Uri.EMPTY,
+            new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE).build());
+        ringtoneChannel.enableVibration(true);
+        NotificationRecord ringtoneNotification = getCallRecord(1, ringtoneChannel, true);
+        assertFalse(mAttentionHelper.shouldMuteNotificationLocked(ringtoneNotification,
+            DEFAULT_SIGNALS));
+
+        mAttentionHelper.buzzBeepBlinkLocked(ringtoneNotification, DEFAULT_SIGNALS);
+        verifyVibrateLooped();
+
+        NotificationRecord interrupter = getBuzzyOtherNotification();
+        assertTrue(mAttentionHelper.shouldMuteNotificationLocked(interrupter, DEFAULT_SIGNALS));
+        mAttentionHelper.buzzBeepBlinkLocked(interrupter, DEFAULT_SIGNALS);
+
+        verifyVibrate(1);
+
+        assertFalse(interrupter.isInterruptive());
+        assertEquals(-1, interrupter.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testCanInterruptRingtoneNonInsistentBeep() throws Exception {
+        NotificationChannel ringtoneChannel =
+            new NotificationChannel("ringtone", "", IMPORTANCE_HIGH);
+        ringtoneChannel.setSound(Settings.System.DEFAULT_RINGTONE_URI,
+            new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE).build());
+        NotificationRecord ringtoneNotification = getCallRecord(1, ringtoneChannel, false);
+
+        mAttentionHelper.buzzBeepBlinkLocked(ringtoneNotification, DEFAULT_SIGNALS);
+        verifyBeepUnlooped();
+
+        NotificationRecord interrupter = getBeepyOtherNotification();
+        mAttentionHelper.buzzBeepBlinkLocked(interrupter, DEFAULT_SIGNALS);
+
+        verifyBeep(2);
+
+        assertTrue(interrupter.isInterruptive());
+    }
+
+    @Test
+    public void testCanInterruptRingtoneNonInsistentBuzz() {
+        NotificationChannel ringtoneChannel =
+            new NotificationChannel("ringtone", "", IMPORTANCE_HIGH);
+        ringtoneChannel.setSound(null,
+            new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE).build());
+        ringtoneChannel.enableVibration(true);
+        NotificationRecord ringtoneNotification = getCallRecord(1, ringtoneChannel, false);
+
+        mAttentionHelper.buzzBeepBlinkLocked(ringtoneNotification, DEFAULT_SIGNALS);
+        verifyVibrate();
+
+        NotificationRecord interrupter = getBuzzyOtherNotification();
+        mAttentionHelper.buzzBeepBlinkLocked(interrupter, DEFAULT_SIGNALS);
+
+        verifyVibrate(2);
+
+        assertTrue(interrupter.isInterruptive());
+    }
+
+    @Test
+    public void testRingtoneInsistentBeep_doesNotBlockFutureSoundsOnceStopped() throws Exception {
+        NotificationChannel ringtoneChannel =
+            new NotificationChannel("ringtone", "", IMPORTANCE_HIGH);
+        ringtoneChannel.setSound(Settings.System.DEFAULT_RINGTONE_URI,
+            new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE).build());
+        NotificationRecord ringtoneNotification = getCallRecord(1, ringtoneChannel, true);
+
+        mAttentionHelper.buzzBeepBlinkLocked(ringtoneNotification, DEFAULT_SIGNALS);
+        verifyBeepLooped();
+
+        mAttentionHelper.clearSoundLocked();
+
+        NotificationRecord interrupter = getBeepyOtherNotification();
+        mAttentionHelper.buzzBeepBlinkLocked(interrupter, DEFAULT_SIGNALS);
+
+        verifyBeep(2);
+
+        assertTrue(interrupter.isInterruptive());
+    }
+
+    @Test
+    public void testRingtoneInsistentBuzz_doesNotBlockFutureSoundsOnceStopped() {
+        NotificationChannel ringtoneChannel =
+            new NotificationChannel("ringtone", "", IMPORTANCE_HIGH);
+        ringtoneChannel.setSound(null,
+            new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE).build());
+        ringtoneChannel.enableVibration(true);
+        NotificationRecord ringtoneNotification = getCallRecord(1, ringtoneChannel, true);
+
+        mAttentionHelper.buzzBeepBlinkLocked(ringtoneNotification, DEFAULT_SIGNALS);
+        verifyVibrateLooped();
+
+        mAttentionHelper.clearVibrateLocked();
+
+        NotificationRecord interrupter = getBuzzyOtherNotification();
+        mAttentionHelper.buzzBeepBlinkLocked(interrupter, DEFAULT_SIGNALS);
+
+        verifyVibrate(2);
+
+        assertTrue(interrupter.isInterruptive());
+    }
+
+    @Test
+    public void testCanInterruptNonRingtoneInsistentBeep() throws Exception {
+        NotificationChannel fakeRingtoneChannel =
+            new NotificationChannel("ringtone", "", IMPORTANCE_HIGH);
+        NotificationRecord ringtoneNotification = getCallRecord(1, fakeRingtoneChannel, true);
+
+        mAttentionHelper.buzzBeepBlinkLocked(ringtoneNotification, DEFAULT_SIGNALS);
+        verifyBeepLooped();
+
+        NotificationRecord interrupter = getBeepyOtherNotification();
+        mAttentionHelper.buzzBeepBlinkLocked(interrupter, DEFAULT_SIGNALS);
+
+        verifyBeep(2);
+
+        assertTrue(interrupter.isInterruptive());
+    }
+
+    @Test
+    public void testCanInterruptNonRingtoneInsistentBuzz() {
+        NotificationChannel fakeRingtoneChannel =
+            new NotificationChannel("ringtone", "", IMPORTANCE_HIGH);
+        fakeRingtoneChannel.enableVibration(true);
+        fakeRingtoneChannel.setSound(null,
+            new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION).build());
+        NotificationRecord ringtoneNotification = getCallRecord(1, fakeRingtoneChannel, true);
+
+        mAttentionHelper.buzzBeepBlinkLocked(ringtoneNotification, DEFAULT_SIGNALS);
+
+        NotificationRecord interrupter = getBuzzyOtherNotification();
+        mAttentionHelper.buzzBeepBlinkLocked(interrupter, DEFAULT_SIGNALS);
+
+        verifyVibrate(2);
+
+        assertTrue(interrupter.isInterruptive());
+    }
+
+    @Test
+    public void testBubbleSuppressedNotificationDoesntMakeSound() {
+        Notification.BubbleMetadata metadata = new Notification.BubbleMetadata.Builder(
+            mock(PendingIntent.class), mock(Icon.class))
+            .build();
+
+        NotificationRecord record = getBuzzyNotification();
+        metadata.setFlags(Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION);
+        record.getNotification().setBubbleMetadata(metadata);
+        record.setAllowBubble(true);
+        record.getNotification().flags |= FLAG_BUBBLE;
+        record.isUpdate = true;
+        record.setInterruptive(false);
+
+        mAttentionHelper.buzzBeepBlinkLocked(record, DEFAULT_SIGNALS);
+        verifyNeverVibrate();
+    }
+
+    @Test
+    public void testOverflowBubbleSuppressedNotificationDoesntMakeSound() {
+        Notification.BubbleMetadata metadata = new Notification.BubbleMetadata.Builder(
+            mock(PendingIntent.class), mock(Icon.class))
+            .build();
+
+        NotificationRecord record = getBuzzyNotification();
+        metadata.setFlags(Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION);
+        record.getNotification().setBubbleMetadata(metadata);
+        record.setFlagBubbleRemoved(true);
+        record.setAllowBubble(true);
+        record.isUpdate = true;
+        record.setInterruptive(false);
+
+        mAttentionHelper.buzzBeepBlinkLocked(record, DEFAULT_SIGNALS);
+        verifyNeverVibrate();
+    }
+
+    @Test
+    public void testBubbleUpdateMakesSound() {
+        Notification.BubbleMetadata metadata = new Notification.BubbleMetadata.Builder(
+            mock(PendingIntent.class), mock(Icon.class))
+            .build();
+
+        NotificationRecord record = getBuzzyNotification();
+        record.getNotification().setBubbleMetadata(metadata);
+        record.setAllowBubble(true);
+        record.getNotification().flags |= FLAG_BUBBLE;
+        record.isUpdate = true;
+        record.setInterruptive(true);
+
+        mAttentionHelper.buzzBeepBlinkLocked(record, DEFAULT_SIGNALS);
+        verifyVibrate(1);
+    }
+
+    @Test
+    public void testNewBubbleSuppressedNotifMakesSound() {
+        Notification.BubbleMetadata metadata = new Notification.BubbleMetadata.Builder(
+            mock(PendingIntent.class), mock(Icon.class))
+            .build();
+
+        NotificationRecord record = getBuzzyNotification();
+        metadata.setFlags(Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION);
+        record.getNotification().setBubbleMetadata(metadata);
+        record.setAllowBubble(true);
+        record.getNotification().flags |= FLAG_BUBBLE;
+        record.isUpdate = false;
+        record.setInterruptive(true);
+
+        mAttentionHelper.buzzBeepBlinkLocked(record, DEFAULT_SIGNALS);
+        verifyVibrate(1);
+    }
+
+    @Test
+    public void testStartFlashNotificationEvent_receiveBeepyNotification() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        verifyBeepUnlooped();
+        verifyNeverVibrate();
+        verify(mAccessibilityService).startFlashNotificationEvent(any(), anyInt(),
+            eq(r.getSbn().getPackageName()));
+        assertTrue(r.isInterruptive());
+        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testStartFlashNotificationEvent_receiveBuzzyNotification() throws Exception {
+        NotificationRecord r = getBuzzyNotification();
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        verifyNeverBeep();
+        verifyVibrate();
+        verify(mAccessibilityService).startFlashNotificationEvent(any(), anyInt(),
+            eq(r.getSbn().getPackageName()));
+        assertTrue(r.isInterruptive());
+        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testStartFlashNotificationEvent_receiveBuzzyBeepyNotification() throws Exception {
+        NotificationRecord r = getBuzzyBeepyNotification();
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        verifyBeepUnlooped();
+        verifyDelayedVibrate(r.getVibration());
+        verify(mAccessibilityService).startFlashNotificationEvent(any(), anyInt(),
+            eq(r.getSbn().getPackageName()));
+        assertTrue(r.isInterruptive());
+        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testStartFlashNotificationEvent_receiveBuzzyBeepyNotification_ringerModeSilent()
+        throws Exception {
+        NotificationRecord r = getBuzzyBeepyNotification();
+        when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
+        when(mAudioManager.getStreamVolume(anyInt())).thenReturn(0);
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        verifyNeverBeep();
+        verifyNeverVibrate();
+        verify(mAccessibilityService).startFlashNotificationEvent(any(), anyInt(),
+            eq(r.getSbn().getPackageName()));
+        assertFalse(r.isInterruptive());
+        assertEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    static class VibrateRepeatMatcher implements ArgumentMatcher<VibrationEffect> {
+        private final int mRepeatIndex;
+
+        VibrateRepeatMatcher(int repeatIndex) {
+            mRepeatIndex = repeatIndex;
+        }
+
+        @Override
+        public boolean matches(VibrationEffect actual) {
+            if (actual instanceof VibrationEffect.Composed
+                && ((VibrationEffect.Composed) actual).getRepeatIndex() == mRepeatIndex) {
+                return true;
+            }
+            // All non-waveform effects are essentially one shots.
+            return mRepeatIndex == -1;
+        }
+
+        @Override
+        public String toString() {
+            return "repeatIndex=" + mRepeatIndex;
+        }
+    }
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 4576e9be07ad..9543a2de1e13 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -84,6 +84,7 @@ import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
 
+import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR;
 import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.FSI_FORCE_DEMOTE;
 import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.SHOW_STICKY_HUN_FOR_DENIED_FSI;
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
@@ -272,6 +273,7 @@ import com.google.common.collect.ImmutableList;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
@@ -279,6 +281,7 @@ import org.mockito.ArgumentMatcher;
 import org.mockito.ArgumentMatchers;
 import org.mockito.InOrder;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
@@ -372,6 +375,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
     private DevicePolicyManagerInternal mDevicePolicyManager;
     @Mock
     private PowerManager mPowerManager;
+    @Mock
+    private LightsManager mLightsManager;
     private final ArrayList<WakeLock> mAcquiredWakeLocks = new ArrayList<>();
     private final TestPostNotificationTrackerFactory mPostNotificationTrackerFactory =
             new TestPostNotificationTrackerFactory();
@@ -503,9 +508,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
 
         setDpmAppOppsExemptFromDismissal(false);
 
-        mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger,
-                mNotificationInstanceIdSequence);
-
         // Use this testable looper.
         mTestableLooper = TestableLooper.get(this);
         // MockPackageManager - default returns ApplicationInfo with matching calling UID
@@ -527,8 +529,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
                     Object[] args = invocation.getArguments();
                     return (int) args[1] == mUid;
                 });
-        final LightsManager mockLightsManager = mock(LightsManager.class);
-        when(mockLightsManager.getLight(anyInt())).thenReturn(mock(LogicalLight.class));
+        when(mLightsManager.getLight(anyInt())).thenReturn(mock(LogicalLight.class));
         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
         when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false);
         when(mUgmInternal.newUriPermissionOwner(anyString())).thenReturn(mPermOwner);
@@ -601,6 +602,15 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
                     return wl;
                 });
 
+        // TODO (b/291907312): remove feature flag
+        mTestFlagResolver.setFlagOverride(ENABLE_ATTENTION_HELPER_REFACTOR, false);
+        initNMS();
+    }
+
+    private void initNMS() throws Exception {
+        mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger,
+                mNotificationInstanceIdSequence);
+
         // apps allowed as convos
         mService.setStringArrayResourceValue(PKG_O);
 
@@ -617,7 +627,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
 
         mWorkerHandler = spy(mService.new WorkerHandler(mTestableLooper.getLooper()));
         mService.init(mWorkerHandler, mRankingHandler, mPackageManager, mPackageManagerClient,
-                mockLightsManager, mListeners, mAssistants, mConditionProviders, mCompanionMgr,
+                mLightsManager, mListeners, mAssistants, mConditionProviders, mCompanionMgr,
                 mSnoozeHelper, mUsageStats, mPolicyFile, mActivityManager, mGroupHelper, mAm, mAtm,
                 mAppUsageStats, mDevicePolicyManager, mUgm, mUgmInternal,
                 mAppOpsManager, mUm, mHistoryManager, mStatsManager,
@@ -628,11 +638,17 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
         // Return first true for RoleObserver main-thread check
         when(mMainLooper.isCurrentThread()).thenReturn(true).thenReturn(false);
         mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY, mMainLooper);
+        Mockito.reset(mHistoryManager);
         verify(mHistoryManager, never()).onBootPhaseAppsCanStart();
         mService.onBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START, mMainLooper);
         verify(mHistoryManager).onBootPhaseAppsCanStart();
 
-        mService.setAudioManager(mAudioManager);
+        // TODO b/291907312: remove feature flag
+        if (mTestFlagResolver.isEnabled(ENABLE_ATTENTION_HELPER_REFACTOR)) {
+            mService.mAttentionHelper.setAudioManager(mAudioManager);
+        } else {
+            mService.setAudioManager(mAudioManager);
+        }
 
         mStrongAuthTracker = mService.new StrongAuthTrackerFake(mContext);
         mService.setStrongAuthTracker(mStrongAuthTracker);
@@ -1652,6 +1668,23 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
         assertThat(call.postDurationMillisLogged).isGreaterThan(0);
     }
 
+    @Test
+    public void testEnqueueNotificationWithTag_WritesExpectedLogs_NAHRefactor() throws Exception {
+        // TODO b/291907312: remove feature flag
+        mTestFlagResolver.setFlagOverride(ENABLE_ATTENTION_HELPER_REFACTOR, true);
+        // Cleanup NMS before re-initializing
+        if (mService != null) {
+            try {
+                mService.onDestroy();
+            } catch (IllegalStateException | IllegalArgumentException e) {
+                // can throw if a broadcast receiver was never registered
+            }
+        }
+        initNMS();
+
+        testEnqueueNotificationWithTag_WritesExpectedLogs();
+    }
+
     @Test
     public void testEnqueueNotificationWithTag_LogsOnMajorUpdates() throws Exception {
         final String tag = "testEnqueueNotificationWithTag_LogsOnMajorUpdates";
@@ -9014,6 +9047,24 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
         verify(mockPlayer).stopAsync();
     }
 
+    @Test
+    public void testOnBubbleMetadataChangedToSuppressNotification_soundStopped_NAHRefactor()
+        throws Exception {
+        // TODO b/291907312: remove feature flag
+        mTestFlagResolver.setFlagOverride(ENABLE_ATTENTION_HELPER_REFACTOR, true);
+        // Cleanup NMS before re-initializing
+        if (mService != null) {
+            try {
+                mService.onDestroy();
+            } catch (IllegalStateException | IllegalArgumentException e) {
+                // can throw if a broadcast receiver was never registered
+            }
+        }
+        initNMS();
+
+        testOnBubbleMetadataChangedToSuppressNotification_soundStopped();
+    }
+
     @Test
     public void testGrantInlineReplyUriPermission_recordExists() throws Exception {
         int userId = UserManager.isHeadlessSystemUserMode()
-- 
GitLab


From 8ac2e966ff3fa7af71a190b12fc1d05c82b11aad Mon Sep 17 00:00:00 2001
From: mrulhania <mrulhania@google.com>
Date: Mon, 21 Aug 2023 17:28:23 -0700
Subject: [PATCH 59/95] device aware self revoke and one time session timeout

Bug: 283978092
Test: atest RevokeSelfPermissionTest
Test: atest OneTimePermissionTest
Test: atest DevicePermissionsTest

Change-Id: I0adef572133a288c17e43b3e1b8adcf53ff68114
---
 core/api/system-current.txt                   |  6 +-
 .../permission/IPermissionController.aidl     |  4 +-
 .../permission/IPermissionManager.aidl        |  2 +-
 .../PermissionControllerManager.java          | 15 +++--
 .../PermissionControllerService.java          | 60 +++++++++++++++++--
 .../android/permission/PermissionManager.java | 10 +++-
 packages/Shell/AndroidManifest.xml            |  1 +
 .../OneTimePermissionUserManager.java         | 39 +++++++-----
 .../permission/PermissionManagerService.java  |  6 +-
 .../permission/DevicePermissionPolicy.kt      | 23 ++++++-
 10 files changed, 127 insertions(+), 39 deletions(-)

diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 7c78f09f0057..69ed5aeda7de 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -10635,12 +10635,14 @@ package android.permission {
     method @BinderThread public abstract void onGetRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.OutputStream, @NonNull Runnable);
     method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_APP_HIBERNATION) public void onGetUnusedAppCount(@NonNull java.util.function.IntConsumer);
     method @BinderThread public abstract void onGrantOrUpgradeDefaultRuntimePermissions(@NonNull Runnable);
-    method @BinderThread public void onOneTimePermissionSessionTimeout(@NonNull String);
+    method @Deprecated @BinderThread public void onOneTimePermissionSessionTimeout(@NonNull String);
+    method @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS) @BinderThread public void onOneTimePermissionSessionTimeout(@NonNull String, int);
     method @Deprecated @BinderThread public void onRestoreDelayedRuntimePermissionsBackup(@NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.function.Consumer<java.lang.Boolean>);
     method @Deprecated @BinderThread public void onRestoreRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.InputStream, @NonNull Runnable);
     method @BinderThread public abstract void onRevokeRuntimePermission(@NonNull String, @NonNull String, @NonNull Runnable);
     method @BinderThread public abstract void onRevokeRuntimePermissions(@NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, @NonNull String, @NonNull java.util.function.Consumer<java.util.Map<java.lang.String,java.util.List<java.lang.String>>>);
-    method @BinderThread public void onRevokeSelfPermissionsOnKill(@NonNull String, @NonNull java.util.List<java.lang.String>, @NonNull Runnable);
+    method @Deprecated @BinderThread public void onRevokeSelfPermissionsOnKill(@NonNull String, @NonNull java.util.List<java.lang.String>, @NonNull Runnable);
+    method @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS) @BinderThread public void onRevokeSelfPermissionsOnKill(@NonNull String, @NonNull java.util.List<java.lang.String>, int, @NonNull Runnable);
     method @Deprecated @BinderThread public abstract void onSetRuntimePermissionGrantStateByDeviceAdmin(@NonNull String, @NonNull String, @NonNull String, int, @NonNull java.util.function.Consumer<java.lang.Boolean>);
     method @BinderThread public void onSetRuntimePermissionGrantStateByDeviceAdmin(@NonNull String, @NonNull android.permission.AdminPermissionControlParams, @NonNull java.util.function.Consumer<java.lang.Boolean>);
     method @BinderThread public void onStageAndApplyRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.InputStream, @NonNull Runnable);
diff --git a/core/java/android/permission/IPermissionController.aidl b/core/java/android/permission/IPermissionController.aidl
index e3f02e73a41f..1cb7930928d0 100644
--- a/core/java/android/permission/IPermissionController.aidl
+++ b/core/java/android/permission/IPermissionController.aidl
@@ -43,7 +43,7 @@ oneway interface IPermissionController {
     void setRuntimePermissionGrantStateByDeviceAdminFromParams(String callerPackageName,
             in AdminPermissionControlParams params, in AndroidFuture callback);
     void grantOrUpgradeDefaultRuntimePermissions(in AndroidFuture callback);
-    void notifyOneTimePermissionSessionTimeout(String packageName);
+    void notifyOneTimePermissionSessionTimeout(String packageName, int deviceId);
     void updateUserSensitiveForApp(int uid, in AndroidFuture callback);
     void getPrivilegesDescriptionStringForProfile(
             in String deviceProfileName,
@@ -60,5 +60,5 @@ oneway interface IPermissionController {
                 in String packageName,
                 in AndroidFuture callback);
     void revokeSelfPermissionsOnKill(in String packageName, in List<String> permissions,
-            in AndroidFuture callback);
+        int deviceId, in AndroidFuture callback);
 }
diff --git a/core/java/android/permission/IPermissionManager.aidl b/core/java/android/permission/IPermissionManager.aidl
index 18ede44dca20..7cecfdca851a 100644
--- a/core/java/android/permission/IPermissionManager.aidl
+++ b/core/java/android/permission/IPermissionManager.aidl
@@ -78,7 +78,7 @@ interface IPermissionManager {
     List<SplitPermissionInfoParcelable> getSplitPermissions();
 
     @EnforcePermission("MANAGE_ONE_TIME_PERMISSION_SESSIONS")
-    void startOneTimePermissionSession(String packageName, int userId, long timeout,
+    void startOneTimePermissionSession(String packageName, int deviceId, int userId, long timeout,
             long revokeAfterKilledDelay);
 
     @EnforcePermission("MANAGE_ONE_TIME_PERMISSION_SESSIONS")
diff --git a/core/java/android/permission/PermissionControllerManager.java b/core/java/android/permission/PermissionControllerManager.java
index 84a197a96531..ba7591814a7b 100644
--- a/core/java/android/permission/PermissionControllerManager.java
+++ b/core/java/android/permission/PermissionControllerManager.java
@@ -764,13 +764,14 @@ public final class PermissionControllerManager {
      * inactive.
      *
      * @param packageName The package which became inactive
-     *
+     * @param deviceId The device ID refers either the primary device i.e. the phone or
+     *                 a virtual device. See {@link Context#DEVICE_ID_DEFAULT}
      * @hide
      */
     @RequiresPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
-    public void notifyOneTimePermissionSessionTimeout(@NonNull String packageName) {
-        mRemoteService.run(
-                service -> service.notifyOneTimePermissionSessionTimeout(packageName));
+    public void notifyOneTimePermissionSessionTimeout(@NonNull String packageName, int deviceId) {
+        mRemoteService.run(service -> service.notifyOneTimePermissionSessionTimeout(
+                packageName, deviceId));
     }
 
     /**
@@ -930,12 +931,14 @@ public final class PermissionControllerManager {
             @NonNull List<String> permissions) {
         mRemoteService.postAsync(service -> {
             AndroidFuture<Void> callback = new AndroidFuture<>();
-            service.revokeSelfPermissionsOnKill(packageName, permissions, callback);
+            service.revokeSelfPermissionsOnKill(packageName, permissions, mContext.getDeviceId(),
+                    callback);
             return callback;
         }).whenComplete((result, err) -> {
             if (err != null) {
                 Log.e(TAG, "Failed to self revoke " + String.join(",", permissions)
-                        + " for package " + packageName, err);
+                        + " for package " + packageName + ", and device " + mContext.getDeviceId(),
+                        err);
             }
         });
     }
diff --git a/core/java/android/permission/PermissionControllerService.java b/core/java/android/permission/PermissionControllerService.java
index 11005a6d265b..9fe2599dd39b 100644
--- a/core/java/android/permission/PermissionControllerService.java
+++ b/core/java/android/permission/PermissionControllerService.java
@@ -30,6 +30,7 @@ import static com.android.internal.util.Preconditions.checkStringNotEmpty;
 
 import android.Manifest;
 import android.annotation.BinderThread;
+import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
@@ -37,6 +38,7 @@ import android.app.Service;
 import android.app.admin.DevicePolicyManager.PermissionGrantState;
 import android.compat.annotation.ChangeId;
 import android.compat.annotation.Disabled;
+import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
@@ -46,6 +48,7 @@ import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
 import android.os.UserHandle;
 import android.permission.PermissionControllerManager.CountPermissionAppsFlag;
+import android.permission.flags.Flags;
 import android.util.ArrayMap;
 import android.util.Log;
 
@@ -296,12 +299,31 @@ public abstract class PermissionControllerService extends Service {
      * This method is called at the end of a one-time permission session
      *
      * @param packageName The package that has been inactive
+     *
+     * @deprecated Implement {@link #onOneTimePermissionSessionTimeout(String, int)} instead.
      */
+    @Deprecated
     @BinderThread
     public void onOneTimePermissionSessionTimeout(@NonNull String packageName) {
         throw new AbstractMethodError("Must be overridden in implementing class");
     }
 
+    /**
+     * Called when a package is considered inactive based on the criteria given by
+     * {@link PermissionManager#startOneTimePermissionSession(String, long, long, int, int)}.
+     * This method is called at the end of a one-time permission session
+     *
+     * @param packageName The package that has been inactive
+     * @param deviceId The device ID refers either the primary device i.e. the phone or
+     *                 a virtual device. See {@link Context#DEVICE_ID_DEFAULT}
+     */
+    @BinderThread
+    @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS)
+    public void onOneTimePermissionSessionTimeout(@NonNull String packageName,
+            int deviceId) {
+        onOneTimePermissionSessionTimeout(packageName);
+    }
+
     /**
      * Get the platform permissions which belong to a particular permission group
      *
@@ -341,13 +363,42 @@ public abstract class PermissionControllerService extends Service {
      * @param callback Callback waiting for operation to be complete.
      *
      * @see android.content.Context#revokeSelfPermissionsOnKill(java.util.Collection)
+     *
+     * @deprecated Implement {@link #onRevokeSelfPermissionsOnKill(String, List, int, Runnable)}
+     * instead.
      */
+    @Deprecated
     @BinderThread
     public void onRevokeSelfPermissionsOnKill(@NonNull String packageName,
             @NonNull List<String> permissions, @NonNull Runnable callback) {
         throw new AbstractMethodError("Must be overridden in implementing class");
     }
 
+    /**
+     * Triggers the revocation of one or more permissions for a package and device.
+     * This should only be called at the request of {@code packageName}.
+     * <p>
+     * Background permissions which have no corresponding foreground permission still granted once
+     * the revocation is effective will also be revoked.
+     * <p>
+     * This revocation happens asynchronously and kills all processes running in the same UID as
+     * {@code packageName}. It will be triggered once it is safe to do so.
+     *
+     * @param packageName The name of the package for which the permissions will be revoked.
+     * @param permissions List of permissions to be revoked.
+     * @param deviceId The device ID refers either the primary device i.e. the phone or
+     *                 a virtual device. See {@link Context#DEVICE_ID_DEFAULT}
+     * @param callback Callback waiting for operation to be complete.
+     *
+     * @see android.content.Context#revokeSelfPermissionsOnKill(java.util.Collection)
+     */
+    @BinderThread
+    @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS)
+    public void onRevokeSelfPermissionsOnKill(@NonNull String packageName,
+            @NonNull List<String> permissions, int deviceId, @NonNull Runnable callback) {
+        onRevokeSelfPermissionsOnKill(packageName, permissions, callback);
+    }
+
     // TODO(b/272129940): Remove this API and device profile role description when we drop T
     //  support.
     /**
@@ -613,12 +664,12 @@ public abstract class PermissionControllerService extends Service {
             }
 
             @Override
-            public void notifyOneTimePermissionSessionTimeout(String packageName) {
+            public void notifyOneTimePermissionSessionTimeout(String packageName, int deviceId) {
                 enforceSomePermissionsGrantedToCaller(
                         Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
                 packageName = Preconditions.checkNotNull(packageName,
                         "packageName cannot be null");
-                onOneTimePermissionSessionTimeout(packageName);
+                onOneTimePermissionSessionTimeout(packageName, deviceId);
             }
 
             @Override
@@ -710,7 +761,8 @@ public abstract class PermissionControllerService extends Service {
 
             @Override
             public void revokeSelfPermissionsOnKill(@NonNull String packageName,
-                    @NonNull List<String> permissions, @NonNull AndroidFuture callback) {
+                    @NonNull List<String> permissions, int deviceId,
+                    @NonNull AndroidFuture callback) {
                 try {
                     Objects.requireNonNull(callback);
 
@@ -721,7 +773,7 @@ public abstract class PermissionControllerService extends Service {
                         enforceSomePermissionsGrantedToCaller(
                                 Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
                     }
-                    onRevokeSelfPermissionsOnKill(packageName, permissions,
+                    onRevokeSelfPermissionsOnKill(packageName, permissions, deviceId,
                             () -> callback.complete(null));
                 } catch (Throwable t) {
                     callback.completeExceptionally(t);
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index 7d3921049712..e10ea10e2a29 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -213,6 +213,12 @@ public final class PermissionManager {
      */
     public static final boolean DEBUG_TRACE_PERMISSION_UPDATES = false;
 
+    /**
+     * Additional debug log for virtual device permissions.
+     * @hide
+     */
+    public static final boolean DEBUG_DEVICE_PERMISSIONS = false;
+
     /**
      * Intent extra: List of PermissionGroupUsages
      * <p>
@@ -1392,8 +1398,8 @@ public final class PermissionManager {
             @ActivityManager.RunningAppProcessInfo.Importance int importanceToResetTimer,
             @ActivityManager.RunningAppProcessInfo.Importance int importanceToKeepSessionAlive) {
         try {
-            mPermissionManager.startOneTimePermissionSession(packageName, mContext.getUserId(),
-                    timeoutMillis, revokeAfterKilledDelayMillis);
+            mPermissionManager.startOneTimePermissionSession(packageName, mContext.getDeviceId(),
+                    mContext.getUserId(), timeoutMillis, revokeAfterKilledDelayMillis);
         } catch (RemoteException e) {
             e.rethrowFromSystemServer();
         }
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 15620b7023e2..11ae9c35898b 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -206,6 +206,7 @@
     <uses-permission android:name="android.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY" />
     <uses-permission android:name="android.permission.GRANT_RUNTIME_PERMISSIONS" />
     <uses-permission android:name="android.permission.REVOKE_RUNTIME_PERMISSIONS" />
+    <uses-permission android:name="android.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS" />
     <uses-permission android:name="android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS" />
     <uses-permission android:name="android.permission.WHITELIST_RESTRICTED_PERMISSIONS" />
     <!-- Permission required for processes that don't own the focused window to switch
diff --git a/services/core/java/com/android/server/pm/permission/OneTimePermissionUserManager.java b/services/core/java/com/android/server/pm/permission/OneTimePermissionUserManager.java
index 3296c1f284af..150ca9ba2853 100644
--- a/services/core/java/com/android/server/pm/permission/OneTimePermissionUserManager.java
+++ b/services/core/java/com/android/server/pm/permission/OneTimePermissionUserManager.java
@@ -91,13 +91,14 @@ public class OneTimePermissionUserManager {
         mHandler = context.getMainThreadHandler();
     }
 
-    void startPackageOneTimeSession(@NonNull String packageName, long timeoutMillis,
+    void startPackageOneTimeSession(@NonNull String packageName, int deviceId, long timeoutMillis,
             long revokeAfterKilledDelayMillis) {
         int uid;
         try {
             uid = mContext.getPackageManager().getPackageUid(packageName, 0);
         } catch (PackageManager.NameNotFoundException e) {
-            Log.e(LOG_TAG, "Unknown package name " + packageName, e);
+            Log.e(LOG_TAG,
+                    "Unknown package name " + packageName + ", device ID " + deviceId, e);
             return;
         }
 
@@ -107,7 +108,7 @@ public class OneTimePermissionUserManager {
                 listener.updateSessionParameters(timeoutMillis, revokeAfterKilledDelayMillis);
                 return;
             }
-            listener = new PackageInactivityListener(uid, packageName, timeoutMillis,
+            listener = new PackageInactivityListener(uid, packageName, deviceId, timeoutMillis,
                     revokeAfterKilledDelayMillis);
             mListeners.put(uid, listener);
         }
@@ -159,6 +160,7 @@ public class OneTimePermissionUserManager {
 
         private final int mUid;
         private final @NonNull String mPackageName;
+        private final int mDeviceId;
         private long mTimeout;
         private long mRevokeAfterKilledDelay;
 
@@ -191,14 +193,15 @@ public class OneTimePermissionUserManager {
             }
         };
 
-        private PackageInactivityListener(int uid, @NonNull String packageName, long timeout,
-                long revokeAfterkilledDelay) {
+        private PackageInactivityListener(int uid, @NonNull String packageName, int deviceId,
+                long timeout, long revokeAfterkilledDelay) {
             Log.i(LOG_TAG,
                     "Start tracking " + packageName + ". uid=" + uid + " timeout=" + timeout
                             + " killedDelay=" + revokeAfterkilledDelay);
 
             mUid = uid;
             mPackageName = packageName;
+            mDeviceId = deviceId;
             mTimeout = timeout;
             mRevokeAfterKilledDelay = revokeAfterkilledDelay == -1
                     ? DeviceConfig.getLong(
@@ -232,7 +235,8 @@ public class OneTimePermissionUserManager {
                                 PROPERTY_KILLED_DELAY_CONFIG_KEY, DEFAULT_KILLED_DELAY_MILLIS)
                                 : revokeAfterKilledDelayMillis);
                 Log.v(LOG_TAG,
-                        "Updated params for " + mPackageName + ". timeout=" + mTimeout
+                        "Updated params for " + mPackageName + ", device ID " + mDeviceId
+                                + ". timeout=" + mTimeout
                                 + " killedDelay=" + mRevokeAfterKilledDelay);
                 updateUidState();
             }
@@ -260,7 +264,7 @@ public class OneTimePermissionUserManager {
 
         private void updateUidState(int state) {
             Log.v(LOG_TAG, "Updating state for " + mPackageName + " (" + mUid + ")."
-                    + " state=" + state);
+                    + " device ID=" + mDeviceId + ", state=" + state);
             synchronized (mInnerLock) {
                 // Remove any pending inactivity callback
                 mHandler.removeCallbacksAndMessages(mToken);
@@ -283,7 +287,7 @@ public class OneTimePermissionUserManager {
                         if (DEBUG) {
                             Log.d(LOG_TAG, "No longer gone after delayed revocation. "
                                     + "Rechecking for " + mPackageName + " (" + mUid
-                                    + ").");
+                                    + "). device ID " + mDeviceId);
                         }
                         updateUidState(currentState);
                     }, mToken, mRevokeAfterKilledDelay);
@@ -292,7 +296,7 @@ public class OneTimePermissionUserManager {
                     if (mTimerStart == TIMER_INACTIVE) {
                         if (DEBUG) {
                             Log.d(LOG_TAG, "Start the timer for "
-                                    + mPackageName + " (" + mUid + ").");
+                                    + mPackageName + " (" + mUid + "). device ID " + mDeviceId);
                         }
                         mTimerStart = System.currentTimeMillis();
                         setAlarmLocked();
@@ -329,7 +333,8 @@ public class OneTimePermissionUserManager {
             }
 
             if (DEBUG) {
-                Log.d(LOG_TAG, "Scheduling alarm for " + mPackageName + " (" + mUid + ").");
+                Log.d(LOG_TAG, "Scheduling alarm for " + mPackageName + " (" + mUid + ")."
+                        + " device ID " + mDeviceId);
             }
             long revokeTime = mTimerStart + mTimeout;
             if (revokeTime > System.currentTimeMillis()) {
@@ -349,7 +354,8 @@ public class OneTimePermissionUserManager {
         private void cancelAlarmLocked() {
             if (mIsAlarmSet) {
                 if (DEBUG) {
-                    Log.d(LOG_TAG, "Canceling alarm for " + mPackageName + " (" + mUid + ").");
+                    Log.d(LOG_TAG, "Canceling alarm for " + mPackageName + " (" + mUid + ")."
+                            + " device ID " + mDeviceId);
                 }
                 mAlarmManager.cancel(this);
                 mIsAlarmSet = false;
@@ -366,17 +372,17 @@ public class OneTimePermissionUserManager {
             }
             if (DEBUG) {
                 Log.d(LOG_TAG, "onPackageInactiveLocked stack trace for "
-                        + mPackageName + " (" + mUid + ").", new RuntimeException());
+                        + mPackageName + " (" + mUid + "). device ID " + mDeviceId,
+                        new RuntimeException());
             }
             mIsFinished = true;
             cancelAlarmLocked();
             mHandler.post(
                     () -> {
                         Log.i(LOG_TAG, "One time session expired for "
-                                + mPackageName + " (" + mUid + ").");
-
+                                + mPackageName + " (" + mUid + "). deviceID " + mDeviceId);
                         mPermissionControllerManager.notifyOneTimePermissionSessionTimeout(
-                                mPackageName);
+                                mPackageName, mDeviceId);
                     });
             try {
                 mIActivityManager.unregisterUidObserver(mObserver);
@@ -391,7 +397,8 @@ public class OneTimePermissionUserManager {
         @Override
         public void onAlarm() {
             if (DEBUG) {
-                Log.d(LOG_TAG, "Alarm received for " + mPackageName + " (" + mUid + ").");
+                Log.d(LOG_TAG, "Alarm received for " + mPackageName + " (" + mUid + ")."
+                        + " device ID " + mDeviceId);
             }
             synchronized (mInnerLock) {
                 if (!mIsAlarmSet) {
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 44eb28fc43f7..9610d051db95 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -404,15 +404,15 @@ public class PermissionManagerService extends IPermissionManager.Stub {
 
     @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS)
     @Override
-    public void startOneTimePermissionSession(String packageName, @UserIdInt int userId,
-            long timeoutMillis, long revokeAfterKilledDelayMillis) {
+    public void startOneTimePermissionSession(String packageName, int deviceId,
+            @UserIdInt int userId, long timeoutMillis, long revokeAfterKilledDelayMillis) {
         startOneTimePermissionSession_enforcePermission();
         Objects.requireNonNull(packageName);
 
         final long token = Binder.clearCallingIdentity();
         try {
             getOneTimePermissionUserManager(userId).startPackageOneTimeSession(packageName,
-                    timeoutMillis, revokeAfterKilledDelayMillis);
+                    deviceId, timeoutMillis, revokeAfterKilledDelayMillis);
         } finally {
             Binder.restoreCallingIdentity(token);
         }
diff --git a/services/permission/java/com/android/server/permission/access/permission/DevicePermissionPolicy.kt b/services/permission/java/com/android/server/permission/access/permission/DevicePermissionPolicy.kt
index b2733d4ddb50..240585c000fd 100644
--- a/services/permission/java/com/android/server/permission/access/permission/DevicePermissionPolicy.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/DevicePermissionPolicy.kt
@@ -16,6 +16,7 @@
 
 package com.android.server.permission.access.permission
 
+import android.permission.PermissionManager
 import android.util.Slog
 import com.android.modules.utils.BinaryXmlPullParser
 import com.android.modules.utils.BinaryXmlSerializer
@@ -164,9 +165,18 @@ class DevicePermissionPolicy : SchemePolicy() {
         deviceId: String,
         userId: Int,
         permissionName: String
-    ): Int =
-        state.userStates[userId]?.appIdDevicePermissionFlags?.get(appId)?.get(deviceId)
-            ?.getWithDefault(permissionName, 0) ?: 0
+    ): Int {
+        val flags = state.userStates[userId]?.appIdDevicePermissionFlags?.get(appId)?.get(deviceId)
+                ?.getWithDefault(permissionName, 0) ?: 0
+        if (PermissionManager.DEBUG_DEVICE_PERMISSIONS) {
+            Slog.i(
+                LOG_TAG, "getPermissionFlags: appId=$appId, userId=$userId," +
+                    " deviceId=$deviceId, permissionName=$permissionName," +
+                    " flags=${PermissionFlags.toString(flags)}"
+            )
+        }
+        return flags
+    }
 
     fun MutateStateScope.setPermissionFlags(
         appId: Int,
@@ -202,6 +212,13 @@ class DevicePermissionPolicy : SchemePolicy() {
         val devicePermissionFlags = appIdDevicePermissionFlags.mutateOrPut(appId) {
             MutableIndexedReferenceMap()
         }
+        if (PermissionManager.DEBUG_DEVICE_PERMISSIONS) {
+            Slog.i(
+                LOG_TAG, "setPermissionFlags(): appId=$appId, userId=$userId," +
+                    " deviceId=$deviceId, permissionName=$permissionName," +
+                    " newFlags=${PermissionFlags.toString(newFlags)}"
+            )
+        }
         val permissionFlags = devicePermissionFlags.mutateOrPut(deviceId) { MutableIndexedMap() }
         permissionFlags.putWithDefault(permissionName, newFlags, 0)
         if (permissionFlags.isEmpty()) {
-- 
GitLab


From d95459651b0a6d3bff2362f31768e9c37b4bf782 Mon Sep 17 00:00:00 2001
From: Brett Chabot <brettchabot@google.com>
Date: Thu, 21 Sep 2023 15:55:00 -0700
Subject: [PATCH 60/95] Update to minSdkVersion 19 for tests.

androidx.test.monitor and other related libraries
have updated their minSdkVersion to 19.
This causes any android_test* target with minSdkVersion
< 19 to fail building.

This commit increments the affected tests to minSdkVersion 19.

Test: m tests
Bug: 299123220
Change-Id: I5cc2c236fb474ac373c5cca4cc79abcd2e558d61
---
 .../hosttests/test-apps/MultiDexLegacyAndException/Android.bp | 4 ++--
 .../hosttests/test-apps/MultiDexLegacyTestApp/Android.bp      | 4 ++--
 .../hosttests/test-apps/MultiDexLegacyTestAppTests/Android.bp | 2 +-
 .../test-apps/MultiDexLegacyTestAppTests2/Android.bp          | 4 ++--
 .../MultiDexLegacyTestAppWithCorruptedDex/AndroidManifest.xml | 4 ++--
 .../test-apps/MultiDexLegacyTestServicesTests2/Android.bp     | 2 +-
 6 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.bp b/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.bp
index d0645b0d8b12..23a2a7fbf0e5 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.bp
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.bp
@@ -28,7 +28,7 @@ android_test_helper_app {
 
     srcs: ["src/**/*.java"],
 
-    sdk_version: "16",
+    sdk_version: "19",
 
     javacflags: ["-nowarn"],
 
@@ -43,5 +43,5 @@ android_test_helper_app {
         enabled: false,
     },
 
-    min_sdk_version: "16",
+    min_sdk_version: "19",
 }
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.bp b/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.bp
index c0c8aba2d2f0..4ddaeef0e4a2 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.bp
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.bp
@@ -40,7 +40,7 @@ android_test_helper_app {
         enabled: false,
     },
 
-    min_sdk_version: "16",
+    min_sdk_version: "19",
 }
 
 android_test_helper_app {
@@ -66,5 +66,5 @@ android_test_helper_app {
         enabled: false,
     },
 
-    min_sdk_version: "16",
+    min_sdk_version: "19",
 }
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyTestAppTests/Android.bp b/core/tests/hosttests/test-apps/MultiDexLegacyTestAppTests/Android.bp
index fe294168586d..afb111d7e2d4 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyTestAppTests/Android.bp
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestAppTests/Android.bp
@@ -28,7 +28,7 @@ android_test {
 
     javacflags: ["-nowarn"],
 
-    min_sdk_version: "16",
+    min_sdk_version: "19",
 
     instrumentation_for: "MultiDexLegacyTestApp",
 }
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyTestAppTests2/Android.bp b/core/tests/hosttests/test-apps/MultiDexLegacyTestAppTests2/Android.bp
index c558153c6a4e..8c57df6707f2 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyTestAppTests2/Android.bp
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestAppTests2/Android.bp
@@ -31,7 +31,7 @@ android_test {
 
     javacflags: ["-nowarn"],
 
-    min_sdk_version: "16",
+    min_sdk_version: "19",
 
     instrumentation_for: "MultiDexLegacyTestApp",
 }
@@ -51,7 +51,7 @@ android_test {
 
     javacflags: ["-nowarn"],
 
-    min_sdk_version: "16",
+    min_sdk_version: "19",
 
     instrumentation_for: "MultiDexLegacyTestApp",
 }
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyTestAppWithCorruptedDex/AndroidManifest.xml b/core/tests/hosttests/test-apps/MultiDexLegacyTestAppWithCorruptedDex/AndroidManifest.xml
index 9a4c3c5d6e81..840daabc2ba9 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyTestAppWithCorruptedDex/AndroidManifest.xml
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestAppWithCorruptedDex/AndroidManifest.xml
@@ -5,8 +5,8 @@
      android:versionCode="1"
      android:versionName="1.0">
 
-    <uses-sdk android:minSdkVersion="18"
-         android:targetSdkVersion="18"/>
+    <uses-sdk android:minSdkVersion="19"
+         android:targetSdkVersion="19"/>
 
     <application android:name="androidx.multidex.MultiDexApplication"
          android:allowBackup="true"
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyTestServicesTests2/Android.bp b/core/tests/hosttests/test-apps/MultiDexLegacyTestServicesTests2/Android.bp
index 75c753cef0fd..2244a830e254 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyTestServicesTests2/Android.bp
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestServicesTests2/Android.bp
@@ -24,5 +24,5 @@ android_test {
     libs: ["android-support-multidex"],
     static_libs: ["androidx.test.rules"],
 
-    sdk_version: "16",
+    sdk_version: "19",
 }
-- 
GitLab


From 4415394cbb49104873154ff6c58c4cd58c41bdd1 Mon Sep 17 00:00:00 2001
From: Sukesh Ram <sukeshram@google.com>
Date: Thu, 21 Sep 2023 22:49:45 +0000
Subject: [PATCH 61/95] Update Window Header Text Font & Position
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Aligned the app name text, app icon, and expand icon positions to be consistent with window header spec. Set the app name text’s font to be “GM3/ Title / Small” (TextAppearance.Material.Title). Changed expand more icon’s drawable to be consistent with launcher’s (ic_expand_more.xml).

Since Header background color and icon colors are still being decided
upon, only the app name font and the app/text/icon alignment aspects of
the spec above are addressed in this CL.

Test: Manual
Bug: 298199770
Change-Id: I63fb223c39a754b3f67cc814a863152e484b3c7a
---
 .../drawable/ic_baseline_expand_more_24.xml    | 14 ++++++++++----
 .../desktop_mode_app_controls_window_decor.xml | 18 +++++++++---------
 2 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/libs/WindowManager/Shell/res/drawable/ic_baseline_expand_more_24.xml b/libs/WindowManager/Shell/res/drawable/ic_baseline_expand_more_24.xml
index 3e0297ab612b..e9df936c3f94 100644
--- a/libs/WindowManager/Shell/res/drawable/ic_baseline_expand_more_24.xml
+++ b/libs/WindowManager/Shell/res/drawable/ic_baseline_expand_more_24.xml
@@ -14,8 +14,14 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License
   -->
-<vector android:height="24dp" android:tint="#000000"
-    android:viewportHeight="24" android:viewportWidth="24"
-    android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
-    <path android:fillColor="@android:color/black" android:pathData="M16.59,8.59L12,13.17 7.41,8.59 6,10l6,6 6,-6z"/>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24"
+    android:tint="?android:attr/textColorSecondary">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M5.41,7.59L4,9l8,8 8,-8 -1.41,-1.41L12,14.17"/>
 </vector>
+
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_app_controls_window_decor.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_app_controls_window_decor.xml
index 7e0c2071dc86..fa56516e0d22 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_app_controls_window_decor.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_app_controls_window_decor.xml
@@ -31,35 +31,35 @@
         android:orientation="horizontal"
         android:clickable="true"
         android:focusable="true"
-        android:paddingStart="8dp">
+        android:paddingStart="16dp">
 
         <ImageView
             android:id="@+id/application_icon"
             android:layout_width="24dp"
             android:layout_height="24dp"
-            android:layout_margin="4dp"
             android:layout_gravity="center_vertical"
             android:contentDescription="@string/app_icon_text" />
 
         <TextView
             android:id="@+id/application_name"
             android:layout_width="0dp"
-            android:layout_height="match_parent"
+            android:layout_height="20dp"
             android:minWidth="80dp"
             android:textColor="@color/desktop_mode_caption_app_name_dark"
+            android:textAppearance="@android:style/TextAppearance.Material.Title"
             android:textSize="14sp"
             android:textFontWeight="500"
-            android:gravity="center_vertical"
+            android:lineHeight="20dp"
+            android:layout_gravity="center_vertical"
             android:layout_weight="1"
-            android:paddingStart="4dp"
-            android:paddingEnd="4dp"
+            android:paddingStart="8dp"
+            android:paddingEnd="8dp"
             tools:text="Gmail"/>
 
         <ImageButton
             android:id="@+id/expand_menu_button"
-            android:layout_width="32dp"
-            android:layout_height="32dp"
-            android:padding="4dp"
+            android:layout_width="16dp"
+            android:layout_height="16dp"
             android:contentDescription="@string/expand_menu_text"
             android:src="@drawable/ic_baseline_expand_more_24"
             android:tint="@color/desktop_mode_caption_expand_button_dark"
-- 
GitLab


From c673f679b7ea31c93cc425088b50246de16806b9 Mon Sep 17 00:00:00 2001
From: petsjonkin <petsjonkin@google.com>
Date: Tue, 19 Sep 2023 14:28:24 +0000
Subject: [PATCH 62/95] Add possibility to ignore animationLimits in
 RampAnimator

Bug: b/283447291
Test: atest DisplayPowerControllerTest atest DisplayPowerController2Test
Change-Id: I586de60cc653397c63796b035764e584af503256
---
 .../display/DisplayPowerController.java       |  2 +-
 .../display/DisplayPowerController2.java      | 10 ++-
 .../android/server/display/RampAnimator.java  | 54 +++++++++---
 .../display/DisplayPowerController2Test.java  | 82 ++++++++++---------
 .../display/DisplayPowerControllerTest.java   | 80 +++++++++---------
 .../server/display/RampAnimatorTest.java      | 36 +++++++-
 6 files changed, 167 insertions(+), 97 deletions(-)

diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 320684fe3a0f..f86b8ca5208b 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -2425,7 +2425,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
             Slog.d(mTag, "Animating brightness: target=" + target + ", sdrTarget=" + sdrTarget
                     + ", rate=" + rate);
         }
-        if (mScreenBrightnessRampAnimator.animateTo(target, sdrTarget, rate)) {
+        if (mScreenBrightnessRampAnimator.animateTo(target, sdrTarget, rate, false)) {
             Trace.traceCounter(Trace.TRACE_TAG_POWER, "TargetScreenBrightness", (int) target);
 
             String propertyKey = "debug.tracing.screen_brightness";
diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java
index 597738e8b293..da299813d525 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController2.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController2.java
@@ -1547,7 +1547,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
                             SCREEN_ANIMATION_RATE_MINIMUM);
                 } else if (customTransitionRate > 0) {
                     animateScreenBrightness(animateValue, sdrAnimateValue,
-                            customTransitionRate);
+                            customTransitionRate, /* ignoreAnimationLimits = */true);
                 } else {
                     boolean isIncreasing = animateValue > currentBrightness;
                     final float rampSpeed;
@@ -2017,11 +2017,17 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
     }
 
     private void animateScreenBrightness(float target, float sdrTarget, float rate) {
+        animateScreenBrightness(target, sdrTarget, rate, /* ignoreAnimationLimits = */false);
+    }
+
+    private void animateScreenBrightness(float target, float sdrTarget, float rate,
+            boolean ignoreAnimationLimits) {
         if (DEBUG) {
             Slog.d(mTag, "Animating brightness: target=" + target + ", sdrTarget=" + sdrTarget
                     + ", rate=" + rate);
         }
-        if (mScreenBrightnessRampAnimator.animateTo(target, sdrTarget, rate)) {
+        if (mScreenBrightnessRampAnimator.animateTo(target, sdrTarget, rate,
+                ignoreAnimationLimits)) {
             Trace.traceCounter(Trace.TRACE_TAG_POWER, "TargetScreenBrightness", (int) target);
 
             String propertyKey = "debug.tracing.screen_brightness";
diff --git a/services/core/java/com/android/server/display/RampAnimator.java b/services/core/java/com/android/server/display/RampAnimator.java
index 378cdba09520..5ba042c51a45 100644
--- a/services/core/java/com/android/server/display/RampAnimator.java
+++ b/services/core/java/com/android/server/display/RampAnimator.java
@@ -30,6 +30,8 @@ class RampAnimator<T> {
     private final T mObject;
     private final FloatProperty<T> mProperty;
 
+    private final Clock mClock;
+
     private float mCurrentValue;
 
     // target in HLG space
@@ -47,10 +49,14 @@ class RampAnimator<T> {
 
     private boolean mFirstTime = true;
 
-
     RampAnimator(T object, FloatProperty<T> property) {
+        this(object, property, System::nanoTime);
+    }
+
+    RampAnimator(T object, FloatProperty<T> property, Clock clock) {
         mObject = object;
         mProperty = property;
+        mClock = clock;
     }
 
     /**
@@ -66,15 +72,24 @@ class RampAnimator<T> {
 
     /**
      * Sets the animation target and the rate of this ramp animator.
-     *
+     * Animation rate will be set ignoring maxTime animation limits
      * If this is the first time the property is being set or if the rate is 0,
      * the value jumps directly to the target.
      *
      * @param targetLinear The target value.
      * @param rate The convergence rate in units per second, or 0 to set the value immediately.
+     * @param ignoreAnimationLimits if mAnimationIncreaseMaxTimeSecs and
+     *                              mAnimationDecreaseMaxTimeSecs should be respected when adjusting
+     *                              animation speed
      * @return True if the target differs from the previous target.
      */
-    boolean setAnimationTarget(float targetLinear, float rate) {
+    boolean setAnimationTarget(float targetLinear, float rate, boolean ignoreAnimationLimits) {
+        float maxIncreaseTimeSecs = ignoreAnimationLimits ? 0 : mAnimationIncreaseMaxTimeSecs;
+        float maxDecreaseTimeSecs = ignoreAnimationLimits ? 0 : mAnimationDecreaseMaxTimeSecs;
+        return setAnimationTarget(targetLinear, rate, maxIncreaseTimeSecs, maxDecreaseTimeSecs);
+    }
+    private boolean setAnimationTarget(float targetLinear, float rate,
+            float maxIncreaseTimeSecs, float maxDecreaseTimeSecs) {
         // Convert the target from the linear into the HLG space.
         final float target = BrightnessUtils.convertLinearToGamma(targetLinear);
 
@@ -94,12 +109,12 @@ class RampAnimator<T> {
         }
 
         // Adjust the rate so that we do not exceed our maximum animation time.
-        if (target > mCurrentValue && mAnimationIncreaseMaxTimeSecs > 0.0f
-                && ((target - mCurrentValue) / rate) > mAnimationIncreaseMaxTimeSecs) {
-            rate = (target - mCurrentValue) / mAnimationIncreaseMaxTimeSecs;
-        } else if (target < mCurrentValue && mAnimationDecreaseMaxTimeSecs > 0.0f
-                && ((mCurrentValue - target) / rate) > mAnimationDecreaseMaxTimeSecs) {
-            rate = (mCurrentValue - target) / mAnimationDecreaseMaxTimeSecs;
+        if (target > mCurrentValue && maxIncreaseTimeSecs > 0.0f
+                && ((target - mCurrentValue) / rate) > maxIncreaseTimeSecs) {
+            rate = (target - mCurrentValue) / maxIncreaseTimeSecs;
+        } else if (target < mCurrentValue && maxDecreaseTimeSecs > 0.0f
+                && ((mCurrentValue - target) / rate) > maxDecreaseTimeSecs) {
+            rate = (mCurrentValue - target) / maxDecreaseTimeSecs;
         }
 
         // Adjust the rate based on the closest target.
@@ -124,7 +139,7 @@ class RampAnimator<T> {
         if (!mAnimating && target != mCurrentValue) {
             mAnimating = true;
             mAnimatedValue = mCurrentValue;
-            mLastFrameTimeNanos = System.nanoTime();
+            mLastFrameTimeNanos = mClock.nanoTime();
         }
 
         return changed;
@@ -184,6 +199,13 @@ class RampAnimator<T> {
         void onAnimationEnd();
     }
 
+    interface Clock {
+        /**
+         * Returns current system time in nanoseconds.
+         */
+        long nanoTime();
+    }
+
     static class DualRampAnimator<T> {
         private final Choreographer mChoreographer;
         private final RampAnimator<T> mFirst;
@@ -219,11 +241,17 @@ class RampAnimator<T> {
          * @param linearFirstTarget The first target value in linear space.
          * @param linearSecondTarget The second target value in linear space.
          * @param rate The convergence rate in units per second, or 0 to set the value immediately.
+         * @param ignoreAnimationLimits if mAnimationIncreaseMaxTimeSecs and
+         *                              mAnimationDecreaseMaxTimeSecs should be respected
+         *                              when adjusting animation speed
          * @return True if either target differs from the previous target.
          */
-        public boolean animateTo(float linearFirstTarget, float linearSecondTarget, float rate) {
-            boolean animationTargetChanged = mFirst.setAnimationTarget(linearFirstTarget, rate);
-            animationTargetChanged |= mSecond.setAnimationTarget(linearSecondTarget, rate);
+        public boolean animateTo(float linearFirstTarget, float linearSecondTarget, float rate,
+                boolean ignoreAnimationLimits) {
+            boolean animationTargetChanged = mFirst.setAnimationTarget(linearFirstTarget, rate,
+                    ignoreAnimationLimits);
+            animationTargetChanged |= mSecond.setAnimationTarget(linearSecondTarget, rate,
+                    ignoreAnimationLimits);
             boolean shouldBeAnimating = isAnimating();
 
             if (shouldBeAnimating != mAwaitingCallback) {
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java
index 89e28cb8ab83..d6b2c8732e50 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java
@@ -335,9 +335,9 @@ public final class DisplayPowerController2Test {
         when(mHolder.brightnessSetting.getBrightness()).thenReturn(leadBrightness);
         listener.onBrightnessChanged(leadBrightness);
         advanceTime(1); // Send messages, run updatePowerState
-        verify(mHolder.animator).animateTo(eq(leadBrightness), anyFloat(), anyFloat());
+        verify(mHolder.animator).animateTo(eq(leadBrightness), anyFloat(), anyFloat(), eq(false));
         verify(followerDpc.animator).animateTo(eq(followerBrightness), anyFloat(),
-                anyFloat());
+                anyFloat(), eq(false));
 
         clearInvocations(mHolder.animator, followerDpc.animator);
 
@@ -351,9 +351,9 @@ public final class DisplayPowerController2Test {
         listener.onBrightnessChanged(brightness);
         advanceTime(1); // Send messages, run updatePowerState
         verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
         verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
     }
 
     @Test
@@ -383,9 +383,9 @@ public final class DisplayPowerController2Test {
         listener.onBrightnessChanged(brightness);
         advanceTime(1); // Send messages, run updatePowerState
         verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
         verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
     }
 
     @Test
@@ -413,9 +413,9 @@ public final class DisplayPowerController2Test {
         listener.onBrightnessChanged(brightness);
         advanceTime(1); // Send messages, run updatePowerState
         verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
         verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
     }
 
     @Test
@@ -445,9 +445,9 @@ public final class DisplayPowerController2Test {
         listener.onBrightnessChanged(brightness);
         advanceTime(1); // Send messages, run updatePowerState
         verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
         verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
     }
 
     @Test
@@ -484,11 +484,11 @@ public final class DisplayPowerController2Test {
         advanceTime(1); // Run updatePowerState
 
         verify(mHolder.animator).animateTo(eq(leadBrightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
         // One triggered by handleBrightnessModeChange, another triggered by setBrightnessToFollow
         verify(followerDpc.hbmController, times(2)).onAmbientLuxChange(ambientLux);
         verify(followerDpc.animator, times(2)).animateTo(eq(followerBrightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
 
         when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(leadBrightness);
         when(followerDpc.displayPowerState.getScreenBrightness()).thenReturn(followerBrightness);
@@ -515,10 +515,10 @@ public final class DisplayPowerController2Test {
 
         // The second time, the animation rate should be slow
         verify(mHolder.animator).animateTo(eq(leadBrightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE));
+                eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE), eq(false));
         verify(followerDpc.hbmController).onAmbientLuxChange(ambientLux);
         verify(followerDpc.animator).animateTo(eq(followerBrightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE));
+                eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE), eq(false));
     }
 
     @Test
@@ -552,7 +552,7 @@ public final class DisplayPowerController2Test {
         followerListener.onBrightnessChanged(initialFollowerBrightness);
         advanceTime(1);
         verify(followerDpc.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
 
         when(followerDpc.displayPowerState.getScreenBrightness())
                 .thenReturn(initialFollowerBrightness);
@@ -573,11 +573,11 @@ public final class DisplayPowerController2Test {
         listener.onBrightnessChanged(brightness);
         advanceTime(1); // Send messages, run updatePowerState
         verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
         verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
         verify(secondFollowerDpc.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
 
         when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness);
         when(followerDpc.displayPowerState.getScreenBrightness()).thenReturn(brightness);
@@ -588,7 +588,7 @@ public final class DisplayPowerController2Test {
         mHolder.dpc.removeDisplayBrightnessFollower(followerDpc.dpc);
         advanceTime(1);
         verify(followerDpc.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE), eq(false));
 
         when(followerDpc.displayPowerState.getScreenBrightness())
                 .thenReturn(initialFollowerBrightness);
@@ -606,10 +606,11 @@ public final class DisplayPowerController2Test {
         listener.onBrightnessChanged(brightness);
         advanceTime(1); // Send messages, run updatePowerState
         verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
-        verify(followerDpc.animator, never()).animateTo(anyFloat(), anyFloat(), anyFloat());
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
+        verify(followerDpc.animator, never()).animateTo(anyFloat(), anyFloat(), anyFloat(),
+                anyBoolean());
         verify(secondFollowerDpc.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
     }
 
     @Test
@@ -652,9 +653,9 @@ public final class DisplayPowerController2Test {
         secondFollowerListener.onBrightnessChanged(initialFollowerBrightness);
         advanceTime(1);
         verify(followerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
         verify(secondFollowerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
 
         when(followerHolder.displayPowerState.getScreenBrightness())
                 .thenReturn(initialFollowerBrightness);
@@ -677,11 +678,11 @@ public final class DisplayPowerController2Test {
         listener.onBrightnessChanged(brightness);
         advanceTime(1); // Send messages, run updatePowerState
         verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
         verify(followerHolder.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
         verify(secondFollowerHolder.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
 
         when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness);
         when(followerHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness);
@@ -692,9 +693,9 @@ public final class DisplayPowerController2Test {
         mHolder.dpc.stop();
         advanceTime(1);
         verify(followerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE), eq(false));
         verify(secondFollowerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE), eq(false));
         clearInvocations(followerHolder.animator, secondFollowerHolder.animator);
     }
 
@@ -716,7 +717,7 @@ public final class DisplayPowerController2Test {
         advanceTime(1); // Run updatePowerState
 
         verify(mHolder.animator).animateTo(eq(sdrBrightness), eq(sdrBrightness),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
 
         when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(sdrBrightness);
         when(mHolder.displayPowerState.getSdrScreenBrightness()).thenReturn(sdrBrightness);
@@ -730,7 +731,7 @@ public final class DisplayPowerController2Test {
         advanceTime(1); // Run updatePowerState
 
         verify(mHolder.animator).animateTo(eq(hdrBrightness), eq(sdrBrightness),
-                eq(BRIGHTNESS_RAMP_RATE_MINIMUM));
+                eq(BRIGHTNESS_RAMP_RATE_MINIMUM), eq(false));
     }
 
     @Test
@@ -756,7 +757,7 @@ public final class DisplayPowerController2Test {
         advanceTime(1); // Run updatePowerState
 
         verify(mHolder.animator).animateTo(eq(hdrBrightness), eq(sdrBrightness),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
 
         when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(hdrBrightness);
         when(mHolder.displayPowerState.getSdrScreenBrightness()).thenReturn(sdrBrightness);
@@ -769,7 +770,7 @@ public final class DisplayPowerController2Test {
         advanceTime(1); // Run updatePowerState
 
         verify(mHolder.animator).animateTo(eq(sdrBrightness), eq(sdrBrightness),
-                eq(BRIGHTNESS_RAMP_RATE_MINIMUM));
+                eq(BRIGHTNESS_RAMP_RATE_MINIMUM), eq(false));
     }
 
     @Test
@@ -823,7 +824,7 @@ public final class DisplayPowerController2Test {
 
         verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
                 .getAutomaticScreenBrightness();
-        verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+        verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat(), eq(false));
     }
 
     @Test
@@ -861,7 +862,7 @@ public final class DisplayPowerController2Test {
 
         verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
                 .getAutomaticScreenBrightness();
-        verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+        verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat(), eq(false));
     }
 
     @Test
@@ -1104,7 +1105,8 @@ public final class DisplayPowerController2Test {
         mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
         advanceTime(1); // Run updatePowerState
         // One triggered by handleBrightnessModeChange, another triggered by onDisplayChanged
-        verify(mHolder.animator, times(2)).animateTo(eq(newBrightness), anyFloat(), anyFloat());
+        verify(mHolder.animator, times(2)).animateTo(eq(newBrightness), anyFloat(), anyFloat(),
+                eq(false));
     }
 
     @Test
@@ -1213,7 +1215,7 @@ public final class DisplayPowerController2Test {
         advanceTime(1); // Run updatePowerState
 
         verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
 
         when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness);
         brightness = 0.05f;
@@ -1225,7 +1227,7 @@ public final class DisplayPowerController2Test {
 
         // The second time, the animation rate should be slow
         verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE));
+                eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE), eq(false));
 
         brightness = 0.9f;
         when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
@@ -1235,7 +1237,7 @@ public final class DisplayPowerController2Test {
         advanceTime(1); // Run updatePowerState
         // The third time, the animation rate should be slow
         verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE));
+                eq(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE), eq(false));
     }
 
     @Test
@@ -1272,7 +1274,7 @@ public final class DisplayPowerController2Test {
         advanceTime(1); // Run updatePowerState
 
         verify(mHolder.animator, atLeastOnce()).animateTo(eq(clampedBrightness), anyFloat(),
-                eq(transitionRate));
+                eq(transitionRate), eq(true));
     }
 
     /**
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
index 971ece365f30..c53e763068b7 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -336,9 +336,9 @@ public final class DisplayPowerControllerTest {
         listener.onBrightnessChanged(leadBrightness);
         advanceTime(1); // Send messages, run updatePowerState
         verify(mHolder.animator).animateTo(eq(leadBrightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
         verify(followerDpc.animator).animateTo(eq(followerBrightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
 
         when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(leadBrightness);
         when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(followerBrightness);
@@ -354,9 +354,9 @@ public final class DisplayPowerControllerTest {
         listener.onBrightnessChanged(brightness);
         advanceTime(1); // Send messages, run updatePowerState
         verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
         verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
     }
 
     @Test
@@ -387,9 +387,9 @@ public final class DisplayPowerControllerTest {
         listener.onBrightnessChanged(brightness);
         advanceTime(1); // Send messages, run updatePowerState
         verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
         verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
     }
 
     @Test
@@ -418,9 +418,9 @@ public final class DisplayPowerControllerTest {
         listener.onBrightnessChanged(brightness);
         advanceTime(1); // Send messages, run updatePowerState
         verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
         verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
     }
 
     @Test
@@ -451,9 +451,9 @@ public final class DisplayPowerControllerTest {
         listener.onBrightnessChanged(brightness);
         advanceTime(1); // Send messages, run updatePowerState
         verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
         verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
     }
 
     @Test
@@ -491,11 +491,11 @@ public final class DisplayPowerControllerTest {
         advanceTime(1); // Run updatePowerState
 
         verify(mHolder.animator).animateTo(eq(leadBrightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
         // One triggered by handleBrightnessModeChange, another triggered by setBrightnessToFollow
         verify(followerDpc.hbmController, times(2)).onAmbientLuxChange(ambientLux);
         verify(followerDpc.animator, times(2)).animateTo(eq(followerBrightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
 
         when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(leadBrightness);
         when(followerDpc.displayPowerState.getScreenBrightness()).thenReturn(followerBrightness);
@@ -522,10 +522,10 @@ public final class DisplayPowerControllerTest {
 
         // The second time, the animation rate should be slow
         verify(mHolder.animator).animateTo(eq(leadBrightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE));
+                eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE), eq(false));
         verify(followerDpc.hbmController).onAmbientLuxChange(ambientLux);
         verify(followerDpc.animator).animateTo(eq(followerBrightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE));
+                eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE), eq(false));
     }
 
     @Test
@@ -560,7 +560,7 @@ public final class DisplayPowerControllerTest {
         followerListener.onBrightnessChanged(initialFollowerBrightness);
         advanceTime(1);
         verify(followerDpc.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
 
         when(followerDpc.displayPowerState.getScreenBrightness())
                 .thenReturn(initialFollowerBrightness);
@@ -581,11 +581,11 @@ public final class DisplayPowerControllerTest {
         listener.onBrightnessChanged(brightness);
         advanceTime(1); // Send messages, run updatePowerState
         verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
         verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
         verify(secondFollowerDpc.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
 
         when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness);
         when(followerDpc.displayPowerState.getScreenBrightness()).thenReturn(brightness);
@@ -596,7 +596,7 @@ public final class DisplayPowerControllerTest {
         mHolder.dpc.removeDisplayBrightnessFollower(followerDpc.dpc);
         advanceTime(1);
         verify(followerDpc.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE), eq(false));
 
         when(followerDpc.displayPowerState.getScreenBrightness())
                 .thenReturn(initialFollowerBrightness);
@@ -614,10 +614,11 @@ public final class DisplayPowerControllerTest {
         listener.onBrightnessChanged(brightness);
         advanceTime(1); // Send messages, run updatePowerState
         verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
-        verify(followerDpc.animator, never()).animateTo(anyFloat(), anyFloat(), anyFloat());
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
+        verify(followerDpc.animator, never()).animateTo(anyFloat(), anyFloat(), anyFloat(),
+                anyBoolean());
         verify(secondFollowerDpc.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
     }
 
     @Test
@@ -661,9 +662,9 @@ public final class DisplayPowerControllerTest {
         secondFollowerListener.onBrightnessChanged(initialFollowerBrightness);
         advanceTime(1);
         verify(followerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
         verify(secondFollowerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
 
         when(followerHolder.displayPowerState.getScreenBrightness())
                 .thenReturn(initialFollowerBrightness);
@@ -686,11 +687,11 @@ public final class DisplayPowerControllerTest {
         listener.onBrightnessChanged(brightness);
         advanceTime(1); // Send messages, run updatePowerState
         verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
         verify(followerHolder.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
         verify(secondFollowerHolder.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
 
         when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness);
         when(followerHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness);
@@ -701,9 +702,9 @@ public final class DisplayPowerControllerTest {
         mHolder.dpc.stop();
         advanceTime(1);
         verify(followerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE), eq(false));
         verify(secondFollowerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE), eq(false));
         clearInvocations(followerHolder.animator, secondFollowerHolder.animator);
     }
 
@@ -756,7 +757,7 @@ public final class DisplayPowerControllerTest {
 
         verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
                 .getAutomaticScreenBrightness();
-        verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+        verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat(), eq(false));
     }
 
     @Test
@@ -793,7 +794,7 @@ public final class DisplayPowerControllerTest {
 
         verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
                 .getAutomaticScreenBrightness();
-        verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+        verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat(), eq(false));
     }
 
     @Test
@@ -1038,7 +1039,8 @@ public final class DisplayPowerControllerTest {
         mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
         advanceTime(1); // Run updatePowerState
         // One triggered by handleBrightnessModeChange, another triggered by onDisplayChanged
-        verify(mHolder.animator, times(2)).animateTo(eq(newBrightness), anyFloat(), anyFloat());
+        verify(mHolder.animator, times(2)).animateTo(eq(newBrightness), anyFloat(), anyFloat(),
+                eq(false));
     }
 
     @Test
@@ -1147,7 +1149,7 @@ public final class DisplayPowerControllerTest {
         advanceTime(1); // Run updatePowerState
 
         verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
 
         when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness);
         brightness = 0.05f;
@@ -1159,7 +1161,7 @@ public final class DisplayPowerControllerTest {
 
         // The second time, the animation rate should be slow
         verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE));
+                eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE), eq(false));
 
         brightness = 0.9f;
         when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
@@ -1169,7 +1171,7 @@ public final class DisplayPowerControllerTest {
         advanceTime(1); // Run updatePowerState
         // The third time, the animation rate should be slow
         verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE));
+                eq(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE), eq(false));
     }
 
     @Test
@@ -1204,7 +1206,7 @@ public final class DisplayPowerControllerTest {
         advanceTime(1); // Run updatePowerState
 
         verify(mHolder.animator).animateTo(eq(sdrBrightness), eq(sdrBrightness),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
 
         when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(sdrBrightness);
         when(mHolder.displayPowerState.getSdrScreenBrightness()).thenReturn(sdrBrightness);
@@ -1218,7 +1220,7 @@ public final class DisplayPowerControllerTest {
         advanceTime(1); // Run updatePowerState
 
         verify(mHolder.animator).animateTo(eq(hdrBrightness), eq(sdrBrightness),
-                eq(BRIGHTNESS_RAMP_RATE_MINIMUM));
+                eq(BRIGHTNESS_RAMP_RATE_MINIMUM), eq(false));
     }
 
     @Test
@@ -1242,7 +1244,7 @@ public final class DisplayPowerControllerTest {
         advanceTime(1); // Run updatePowerState
 
         verify(mHolder.animator).animateTo(eq(hdrBrightness), eq(sdrBrightness),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
 
         when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(hdrBrightness);
         when(mHolder.displayPowerState.getSdrScreenBrightness()).thenReturn(sdrBrightness);
@@ -1255,7 +1257,7 @@ public final class DisplayPowerControllerTest {
         advanceTime(1); // Run updatePowerState
 
         verify(mHolder.animator).animateTo(eq(sdrBrightness), eq(sdrBrightness),
-                eq(BRIGHTNESS_RAMP_RATE_MINIMUM));
+                eq(BRIGHTNESS_RAMP_RATE_MINIMUM), eq(false));
     }
 
     private void advanceTime(long timeMs) {
diff --git a/services/tests/displayservicetests/src/com/android/server/display/RampAnimatorTest.java b/services/tests/displayservicetests/src/com/android/server/display/RampAnimatorTest.java
index 2820da7c49c1..810a8b2c8297 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/RampAnimatorTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/RampAnimatorTest.java
@@ -28,6 +28,8 @@ import org.junit.Test;
 @SmallTest
 public class RampAnimatorTest {
 
+    private static final float FLOAT_TOLERANCE = 0.0000001f;
+
     private RampAnimator<TestObject> mRampAnimator;
 
     private final TestObject mTestObject = new TestObject();
@@ -46,16 +48,46 @@ public class RampAnimatorTest {
 
     @Before
     public void setUp() {
-        mRampAnimator = new RampAnimator<>(mTestObject, mTestProperty);
+        mRampAnimator = new RampAnimator<>(mTestObject, mTestProperty, () -> 0);
     }
 
     @Test
     public void testInitialValueUsedInLastAnimationStep() {
-        mRampAnimator.setAnimationTarget(0.67f, 0.1f);
+        mRampAnimator.setAnimationTarget(0.67f, 0.1f, false);
 
         assertEquals(0.67f, mTestObject.mValue, 0);
     }
 
+    @Test
+    public void testAnimationStep_respectTimeLimits() {
+        // animation is limited to 2s
+        mRampAnimator.setAnimationTimeLimits(2_000, 2_000);
+        // initial brightness value, applied immediately, in HLG = 0.8716434
+        mRampAnimator.setAnimationTarget(0.5f, 0.1f, false);
+        // expected brightness, in HLG = 0.9057269
+        // delta = 0.0340835, duration = 3.40835s > 2s
+        // new rate = delta/2 = 0.01704175 u/s
+        mRampAnimator.setAnimationTarget(0.6f, 0.01f, false);
+        // animation step = 1s, new HGL = 0.88868515
+        mRampAnimator.performNextAnimationStep(1_000_000_000);
+        // converted back to Linear
+        assertEquals(0.54761934f, mTestObject.mValue, FLOAT_TOLERANCE);
+    }
+
+    @Test
+    public void testAnimationStep_ignoreTimeLimits() {
+        // animation is limited to 2s
+        mRampAnimator.setAnimationTimeLimits(2_000, 2_000);
+        // initial brightness value, applied immediately, in HLG = 0.8716434
+        mRampAnimator.setAnimationTarget(0.5f, 0.1f, false);
+        // rate = 0.01f, time limits are ignored
+        mRampAnimator.setAnimationTarget(0.6f, 0.01f, true);
+        // animation step = 1s, new HGL = 0.8816434
+        mRampAnimator.performNextAnimationStep(1_000_000_000);
+        // converted back to Linear
+        assertEquals(0.52739114f, mTestObject.mValue, FLOAT_TOLERANCE);
+    }
+
     private static class TestObject {
         private float mValue;
     }
-- 
GitLab


From cb4cb3e53b2a9d060634e8bcfb57df1c2e5f6705 Mon Sep 17 00:00:00 2001
From: Hakjun Choi <hakjunc@google.com>
Date: Fri, 22 Sep 2023 00:12:02 +0000
Subject: [PATCH 63/95] Fix Build Breakage

-    method @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) public boolean isNtn();
+    method @FlaggedApi(com.android.internal.telephony.flags.oem_enabled_satellite_flag) public boolean isNtn();
from api/current.txt

Bug: 301517271
Test: Build Test
Change-Id: Ib8700d1c830f4ede76bf0193675fd53e3208a1fb
---
 core/api/current.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/api/current.txt b/core/api/current.txt
index 904b0d21a3e3..1eb9e97db42b 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -44888,7 +44888,7 @@ package android.telephony {
     method public int getSubscriptionType();
     method public int getUsageSetting();
     method public boolean isEmbedded();
-    method @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) public boolean isNtn();
+    method @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") public boolean isNtn();
     method public boolean isOpportunistic();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SubscriptionInfo> CREATOR;
-- 
GitLab


From 65f8b76112bbe0674f2722b0517938827bc34ca0 Mon Sep 17 00:00:00 2001
From: Jihoon Kang <jihoonkang@google.com>
Date: Fri, 22 Sep 2023 00:30:24 +0000
Subject: [PATCH 64/95] RESTRICT AUTOMERGE Move java_api_library modules to
 f/b/api/StubLibraries.bp

This change was already submitted with
https://android-review.git.corp.google.com/q/topic:%22revert-2713677-revert-2655262-move_java_api_libraries-JTESUMBERD-FPSEKJYXCE%22
but was never propagated to downstream.

Test: m nothing --build-from-text-stub
Change-Id: I0d107ceb59cc53ec6663145796f4e4b0b74f2dc9
---
 api/StubLibraries.bp | 164 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 164 insertions(+)

diff --git a/api/StubLibraries.bp b/api/StubLibraries.bp
index 9a0053f8add6..c1edfd2c2920 100644
--- a/api/StubLibraries.bp
+++ b/api/StubLibraries.bp
@@ -572,6 +572,170 @@ java_genrule {
     },
 }
 
+//
+// Java API defaults and libraries for single tree build
+//
+
+java_defaults {
+    name: "stub-annotation-defaults",
+    libs: [
+        "stub-annotations",
+    ],
+    static_libs: [
+        // stub annotations do not contribute to the API surfaces but are statically
+        // linked in the stubs for API surfaces (see frameworks/base/StubLibraries.bp).
+        // This is because annotation processors insist on loading the classes for any
+        // annotations found, thus should exist inside android.jar.
+        "private-stub-annotations-jar",
+    ],
+}
+
+// Listing of API domains contribution and dependencies per API surfaces
+java_defaults {
+    name: "android_test_stubs_current_contributions",
+    api_surface: "test",
+    api_contributions: [
+        "test-api-stubs-docs-non-updatable.api.contribution",
+        "framework-virtualization.stubs.source.test.api.contribution",
+    ],
+}
+
+java_defaults {
+    name: "android_test_frameworks_core_stubs_current_contributions",
+    api_surface: "test",
+    api_contributions: [
+        "test-api-stubs-docs-non-updatable.api.contribution",
+    ],
+}
+
+java_defaults {
+    name: "android_module_lib_stubs_current_contributions",
+    api_surface: "module-lib",
+    api_contributions: [
+        "api-stubs-docs-non-updatable.api.contribution",
+        "system-api-stubs-docs-non-updatable.api.contribution",
+        "module-lib-api-stubs-docs-non-updatable.api.contribution",
+        "art.module.public.api.stubs.source.api.contribution",
+        "art.module.public.api.stubs.source.system.api.contribution",
+        "art.module.public.api.stubs.source.module_lib.api.contribution",
+        "i18n.module.public.api.stubs.source.api.contribution",
+        "i18n.module.public.api.stubs.source.system.api.contribution",
+        "i18n.module.public.api.stubs.source.module_lib.api.contribution",
+    ],
+}
+
+// Java API library definitions per API surface
+java_api_library {
+    name: "android_stubs_current.from-text",
+    api_surface: "public",
+    defaults: [
+        // This module is dynamically created at frameworks/base/api/api.go
+        // instead of being written out, in order to minimize edits in the codebase
+        // when there is a change in the list of modules.
+        // that contributes to an api surface.
+        "android_stubs_current_contributions",
+        "stub-annotation-defaults",
+    ],
+    api_contributions: [
+        "api-stubs-docs-non-updatable.api.contribution",
+    ],
+    visibility: ["//visibility:public"],
+}
+
+java_api_library {
+    name: "android_system_stubs_current.from-text",
+    api_surface: "system",
+    defaults: [
+        "android_stubs_current_contributions",
+        "android_system_stubs_current_contributions",
+        "stub-annotation-defaults",
+    ],
+    api_contributions: [
+        "api-stubs-docs-non-updatable.api.contribution",
+        "system-api-stubs-docs-non-updatable.api.contribution",
+    ],
+    visibility: ["//visibility:public"],
+}
+
+java_api_library {
+    name: "android_test_stubs_current.from-text",
+    api_surface: "test",
+    defaults: [
+        "android_stubs_current_contributions",
+        "android_system_stubs_current_contributions",
+        "android_test_stubs_current_contributions",
+        "stub-annotation-defaults",
+    ],
+    api_contributions: [
+        "api-stubs-docs-non-updatable.api.contribution",
+        "system-api-stubs-docs-non-updatable.api.contribution",
+    ],
+    visibility: ["//visibility:public"],
+}
+
+java_api_library {
+    name: "android_test_frameworks_core_stubs_current.from-text",
+    api_surface: "test",
+    defaults: [
+        "android_stubs_current_contributions",
+        "android_system_stubs_current_contributions",
+        "android_test_frameworks_core_stubs_current_contributions",
+        "stub-annotation-defaults",
+    ],
+    api_contributions: [
+        "api-stubs-docs-non-updatable.api.contribution",
+        "system-api-stubs-docs-non-updatable.api.contribution",
+    ],
+}
+
+java_api_library {
+    name: "android_module_lib_stubs_current_full.from-text",
+    api_surface: "module-lib",
+    defaults: [
+        "android_stubs_current_contributions",
+        "android_system_stubs_current_contributions",
+        "android_module_lib_stubs_current_contributions_full",
+    ],
+    libs: [
+        "stub-annotations",
+    ],
+    api_contributions: [
+        "api-stubs-docs-non-updatable.api.contribution",
+        "system-api-stubs-docs-non-updatable.api.contribution",
+        "module-lib-api-stubs-docs-non-updatable.api.contribution",
+    ],
+    visibility: ["//visibility:public"],
+}
+
+java_api_library {
+    name: "android_module_lib_stubs_current.from-text",
+    api_surface: "module-lib",
+    defaults: [
+        "android_module_lib_stubs_current_contributions",
+    ],
+    libs: [
+        "android_module_lib_stubs_current_full.from-text",
+        "stub-annotations",
+    ],
+    visibility: ["//visibility:public"],
+}
+
+java_api_library {
+    name: "android_system_server_stubs_current.from-text",
+    api_surface: "system-server",
+    api_contributions: [
+        "services-non-updatable-stubs.api.contribution",
+    ],
+    libs: [
+        "android_module_lib_stubs_current.from-text",
+        "stub-annotations",
+    ],
+    static_libs: [
+        "android_module_lib_stubs_current.from-text",
+    ],
+    visibility: ["//visibility:public"],
+}
+
 ////////////////////////////////////////////////////////////////////////
 // api-versions.xml generation, for public and system. This API database
 // also contains the android.test.* APIs.
-- 
GitLab


From 0c9b699e79fce12e0f853cd063be9f93aad3ce36 Mon Sep 17 00:00:00 2001
From: Matt Walliser <mattwalliser@google.com>
Date: Thu, 21 Sep 2023 22:57:59 +0000
Subject: [PATCH 65/95] Clean up SharedConnectivityManager on unbind.

mService is used by registerCallback as an indication of if the service is bound to. This was only being set to null when the service was unbound from the service side, not when unbound from the manager side.

Bug: 301296167
Test: atest -c android.net.wifi.sharedconnectivity.cts.app.SharedConnectivityManagerTest
Change-Id: I2ef94cf0489b41a48a4279fbe3f9041ae0271280
---
 .../wifi/sharedconnectivity/app/SharedConnectivityManager.java   | 1 +
 1 file changed, 1 insertion(+)

diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManager.java b/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManager.java
index bc41829f16d2..71ac94ba2ee4 100644
--- a/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManager.java
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManager.java
@@ -334,6 +334,7 @@ public class SharedConnectivityManager {
         if (mServiceConnection != null) {
             mContext.unbindService(mServiceConnection);
             mServiceConnection = null;
+            mService = null;
         }
     }
 
-- 
GitLab


From 039334381ea0bd19fcad15d1940af98d0ad51428 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thi=C3=A9baud=20Weksteen?= <tweek@google.com>
Date: Thu, 21 Sep 2023 16:44:52 +1000
Subject: [PATCH 66/95] lint_fix: fix CLI arguments use

Commit df4cd065 updated how command line arguments are parsed. However,
sys.argv[0] should be ignored (as this is the name of the program).
Remove the argument, so the default value (sys.argv[1:]) is used.

Also, use the embedded_launcher so that the help renders
as:
    usage: lint_fix [-h]
instead of:
    usage: usage: __soong_entrypoint_redirector__.py [-h]

Test: lint_fix --print --no-fix --check AnnotatedAidlCounter \
       --lint-module AndroidUtilsLintChecker services.autofill
Change-Id: I00e3e3b70c9715e363d3448ae84bf9ff161f2306
---
 tools/lint/fix/Android.bp        | 5 +++++
 tools/lint/fix/soong_lint_fix.py | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/tools/lint/fix/Android.bp b/tools/lint/fix/Android.bp
index 43f21221ae5a..ddacf57c3a3e 100644
--- a/tools/lint/fix/Android.bp
+++ b/tools/lint/fix/Android.bp
@@ -25,6 +25,11 @@ python_binary_host {
     name: "lint_fix",
     main: "soong_lint_fix.py",
     srcs: ["soong_lint_fix.py"],
+    version: {
+        py3: {
+            embedded_launcher: true,
+        },
+    },
 }
 
 python_library_host {
diff --git a/tools/lint/fix/soong_lint_fix.py b/tools/lint/fix/soong_lint_fix.py
index b42f9eec99d0..4a2e37e51d71 100644
--- a/tools/lint/fix/soong_lint_fix.py
+++ b/tools/lint/fix/soong_lint_fix.py
@@ -213,5 +213,5 @@ def _setup_parser():
 
 if __name__ == "__main__":
     opts = SoongLintFixOptions()
-    opts.parse_args(sys.argv)
+    opts.parse_args()
     SoongLintFix(opts).run()
-- 
GitLab


From 213e577bdd2b8e46e51c5863dcec1d8a5d649735 Mon Sep 17 00:00:00 2001
From: Diego Vela <diegovela@google.com>
Date: Mon, 11 Sep 2023 22:06:41 +0000
Subject: [PATCH 67/95] Report folding features to letterboxed apps.

Letterboxed apps lost support for Folding Features. We are enabling
reporting folding features to letterboxed apps again.
Report folding features if an Activity is embedded or not in
PiP.

Bug: 295785410
Test: atest CtsWindowManagerJetpackTestCases
Change-Id: Ib964b22278c31982a3d6bf66abaab3dac0c4093b
---
 .../extensions/WindowExtensionsImpl.java      |  9 +---
 .../layout/WindowLayoutComponentImpl.java     | 46 +++----------------
 2 files changed, 7 insertions(+), 48 deletions(-)

diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java
index c3d8f9a99d79..a663f9fafb50 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java
@@ -20,7 +20,6 @@ import android.app.ActivityTaskManager;
 import android.app.ActivityThread;
 import android.app.Application;
 import android.content.Context;
-import android.window.TaskFragmentOrganizer;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -83,13 +82,7 @@ public class WindowExtensionsImpl implements WindowExtensions {
                     Context context = getApplication();
                     DeviceStateManagerFoldingFeatureProducer producer =
                             getFoldingFeatureProducer();
-                    // TODO(b/263263909) Use the organizer to tell if an Activity is embededed.
-                    // Need to improve our Dependency Injection and centralize the logic.
-                    TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(command -> {
-                        throw new RuntimeException("Not allowed!");
-                    });
-                    mWindowLayoutComponent = new WindowLayoutComponentImpl(context, organizer,
-                            producer);
+                    mWindowLayoutComponent = new WindowLayoutComponentImpl(context, producer);
                 }
             }
         }
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
index ba57b76020b4..e0942b74e0a2 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
@@ -17,6 +17,7 @@
 package androidx.window.extensions.layout;
 
 import static android.view.Display.DEFAULT_DISPLAY;
+
 import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_FLAT;
 import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_HALF_OPENED;
 import static androidx.window.util.ExtensionHelper.isZero;
@@ -24,7 +25,6 @@ import static androidx.window.util.ExtensionHelper.rotateRectToDisplayRotation;
 import static androidx.window.util.ExtensionHelper.transformToWindowSpaceRect;
 
 import android.app.Activity;
-import android.app.ActivityClient;
 import android.app.Application;
 import android.app.WindowConfiguration;
 import android.content.ComponentCallbacks;
@@ -34,8 +34,6 @@ import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.util.ArrayMap;
-import android.view.WindowManager;
-import android.window.TaskFragmentOrganizer;
 
 import androidx.annotation.GuardedBy;
 import androidx.annotation.NonNull;
@@ -51,7 +49,6 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
 import java.util.Set;
 
 /**
@@ -85,16 +82,12 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
     private final Map<java.util.function.Consumer<WindowLayoutInfo>, Consumer<WindowLayoutInfo>>
             mJavaToExtConsumers = new ArrayMap<>();
 
-    private final TaskFragmentOrganizer mTaskFragmentOrganizer;
-
     public WindowLayoutComponentImpl(@NonNull Context context,
-            @NonNull TaskFragmentOrganizer taskFragmentOrganizer,
             @NonNull DeviceStateManagerFoldingFeatureProducer foldingFeatureProducer) {
         ((Application) context.getApplicationContext())
                 .registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged());
         mFoldingFeatureProducer = foldingFeatureProducer;
         mFoldingFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
-        mTaskFragmentOrganizer = taskFragmentOrganizer;
     }
 
     /**
@@ -374,38 +367,11 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
             // Display features are not supported on secondary displays.
             return false;
         }
-        final int windowingMode;
-        IBinder activityToken = context.getActivityToken();
-        if (activityToken != null) {
-            final Configuration taskConfig = ActivityClient.getInstance().getTaskConfiguration(
-                    activityToken);
-            if (taskConfig == null) {
-                // If we cannot determine the task configuration for any reason, it is likely that
-                // we won't be able to determine its position correctly as well. DisplayFeatures'
-                // bounds in this case can't be computed correctly, so we should skip.
-                return false;
-            }
-            final Rect taskBounds = taskConfig.windowConfiguration.getBounds();
-            final WindowManager windowManager = Objects.requireNonNull(
-                    context.getSystemService(WindowManager.class));
-            final Rect maxBounds = windowManager.getMaximumWindowMetrics().getBounds();
-            boolean isTaskExpanded = maxBounds.equals(taskBounds);
-            /*
-             * We need to proxy being in full screen because when a user enters PiP and exits PiP
-             * the task windowingMode will report multi-window/pinned until the transition is
-             * finished in WM Shell.
-             * maxBounds == taskWindowBounds is a proxy check to verify the window is full screen
-             */
-            return isTaskExpanded;
-        } else {
-            // TODO(b/242674941): use task windowing mode for window context that associates with
-            //  activity.
-            windowingMode = context.getResources().getConfiguration().windowConfiguration
-                    .getWindowingMode();
-        }
-        // It is recommended not to report any display features in multi-window mode, since it
-        // won't be possible to synchronize the display feature positions with window movement.
-        return !WindowConfiguration.inMultiWindowMode(windowingMode);
+
+        // We do not report folding features for Activities in PiP because the bounds are
+        // not updated fast enough and the window is too small for the UI to adapt.
+        return context.getResources().getConfiguration().windowConfiguration
+                .getWindowingMode() != WindowConfiguration.WINDOWING_MODE_PINNED;
     }
 
     @GuardedBy("mLock")
-- 
GitLab


From 5a7a5946dceb80509e65d3274cd82933ec67fcc7 Mon Sep 17 00:00:00 2001
From: Yeabkal Wubshit <yeabkal@google.com>
Date: Thu, 21 Sep 2023 22:52:58 +0000
Subject: [PATCH 68/95] Enable Rotary Scroll haptics for Wear

Bug: 299587011
Change-Id: I335056bd3253824932840a6baf41a601af0e3799
Test: manual
---
 core/res/res/values-watch/config.xml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/core/res/res/values-watch/config.xml b/core/res/res/values-watch/config.xml
index 4027f5c78035..af305329da1a 100644
--- a/core/res/res/values-watch/config.xml
+++ b/core/res/res/values-watch/config.xml
@@ -41,6 +41,10 @@
          measured in dips per second. Setting this to -1dp disables rotary encoder fling.  -->
     <dimen name="config_viewMaxRotaryEncoderFlingVelocity">8000dp</dimen>
 
+    <!-- Whether the View-based scroll haptic feedback implementation is enabled for
+         {@link InputDevice#SOURCE_ROTARY_ENCODER}s. -->
+    <bool name="config_viewBasedRotaryEncoderHapticsEnabled">true</bool>
+
     <!-- Number of notifications to keep in the notification service historical archive.
          Reduced intentionally for watches to retain minimal memory footprint -->
     <integer name="config_notificationServiceArchiveSize">1</integer>
-- 
GitLab


From 2249f626e4b12b8e08cfbafac6ae1b6b24a44170 Mon Sep 17 00:00:00 2001
From: Charlotte Lu <charlottelu@google.com>
Date: Tue, 19 Sep 2023 19:13:14 +0800
Subject: [PATCH 69/95] Add SettingsExposedDropdownMenuCheckBox.
 SettingsExposedDropdownMenuCheckBox requires input index.

Bug: 298906796
Test: Munual
Change-Id: I6059bd5371a2472fbbb9a6b0aa83be769f90264e
---
 ...tingsExposedDropdownMenuCheckBoxProvider.kt |  2 +-
 .../SettingsExposedDropdownMenuCheckBox.kt     | 18 ++++++++++--------
 .../SettingsExposedDropdownMenuCheckBoxTest.kt |  2 +-
 3 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/editor/SettingsExposedDropdownMenuCheckBoxProvider.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/editor/SettingsExposedDropdownMenuCheckBoxProvider.kt
index 37c8eef8a90d..d28964676bdd 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/editor/SettingsExposedDropdownMenuCheckBoxProvider.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/editor/SettingsExposedDropdownMenuCheckBoxProvider.kt
@@ -37,7 +37,7 @@ object SettingsExposedDropdownMenuCheckBoxProvider : SettingsPageProvider {
     override val name = "SettingsExposedDropdownMenuCheckBox"
     private const val exposedDropdownMenuCheckBoxLabel = "ExposedDropdownMenuCheckBoxLabel"
     private val options = listOf("item1", "item2", "item3")
-    private val selectedOptionsState1 = mutableStateListOf("item1", "item2")
+    private val selectedOptionsState1 = mutableStateListOf(0, 1)
 
     override fun getTitle(arguments: Bundle?): String {
         return TITLE
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/SettingsExposedDropdownMenuCheckBox.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/SettingsExposedDropdownMenuCheckBox.kt
index a25818553c05..5d248e192c7a 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/SettingsExposedDropdownMenuCheckBox.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/SettingsExposedDropdownMenuCheckBox.kt
@@ -51,7 +51,8 @@ import com.android.settingslib.spa.framework.theme.SettingsTheme
 fun SettingsExposedDropdownMenuCheckBox(
     label: String,
     options: List<String>,
-    selectedOptionsState: SnapshotStateList<String>,
+    selectedOptionsState: SnapshotStateList<Int>,
+    emptyVal: String = "",
     enabled: Boolean,
     onSelectedOptionStateChange: () -> Unit,
 ) {
@@ -70,7 +71,8 @@ fun SettingsExposedDropdownMenuCheckBox(
             modifier = Modifier
                 .menuAnchor()
                 .fillMaxWidth(),
-            value = selectedOptionsState.joinToString(", "),
+            value = if (selectedOptionsState.size == 0) emptyVal
+                    else selectedOptionsState.joinToString { options[it] },
             onValueChange = {},
             label = { Text(text = label) },
             trailingIcon = {
@@ -89,19 +91,19 @@ fun SettingsExposedDropdownMenuCheckBox(
                     .width(with(LocalDensity.current) { dropDownWidth.toDp() }),
                 onDismissRequest = { expanded = false },
             ) {
-                options.forEach { option ->
+                options.forEachIndexed { index, option ->
                     TextButton(
                         modifier = Modifier
                             .fillMaxHeight()
                             .fillMaxWidth(),
                         onClick = {
-                            if (selectedOptionsState.contains(option)) {
+                            if (selectedOptionsState.contains(index)) {
                                 selectedOptionsState.remove(
-                                    option
+                                    index
                                 )
                             } else {
                                 selectedOptionsState.add(
-                                    option
+                                    index
                                 )
                             }
                             onSelectedOptionStateChange()
@@ -114,7 +116,7 @@ fun SettingsExposedDropdownMenuCheckBox(
                             verticalAlignment = Alignment.CenterVertically
                         ) {
                             Checkbox(
-                                checked = selectedOptionsState.contains(option),
+                                checked = selectedOptionsState.contains(index),
                                 onCheckedChange = null,
                             )
                             Text(text = option)
@@ -130,7 +132,7 @@ fun SettingsExposedDropdownMenuCheckBox(
 @Composable
 private fun ActionButtonsPreview() {
     val options = listOf("item1", "item2", "item3")
-    val selectedOptionsState = remember { mutableStateListOf("item1", "item2") }
+    val selectedOptionsState = remember { mutableStateListOf(0, 1) }
     SettingsTheme {
         SettingsExposedDropdownMenuCheckBox(
             label = "label",
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/editor/SettingsExposedDropdownMenuCheckBoxTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/editor/SettingsExposedDropdownMenuCheckBoxTest.kt
index b0271ae1d98c..2b78ed7d6fa2 100644
--- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/editor/SettingsExposedDropdownMenuCheckBoxTest.kt
+++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/editor/SettingsExposedDropdownMenuCheckBoxTest.kt
@@ -39,7 +39,7 @@ class SettingsExposedDropdownMenuCheckBoxTest {
     private val item2 = "item2"
     private val item3 = "item3"
     private val options = listOf(item1, item2, item3)
-    private val selectedOptionsState1 = mutableStateListOf(item1, item2)
+    private val selectedOptionsState1 = mutableStateListOf(0, 1)
     private val exposedDropdownMenuCheckBoxLabel = "ExposedDropdownMenuCheckBoxLabel"
 
     @Test
-- 
GitLab


From 1582f4833b60d42716382202b9e7844f96357d57 Mon Sep 17 00:00:00 2001
From: Diego Vela <diegovela@google.com>
Date: Fri, 15 Sep 2023 21:27:06 +0000
Subject: [PATCH 70/95] Add raw configuration change listener updates.

Add raw configuration change listener updates. Letterboxed Activities do
not receive a configuration update when they are repositioned. Listening
to all configuration changes will correctly update folding features.
Change exceptions from hard exceptions to Log.wtf so that we do not
crash on production apps.

Bug: 295785410
Test: Open Samples and open the slim (letterbox) Activities.
Change-Id: Ia079d06a403a59bb0f1eafdaad6ce238749a2af2
---
 core/java/android/app/ActivityThread.java     |  24 ++++
 ...onfigurationChangedListenerController.java | 116 ++++++++++++++++++
 .../layout/WindowLayoutComponentImpl.java     |  39 +++++-
 3 files changed, 175 insertions(+), 4 deletions(-)
 create mode 100644 core/java/android/app/ConfigurationChangedListenerController.java

diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 01912012f04a..c51dab7f7865 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -36,6 +36,7 @@ import static android.view.Display.INVALID_DISPLAY;
 import static android.window.ConfigurationHelper.freeTextLayoutCachesIfNeeded;
 import static android.window.ConfigurationHelper.isDifferentDisplay;
 import static android.window.ConfigurationHelper.shouldUpdateResources;
+
 import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
 import static com.android.internal.os.SafeZipPathValidatorCallback.VALIDATE_ZIP_PATH_FOR_PATH_TRAVERSAL;
 import static com.android.sdksandbox.flags.Flags.sandboxActivitySdkBasedContext;
@@ -265,6 +266,7 @@ import java.util.Objects;
 import java.util.TimeZone;
 import java.util.concurrent.Executor;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
 
 /**
  * This manages the execution of the main thread in an
@@ -382,6 +384,11 @@ public final class ActivityThread extends ClientTransactionHandler
     @GuardedBy("mAppThread")
     private int mLastProcessState = PROCESS_STATE_UNKNOWN;
     final ArrayList<WeakReference<AssistStructure>> mLastAssistStructures = new ArrayList<>();
+
+    @NonNull
+    private final ConfigurationChangedListenerController mConfigurationChangedListenerController =
+            new ConfigurationChangedListenerController();
+
     private int mLastSessionId;
     // Holds the value of the last reported device ID value from the server for the top activity.
     int mLastReportedDeviceId;
@@ -3608,6 +3615,21 @@ public final class ActivityThread extends ClientTransactionHandler
         return mConfigurationController.getConfiguration();
     }
 
+    /**
+     * @hide
+     */
+    public void addConfigurationChangedListener(Executor executor,
+            Consumer<IBinder> consumer) {
+        mConfigurationChangedListenerController.addListener(executor, consumer);
+    }
+
+    /**
+     * @hide
+     */
+    public void removeConfigurationChangedListener(Consumer<IBinder> consumer) {
+        mConfigurationChangedListenerController.removeListener(consumer);
+    }
+
     @Override
     public void updatePendingConfiguration(Configuration config) {
         final Configuration updatedConfig =
@@ -6252,6 +6274,8 @@ public final class ActivityThread extends ClientTransactionHandler
                                 " did not call through to super.onConfigurationChanged()");
             }
         }
+        mConfigurationChangedListenerController
+                .dispatchOnConfigurationChanged(activity.getActivityToken());
 
         return configToReport;
     }
diff --git a/core/java/android/app/ConfigurationChangedListenerController.java b/core/java/android/app/ConfigurationChangedListenerController.java
new file mode 100644
index 000000000000..c644d57fb9a7
--- /dev/null
+++ b/core/java/android/app/ConfigurationChangedListenerController.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2023 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 android.annotation.NonNull;
+import android.os.IBinder;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+
+/**
+ * Manages listeners for unfiltered configuration changes.
+ * @hide
+ */
+class ConfigurationChangedListenerController {
+
+    private final Object mLock = new Object();
+
+    @GuardedBy("mLock")
+    private final List<ListenerContainer> mListenerContainers = new ArrayList<>();
+
+    /**
+     * Adds a listener to receive updates when they are dispatched. This only dispatches updates and
+     * does not relay the last emitted value. If called with the same listener then this method does
+     * not have any effect.
+     * @param executor an executor that is used to dispatch the updates.
+     * @param consumer a listener interested in receiving updates.
+     */
+    void addListener(@NonNull Executor executor,
+            @NonNull Consumer<IBinder> consumer) {
+        synchronized (mLock) {
+            if (indexOf(consumer) > -1) {
+                return;
+            }
+            mListenerContainers.add(new ListenerContainer(executor, consumer));
+        }
+    }
+
+    /**
+     * Removes the listener that was previously registered. If the listener was not registered this
+     * method does not have any effect.
+     */
+    void removeListener(@NonNull Consumer<IBinder> consumer) {
+        synchronized (mLock) {
+            final int index = indexOf(consumer);
+            if (index > -1) {
+                mListenerContainers.remove(index);
+            }
+        }
+    }
+
+    /**
+     * Dispatches the update to all registered listeners
+     * @param activityToken a token for the {@link Activity} that received a configuration update.
+     */
+    void dispatchOnConfigurationChanged(@NonNull IBinder activityToken) {
+        final List<ListenerContainer> consumers;
+        synchronized (mLock) {
+            consumers = new ArrayList<>(mListenerContainers);
+        }
+        for (int i = 0; i < consumers.size(); i++) {
+            consumers.get(i).accept(activityToken);
+        }
+    }
+
+    @GuardedBy("mLock")
+    private int indexOf(Consumer<IBinder> consumer) {
+        for (int i = 0; i < mListenerContainers.size(); i++) {
+            if (mListenerContainers.get(i).isMatch(consumer)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    private static final class ListenerContainer {
+
+        @NonNull
+        private final Executor mExecutor;
+        @NonNull
+        private final Consumer<IBinder> mConsumer;
+
+        ListenerContainer(@NonNull Executor executor,
+                @NonNull Consumer<IBinder> consumer) {
+            mExecutor = executor;
+            mConsumer = consumer;
+        }
+
+        public boolean isMatch(@NonNull Consumer<IBinder> consumer) {
+            return mConsumer.equals(consumer);
+        }
+
+        public void accept(@NonNull IBinder activityToken) {
+            mExecutor.execute(() -> mConsumer.accept(activityToken));
+        }
+
+    }
+}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
index e0942b74e0a2..9b84a48cdbda 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
@@ -25,6 +25,7 @@ import static androidx.window.util.ExtensionHelper.rotateRectToDisplayRotation;
 import static androidx.window.util.ExtensionHelper.transformToWindowSpaceRect;
 
 import android.app.Activity;
+import android.app.ActivityThread;
 import android.app.Application;
 import android.app.WindowConfiguration;
 import android.content.ComponentCallbacks;
@@ -34,6 +35,7 @@ import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.util.ArrayMap;
+import android.util.Log;
 
 import androidx.annotation.GuardedBy;
 import androidx.annotation.NonNull;
@@ -60,7 +62,7 @@ import java.util.Set;
  * Please refer to {@link androidx.window.sidecar.SampleSidecarImpl} instead.
  */
 public class WindowLayoutComponentImpl implements WindowLayoutComponent {
-    private static final String TAG = "SampleExtension";
+    private static final String TAG = WindowLayoutComponentImpl.class.getSimpleName();
 
     private final Object mLock = new Object();
 
@@ -82,6 +84,9 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
     private final Map<java.util.function.Consumer<WindowLayoutInfo>, Consumer<WindowLayoutInfo>>
             mJavaToExtConsumers = new ArrayMap<>();
 
+    private final RawConfigurationChangedListener mRawConfigurationChangedListener =
+            new RawConfigurationChangedListener();
+
     public WindowLayoutComponentImpl(@NonNull Context context,
             @NonNull DeviceStateManagerFoldingFeatureProducer foldingFeatureProducer) {
         ((Application) context.getApplicationContext())
@@ -102,6 +107,7 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
         final Consumer<WindowLayoutInfo> extConsumer = consumer::accept;
         synchronized (mLock) {
             mJavaToExtConsumers.put(consumer, extConsumer);
+            updateListenerRegistrations();
         }
         addWindowLayoutInfoListener(activity, extConsumer);
     }
@@ -155,6 +161,7 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
         final Consumer<WindowLayoutInfo> extConsumer;
         synchronized (mLock) {
             extConsumer = mJavaToExtConsumers.remove(consumer);
+            updateListenerRegistrations();
         }
         if (extConsumer != null) {
             removeWindowLayoutInfoListener(extConsumer);
@@ -184,6 +191,17 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
         }
     }
 
+    @GuardedBy("mLock")
+    private void updateListenerRegistrations() {
+        ActivityThread currentThread = ActivityThread.currentActivityThread();
+        if (mJavaToExtConsumers.isEmpty()) {
+            currentThread.removeConfigurationChangedListener(mRawConfigurationChangedListener);
+        } else {
+            currentThread.addConfigurationChangedListener(Runnable::run,
+                    mRawConfigurationChangedListener);
+        }
+    }
+
     @GuardedBy("mLock")
     @NonNull
     private Set<Context> getContextsListeningForLayoutChanges() {
@@ -329,25 +347,28 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
                 continue;
             }
             if (featureRect.left != 0 && featureRect.top != 0) {
-                throw new IllegalArgumentException("Bounding rectangle must start at the top or "
+                Log.wtf(TAG, "Bounding rectangle must start at the top or "
                         + "left of the window. BaseFeatureRect: " + baseFeature.getRect()
                         + ", FeatureRect: " + featureRect
                         + ", WindowConfiguration: " + windowConfiguration);
+                continue;
 
             }
             if (featureRect.left == 0
                     && featureRect.width() != windowConfiguration.getBounds().width()) {
-                throw new IllegalArgumentException("Horizontal FoldingFeature must have full width."
+                Log.wtf(TAG, "Horizontal FoldingFeature must have full width."
                         + " BaseFeatureRect: " + baseFeature.getRect()
                         + ", FeatureRect: " + featureRect
                         + ", WindowConfiguration: " + windowConfiguration);
+                continue;
             }
             if (featureRect.top == 0
                     && featureRect.height() != windowConfiguration.getBounds().height()) {
-                throw new IllegalArgumentException("Vertical FoldingFeature must have full height."
+                Log.wtf(TAG, "Vertical FoldingFeature must have full height."
                         + " BaseFeatureRect: " + baseFeature.getRect()
                         + ", FeatureRect: " + featureRect
                         + ", WindowConfiguration: " + windowConfiguration);
+                continue;
             }
             features.add(new FoldingFeature(featureRect, baseFeature.getType(), state));
         }
@@ -400,6 +421,16 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
         }
     }
 
+    private final class RawConfigurationChangedListener implements
+            java.util.function.Consumer<IBinder> {
+        @Override
+        public void accept(IBinder activityToken) {
+            synchronized (mLock) {
+                onDisplayFeaturesChangedIfListening(activityToken);
+            }
+        }
+    }
+
     private final class ConfigurationChangeListener implements ComponentCallbacks {
         final IBinder mToken;
 
-- 
GitLab


From 1ef586cbc7d28a23c20695c3d1be58e5832d56fa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A1s=20Kurucz?= <kurucz@google.com>
Date: Thu, 21 Sep 2023 08:34:15 +0000
Subject: [PATCH 71/95] Disable bigpicture lazy loading for unsupported icons

Don't set placeholders for bitmap or data based icons inside
BigPictureStyle Notifications, because it doesn't save on memory.

Bug: 283082473
Test: atest BigPictureIconManager
Change-Id: I547668b5b35cf1f9932eee77d941b69d9e023e38
---
 .../notification/row/BigPictureIconManager.kt | 16 +++++-
 .../row/BigPictureIconManagerTest.kt          | 53 ++++++++++++++++---
 2 files changed, 60 insertions(+), 9 deletions(-)

diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BigPictureIconManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BigPictureIconManager.kt
index 88dbb4cf1342..ba1e6dd8ca4a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BigPictureIconManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BigPictureIconManager.kt
@@ -89,6 +89,7 @@ constructor(
             this.lastLoadingJob?.cancel()
             this.lastLoadingJob =
                 when {
+                    skipLazyLoading(state.icon) -> null
                     state is Empty && shown -> state.icon?.let(::startLoadingJob)
                     state is PlaceHolder && shown -> startLoadingJob(state.icon)
                     state is FullImage && !shown ->
@@ -144,7 +145,7 @@ constructor(
     private fun loadImageOrPlaceHolderSync(icon: Icon?): Drawable? {
         icon ?: return null
 
-        if (viewShown) {
+        if (viewShown || skipLazyLoading(icon)) {
             return loadImageSync(icon)
         }
 
@@ -228,6 +229,19 @@ constructor(
             }
         )
 
+    /**
+     * We don't support lazy-loading or set placeholders for bitmap and data based icons, because
+     * they gonna stay in memory anyways.
+     */
+    private fun skipLazyLoading(icon: Icon?): Boolean =
+        when (icon?.type) {
+            Icon.TYPE_BITMAP,
+            Icon.TYPE_ADAPTIVE_BITMAP,
+            Icon.TYPE_DATA,
+            null -> true
+            else -> false
+        }
+
     private fun log(msg: String) {
         if (DEBUG) {
             Log.d(TAG, "$msg state=${getDebugString()}")
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt
index c650e01263bc..e7bcf3f0201f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt
@@ -70,7 +70,7 @@ class BigPictureIconManagerTest : SysuiTestCase() {
     }
     private val unsupportedIcon by lazy {
         Icon.createWithBitmap(
-            BitmapFactory.decodeResource(context.resources, R.drawable.dessert_zombiegingerbread)
+            BitmapFactory.decodeResource(context.resources, R.drawable.dessert_donutburger)
         )
     }
     private val invalidIcon by lazy { Icon.createWithContentUri(Uri.parse("this.is/broken")) }
@@ -100,7 +100,7 @@ class BigPictureIconManagerTest : SysuiTestCase() {
         }
 
     @Test
-    fun onIconUpdated_notSupportedType_fullImageLoaded() =
+    fun onIconUpdated_unsupportedType_fullImageLoaded() =
         testScope.runTest {
             // WHEN update with an unsupported icon
             iconManager.updateIcon(mockConsumer, unsupportedIcon).run()
@@ -153,6 +153,24 @@ class BigPictureIconManagerTest : SysuiTestCase() {
         }
 
     @Test
+    fun onIconUpdated_iconAlreadySetForUnsupportedIcon_loadsNewIcon() =
+        testScope.runTest {
+            // GIVEN an unsupported icon is set
+            iconManager.updateIcon(mockConsumer, unsupportedIcon).run()
+            // AND the view is shown
+            iconManager.onViewShown(true)
+            reset(mockConsumer)
+
+            // WHEN a new icon is set
+            iconManager.updateIcon(mockConsumer, supportedIcon).run()
+
+            // THEN consumer is updated with the new image
+            verify(mockConsumer).setImageDrawable(drawableCaptor.capture())
+            assertIsFullImage(drawableCaptor.value)
+            assertSize(drawableCaptor.value)
+        }
+
+        @Test
     fun onIconUpdated_supportedTypeButTooWide_resizedPlaceholderLoaded() =
         testScope.runTest {
             // GIVEN the max width is smaller than our image
@@ -249,12 +267,10 @@ class BigPictureIconManagerTest : SysuiTestCase() {
             verifyZeroInteractions(mockConsumer)
         }
 
-    // nice to have tests
-
     @Test
-    fun onViewShown_fullImageLoaded_nothingHappens() =
+    fun onViewShown_unsupportedIconLoaded_nothingHappens() =
         testScope.runTest {
-            // GIVEN full image is showing
+            // GIVEN full image is showing for an unsupported icon
             iconManager.updateIcon(mockConsumer, unsupportedIcon).run()
             reset(mockConsumer)
 
@@ -266,11 +282,31 @@ class BigPictureIconManagerTest : SysuiTestCase() {
             verifyZeroInteractions(mockConsumer)
         }
 
+    @Test
+    fun onViewHidden_unsupportedIconLoadedAndViewIsShown_nothingHappens() =
+        testScope.runTest {
+            // GIVEN full image is showing for an unsupported icon
+            iconManager.updateIcon(mockConsumer, unsupportedIcon).run()
+            // AND the view is shown
+            iconManager.onViewShown(true)
+            runCurrent()
+            reset(mockConsumer)
+
+            // WHEN the view goes off the screen
+            iconManager.onViewShown(false)
+            // AND we wait a bit
+            advanceTimeBy(FREE_IMAGE_DELAY_MS)
+            runCurrent()
+
+            // THEN nothing happens
+            verifyZeroInteractions(mockConsumer)
+        }
+
     @Test
     fun onViewHidden_placeholderShowing_nothingHappens() =
         testScope.runTest {
             // GIVEN placeholder image is showing
-            iconManager.updateIcon(mockConsumer, unsupportedIcon).run()
+            iconManager.updateIcon(mockConsumer, supportedIcon).run()
             reset(mockConsumer)
 
             // WHEN the view is hidden
@@ -296,6 +332,7 @@ class BigPictureIconManagerTest : SysuiTestCase() {
             iconManager.onViewShown(true)
             runCurrent()
 
+            // THEN nothing happens
             verifyZeroInteractions(mockConsumer)
         }
 
@@ -303,7 +340,7 @@ class BigPictureIconManagerTest : SysuiTestCase() {
     fun onViewHidden_alreadyHidden_nothingHappens() =
         testScope.runTest {
             // GIVEN placeholder image is showing and the view is hidden
-            iconManager.updateIcon(mockConsumer, unsupportedIcon).run()
+            iconManager.updateIcon(mockConsumer, supportedIcon).run()
             iconManager.onViewShown(false)
             advanceTimeBy(FREE_IMAGE_DELAY_MS)
             runCurrent()
-- 
GitLab


From f036bb66357dcdc6e2cf07ea81dee7955fd48025 Mon Sep 17 00:00:00 2001
From: Songchun Fan <schfan@google.com>
Date: Mon, 18 Sep 2023 14:23:17 -0700
Subject: [PATCH 72/95] [framweweworks] clean up broadcast receivers after test

BUG: 298063459
Test: presubmit

Change-Id: Id0f728120fe4db6b86f9e753f3eaa17780aa5db0
Merged-In: Id0f728120fe4db6b86f9e753f3eaa17780aa5db0
---
 .../src/android/content/BroadcastReceiverTests.java  | 12 +++++++++++-
 .../android/internal/os/BatteryInputSuspendTest.java |  1 +
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/core/tests/coretests/src/android/content/BroadcastReceiverTests.java b/core/tests/coretests/src/android/content/BroadcastReceiverTests.java
index 5dbeac2f32e9..407c6c3e2e2c 100644
--- a/core/tests/coretests/src/android/content/BroadcastReceiverTests.java
+++ b/core/tests/coretests/src/android/content/BroadcastReceiverTests.java
@@ -26,6 +26,9 @@ import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.ArrayList;
+import java.util.List;
+
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class BroadcastReceiverTests {
@@ -47,15 +50,22 @@ public class BroadcastReceiverTests {
     @Test
     public void testReceiverLimit() {
         final IntentFilter mockFilter = new IntentFilter("android.content.tests.TestAction");
+        final List<EmptyReceiver> receivers = new ArrayList<>(RECEIVER_LIMIT_PER_APP);
         try {
             for (int i = 0; i < RECEIVER_LIMIT_PER_APP + 1; i++) {
-                mContext.registerReceiver(new EmptyReceiver(), mockFilter,
+                final EmptyReceiver receiver = new EmptyReceiver();
+                mContext.registerReceiver(receiver, mockFilter,
                         Context.RECEIVER_EXPORTED_UNAUDITED);
+                receivers.add(receiver);
             }
             fail("No exception thrown when registering "
                     + (RECEIVER_LIMIT_PER_APP + 1) + " receivers");
         } catch (IllegalStateException ise) {
             // Expected
+        } finally {
+            for (int i = receivers.size() - 1; i >= 0; i--) {
+                mContext.unregisterReceiver(receivers.remove(i));
+            }
         }
     }
 }
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryInputSuspendTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryInputSuspendTest.java
index e870d6022058..8d825e4deb81 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryInputSuspendTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryInputSuspendTest.java
@@ -99,6 +99,7 @@ public class BatteryInputSuspendTest {
                     if (isCharging(intent) == mExpectedChargingState) {
                         mReady.open();
                     }
+                    context.unregisterReceiver(this);
                 }
             }, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
         }
-- 
GitLab


From 3b61ee74224d24d0597ecfc1da87e7f65d37b835 Mon Sep 17 00:00:00 2001
From: axfordjc <axfordjc@google.com>
Date: Thu, 21 Sep 2023 09:45:17 +0000
Subject: [PATCH 73/95] is_small_screen_landscape resource

Intended to be used alongside the flag "lockscreen.enable_landscape" (b/293252410)

Bug: 293252410

Test: None
Change-Id: I02ba5884780eb511dac3ba5cdfbfbca0e6420f56
---
 packages/SystemUI/res/values-land/bools.xml         | 3 +++
 packages/SystemUI/res/values-sw600dp-land/bools.xml | 3 +++
 packages/SystemUI/res/values/bools.xml              | 3 +++
 3 files changed, 9 insertions(+)

diff --git a/packages/SystemUI/res/values-land/bools.xml b/packages/SystemUI/res/values-land/bools.xml
index e24792dc7dd7..c112edcf22bf 100644
--- a/packages/SystemUI/res/values-land/bools.xml
+++ b/packages/SystemUI/res/values-land/bools.xml
@@ -19,4 +19,7 @@
     <!-- Only use small clock on lockscreen.
      True here because only small clock used on small devices in landscape -->
     <bool name="force_small_clock_on_lockscreen">true</bool>
+
+    <!--  True when small screen (<sw600dp) is landscape. -->
+    <bool name="is_small_screen_landscape">true</bool>
 </resources>
diff --git a/packages/SystemUI/res/values-sw600dp-land/bools.xml b/packages/SystemUI/res/values-sw600dp-land/bools.xml
index c4d77e894141..36926a2b4813 100644
--- a/packages/SystemUI/res/values-sw600dp-land/bools.xml
+++ b/packages/SystemUI/res/values-sw600dp-land/bools.xml
@@ -19,4 +19,7 @@
     <!-- Only use small clock on lockscreen.
      False here because large clock is allowed on large devices in landscape -->
     <bool name="force_small_clock_on_lockscreen">false</bool>
+
+    <!--  True when small screen (<sw600dp) is landscape. -->
+    <bool name="is_small_screen_landscape">false</bool>
 </resources>
diff --git a/packages/SystemUI/res/values/bools.xml b/packages/SystemUI/res/values/bools.xml
index 39566622a5f4..234c6df69d0b 100644
--- a/packages/SystemUI/res/values/bools.xml
+++ b/packages/SystemUI/res/values/bools.xml
@@ -63,4 +63,7 @@
     <!-- Only use small clock on lockscreen.
      False here because large clock used by default, unless otherwise specified -->
     <bool name="force_small_clock_on_lockscreen">false</bool>
+
+    <!--  True when small screen (<sw600dp) is landscape. -->
+    <bool name="is_small_screen_landscape">false</bool>
 </resources>
-- 
GitLab


From bdf9641f553380abff35ae95e3ff8cf068833db4 Mon Sep 17 00:00:00 2001
From: axfordjc <axfordjc@google.com>
Date: Sat, 9 Sep 2023 18:14:51 +0000
Subject: [PATCH 74/95] Wider notifications on landscape lockscreen

Guarded by flag lockscreen.enable_landscape, skinny notifications are no longer used on small landscape screens so notifications will take up the full width of the notification stack. This is required for small landscape lockscreen feature.

Bug: 296571001
Bug: 293252410

Test: NotificationStackScrollLayoutTest
Change-Id: I469ab15eed507ef2c4e4d1b8c4d565dd44051a2f
---
 .../stack/NotificationStackScrollLayout.java      | 15 ++++++++++++++-
 .../stack/NotificationStackScrollLayoutTest.java  |  1 +
 2 files changed, 15 insertions(+), 1 deletion(-)

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 e8521d1673cf..757ae6d9bd80 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
@@ -569,6 +569,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
     private boolean mShouldUseSplitNotificationShade;
     private boolean mHasFilteredOutSeenNotifications;
     @Nullable private SplitShadeStateController mSplitShadeStateController = null;
+    private boolean mIsSmallLandscapeLockscreenEnabled = false;
 
     /** Pass splitShadeStateController to view and update split shade */
     public void passSplitShadeStateController(SplitShadeStateController splitShadeStateController) {
@@ -628,6 +629,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
         super(context, attrs, 0, 0);
         Resources res = getResources();
         FeatureFlags featureFlags = Dependency.get(FeatureFlags.class);
+        mIsSmallLandscapeLockscreenEnabled = featureFlags.isEnabled(
+                Flags.LOCKSCREEN_ENABLE_LANDSCAPE);
         mDebugLines = featureFlags.isEnabled(Flags.NSSL_DEBUG_LINES);
         mDebugRemoveAnimation = featureFlags.isEnabled(Flags.NSSL_DEBUG_REMOVE_ANIMATION);
         mSensitiveRevealAnimEndabled = featureFlags.isEnabled(Flags.SENSITIVE_REVEAL_ANIM);
@@ -1054,6 +1057,17 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
         mOverflingDistance = configuration.getScaledOverflingDistance();
 
         Resources res = context.getResources();
+        boolean useSmallLandscapeLockscreenResources = mIsSmallLandscapeLockscreenEnabled
+                && res.getBoolean(R.bool.is_small_screen_landscape);
+        // TODO (b/293252410) remove condition here when flag is launched
+        //  Instead update the config_skinnyNotifsInLandscape to be false whenever
+        //  is_small_screen_landscape is true. Then, only use the config_skinnyNotifsInLandscape.
+        if (useSmallLandscapeLockscreenResources) {
+            mSkinnyNotifsInLandscape = false;
+        } else {
+            mSkinnyNotifsInLandscape = res.getBoolean(
+                    R.bool.config_skinnyNotifsInLandscape);
+        }
         mGapHeight = res.getDimensionPixelSize(R.dimen.notification_section_divider_height);
         mStackScrollAlgorithm.initView(context);
         mAmbientState.reload(context);
@@ -1065,7 +1079,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
         mBottomPadding = res.getDimensionPixelSize(R.dimen.notification_panel_padding_bottom);
         mMinimumPaddings = res.getDimensionPixelSize(R.dimen.notification_side_paddings);
         mQsTilePadding = res.getDimensionPixelOffset(R.dimen.qs_tile_margin_horizontal);
-        mSkinnyNotifsInLandscape = res.getBoolean(R.bool.config_skinnyNotifsInLandscape);
         mSidePaddings = mMinimumPaddings;  // Updated in onMeasure by updateSidePadding()
         mMinInteractionHeight = res.getDimensionPixelSize(
                 R.dimen.notification_min_interaction_height);
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 4307066e2d44..036a27c3831a 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
@@ -154,6 +154,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
         assertFalse(Flags.NSSL_DEBUG_REMOVE_ANIMATION.getDefault());
         mFeatureFlags.set(Flags.NSSL_DEBUG_LINES, false);
         mFeatureFlags.set(Flags.NSSL_DEBUG_REMOVE_ANIMATION, false);
+        mFeatureFlags.set(Flags.LOCKSCREEN_ENABLE_LANDSCAPE, false);
 
         // Register the feature flags we use
         // TODO: Ideally we wouldn't need to set these unless a test actually reads them,
-- 
GitLab


From 37092e449ae3d89921668bbd641e5184a497395b Mon Sep 17 00:00:00 2001
From: Vladimir Komsiyski <vladokom@google.com>
Date: Fri, 22 Sep 2023 10:29:44 +0200
Subject: [PATCH 75/95] Compat changes for VDM display flags

Fix: 300905478
Test: presubmit
Change-Id: Ie681a97bb75c0797d3d34c4c368316051025d99c
---
 .../companion/virtual/VirtualDeviceImpl.java  | 43 ++++++++++++++++---
 1 file changed, 38 insertions(+), 5 deletions(-)

diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
index 3b13410720af..f328b22352ae 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
@@ -37,6 +37,7 @@ import android.app.Activity;
 import android.app.ActivityOptions;
 import android.app.PendingIntent;
 import android.app.admin.DevicePolicyManager;
+import android.app.compat.CompatChanges;
 import android.companion.AssociationInfo;
 import android.companion.virtual.IVirtualDevice;
 import android.companion.virtual.IVirtualDeviceActivityListener;
@@ -51,6 +52,8 @@ import android.companion.virtual.audio.IAudioRoutingCallback;
 import android.companion.virtual.flags.Flags;
 import android.companion.virtual.sensor.VirtualSensor;
 import android.companion.virtual.sensor.VirtualSensorEvent;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
 import android.content.AttributionSource;
 import android.content.ComponentName;
 import android.content.Context;
@@ -75,6 +78,7 @@ import android.hardware.input.VirtualNavigationTouchpadConfig;
 import android.hardware.input.VirtualTouchEvent;
 import android.hardware.input.VirtualTouchscreenConfig;
 import android.os.Binder;
+import android.os.Build;
 import android.os.IBinder;
 import android.os.LocaleList;
 import android.os.Looper;
@@ -115,12 +119,33 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
 
     private static final String TAG = "VirtualDeviceImpl";
 
+    /**
+     * Virtual displays created by a {@link VirtualDeviceManager.VirtualDevice} are more consistent
+     * with virtual displays created via {@link DisplayManager} and allow for the creation of
+     * private, auto-mirror, and fixed orientation displays since
+     * {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM}.
+     *
+     * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_PUBLIC
+     * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY
+     * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR
+     * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT
+     */
+    @ChangeId
+    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
+    public static final long MAKE_VIRTUAL_DISPLAY_FLAGS_CONSISTENT_WITH_DISPLAY_MANAGER =
+            294837146L;
+
     private static final int DEFAULT_VIRTUAL_DISPLAY_FLAGS =
             DisplayManager.VIRTUAL_DISPLAY_FLAG_TOUCH_FEEDBACK_DISABLED
                     | DisplayManager.VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL
                     | DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH
                     | DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_FOCUS;
 
+    private static final int DEFAULT_VIRTUAL_DISPLAY_FLAGS_PRE_VIC =
+            DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC
+                    | DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT
+                    | DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;
+
     private static final String PERSISTENT_ID_PREFIX_CDM_ASSOCIATION = "companion:";
 
     /**
@@ -130,6 +155,8 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
 
     private final Object mVirtualDeviceLock = new Object();
 
+    private final int mBaseVirtualDisplayFlags;
+
     private final Context mContext;
     private final AssociationInfo mAssociationInfo;
     private final VirtualDeviceManagerService mService;
@@ -311,6 +338,16 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
                             ? mParams.getBlockedActivities()
                             : mParams.getAllowedActivities();
         }
+
+        int flags = DEFAULT_VIRTUAL_DISPLAY_FLAGS;
+        if (!CompatChanges.isChangeEnabled(
+                MAKE_VIRTUAL_DISPLAY_FLAGS_CONSISTENT_WITH_DISPLAY_MANAGER, mOwnerUid)) {
+            flags |= DEFAULT_VIRTUAL_DISPLAY_FLAGS_PRE_VIC;
+        }
+        if (mParams.getLockState() == VirtualDeviceParams.LOCK_STATE_ALWAYS_UNLOCKED) {
+            flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED;
+        }
+        mBaseVirtualDisplayFlags = flags;
     }
 
     @VisibleForTesting
@@ -323,11 +360,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
      * device.
      */
     int getBaseVirtualDisplayFlags() {
-        int flags = DEFAULT_VIRTUAL_DISPLAY_FLAGS;
-        if (mParams.getLockState() == VirtualDeviceParams.LOCK_STATE_ALWAYS_UNLOCKED) {
-            flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED;
-        }
-        return flags;
+        return mBaseVirtualDisplayFlags;
     }
 
     /** Returns the camera access controller of this device. */
-- 
GitLab


From 0c5993fa0e39e4959a18994663923bbb2ddc44e1 Mon Sep 17 00:00:00 2001
From: beatricemarch <beatricemarch@google.com>
Date: Thu, 31 Aug 2023 12:53:16 +0000
Subject: [PATCH 76/95] Implement the ability to log extras relating to version
 mismatches between packages on the source and target. Imporve readability of
 events in dumpsys.

Test: manual, do restore on test device, verify that the correct events
are printed in the dumpsys
atest CtsBackupHostTestCases, GtsBackupHostTestCases
atest BackupManagerMonitorDumpsysUtilsTest
Bug: 296818666

Change-Id: Ifd2d68861fcd33637c49f0e7802c456e43ffd9a2
---
 .../BackupManagerMonitorDumpsysUtils.java     | 56 ++++++++++++++-----
 1 file changed, 43 insertions(+), 13 deletions(-)

diff --git a/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtils.java b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtils.java
index 4b0d5a4928b6..797aed9297a3 100644
--- a/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtils.java
@@ -84,15 +84,15 @@ public class BackupManagerMonitorDumpsysUtils {
      * - Agent logs (if available)
      *
      * Example of formatting:
-     * RESTORE Event: [2023-08-18 17:16:00.735] Agent - Agent logging results
-     * Package name: com.android.wallpaperbackup
-     * Agent Logs:
-     * Data Type: wlp_img_system
-     * Item restored: 0/1
-     * Agent Error - Category: no_wallpaper, Count: 1
-     * Data Type: wlp_img_lock
-     * Item restored: 0/1
-     * Agent Error - Category: no_wallpaper, Count: 1
+     * [2023-09-21 14:43:33.824] - Agent logging results
+     *   Package: com.android.wallpaperbackup
+     *   Agent Logs:
+     *           Data Type: wlp_img_system
+     *                   Item restored: 0/1
+     *                   Agent Error - Category: no_wallpaper, Count: 1
+     *           Data Type: wlp_img_lock
+     *                   Item restored: 0/1
+     *                   Agent Error - Category: no_wallpaper, Count: 1
      */
     public void parseBackupManagerMonitorRestoreEventForDumpsys(Bundle eventBundle) {
         if (isAfterRetentionPeriod()) {
@@ -139,17 +139,16 @@ public class BackupManagerMonitorDumpsysUtils {
                 return;
             }
 
-            pw.println("RESTORE Event: [" + timestamp() + "] " +
-                    getCategory(eventCategory) + " - " +
-                    getId(eventId));
+            pw.println("[" + timestamp() + "] - " + getId(eventId));
 
             if (eventBundle.containsKey(BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_NAME)) {
-                pw.println("\tPackage name: "
+                pw.println("\tPackage: "
                         + eventBundle.getString(BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_NAME));
             }
 
             // TODO(b/296818666): add extras to the events
             addAgentLogsIfAvailable(eventBundle, pw);
+            addExtrasIfAvailable(eventBundle, pw);
         } catch (java.io.IOException e) {
             Slog.e(TAG, "IO Exception when writing BMM events to file: " + e);
         }
@@ -194,6 +193,37 @@ public class BackupManagerMonitorDumpsysUtils {
         }
     }
 
+    /**
+     * Extracts some extras (defined in BackupManagerMonitor as EXTRA_LOG_<description>)
+     * from the BackupManagerMonitor event. Not all extras have the same importance. For now only
+     * focus on extras relating to version mismatches between packages on the source and target.
+     *
+     * When an event with ID LOG_EVENT_ID_RESTORE_VERSION_HIGHER (trying to restore from higher to
+     * lower version of a package) parse:
+     * EXTRA_LOG_RESTORE_VERSION [int]: the version of the package on the source
+     * EXTRA_LOG_RESTORE_ANYWAY [bool]: if the package allows restore any version
+     * EXTRA_LOG_RESTORE_VERSION_TARGET [int]: an extra to record the package version on the target
+     */
+    private void addExtrasIfAvailable(Bundle eventBundle, PrintWriter pw) {
+        if (eventBundle.getInt(BackupManagerMonitor.EXTRA_LOG_EVENT_ID) ==
+                BackupManagerMonitor.LOG_EVENT_ID_RESTORE_VERSION_HIGHER) {
+            if (eventBundle.containsKey(BackupManagerMonitor.EXTRA_LOG_RESTORE_ANYWAY)) {
+                pw.println("\t\tPackage supports RestoreAnyVersion: "
+                        + eventBundle.getBoolean(BackupManagerMonitor.EXTRA_LOG_RESTORE_ANYWAY));
+            }
+            if (eventBundle.containsKey(BackupManagerMonitor.EXTRA_LOG_RESTORE_VERSION)) {
+                pw.println("\t\tPackage version on source: "
+                        + eventBundle.getLong(BackupManagerMonitor.EXTRA_LOG_RESTORE_VERSION));
+            }
+            if (eventBundle.containsKey(
+                      BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_LONG_VERSION)) {
+                pw.println("\t\tPackage version on target: "
+                        + eventBundle.getLong(
+                        BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_LONG_VERSION));
+            }
+        }
+    }
+
     /*
      * Get the path of the text files which stores the BMM events
      */
-- 
GitLab


From 0f0cdccd74dc93d68fe96caac6563c2ac0ff9833 Mon Sep 17 00:00:00 2001
From: Matt Pietal <mpietal@google.com>
Date: Fri, 22 Sep 2023 11:32:11 +0000
Subject: [PATCH 77/95] Ensure keyguard shows, and tells WM

Many race conditions can occur, especially with SideFPS. In this case,
a successful auth followed by numerous power button pushes, and having
distinct home and lockscreen wallpapers, produced a scenario where
keyguard was correctly thinking it should be visible but was not
always telling WM. This left the device in a state with just a blank
screen, behaving in a manner like it was occluded by another activity.

Always tell WM that sysui is showing, as there should be no harm in
telling it again (just in case).

Fixes: 301409430
Fixes: 300899918
Test: race condition - Enable 2 different wallpapers on
home/lockscreen, setup sidefps, authenticate, and slam the power
button over and over. This is easier to accomplish if you disabling
the double-tap camera launch gesture

Change-Id: I5c7137dfcf20fb27c697a60df21141d15979e03e
---
 .../com/android/systemui/keyguard/KeyguardViewMediator.java   | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 9241776191d4..f47e6159e817 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -3231,7 +3231,11 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
                         + "mPendingLock=" + mPendingLock + "."
                         + "One of these being false means we re-locked the device during unlock. "
                         + "Do not proceed to finish keyguard exit and unlock.");
+                doKeyguardLocked(null);
                 finishSurfaceBehindRemoteAnimation(true /* showKeyguard */);
+                // Ensure WM is notified that we made a decision to show
+                setShowingLocked(true /* showing */, true /* force */);
+
                 return;
             }
 
-- 
GitLab


From 1063ac01cbd6e0f7b24107152593102b40caa1d4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A1s=20Kurucz?= <kurucz@google.com>
Date: Fri, 22 Sep 2023 08:06:08 +0000
Subject: [PATCH 78/95] Make BigPictureIconManager reload the image on each
 icon update

This way we reload the URI every time a BigPicture Notification is
reinflated, which means that when the system theme changes the app is
given an opportunity to provide a version of the image for the current
system theme. This matches the behaviour before the lazy loading.

Bug: 283082473
Test: atest BigPictureIconManager
Change-Id: I54cf91bd42f0eb760774caf88005150f0a4cec3d
---
 .../notification/row/BigPictureIconManager.kt | 15 ------
 .../row/BigPictureIconManagerTest.kt          | 46 ++++++++++++++++++-
 2 files changed, 45 insertions(+), 16 deletions(-)

diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BigPictureIconManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BigPictureIconManager.kt
index ba1e6dd8ca4a..a5b32b8d4fa7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BigPictureIconManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BigPictureIconManager.kt
@@ -120,12 +120,6 @@ constructor(
             return Runnable {}
         }
 
-        if (displayedState.iconSameAs(icon)) {
-            // We're already handling this icon, nothing to do here.
-            log("skipping updateIcon for consumer:$drawableConsumer with icon:$icon")
-            return Runnable {}
-        }
-
         this.drawableConsumer = drawableConsumer
         this.displayedState = Empty(icon)
         this.lastLoadingJob?.cancel()
@@ -256,15 +250,6 @@ constructor(
         data class PlaceHolder(override val icon: Icon, val drawableSize: Size) :
             DrawableState(icon)
         data class FullImage(override val icon: Icon, val drawableSize: Size) : DrawableState(icon)
-
-        fun iconSameAs(other: Icon?): Boolean {
-            val displayedIcon = icon
-            return when {
-                displayedIcon == null && other == null -> true
-                displayedIcon != null && other != null -> displayedIcon.sameAs(other)
-                else -> false
-            }
-        }
     }
 }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt
index e7bcf3f0201f..311b16cff808 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt
@@ -111,6 +111,16 @@ class BigPictureIconManagerTest : SysuiTestCase() {
             assertSize(drawableCaptor.value)
         }
 
+    @Test
+    fun onIconUpdated_withNull_drawableIsNull() =
+        testScope.runTest {
+            // WHEN update with null
+            iconManager.updateIcon(mockConsumer, null).run()
+
+            // THEN consumer is updated with null
+            verify(mockConsumer).setImageDrawable(null)
+        }
+
     @Test
     fun onIconUpdated_invalidIcon_drawableIsNull() =
         testScope.runTest {
@@ -152,6 +162,24 @@ class BigPictureIconManagerTest : SysuiTestCase() {
             assertSize(drawableCaptor.value)
         }
 
+    @Test
+    fun onIconUpdated_iconAlreadySetForTheSameIcon_loadsIconAgain() =
+        testScope.runTest {
+            // GIVEN an icon is set
+            iconManager.updateIcon(mockConsumer, supportedIcon).run()
+            // AND the view is shown
+            iconManager.onViewShown(true)
+            runCurrent()
+            reset(mockConsumer)
+            // WHEN the icon is set again
+            iconManager.updateIcon(mockConsumer, supportedIcon).run()
+
+            // THEN consumer is updated with the new image
+            verify(mockConsumer).setImageDrawable(drawableCaptor.capture())
+            assertIsFullImage(drawableCaptor.value)
+            assertSize(drawableCaptor.value)
+        }
+
     @Test
     fun onIconUpdated_iconAlreadySetForUnsupportedIcon_loadsNewIcon() =
         testScope.runTest {
@@ -159,6 +187,7 @@ class BigPictureIconManagerTest : SysuiTestCase() {
             iconManager.updateIcon(mockConsumer, unsupportedIcon).run()
             // AND the view is shown
             iconManager.onViewShown(true)
+            runCurrent()
             reset(mockConsumer)
 
             // WHEN a new icon is set
@@ -170,7 +199,7 @@ class BigPictureIconManagerTest : SysuiTestCase() {
             assertSize(drawableCaptor.value)
         }
 
-        @Test
+    @Test
     fun onIconUpdated_supportedTypeButTooWide_resizedPlaceholderLoaded() =
         testScope.runTest {
             // GIVEN the max width is smaller than our image
@@ -282,6 +311,21 @@ class BigPictureIconManagerTest : SysuiTestCase() {
             verifyZeroInteractions(mockConsumer)
         }
 
+    @Test
+    fun onViewShown_nullSetForIcon_nothingHappens() =
+        testScope.runTest {
+            // GIVEN null is set for the icon
+            iconManager.updateIcon(mockConsumer, null).run()
+            reset(mockConsumer)
+
+            // WHEN the view is shown
+            iconManager.onViewShown(true)
+            runCurrent()
+
+            // THEN nothing happens
+            verifyZeroInteractions(mockConsumer)
+        }
+
     @Test
     fun onViewHidden_unsupportedIconLoadedAndViewIsShown_nothingHappens() =
         testScope.runTest {
-- 
GitLab


From ee321a75b81a120b0831e834fed08eb378993e79 Mon Sep 17 00:00:00 2001
From: petsjonkin <petsjonkin@google.com>
Date: Mon, 18 Sep 2023 17:21:20 +0000
Subject: [PATCH 79/95] HdrClamper using feature flag and configuration

Bug: b/283447291
Test: atest HdrClamperTest
Change-Id: I441f2f91ee294c7bb90eca7afaccded64a9ea734
---
 .../display/BrightnessRangeController.java    | 27 ++++--
 .../brightness/clamper/HdrClamper.java        | 96 +++++++++++--------
 .../display/config/HdrBrightnessData.java     |  5 +-
 .../display/feature/DisplayManagerFlags.java  |  8 ++
 .../display/feature/display_flags.aconfig     | 10 +-
 .../display/DisplayPowerController2Test.java  | 37 ++++++-
 .../brightness/clamper/HdrClamperTest.java    | 16 +++-
 7 files changed, 142 insertions(+), 57 deletions(-)

diff --git a/services/core/java/com/android/server/display/BrightnessRangeController.java b/services/core/java/com/android/server/display/BrightnessRangeController.java
index 21273e0f2785..13ee47eb91c8 100644
--- a/services/core/java/com/android/server/display/BrightnessRangeController.java
+++ b/services/core/java/com/android/server/display/BrightnessRangeController.java
@@ -19,6 +19,7 @@ package com.android.server.display;
 import android.hardware.display.BrightnessInfo;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.PowerManager;
 
 import com.android.server.display.brightness.clamper.HdrClamper;
 import com.android.server.display.feature.DisplayManagerFlags;
@@ -52,17 +53,26 @@ class BrightnessRangeController {
             HdrClamper hdrClamper, DisplayManagerFlags flags) {
         mHbmController = hbmController;
         mModeChangeCallback = modeChangeCallback;
-        mUseHdrClamper = false;
-        mUseNbmController = flags.isNbmControllerEnabled();
-        mNormalBrightnessModeController.resetNbmData(displayDeviceConfig.getLuxThrottlingData());
         mHdrClamper = hdrClamper;
+        mUseHdrClamper = flags.isHdrClamperEnabled();
+        mUseNbmController = flags.isNbmControllerEnabled();
+        if (mUseNbmController) {
+            mNormalBrightnessModeController.resetNbmData(
+                    displayDeviceConfig.getLuxThrottlingData());
+        }
+        if (mUseHdrClamper) {
+            mHdrClamper.resetHdrConfig(displayDeviceConfig.getHdrBrightnessData());
+        }
+
     }
 
     void dump(PrintWriter pw) {
         pw.println("BrightnessRangeController:");
         pw.println("  mUseNormalBrightnessController=" + mUseNbmController);
+        pw.println("  mUseHdrClamper=" + mUseHdrClamper);
         mHbmController.dump(pw);
         mNormalBrightnessModeController.dump(pw);
+        mHdrClamper.dump(pw);
     }
 
     void onAmbientLuxChange(float ambientLux) {
@@ -91,6 +101,9 @@ class BrightnessRangeController {
                             displayDeviceConfig::getHdrBrightnessFromSdr);
                 }
         );
+        if (mUseHdrClamper) {
+            mHdrClamper.resetHdrConfig(displayDeviceConfig.getHdrBrightnessData());
+        }
     }
 
     void stop() {
@@ -128,8 +141,10 @@ class BrightnessRangeController {
     }
 
     float getHdrBrightnessValue() {
-        float hdrBrightness =  mHbmController.getHdrBrightnessValue();
-        return Math.min(hdrBrightness, mHdrClamper.getMaxBrightness());
+        float hdrBrightness = mHbmController.getHdrBrightnessValue();
+        float brightnessMax = mUseHdrClamper ? mHdrClamper.getMaxBrightness()
+                : PowerManager.BRIGHTNESS_MAX;
+        return Math.min(hdrBrightness, brightnessMax);
     }
 
     float getTransitionPoint() {
@@ -151,6 +166,6 @@ class BrightnessRangeController {
     }
 
     public float getHdrTransitionRate() {
-        return mHdrClamper.getTransitionRate();
+        return mUseHdrClamper ? mHdrClamper.getTransitionRate() : -1;
     }
 }
diff --git a/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java b/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java
index 079a196234a8..a514136e62a2 100644
--- a/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java
+++ b/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java
@@ -16,40 +16,41 @@
 
 package com.android.server.display.brightness.clamper;
 
+import android.annotation.Nullable;
 import android.os.Handler;
 import android.os.PowerManager;
 
-import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.display.config.HdrBrightnessData;
 
-import java.util.HashMap;
+import java.io.PrintWriter;
 import java.util.Map;
 
 public class HdrClamper {
 
-    private final Configuration mConfiguration = new Configuration();
-
     private final BrightnessClamperController.ClamperChangeListener mClamperChangeListener;
 
     private final Handler mHandler;
 
     private final Runnable mDebouncer;
 
-    private float mMaxBrightness = PowerManager.BRIGHTNESS_MAX;
+    @Nullable
+    private HdrBrightnessData mHdrBrightnessData = null;
 
-    // brightness change speed, in units per seconds,
-    private float mTransitionRate = -1f;
+    private float mAmbientLux = Float.MAX_VALUE;
 
+    private float mMaxBrightness = PowerManager.BRIGHTNESS_MAX;
     private float mDesiredMaxBrightness = PowerManager.BRIGHTNESS_MAX;
 
-    private float mDesiredTransitionDuration = -1; // in seconds
+    // brightness change speed, in units per seconds,
+    private float mTransitionRate = -1f;
+    private float mDesiredTransitionRate = -1f;
 
     public HdrClamper(BrightnessClamperController.ClamperChangeListener clamperChangeListener,
             Handler handler) {
         mClamperChangeListener = clamperChangeListener;
         mHandler = handler;
         mDebouncer = () -> {
-            mTransitionRate = Math.abs((mMaxBrightness - mDesiredMaxBrightness)
-                    / mDesiredTransitionDuration);
+            mTransitionRate = mDesiredTransitionRate;
             mMaxBrightness = mDesiredMaxBrightness;
             mClamperChangeListener.onChanged();
         };
@@ -65,46 +66,74 @@ public class HdrClamper {
         return mTransitionRate;
     }
 
-
     /**
      * Updates brightness cap in response to ambient lux change.
      * Called by ABC in same looper: mHandler.getLooper()
      */
     public void onAmbientLuxChange(float ambientLux) {
-        float expectedMaxBrightness = findBrightnessLimit(ambientLux);
+        mAmbientLux = ambientLux;
+        recalculateBrightnessCap(mHdrBrightnessData, ambientLux);
+    }
+
+    /**
+     * Updates brightness cap config.
+     * Called in same looper: mHandler.getLooper()
+     */
+    public void resetHdrConfig(HdrBrightnessData data) {
+        mHdrBrightnessData = data;
+        recalculateBrightnessCap(data, mAmbientLux);
+    }
+
+    /**
+     * Dumps the state of HdrClamper.
+     */
+    public void dump(PrintWriter pw) {
+        pw.println("HdrClamper:");
+        pw.println("  mMaxBrightness=" + mMaxBrightness);
+        pw.println("  mDesiredMaxBrightness=" + mDesiredMaxBrightness);
+        pw.println("  mTransitionRate=" + mTransitionRate);
+        pw.println("  mDesiredTransitionRate=" + mDesiredTransitionRate);
+        pw.println("  mHdrBrightnessData=" + (mHdrBrightnessData == null ? "null"
+                : mHdrBrightnessData.toString()));
+        pw.println("  mAmbientLux=" + mAmbientLux);
+    }
+
+    private void recalculateBrightnessCap(HdrBrightnessData data, float ambientLux) {
+        if (data == null) {
+            mHandler.removeCallbacks(mDebouncer);
+            return;
+        }
+        float expectedMaxBrightness = findBrightnessLimit(data, ambientLux);
+
         if (mMaxBrightness == expectedMaxBrightness) {
             mDesiredMaxBrightness = mMaxBrightness;
-            mDesiredTransitionDuration = -1;
+            mDesiredTransitionRate = -1f;
             mTransitionRate = -1f;
             mHandler.removeCallbacks(mDebouncer);
         } else if (mDesiredMaxBrightness != expectedMaxBrightness) {
             mDesiredMaxBrightness = expectedMaxBrightness;
             long debounceTime;
+            long transitionDuration;
             if (mDesiredMaxBrightness > mMaxBrightness) {
-                debounceTime = mConfiguration.mIncreaseConfig.mDebounceTimeMillis;
-                mDesiredTransitionDuration =
-                        (float) mConfiguration.mIncreaseConfig.mTransitionTimeMillis / 1000;
+                debounceTime = mHdrBrightnessData.mBrightnessIncreaseDebounceMillis;
+                transitionDuration = mHdrBrightnessData.mBrightnessIncreaseDurationMillis;
             } else {
-                debounceTime = mConfiguration.mDecreaseConfig.mDebounceTimeMillis;
-                mDesiredTransitionDuration =
-                        (float) mConfiguration.mDecreaseConfig.mTransitionTimeMillis / 1000;
+                debounceTime = mHdrBrightnessData.mBrightnessDecreaseDebounceMillis;
+                transitionDuration = mHdrBrightnessData.mBrightnessDecreaseDurationMillis;
             }
+            mDesiredTransitionRate = Math.abs(
+                    (mMaxBrightness - mDesiredMaxBrightness) * 1000f / transitionDuration);
 
             mHandler.removeCallbacks(mDebouncer);
             mHandler.postDelayed(mDebouncer, debounceTime);
         }
     }
 
-    @VisibleForTesting
-    Configuration getConfiguration() {
-        return mConfiguration;
-    }
-
-    private float findBrightnessLimit(float ambientLux) {
+    private float findBrightnessLimit(HdrBrightnessData data, float ambientLux) {
         float foundAmbientBoundary = Float.MAX_VALUE;
         float foundMaxBrightness = PowerManager.BRIGHTNESS_MAX;
         for (Map.Entry<Float, Float> brightnessPoint :
-                mConfiguration.mMaxBrightnessLimits.entrySet()) {
+                data.mMaxBrightnessLimits.entrySet()) {
             float ambientBoundary = brightnessPoint.getKey();
             // find ambient lux upper boundary closest to current ambient lux
             if (ambientBoundary > ambientLux && ambientBoundary < foundAmbientBoundary) {
@@ -114,19 +143,4 @@ public class HdrClamper {
         }
         return foundMaxBrightness;
     }
-
-    @VisibleForTesting
-    static class Configuration {
-        final Map<Float, Float> mMaxBrightnessLimits = new HashMap<>();
-        final TransitionConfiguration mIncreaseConfig = new TransitionConfiguration();
-
-        final TransitionConfiguration mDecreaseConfig = new TransitionConfiguration();
-    }
-
-    @VisibleForTesting
-    static class TransitionConfiguration {
-        long mDebounceTimeMillis;
-
-        long mTransitionTimeMillis;
-    }
 }
diff --git a/services/core/java/com/android/server/display/config/HdrBrightnessData.java b/services/core/java/com/android/server/display/config/HdrBrightnessData.java
index 06d3c5b87520..48d671d356f7 100644
--- a/services/core/java/com/android/server/display/config/HdrBrightnessData.java
+++ b/services/core/java/com/android/server/display/config/HdrBrightnessData.java
@@ -18,6 +18,8 @@ package com.android.server.display.config;
 
 import android.annotation.Nullable;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -52,7 +54,8 @@ public class HdrBrightnessData {
      */
     public final long mBrightnessDecreaseDurationMillis;
 
-    private HdrBrightnessData(Map<Float, Float> maxBrightnessLimits,
+    @VisibleForTesting
+    public HdrBrightnessData(Map<Float, Float> maxBrightnessLimits,
             long brightnessIncreaseDebounceMillis, long brightnessIncreaseDurationMillis,
             long brightnessDecreaseDebounceMillis, long brightnessDecreaseDurationMillis) {
         mMaxBrightnessLimits = maxBrightnessLimits;
diff --git a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
index aebd8a08ee3f..d23c4fe91c84 100644
--- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
+++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
@@ -39,6 +39,10 @@ public class DisplayManagerFlags {
             Flags.FLAG_ENABLE_NBM_CONTROLLER,
             Flags::enableNbmController);
 
+    private final FlagState mHdrClamperFlagState = new FlagState(
+            Flags.FLAG_ENABLE_HDR_CLAMPER,
+            Flags::enableHdrClamper);
+
     /** Returns whether connected display management is enabled or not. */
     public boolean isConnectedDisplayManagementEnabled() {
         return mConnectedDisplayManagementFlagState.isEnabled();
@@ -49,6 +53,10 @@ public class DisplayManagerFlags {
         return mNbmControllerFlagState.isEnabled();
     }
 
+    public boolean isHdrClamperEnabled() {
+        return mHdrClamperFlagState.isEnabled();
+    }
+
     private static class FlagState {
 
         private final String mName;
diff --git a/services/core/java/com/android/server/display/feature/display_flags.aconfig b/services/core/java/com/android/server/display/feature/display_flags.aconfig
index 12306b039225..ce64bd389839 100644
--- a/services/core/java/com/android/server/display/feature/display_flags.aconfig
+++ b/services/core/java/com/android/server/display/feature/display_flags.aconfig
@@ -14,6 +14,14 @@ flag {
     name: "enable_nbm_controller"
     namespace: "display_manager"
     description: "Feature flag for Normal Brightness Mode Controller"
-    bug: "277877297"
+    bug: "299527549"
+    is_fixed_read_only: true
+}
+
+flag {
+    name: "enable_hdr_clamper"
+    namespace: "display_manager"
+    description: "Feature flag for HDR Clamper"
+    bug: "295100043"
     is_fixed_read_only: true
 }
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java
index d6b2c8732e50..85406b5d12dd 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java
@@ -1256,9 +1256,35 @@ public final class DisplayPowerController2Test {
     }
 
     @Test
-    public void testRampRateForHdrContent() {
+    public void testRampRateForHdrContent_HdrClamperOff() {
+        float hdrBrightness = 0.8f;
         float clampedBrightness = 0.6f;
-        float transitionRate = 35.5f;
+        float transitionRate = 1.5f;
+
+        DisplayPowerRequest dpr = new DisplayPowerRequest();
+        when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
+        when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(.2f);
+        when(mHolder.displayPowerState.getSdrScreenBrightness()).thenReturn(.1f);
+        when(mHolder.hbmController.getHighBrightnessMode()).thenReturn(
+                BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR);
+        when(mHolder.hbmController.getHdrBrightnessValue()).thenReturn(hdrBrightness);
+        when(mHolder.hdrClamper.getMaxBrightness()).thenReturn(clampedBrightness);
+        when(mHolder.hdrClamper.getTransitionRate()).thenReturn(transitionRate);
+
+        mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        advanceTime(1); // Run updatePowerState
+
+        verify(mHolder.animator, atLeastOnce()).animateTo(eq(hdrBrightness), anyFloat(),
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
+    }
+
+    @Test
+    public void testRampRateForHdrContent_HdrClamperOn() {
+        float clampedBrightness = 0.6f;
+        float transitionRate = 1.5f;
+        DisplayManagerFlags flags = mock(DisplayManagerFlags.class);
+        when(flags.isHdrClamperEnabled()).thenReturn(true);
+        mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID, /* isEnabled= */ true, flags);
 
         DisplayPowerRequest dpr = new DisplayPowerRequest();
         when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
@@ -1361,6 +1387,12 @@ public final class DisplayPowerController2Test {
 
     private DisplayPowerControllerHolder createDisplayPowerController(int displayId,
             String uniqueId, boolean isEnabled) {
+        return createDisplayPowerController(displayId, uniqueId, isEnabled,
+                mock(DisplayManagerFlags.class));
+    }
+
+    private DisplayPowerControllerHolder createDisplayPowerController(int displayId,
+            String uniqueId, boolean isEnabled, DisplayManagerFlags flags) {
         final DisplayPowerState displayPowerState = mock(DisplayPowerState.class);
         final DualRampAnimator<DisplayPowerState> animator = mock(DualRampAnimator.class);
         final AutomaticBrightnessController automaticBrightnessController =
@@ -1373,7 +1405,6 @@ public final class DisplayPowerController2Test {
                 mock(ScreenOffBrightnessSensorController.class);
         final HighBrightnessModeController hbmController = mock(HighBrightnessModeController.class);
         final HdrClamper hdrClamper = mock(HdrClamper.class);
-        final DisplayManagerFlags flags = mock(DisplayManagerFlags.class);
 
         when(hbmController.getCurrentBrightnessMax()).thenReturn(PowerManager.BRIGHTNESS_MAX);
 
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java
index 0ebe46ac0c88..37d966d044c5 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java
@@ -24,6 +24,7 @@ import android.os.PowerManager;
 
 import androidx.test.filters.SmallTest;
 
+import com.android.server.display.config.HdrBrightnessData;
 import com.android.server.testutils.OffsettableClock;
 import com.android.server.testutils.TestHandler;
 
@@ -34,6 +35,8 @@ import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 
+import java.util.Map;
+
 @SmallTest
 public class HdrClamperTest {
 
@@ -108,10 +111,13 @@ public class HdrClamperTest {
     }
 
     private void configureClamper() {
-        mHdrClamper.getConfiguration().mMaxBrightnessLimits.put(500f, 0.6f);
-        mHdrClamper.getConfiguration().mIncreaseConfig.mDebounceTimeMillis = 1000;
-        mHdrClamper.getConfiguration().mIncreaseConfig.mTransitionTimeMillis = 1500;
-        mHdrClamper.getConfiguration().mDecreaseConfig.mDebounceTimeMillis = 2000;
-        mHdrClamper.getConfiguration().mDecreaseConfig.mTransitionTimeMillis = 2500;
+        HdrBrightnessData data = new HdrBrightnessData(
+                Map.of(500f, 0.6f),
+                /* brightnessIncreaseDebounceMillis= */ 1000,
+                /* brightnessIncreaseDurationMillis= */ 1500,
+                /* brightnessDecreaseDebounceMillis= */ 2000,
+                /* brightnessDecreaseDurationMillis= */2500
+        );
+        mHdrClamper.resetHdrConfig(data);
     }
 }
-- 
GitLab


From 2aaeb2542b71bee6b5cceeeb1cf293a152cca43a Mon Sep 17 00:00:00 2001
From: Beverly <beverlyt@google.com>
Date: Thu, 21 Sep 2023 19:41:57 +0000
Subject: [PATCH 80/95] Manually control the animation LS => bouncer when
 dragging

Set the animator to null instead of using the
default animator. The animation wasn't being properly set back to
the lockscreen when the bouncer dragging was quickly abandoned
since the default animator was being used instead of the
manual animation.

Test: manual
Test: atest KeyguardTransitionScenariosTest
Fixes: 299172035

Change-Id: Ic66eb13e7ac0101031622104500d2ebeb85b4032
---
 .../FromLockscreenTransitionInteractor.kt     |  6 +-
 .../KeyguardTransitionScenariosTest.kt        | 60 ++++++++++++++++++-
 .../FakeKeyguardTransitionRepository.kt       |  2 +-
 3 files changed, 64 insertions(+), 4 deletions(-)

diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
index 9c6a1b1b6cc0..8f3943133eb1 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
@@ -265,7 +265,11 @@ constructor(
                                 !isKeyguardUnlocked &&
                                 statusBarState == KEYGUARD
                         ) {
-                            transitionId = startTransitionTo(KeyguardState.PRIMARY_BOUNCER)
+                            transitionId =
+                                startTransitionTo(
+                                    toState = KeyguardState.PRIMARY_BOUNCER,
+                                    animator = null, // transition will be manually controlled
+                                )
                         }
                     }
                 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
index d4576053f9c7..f2636c543844 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
@@ -32,6 +32,7 @@ import com.android.systemui.keyguard.shared.model.BiometricUnlockModel
 import com.android.systemui.keyguard.shared.model.DozeStateModel
 import com.android.systemui.keyguard.shared.model.DozeTransitionModel
 import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.StatusBarState
 import com.android.systemui.keyguard.shared.model.TransitionInfo
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
@@ -39,11 +40,12 @@ import com.android.systemui.keyguard.shared.model.WakeSleepReason
 import com.android.systemui.keyguard.shared.model.WakefulnessModel
 import com.android.systemui.keyguard.shared.model.WakefulnessState
 import com.android.systemui.shade.data.repository.FakeShadeRepository
-import com.android.systemui.shade.data.repository.ShadeRepository
+import com.android.systemui.shade.domain.model.ShadeModel
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.mockito.withArgCaptor
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.cancelChildren
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.advanceUntilIdle
@@ -56,6 +58,7 @@ import org.junit.runners.JUnit4
 import org.mockito.ArgumentMatchers.anyBoolean
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Mock
+import org.mockito.Mockito.clearInvocations
 import org.mockito.Mockito.never
 import org.mockito.Mockito.reset
 import org.mockito.Mockito.spy
@@ -66,6 +69,7 @@ import org.mockito.MockitoAnnotations
  * Class for testing user journeys through the interactors. They will all be activated during setup,
  * to ensure the expected transitions are still triggered.
  */
+@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(JUnit4::class)
 class KeyguardTransitionScenariosTest : SysuiTestCase() {
@@ -74,7 +78,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
     private lateinit var keyguardRepository: FakeKeyguardRepository
     private lateinit var bouncerRepository: FakeKeyguardBouncerRepository
     private lateinit var commandQueue: FakeCommandQueue
-    private lateinit var shadeRepository: ShadeRepository
+    private lateinit var shadeRepository: FakeShadeRepository
     private lateinit var transitionRepository: FakeKeyguardTransitionRepository
     private lateinit var transitionInteractor: KeyguardTransitionInteractor
     private lateinit var featureFlags: FakeFeatureFlags
@@ -1213,6 +1217,58 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
             coroutineContext.cancelChildren()
         }
 
+    @Test
+    fun lockscreenToPrimaryBouncerDragging() =
+        testScope.runTest {
+            // GIVEN a prior transition has run to LOCKSCREEN
+            runTransition(KeyguardState.AOD, KeyguardState.LOCKSCREEN)
+            runCurrent()
+
+            // GIVEN the keyguard is showing locked
+            keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
+            keyguardRepository.setKeyguardUnlocked(false)
+            runCurrent()
+            shadeRepository.setShadeModel(
+                ShadeModel(
+                    expansionAmount = .9f,
+                    isUserDragging = true,
+                )
+            )
+            runCurrent()
+
+            // THEN a transition from LOCKSCREEN => PRIMARY_BOUNCER should occur
+            val info =
+                withArgCaptor<TransitionInfo> {
+                    verify(transitionRepository).startTransition(capture(), anyBoolean())
+                }
+            assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor")
+            assertThat(info.from).isEqualTo(KeyguardState.LOCKSCREEN)
+            assertThat(info.to).isEqualTo(KeyguardState.PRIMARY_BOUNCER)
+            assertThat(info.animator).isNull() // dragging should be manually animated
+
+            // WHEN the user stops dragging and shade is back to expanded
+            clearInvocations(transitionRepository)
+            runTransition(KeyguardState.LOCKSCREEN, KeyguardState.PRIMARY_BOUNCER)
+            shadeRepository.setShadeModel(
+                ShadeModel(
+                    expansionAmount = 1f,
+                    isUserDragging = false,
+                )
+            )
+            runCurrent()
+
+            // THEN a transition from PRIMARY_BOUNCER => LOCKSCREEN should occur
+            val info2 =
+                withArgCaptor<TransitionInfo> {
+                    verify(transitionRepository).startTransition(capture(), anyBoolean())
+                }
+            assertThat(info2.from).isEqualTo(KeyguardState.PRIMARY_BOUNCER)
+            assertThat(info2.to).isEqualTo(KeyguardState.LOCKSCREEN)
+            assertThat(info2.animator).isNotNull()
+
+            coroutineContext.cancelChildren()
+        }
+
     private fun startingToWake() =
         WakefulnessModel(
             WakefulnessState.STARTING_TO_WAKE,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt
index 16442bb525b6..dd513db03d34 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt
@@ -38,7 +38,7 @@ class FakeKeyguardTransitionRepository : KeyguardTransitionRepository {
     }
 
     override fun startTransition(info: TransitionInfo, resetIfCanceled: Boolean): UUID? {
-        return null
+        return if (info.animator == null) UUID.randomUUID() else null
     }
 
     override fun updateTransition(
-- 
GitLab


From e51c36f0570146859e9d7272648a06899756b669 Mon Sep 17 00:00:00 2001
From: Santiago Seifert <aquilescanta@google.com>
Date: Fri, 22 Sep 2023 12:35:27 +0000
Subject: [PATCH 81/95] Add mShouldPerformActiveScan to
 RouteDiscoveryPreference#dump

Bug: 205124386
Change-Id: Ia9457568662e2014d0d831667f9ebc0f59069d61
Test: adb shell dumpsys media_router
---
 media/java/android/media/RouteDiscoveryPreference.java | 1 +
 1 file changed, 1 insertion(+)

diff --git a/media/java/android/media/RouteDiscoveryPreference.java b/media/java/android/media/RouteDiscoveryPreference.java
index 71d8261b09bf..161fd2fb7f96 100644
--- a/media/java/android/media/RouteDiscoveryPreference.java
+++ b/media/java/android/media/RouteDiscoveryPreference.java
@@ -194,6 +194,7 @@ public final class RouteDiscoveryPreference implements Parcelable {
 
         String indent = prefix + "  ";
 
+        pw.println(indent + "mShouldPerformActiveScan=" + mShouldPerformActiveScan);
         pw.println(indent + "mPreferredFeatures=" + mPreferredFeatures);
         pw.println(indent + "mPackageOrder=" + mPackageOrder);
         pw.println(indent + "mAllowedPackages=" + mAllowedPackages);
-- 
GitLab


From f324a0d84fc3e46f3f1c80f9e02a07bde256a4d7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Aur=C3=A9lien=20Pomini?= <pomini@google.com>
Date: Tue, 29 Aug 2023 13:05:21 +0000
Subject: [PATCH 82/95] =?UTF-8?q?WallpaperManager=20clear=20API=C2=A0chang?=
 =?UTF-8?q?es?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The goal is to align WallpaperManager#clear with
WallpaperManager#clearWallpaper.

There are two changes:
 - clear(FLAG_SYSTEM) will no longer clear both wallpapers, it will only
 clear the FLAG_SYSTEM wallpaper (and migrate it to the lock screen if it
 is a shared wallpaper)

 - clear() and clear(which) will always set the default wallpaper
 defined for the device. They won't set an ImageWallpaper unless it's the
 default wallpaper.

Bug: 295176688
Test: atest WallpaperManagerTest

Change-Id: I48a83b13eed9a5035f00405f679baf0163bd217d
---
 core/java/android/app/WallpaperManager.java | 28 +++++++++++++--------
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index c31aa01a6b7c..fce5e4f1fd21 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -2429,11 +2429,8 @@ public class WallpaperManager {
     }
 
     /**
-     * Reset all wallpaper to the factory default. As opposed to {@link #clear()}, if the device
-     * is configured to have a live wallpaper by default, apply it.
-     *
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#SET_WALLPAPER}.
+     * Equivalent to {@link #clear()}.
+     * @see #clear()
      */
     @RequiresPermission(android.Manifest.permission.SET_WALLPAPER)
     public void clearWallpaper() {
@@ -2767,8 +2764,7 @@ public class WallpaperManager {
 
     /**
      * Remove any currently set system wallpaper, reverting to the system's built-in
-     * wallpaper. As opposed to {@link #clearWallpaper()}, this method always set a static wallpaper
-     * with the default image, even if the device is configured to have a live wallpaper by default.
+     * wallpaper.
      * On success, the intent {@link Intent#ACTION_WALLPAPER_CHANGED} is broadcast.
      *
      * <p>This method requires the caller to hold the permission
@@ -2779,6 +2775,10 @@ public class WallpaperManager {
      */
     @RequiresPermission(android.Manifest.permission.SET_WALLPAPER)
     public void clear() throws IOException {
+        if (isLockscreenLiveWallpaperEnabled()) {
+            clear(FLAG_SYSTEM | FLAG_LOCK);
+            return;
+        }
         setStream(openDefaultWallpaper(mContext, FLAG_SYSTEM), null, false);
     }
 
@@ -2787,10 +2787,15 @@ public class WallpaperManager {
      * display for each one. On success, the intent {@link Intent#ACTION_WALLPAPER_CHANGED}
      * is broadcast.
      * <ul>
-     *     <li> If {@link #FLAG_SYSTEM} is set in the {@code which} parameter, put the default
-     *     wallpaper on both home and lock screen, removing any user defined wallpaper. </li>
      *     <li> When called with {@code which=}{@link #FLAG_LOCK}, clear the lockscreen wallpaper.
      *     The home screen wallpaper will become visible on the lock screen. </li>
+     *
+     *     <li> When called with {@code which=}{@link #FLAG_SYSTEM}, revert the home screen
+     *     wallpaper to default. The lockscreen wallpaper will be unchanged: if the previous
+     *     wallpaper was shared between home and lock screen, it will become lock screen only. </li>
+     *
+     *     <li> When called with {@code which=}({@link #FLAG_LOCK} | {@link #FLAG_SYSTEM}), put the
+     *     default wallpaper on both home and lock screen, removing any user defined wallpaper.</li>
      * </ul>
      *
      * @param which A bitwise combination of {@link #FLAG_SYSTEM} or
@@ -2799,9 +2804,12 @@ public class WallpaperManager {
      */
     @RequiresPermission(android.Manifest.permission.SET_WALLPAPER)
     public void clear(@SetWallpaperFlags int which) throws IOException {
+        if (isLockscreenLiveWallpaperEnabled()) {
+            clearWallpaper(which, mContext.getUserId());
+            return;
+        }
         if ((which & FLAG_SYSTEM) != 0) {
             clear();
-            if (isLockscreenLiveWallpaperEnabled()) return;
         }
         if ((which & FLAG_LOCK) != 0) {
             clearWallpaper(FLAG_LOCK, mContext.getUserId());
-- 
GitLab


From 4272c4c6461523e98cac4a4ad117ec6a0c187689 Mon Sep 17 00:00:00 2001
From: Shaquille Johnson <ssjohnson@google.com>
Date: Thu, 21 Sep 2023 15:50:37 +0100
Subject: [PATCH 83/95] Add aconfig for biometrics flags

Bug: 282058146
Test: Treehugger
Change-Id: Idd66455b28cc61e53c68f559244ad2d022cf65d3
---
 AconfigFlags.bp                                    | 14 ++++++++++++++
 .../java/android/hardware/biometrics/flags.aconfig |  9 +++++++++
 2 files changed, 23 insertions(+)
 create mode 100644 core/java/android/hardware/biometrics/flags.aconfig

diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 3abaa69270ef..0ec68d7f94e8 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -21,6 +21,7 @@ aconfig_srcjars = [
     ":android.view.flags-aconfig-java{.generated_srcjars}",
     ":camera_platform_flags_core_java_lib{.generated_srcjars}",
     ":com.android.window.flags.window-aconfig-java{.generated_srcjars}",
+    ":android.hardware.biometrics.flags-aconfig-java{.generated_srcjars}",
     ":com.android.hardware.input-aconfig-java{.generated_srcjars}",
     ":com.android.text.flags-aconfig-java{.generated_srcjars}",
     ":telecom_flags_core_java_lib{.generated_srcjars}",
@@ -271,6 +272,19 @@ java_aconfig_library {
     defaults: ["framework-minus-apex-aconfig-java-defaults"],
 }
 
+// Biometrics
+aconfig_declarations {
+    name: "android.hardware.biometrics.flags-aconfig",
+    package: "android.hardware.biometrics",
+    srcs: ["core/java/android/hardware/biometrics/flags.aconfig"],
+}
+
+java_aconfig_library {
+    name: "android.hardware.biometrics.flags-aconfig-java",
+    aconfig_declarations: "android.hardware.biometrics.flags-aconfig",
+    defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
+
 // Graphics
 java_aconfig_library {
     name: "hwui_flags_java_lib",
diff --git a/core/java/android/hardware/biometrics/flags.aconfig b/core/java/android/hardware/biometrics/flags.aconfig
new file mode 100644
index 000000000000..66429e5046d8
--- /dev/null
+++ b/core/java/android/hardware/biometrics/flags.aconfig
@@ -0,0 +1,9 @@
+package: "android.hardware.biometrics"
+
+flag {
+  name: "add_key_agreement_crypto_object"
+  namespace: "biometrics"
+  description: "Feature flag for adding KeyAgreement api to CryptoObject."
+  bug: "282058146"
+}
+
-- 
GitLab


From aabd499a8719ea19238c048dab2df3f9590fd1d9 Mon Sep 17 00:00:00 2001
From: Hawkwood Glazier <jglazier@google.com>
Date: Thu, 21 Sep 2023 18:53:25 +0000
Subject: [PATCH 84/95] Attempt to reload providers when selected provider is
 available but unloaded

A more minor race may still be present, but this fix should
reduce incidence of the issue and be safer than reorganizing
the multithreading in verifyLoadedProviders. A subsequent
change will address that more directly.

Bug: 300671811
Test: Manually forced and checked race condition
Change-Id: I5258dddd50b9c89f28340254c53bc1839351e28e
---
 .../com/android/systemui/shared/clocks/ClockRegistry.kt  | 9 ++++++++-
 .../android/systemui/shared/plugins/PluginInstance.java  | 2 +-
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
index fd4a723352e4..ecc0dbad70d0 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
@@ -148,7 +148,7 @@ open class ClockRegistry(
             override fun onPluginAttached(
                 manager: PluginLifecycleManager<ClockProviderPlugin>
             ): Boolean {
-                manager.isDebug = true
+                manager.isDebug = !keepAllLoaded
 
                 if (keepAllLoaded) {
                     // Always load new plugins if requested
@@ -511,6 +511,12 @@ open class ClockRegistry(
     fun verifyLoadedProviders() {
         val shouldSchedule = isVerifying.compareAndSet(false, true)
         if (!shouldSchedule) {
+            logger.tryLog(
+                TAG,
+                LogLevel.VERBOSE,
+                {},
+                { "verifyLoadedProviders: shouldSchedule=false" }
+            )
             return
         }
 
@@ -670,6 +676,7 @@ open class ClockRegistry(
                     { str1 = clockId },
                     { "Clock $str1 not loaded; using default" }
                 )
+                verifyLoadedProviders()
             } else {
                 logger.tryLog(
                     TAG,
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstance.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstance.java
index 7719e95b9416..f9f2c63c0469 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstance.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstance.java
@@ -73,7 +73,7 @@ public class PluginInstance<T extends Plugin> implements PluginLifecycleManager
         mComponentName = componentName;
         mPluginFactory = pluginFactory;
         mPlugin = plugin;
-        mTag = TAG + mComponentName.toShortString()
+        mTag = TAG + "[" + mComponentName.getShortClassName() + "]"
                 + '@' + Integer.toHexString(hashCode());
 
         if (mPlugin != null) {
-- 
GitLab


From e17d87347d611e52d022bbf246c933a2222a1ed7 Mon Sep 17 00:00:00 2001
From: Eghosa Ewansiha-Vlachavas <eevlachavas@google.com>
Date: Wed, 20 Sep 2023 19:50:53 +0000
Subject: [PATCH 85/95] [3/n] Optimize user aspect ratio button heuristic

If `updateCompatInfo` is called while the user aspect ratio button is
showing, the buton will be removed as we no longer consider the layout
to have a button as it has already been shown.

Update `getHasUserAspectRatioSettingsButton` so the layout is consider
to have a button for the duration the button is visible and only once
the button has been shown and timed out, will the layout be considered
to not have a button.

Test: atest WMShellUnitTests:UserAspectRatioSettingsWindowManagerTest
Bug: 301323072
Bug: 289356588
Change-Id: Ie4be836d52b74e285a501a799094022be24870fe
---
 .../UserAspectRatioSettingsWindowManager.java |  8 +++-
 ...rAspectRatioSettingsWindowManagerTest.java | 43 ++++++++++++++++++-
 2 files changed, 48 insertions(+), 3 deletions(-)

diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManager.java
index 96470012af03..c2dec623416b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManager.java
@@ -192,6 +192,12 @@ class UserAspectRatioSettingsWindowManager extends CompatUIWindowManagerAbstract
         }
     }
 
+    @VisibleForTesting
+    boolean isShowingButton() {
+        return (mUserAspectRatioButtonShownChecker.get()
+                && !isHideDelayReached(mNextButtonHideTimeMs));
+    }
+
     private void showUserAspectRatioButton() {
         if (mLayout == null) {
             return;
@@ -224,7 +230,7 @@ class UserAspectRatioSettingsWindowManager extends CompatUIWindowManagerAbstract
         return taskInfo.topActivityEligibleForUserAspectRatioButton
                 && (taskInfo.topActivityBoundsLetterboxed
                     || taskInfo.isUserFullscreenOverrideEnabled)
-                && !mUserAspectRatioButtonShownChecker.get();
+                && (!mUserAspectRatioButtonShownChecker.get() || isShowingButton());
     }
 
     private long getDisappearTimeMs() {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java
index 2a9b72a0bc49..5a4d6c812c17 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java
@@ -36,6 +36,7 @@ import android.content.ComponentName;
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
 import android.util.Pair;
 import android.view.DisplayInfo;
 import android.view.InsetsSource;
@@ -66,6 +67,7 @@ import org.mockito.MockitoAnnotations;
 import java.util.HashSet;
 import java.util.Set;
 import java.util.function.BiConsumer;
+import java.util.function.Supplier;
 
 /**
  * Tests for {@link UserAspectRatioSettingsWindowManager}.
@@ -74,6 +76,7 @@ import java.util.function.BiConsumer;
  *  atest WMShellUnitTests:UserAspectRatioSettingsWindowManagerTest
  */
 @RunWith(AndroidTestingRunner.class)
+@RunWithLooper
 @SmallTest
 public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase {
 
@@ -81,6 +84,8 @@ public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase {
 
     @Mock private SyncTransactionQueue mSyncTransactionQueue;
     @Mock
+    private Supplier<Boolean> mUserAspectRatioButtonShownChecker;
+    @Mock
     private BiConsumer<TaskInfo, ShellTaskOrganizer.TaskListener>
             mOnUserAspectRatioSettingsButtonClicked;
     @Mock private ShellTaskOrganizer.TaskListener mTaskListener;
@@ -106,11 +111,12 @@ public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase {
                 false, /* topActivityBoundsLetterboxed */ true);
         mWindowManager = new UserAspectRatioSettingsWindowManager(mContext, mTaskInfo,
                 mSyncTransactionQueue, mTaskListener, new DisplayLayout(), new CompatUIHintsState(),
-                mOnUserAspectRatioSettingsButtonClicked, mExecutor, flags -> 0, () -> false,
-                s -> {});
+                mOnUserAspectRatioSettingsButtonClicked, mExecutor, flags -> 0,
+                mUserAspectRatioButtonShownChecker, s -> {});
         spyOn(mWindowManager);
         doReturn(mLayout).when(mWindowManager).inflateLayout();
         doReturn(mViewHost).when(mWindowManager).createSurfaceViewHost();
+        doReturn(false).when(mUserAspectRatioButtonShownChecker).get();
     }
 
     @Test
@@ -293,6 +299,39 @@ public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase {
         verify(mLayout).setVisibility(View.VISIBLE);
     }
 
+    @Test
+    public void testLayoutHasUserAspectRatioSettingsButton() {
+        clearInvocations(mWindowManager);
+        spyOn(mWindowManager);
+        TaskInfo taskInfo = createTaskInfo(/* eligibleForUserAspectRatioButton= */
+                true, /* topActivityBoundsLetterboxed */ true);
+
+        // User aspect ratio settings button has not yet been shown.
+        doReturn(false).when(mUserAspectRatioButtonShownChecker).get();
+
+        // Check the layout has the user aspect ratio settings button.
+        mWindowManager.updateCompatInfo(taskInfo, mTaskListener, /* canShow= */ true);
+        assertTrue(mWindowManager.mHasUserAspectRatioSettingsButton);
+
+        // User aspect ratio settings button has been shown and is still visible.
+        spyOn(mWindowManager);
+        doReturn(true).when(mWindowManager).isShowingButton();
+        doReturn(true).when(mUserAspectRatioButtonShownChecker).get();
+
+        // Check the layout still has the user aspect ratio settings button.
+        mWindowManager.updateCompatInfo(taskInfo, mTaskListener, /* canShow= */ true);
+        assertTrue(mWindowManager.mHasUserAspectRatioSettingsButton);
+
+        // User aspect ratio settings button has been shown and has timed out so is no longer
+        // visible.
+        doReturn(false).when(mWindowManager).isShowingButton();
+        doReturn(true).when(mUserAspectRatioButtonShownChecker).get();
+
+        // Check the layout no longer has the user aspect ratio button.
+        mWindowManager.updateCompatInfo(taskInfo, mTaskListener, /* canShow= */ true);
+        assertFalse(mWindowManager.mHasUserAspectRatioSettingsButton);
+    }
+
     @Test
     public void testAttachToParentSurface() {
         final SurfaceControl.Builder b = new SurfaceControl.Builder();
-- 
GitLab


From dd87ba45c6e04bbabb1d3b8a68a7495a8cdd3c5c Mon Sep 17 00:00:00 2001
From: Vishnu Nair <vishnun@google.com>
Date: Thu, 21 Sep 2023 21:58:03 -0700
Subject: [PATCH 86/95] Denoise hermetric surfaceflinger perf tests

Remove overheard by disabling features during the test including:
- perfetto tracing
- region sampling by hiding navbar
- transaction tracing

Reduce variations between each frame by
- forcing max frame rate (avoids any frame misses)
- consuming transform hint (avoids gpu comp)
- starting simpleperf after test setup to move test activity
launch outside of measurement window

Test: atest android.surfaceflinger.SurfaceFlingerPerfTest
Bug: 298240242
Change-Id: Ida7422c37b9afa323147949c9776c042ca97cd08
---
 .../perftests/surfaceflinger/Android.bp       |  1 +
 .../surfaceflinger/AndroidManifest.xml        |  4 +-
 .../perftests/surfaceflinger/AndroidTest.xml  | 11 +--
 .../android/surfaceflinger/BufferFlinger.java | 22 ++++--
 .../SurfaceFlingerPerfTest.java               | 68 +++++++++++++++++--
 .../SurfaceFlingerTestActivity.java           | 15 ++++
 6 files changed, 100 insertions(+), 21 deletions(-)

diff --git a/apct-tests/perftests/surfaceflinger/Android.bp b/apct-tests/perftests/surfaceflinger/Android.bp
index 0c28bcef469c..21d0d44fdd2f 100644
--- a/apct-tests/perftests/surfaceflinger/Android.bp
+++ b/apct-tests/perftests/surfaceflinger/Android.bp
@@ -32,6 +32,7 @@ android_test {
         "apct-perftests-utils",
         "collector-device-lib",
         "platform-test-annotations",
+        "cts-wm-util",
     ],
     test_suites: ["device-tests"],
     data: [":perfetto_artifacts"],
diff --git a/apct-tests/perftests/surfaceflinger/AndroidManifest.xml b/apct-tests/perftests/surfaceflinger/AndroidManifest.xml
index 26f25863f055..aa55b01cc787 100644
--- a/apct-tests/perftests/surfaceflinger/AndroidManifest.xml
+++ b/apct-tests/perftests/surfaceflinger/AndroidManifest.xml
@@ -16,9 +16,11 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="android.perftests.surfaceflinger">
 
-    <!-- permission needed to write perfetto trace and read/write simpleperf report -->
+    <!-- permission needed to read/write simpleperf report -->
     <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <!-- permission needed to disable tracing -->
+    <uses-permission android:name="android.permission.HARDWARE_TEST" />
 
     <application android:label="SurfaceFlingerPerfTests">
         <uses-library android:name="android.test.runner" />
diff --git a/apct-tests/perftests/surfaceflinger/AndroidTest.xml b/apct-tests/perftests/surfaceflinger/AndroidTest.xml
index 58cf58b89782..6dcd86e156d9 100644
--- a/apct-tests/perftests/surfaceflinger/AndroidTest.xml
+++ b/apct-tests/perftests/surfaceflinger/AndroidTest.xml
@@ -44,17 +44,12 @@
         <option name="hidden-api-checks" value="false"/>
 
         <!-- Listener related args for collecting the traces and waiting for the device to stabilize. -->
-        <option name="device-listeners" value="android.device.collectors.ProcLoadListener,android.device.collectors.PerfettoListener,android.device.collectors.SimpleperfListener" />
-
-        <!-- Guarantee that user defined RunListeners will be running before any of the default listeners defined in this runner. -->
-        <option name="instrumentation-arg" key="newRunListenerMode" value="true" />
+        <option name="device-listeners" value="android.device.collectors.ProcLoadListener,android.device.collectors.SimpleperfListener" />
 
         <option name="instrumentation-arg" key="profiling-iterations" value="525" />
-        <!-- PerfettoListener related arguments -->
-        <option name="instrumentation-arg" key="perfetto_config_text_proto" value="true" />
-        <option name="instrumentation-arg" key="perfetto_config_file" value="trace_config.textproto" />
 
         <!-- SimpleperfListener related arguments -->
+        <option name="instrumentation-arg" key="record" value="false"/>
         <option name="instrumentation-arg" key="report" value="true" />
         <option name="instrumentation-arg" key="arguments" value="-g" />
         <option name="instrumentation-arg" key="events_to_record" value="instructions,cpu-cycles,raw-l3d-cache-refill,sched:sched_waking" />
@@ -70,13 +65,11 @@
         <option name="instrumentation-arg" key="proc-loadavg-threshold" value="3" />
         <option name="instrumentation-arg" key="proc-loadavg-timeout" value="120000" />
         <option name="instrumentation-arg" key="proc-loadavg-interval" value="10000" />
-
     </test>
 
     <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
         <option name="directory-keys" value="/data/local/tmp/SurfaceFlingerPerfTests" />
         <!-- Needed for pulling the collected trace config on to the host -->
-        <option name="pull-pattern-keys" value="perfetto_file_path" />
         <option name="pull-pattern-keys" value="simpleperf_file_path" />
     </metrics_collector>
 
diff --git a/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/BufferFlinger.java b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/BufferFlinger.java
index 8a447bb801f2..8d6dd127645f 100644
--- a/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/BufferFlinger.java
+++ b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/BufferFlinger.java
@@ -16,6 +16,10 @@
 
 package android.surfaceflinger;
 
+import static android.view.SurfaceControl.BUFFER_TRANSFORM_IDENTITY;
+import static android.view.SurfaceControl.BUFFER_TRANSFORM_ROTATE_270;
+import static android.view.SurfaceControl.BUFFER_TRANSFORM_ROTATE_90;
+
 import android.annotation.ColorInt;
 import android.graphics.Canvas;
 import android.graphics.GraphicBuffer;
@@ -33,9 +37,11 @@ import java.util.concurrent.ArrayBlockingQueue;
  * @hide
  */
 public class BufferFlinger {
+    private final int mTransformHint;
     ArrayBlockingQueue<GraphicBuffer> mBufferQ;
 
-    public BufferFlinger(int numOfBuffers, @ColorInt int color) {
+    public BufferFlinger(int numOfBuffers, @ColorInt int color, int bufferTransformHint) {
+        mTransformHint = bufferTransformHint;
         mBufferQ = new ArrayBlockingQueue<>(numOfBuffers);
 
         while (numOfBuffers > 0) {
@@ -56,12 +62,18 @@ public class BufferFlinger {
     public void addBuffer(SurfaceControl.Transaction t, SurfaceControl surfaceControl) {
         try {
             final GraphicBuffer buffer = mBufferQ.take();
-            t.setBuffer(surfaceControl,
+            int transform = BUFFER_TRANSFORM_IDENTITY;
+            if (mTransformHint == BUFFER_TRANSFORM_ROTATE_90) {
+                transform = BUFFER_TRANSFORM_ROTATE_270;
+            } else if (mTransformHint == BUFFER_TRANSFORM_ROTATE_270) {
+                transform = BUFFER_TRANSFORM_ROTATE_90;
+            }
+            t.setBufferTransform(surfaceControl, transform);
+            t.setBuffer(
+                    surfaceControl,
                     HardwareBuffer.createFromGraphicBuffer(buffer),
                     null,
-                    (SyncFence fence) -> {
-                        releaseCallback(fence, buffer);
-                    });
+                    (SyncFence fence) -> releaseCallback(fence, buffer));
         } catch (InterruptedException ignore) {
         }
     }
diff --git a/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerPerfTest.java b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerPerfTest.java
index dca818ec9708..fd9d99181fbf 100644
--- a/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerPerfTest.java
+++ b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerPerfTest.java
@@ -16,6 +16,9 @@
 
 package android.surfaceflinger;
 
+import static android.server.wm.CtsWindowInfoUtils.waitForWindowOnTop;
+
+import android.app.Instrumentation;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -25,12 +28,13 @@ import android.view.SurfaceControl;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 
-
 import androidx.test.ext.junit.rules.ActivityScenarioRule;
 import androidx.test.filters.LargeTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.helpers.SimpleperfHelper;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -39,6 +43,8 @@ import org.junit.Test;
 import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 
+import java.io.IOException;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Random;
 
@@ -63,12 +69,33 @@ public class SurfaceFlingerPerfTest {
     public final RuleChain mAllRules = RuleChain
             .outerRule(mActivityRule);
 
+    private int mTransformHint;
+    private SimpleperfHelper mSimpleperfHelper = new SimpleperfHelper();
+
+    /** Start simpleperf sampling. */
+    public void startSimpleperf(String subcommand, String arguments) {
+        if (!mSimpleperfHelper.startCollecting(subcommand, arguments)) {
+            Log.e(TAG, "Simpleperf did not start successfully.");
+        }
+    }
+
+    /** Stop simpleperf sampling and dump the collected file into the given path. */
+    private void stopSimpleperf(Path path) {
+        if (!mSimpleperfHelper.stopCollecting(path.toString())) {
+            Log.e(TAG, "Failed to collect the simpleperf output.");
+        }
+    }
+
     @BeforeClass
     public static void suiteSetup() {
         final Bundle arguments = InstrumentationRegistry.getArguments();
         sProfilingIterations = Integer.parseInt(
                 arguments.getString(ARGUMENT_PROFILING_ITERATIONS, DEFAULT_PROFILING_ITERATIONS));
         Log.d(TAG, "suiteSetup: mProfilingIterations = " + sProfilingIterations);
+        // disable transaction tracing
+        InstrumentationRegistry.getInstrumentation()
+                .getUiAutomation()
+                .executeShellCommand("service call SurfaceFlinger 1041 i32 -1");
     }
 
     @Before
@@ -77,17 +104,45 @@ public class SurfaceFlingerPerfTest {
         SurfaceControl.Transaction t = new SurfaceControl.Transaction();
         for (int i = 0; i < MAX_BUFFERS; i++) {
             SurfaceControl sc = createSurfaceControl();
-            BufferFlinger bufferTracker = createBufferTracker(Color.argb(getRandomColorComponent(),
-                    getRandomColorComponent(), getRandomColorComponent(),
-                    getRandomColorComponent()));
+            BufferFlinger bufferTracker =
+                    createBufferTracker(
+                            Color.argb(
+                                    getRandomColorComponent(),
+                                    getRandomColorComponent(),
+                                    getRandomColorComponent(),
+                                    getRandomColorComponent()),
+                            mActivity.getBufferTransformHint());
             bufferTracker.addBuffer(t, sc);
             t.setPosition(sc, i * 10, i * 10);
         }
         t.apply(true);
+        mBufferTrackers.get(0).addBuffer(mTransaction, mSurfaceControls.get(0));
+        mTransaction.show(mSurfaceControls.get(0)).apply(true);
+        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+
+        instrumentation.waitForIdleSync();
+        // Wait for device animation that shows above the activity to leave.
+        try {
+            waitForWindowOnTop(mActivity.getWindow());
+        } catch (InterruptedException e) {
+            Log.e(TAG, "Failed to wait for window", e);
+        }
+        String args =
+                "-o /data/local/tmp/perf.data -g -e"
+                    + " instructions,cpu-cycles,raw-l3d-cache-refill,sched:sched_waking -p "
+                        + mSimpleperfHelper.getPID("surfaceflinger")
+                        + ","
+                        + mSimpleperfHelper.getPID("android.perftests.surfaceflinger");
+        startSimpleperf("record", args);
     }
 
     @After
     public void teardown() {
+        try {
+            mSimpleperfHelper.stopSimpleperf();
+        } catch (IOException e) {
+            Log.e(TAG, "Failed to stop simpleperf", e);
+        }
         mSurfaceControls.forEach(SurfaceControl::release);
         mBufferTrackers.forEach(BufferFlinger::freeBuffers);
     }
@@ -97,8 +152,9 @@ public class SurfaceFlingerPerfTest {
     }
 
     private final ArrayList<BufferFlinger> mBufferTrackers = new ArrayList<>();
-    private BufferFlinger createBufferTracker(int color) {
-        BufferFlinger bufferTracker = new BufferFlinger(BUFFER_COUNT, color);
+
+    private BufferFlinger createBufferTracker(int color, int bufferTransformHint) {
+        BufferFlinger bufferTracker = new BufferFlinger(BUFFER_COUNT, color, bufferTransformHint);
         mBufferTrackers.add(bufferTracker);
         return bufferTracker;
     }
diff --git a/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerTestActivity.java b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerTestActivity.java
index bb956596c7eb..5f1f44d826e5 100644
--- a/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerTestActivity.java
+++ b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerTestActivity.java
@@ -16,12 +16,15 @@
 
 package android.surfaceflinger;
 
+import static android.view.Surface.FRAME_RATE_COMPATIBILITY_DEFAULT;
+
 import android.app.Activity;
 import android.content.Context;
 import android.os.Bundle;
 import android.view.SurfaceControl;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
+import android.view.View;
 import android.view.Window;
 import android.view.WindowManager;
 
@@ -42,6 +45,11 @@ public class SurfaceFlingerTestActivity extends Activity {
         requestWindowFeature(Window.FEATURE_NO_TITLE);
         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                 WindowManager.LayoutParams.FLAG_FULLSCREEN);
+        View decorView = getWindow().getDecorView();
+        // Hide both the navigation bar and the status bar.
+        int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN;
+        decorView.setSystemUiVisibility(uiOptions);
+
         getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
         mTestSurfaceView = new TestSurfaceView(this);
         setContentView(mTestSurfaceView);
@@ -51,6 +59,10 @@ public class SurfaceFlingerTestActivity extends Activity {
         return mTestSurfaceView.getChildSurfaceControlHelper();
     }
 
+    public int getBufferTransformHint() {
+        return mTestSurfaceView.getRootSurfaceControl().getBufferTransformHint();
+    }
+
     public class TestSurfaceView extends SurfaceView {
         public TestSurfaceView(Context context) {
             super(context);
@@ -79,6 +91,9 @@ public class SurfaceFlingerTestActivity extends Activity {
             // check to see if surface is valid
             if (holder.getSurface().isValid()) {
                 mSurfaceControl = getSurfaceControl();
+                new SurfaceControl.Transaction()
+                        .setFrameRate(mSurfaceControl, 1000, FRAME_RATE_COMPATIBILITY_DEFAULT)
+                        .apply(true);
             }
             return new SurfaceControl.Builder()
                     .setName("ChildSurfaceControl")
-- 
GitLab


From 0fe6689f092aed6c312278d1b04ba8f8743fe032 Mon Sep 17 00:00:00 2001
From: Charles Wang <charlesswang@google.com>
Date: Fri, 15 Sep 2023 16:19:57 +0000
Subject: [PATCH 87/95] Save dialog changes so that buttons are shown in
 landscape - screenshots at http://shortn/_n52tNerWx6 Test: locally tested on
 pixel/foldable/tablet Bug: b/290785192

Change-Id: I6b6d2dd9f43964e97bc7db2c050e5919b4f02916
---
 core/res/res/layout/autofill_fill_dialog.xml  |   2 +-
 core/res/res/layout/autofill_save.xml         |  84 +++++++-------
 core/res/res/values-sw640dp/dimens.xml        |  20 ++++
 core/res/res/values-w640dp/bools.xml          |  21 ++++
 core/res/res/values-w640dp/dimens.xml         |  20 ++++
 core/res/res/values/bools.xml                 |   2 +
 core/res/res/values/dimens.xml                |   5 +-
 core/res/res/values/symbols.xml               |   5 +
 .../server/autofill/ui/BottomSheetLayout.java | 108 ++++++++++++++++++
 .../android/server/autofill/ui/SaveUi.java    |   8 --
 10 files changed, 226 insertions(+), 49 deletions(-)
 create mode 100644 core/res/res/values-sw640dp/dimens.xml
 create mode 100644 core/res/res/values-w640dp/bools.xml
 create mode 100644 core/res/res/values-w640dp/dimens.xml
 create mode 100644 services/autofill/java/com/android/server/autofill/ui/BottomSheetLayout.java

diff --git a/core/res/res/layout/autofill_fill_dialog.xml b/core/res/res/layout/autofill_fill_dialog.xml
index 37d2fa0540f0..196af6dfb6df 100644
--- a/core/res/res/layout/autofill_fill_dialog.xml
+++ b/core/res/res/layout/autofill_fill_dialog.xml
@@ -27,7 +27,7 @@
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:gravity="center_horizontal"
-        android:layout_marginTop="@dimen/autofill_save_outer_top_margin"
+        android:layout_marginTop="@dimen/autofill_save_outer_margin"
         android:layout_marginBottom="24dp"
         android:layout_marginStart="24dp"
         android:layout_marginEnd="24dp"
diff --git a/core/res/res/layout/autofill_save.xml b/core/res/res/layout/autofill_save.xml
index bed19a87eb16..8b6c90141bb7 100644
--- a/core/res/res/layout/autofill_save.xml
+++ b/core/res/res/layout/autofill_save.xml
@@ -22,59 +22,66 @@
     android:background="@drawable/autofill_bottomsheet_background"
     android:orientation="vertical">
 
-    <LinearLayout
+    <com.android.server.autofill.ui.BottomSheetLayout
         android:id="@+id/autofill_save"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
-        android:layout_marginTop="@dimen/autofill_save_outer_top_margin"
-        android:layout_marginStart="24dp"
-        android:layout_marginEnd="24dp"
+        android:layout_marginTop="@dimen/autofill_save_outer_margin"
         android:background="?android:attr/colorSurface"
         android:gravity="center_horizontal"
         android:orientation="vertical">
-
-        <LinearLayout
+        <ScrollView
             android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:orientation="vertical">
-
-            <ImageView
-                android:id="@+id/autofill_save_icon"
-                android:scaleType="fitCenter"
-                android:layout_gravity="center"
-                android:layout_height="@dimen/autofill_save_icon_max_height"
-                android:layout_width="fill_parent"/>
-
-            <TextView
-                android:id="@+id/autofill_save_title"
+            android:layout_height="0dp"
+            android:fillViewport="true"
+            android:layout_weight="1"
+            android:layout_marginBottom="8dp">
+            <LinearLayout
+                android:layout_marginStart="@dimen/autofill_save_outer_margin"
+                android:layout_marginEnd="@dimen/autofill_save_outer_margin"
                 android:layout_width="fill_parent"
+                android:orientation="vertical"
                 android:layout_height="wrap_content"
-                android:text="@string/autofill_save_title"
-                android:layout_marginTop="16dp"
-                android:paddingBottom="24dp"
-                android:gravity="center"
-                android:textAppearance="@style/AutofillSaveUiTitle">
-            </TextView>
-
-            <com.android.server.autofill.ui.CustomScrollView
-                android:id="@+id/autofill_save_custom_subtitle"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:visibility="gone"/>
-
-        </LinearLayout>
+                >
+                <ImageView
+                    android:id="@+id/autofill_save_icon"
+                    android:scaleType="fitCenter"
+                    android:layout_gravity="center"
+                    android:layout_height="@dimen/autofill_save_icon_max_height"
+                    android:layout_width="fill_parent"/>
+
+                <TextView
+                    android:id="@+id/autofill_save_title"
+                    android:layout_width="fill_parent"
+                    android:layout_height="wrap_content"
+                    android:text="@string/autofill_save_title"
+                    android:layout_marginTop="16dp"
+                    android:paddingBottom="24dp"
+                    android:gravity="center"
+                    android:textAppearance="@style/AutofillSaveUiTitle">
+                </TextView>
+                <LinearLayout
+                    android:id="@+id/autofill_save_custom_subtitle"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:visibility="gone"/>
+
+            </LinearLayout>
+        </ScrollView>
 
         <com.android.internal.widget.ButtonBarLayout
             android:layout_width="match_parent"
             android:layout_height="48dp"
             android:layout_gravity="end"
             android:clipToPadding="false"
-            android:layout_marginTop="32dp"
-            android:layout_marginBottom="18dp"
+            android:layout_marginTop="16dp"
+            android:layout_marginBottom="8dp"
             android:theme="@style/Theme.DeviceDefault.AutofillHalfScreenDialogButton"
             android:orientation="horizontal"
-            android:gravity="center_vertical">
-
+            android:gravity="center_vertical"
+            android:layout_marginStart="@dimen/autofill_save_outer_margin"
+            android:layout_marginEnd="@dimen/autofill_save_outer_margin"
+            >
             <Button
                 android:id="@+id/autofill_save_no"
                 android:layout_width="wrap_content"
@@ -106,6 +113,5 @@
 
         </com.android.internal.widget.ButtonBarLayout>
 
-    </LinearLayout>
-
-</LinearLayout>
+    </com.android.server.autofill.ui.BottomSheetLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/values-sw640dp/dimens.xml b/core/res/res/values-sw640dp/dimens.xml
new file mode 100644
index 000000000000..c632176ba1dd
--- /dev/null
+++ b/core/res/res/values-sw640dp/dimens.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 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.
+  -->
+<resources>
+    <!-- Top and side margins for autofill dialog on tablets -->
+    <dimen name="autofill_save_outer_margin">32dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/core/res/res/values-w640dp/bools.xml b/core/res/res/values-w640dp/bools.xml
new file mode 100644
index 000000000000..64b20f7eaa96
--- /dev/null
+++ b/core/res/res/values-w640dp/bools.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 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.
+  -->
+
+<resources>
+    <!-- Whether or not to include horizontal space around the dialog -->
+    <bool name="autofill_dialog_horizontal_space_included">true</bool>
+</resources>
\ No newline at end of file
diff --git a/core/res/res/values-w640dp/dimens.xml b/core/res/res/values-w640dp/dimens.xml
new file mode 100644
index 000000000000..1f0c0b878610
--- /dev/null
+++ b/core/res/res/values-w640dp/dimens.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 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.
+  -->
+<resources>
+    <!-- How much extra space should be left around the autofill dialog -->
+    <dimen name="autofill_dialog_offset">56dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/core/res/res/values/bools.xml b/core/res/res/values/bools.xml
index fe296c704095..b097a613ebc1 100644
--- a/core/res/res/values/bools.xml
+++ b/core/res/res/values/bools.xml
@@ -30,4 +30,6 @@
          lockscreen, setting this to true should come with customized drawables. -->
     <bool name="use_lock_pattern_drawable">false</bool>
     <bool name="resolver_landscape_phone">true</bool>
+    <!-- Whether or not to include horizontal space around the dialog -->
+    <bool name="autofill_dialog_horizontal_space_included">false</bool>
 </resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index b129321008d8..190b7a62e2e0 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -871,7 +871,7 @@
     <dimen name="autofill_dataset_picker_max_height">90%</dimen>
 
     <!-- Autofill save dialog padding -->
-    <dimen name="autofill_save_outer_top_margin">24dp</dimen>
+    <dimen name="autofill_save_outer_margin">24dp</dimen>
     <dimen name="autofill_save_outer_top_padding">16dp</dimen>
     <dimen name="autofill_elevation">32dp</dimen>
     <dimen name="autofill_save_inner_padding">16dp</dimen>
@@ -882,6 +882,9 @@
     <dimen name="autofill_save_button_bar_padding">16dp</dimen>
     <dimen name="autofill_dialog_corner_radius">24dp</dimen>
 
+    <!-- How much extra space should be left around the autofill dialog -->
+    <dimen name="autofill_dialog_offset">72dp</dimen>
+
     <!-- Max height of the the autofill save custom subtitle as a fraction of the screen width/height -->
     <dimen name="autofill_save_custom_subtitle_max_height">20%</dimen>
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index be43a4fc238d..e661eda96a02 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3629,6 +3629,7 @@
   <java-symbol type="layout" name="autofill_dataset_picker_fullscreen"/>
   <java-symbol type="layout" name="autofill_dataset_picker_header_footer"/>
   <java-symbol type="layout" name="autofill_fill_dialog"/>
+  <java-symbol type="id" name="autofill_save_icon"/>
   <java-symbol type="id" name="autofill" />
   <java-symbol type="id" name="autofill_dataset_footer"/>
   <java-symbol type="id" name="autofill_dataset_header"/>
@@ -3685,6 +3686,10 @@
   <java-symbol type="dimen" name="autofill_save_custom_subtitle_max_height"/>
   <java-symbol type="integer" name="autofill_max_visible_datasets" />
   <java-symbol type="dimen" name="autofill_dialog_max_width" />
+  <java-symbol type="dimen" name="autofill_dialog_offset"/>
+  <java-symbol type="dimen" name="autofill_save_outer_margin"/>
+
+  <java-symbol type="bool" name="autofill_dialog_horizontal_space_included"/>
 
   <java-symbol type="style" name="Theme.DeviceDefault.Autofill" />
   <java-symbol type="style" name="Theme.DeviceDefault.Light.Autofill" />
diff --git a/services/autofill/java/com/android/server/autofill/ui/BottomSheetLayout.java b/services/autofill/java/com/android/server/autofill/ui/BottomSheetLayout.java
new file mode 100644
index 000000000000..06bbc2b0bdcb
--- /dev/null
+++ b/services/autofill/java/com/android/server/autofill/ui/BottomSheetLayout.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2023 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.autofill.ui;
+
+import static com.android.server.autofill.Helper.sDebug;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.Slog;
+import android.widget.LinearLayout;
+
+import com.android.internal.R;
+
+/**
+ {@link LinearLayout} that displays content of save dialog.
+ */
+public class BottomSheetLayout extends LinearLayout {
+
+    private static final String TAG = "BottomSheetLayout";
+
+    public BottomSheetLayout(Context context) {
+        super(context);
+    }
+
+    public BottomSheetLayout(Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public BottomSheetLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    @Override
+    public void onMeasure(int widthSpec, int heightSpec) {
+        if (getContext() == null || getContext().getResources() == null) {
+            super.onMeasure(widthSpec, heightSpec);
+            Slog.w(TAG, "onMeasure failed due to missing context or missing resources.");
+            return;
+        }
+
+        if (getChildCount() == 0) {
+            // Should not happen
+            super.onMeasure(widthSpec, heightSpec);
+            Slog.wtf(TAG, "onMeasure failed due to missing children views.");
+            return;
+        }
+
+        DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
+
+        final int pxOffset = getContext().getResources().getDimensionPixelSize(
+                R.dimen.autofill_dialog_offset);
+        final int outerMargin = getContext().getResources().getDimensionPixelSize(
+                R.dimen.autofill_save_outer_margin);
+
+        final boolean includeHorizontalSpace =
+                getContext().getResources().getBoolean(
+                        R.bool.autofill_dialog_horizontal_space_included);
+
+
+        final int screenHeight = displayMetrics.heightPixels;
+        final int screenWidth = displayMetrics.widthPixels;
+
+        final int maxHeight = screenHeight - pxOffset - outerMargin;
+
+        int maxWidth = screenWidth;
+
+        if (includeHorizontalSpace) {
+            maxWidth -= 2 * pxOffset;
+        }
+
+        maxWidth =
+                Math.min(maxWidth, getContext().getResources().getDimensionPixelSize(
+                        R.dimen.autofill_dialog_max_width));
+
+        super.onMeasure(MeasureSpec.makeMeasureSpec(maxWidth, MeasureSpec.EXACTLY),
+                MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST));
+
+
+        if (sDebug) {
+            Slog.d(TAG, "onMeasure() values in dp:"
+                    + " screenHeight: " + screenHeight / displayMetrics.density + ", screenWidth: "
+                    + screenWidth / displayMetrics.density
+                    + ", maxHeight: " + maxHeight / displayMetrics.density
+                    + ", maxWidth: " + maxWidth / displayMetrics.density + ", getMeasuredWidth(): "
+                    + getMeasuredWidth() / displayMetrics.density + ", getMeasuredHeight(): "
+                    + getMeasuredHeight() / displayMetrics.density);
+        }
+        setMeasuredDimension(getMeasuredWidth(), getMeasuredHeight());
+    }
+
+
+}
diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
index 70382f1d5274..3581db238ff3 100644
--- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
@@ -48,7 +48,6 @@ import android.text.TextUtils;
 import android.text.method.LinkMovementMethod;
 import android.text.style.ClickableSpan;
 import android.util.ArraySet;
-import android.util.DisplayMetrics;
 import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -363,13 +362,6 @@ final class SaveUi {
         window.setCloseOnTouchOutside(true);
         final WindowManager.LayoutParams params = window.getAttributes();
 
-        DisplayMetrics displayMetrics = new DisplayMetrics();
-        window.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
-        final int screenWidth = displayMetrics.widthPixels;
-        final int maxWidth =
-                context.getResources().getDimensionPixelSize(R.dimen.autofill_dialog_max_width);
-        params.width = Math.min(screenWidth, maxWidth);
-
         params.accessibilityTitle = context.getString(R.string.autofill_save_accessibility_title);
         params.windowAnimations = R.style.AutofillSaveAnimation;
         params.setTrustedOverlay();
-- 
GitLab


From d544c6464094353b9e45a591ab89d75e4ae59234 Mon Sep 17 00:00:00 2001
From: Juan Sebastian Martinez <juansmartinez@google.com>
Date: Fri, 18 Aug 2023 13:50:21 -0700
Subject: [PATCH 88/95] Introducing the Slider State Listener components for
 sliders in SysUI.

The interface for a slider listener as well as its implementation are
introduced. The implementation represents the haptic provider that plays
haptics on slider events.

Test: atest SliderHapticFeedbackProviderTest
Bug: 295932558
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:13ee3310de4da0901648dfa801e9822c0c886e24)

Change-Id: Ie0b6ae9a262a7a79e9d92ae2a420cf12cf44af7a
---
 .../slider/SliderHapticFeedbackConfig.kt      |  43 +++
 .../slider/SliderHapticFeedbackProvider.kt    | 160 ++++++++++++
 .../haptics/slider/SliderStateListener.kt     |  64 +++++
 .../systemui/statusbar/VibratorHelper.java    |  21 ++
 .../SliderHapticFeedbackProviderTest.kt       | 247 ++++++++++++++++++
 .../systemui/statusbar/VibratorHelperTest.kt  |  12 +
 6 files changed, 547 insertions(+)
 create mode 100644 packages/SystemUI/src/com/android/systemui/haptics/slider/SliderHapticFeedbackConfig.kt
 create mode 100644 packages/SystemUI/src/com/android/systemui/haptics/slider/SliderHapticFeedbackProvider.kt
 create mode 100644 packages/SystemUI/src/com/android/systemui/haptics/slider/SliderStateListener.kt
 create mode 100644 packages/SystemUI/tests/src/com/android/systemui/haptics/slider/SliderHapticFeedbackProviderTest.kt

diff --git a/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderHapticFeedbackConfig.kt b/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderHapticFeedbackConfig.kt
new file mode 100644
index 000000000000..20d99d1e75fb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderHapticFeedbackConfig.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 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.haptics.slider
+
+import androidx.annotation.FloatRange
+
+/** Configuration parameters of a [SliderHapticFeedbackProvider] */
+data class SliderHapticFeedbackConfig(
+    /** Interpolator factor for velocity-based vibration scale interpolations. Must be positive */
+    val velocityInterpolatorFactor: Float = 1f,
+    /** Interpolator factor for progress-based vibration scale interpolations. Must be positive */
+    val progressInterpolatorFactor: Float = 1f,
+    /** Minimum vibration scale for vibrations based on slider progress */
+    @FloatRange(from = 0.0, to = 1.0) val progressBasedDragMinScale: Float = 0f,
+    /** Maximum vibration scale for vibrations based on slider progress */
+    @FloatRange(from = 0.0, to = 1.0) val progressBasedDragMaxScale: Float = 0.2f,
+    /** Additional vibration scaling due to velocity */
+    @FloatRange(from = 0.0, to = 1.0) val additionalVelocityMaxBump: Float = 0.15f,
+    /** Additional time delta to wait between drag texture vibrations */
+    @FloatRange(from = 0.0) val deltaMillisForDragInterval: Float = 0f,
+    /** Number of low ticks in a drag texture composition. This is not expected to change */
+    val numberOfLowTicks: Int = 5,
+    /** Maximum velocity allowed for vibration scaling. This is not expected to change. */
+    val maxVelocityToScale: Float = 2000f, /* In pixels/sec */
+    /** Vibration scale at the upper bookend of the slider */
+    @FloatRange(from = 0.0, to = 1.0) val upperBookendScale: Float = 1f,
+    /** Vibration scale at the lower bookend of the slider */
+    @FloatRange(from = 0.0, to = 1.0) val lowerBookendScale: Float = 0.05f,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderHapticFeedbackProvider.kt b/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderHapticFeedbackProvider.kt
new file mode 100644
index 000000000000..e6de156de0c4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderHapticFeedbackProvider.kt
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2023 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.haptics.slider
+
+import android.os.VibrationAttributes
+import android.os.VibrationEffect
+import android.view.VelocityTracker
+import android.view.animation.AccelerateInterpolator
+import androidx.annotation.FloatRange
+import com.android.systemui.statusbar.VibratorHelper
+import kotlin.math.abs
+import kotlin.math.min
+
+/**
+ * Listener of slider events that triggers haptic feedback.
+ *
+ * @property[vibratorHelper] Singleton instance of the [VibratorHelper] to deliver haptics.
+ * @property[velocityTracker] Instance of a [VelocityTracker] that tracks slider dragging velocity.
+ * @property[config] Configuration parameters for vibration encapsulated as a
+ *   [SliderHapticFeedbackConfig].
+ * @property[clock] Clock to obtain elapsed real time values.
+ */
+class SliderHapticFeedbackProvider(
+    private val vibratorHelper: VibratorHelper,
+    private val velocityTracker: VelocityTracker,
+    private val config: SliderHapticFeedbackConfig = SliderHapticFeedbackConfig(),
+    private val clock: com.android.systemui.util.time.SystemClock,
+) : SliderStateListener {
+
+    private val velocityAccelerateInterpolator =
+        AccelerateInterpolator(config.velocityInterpolatorFactor)
+    private val positionAccelerateInterpolator =
+        AccelerateInterpolator(config.progressInterpolatorFactor)
+    private var dragTextureLastTime = clock.elapsedRealtime()
+    private val lowTickDurationMs =
+        vibratorHelper.getPrimitiveDurations(VibrationEffect.Composition.PRIMITIVE_LOW_TICK)[0]
+    private var hasVibratedAtLowerBookend = false
+    private var hasVibratedAtUpperBookend = false
+
+    /** Time threshold to wait before making new API call. */
+    private val thresholdUntilNextDragCallMillis =
+        lowTickDurationMs * config.numberOfLowTicks + config.deltaMillisForDragInterval
+
+    /**
+     * Vibrate when the handle reaches either bookend with a certain velocity.
+     *
+     * @param[absoluteVelocity] Velocity of the handle when it reached the bookend.
+     */
+    private fun vibrateOnEdgeCollision(absoluteVelocity: Float) {
+        val velocityInterpolated =
+            velocityAccelerateInterpolator.getInterpolation(
+                min(absoluteVelocity / config.maxVelocityToScale, 1f)
+            )
+        val bookendScaleRange = config.upperBookendScale - config.lowerBookendScale
+        val bookendsHitScale = bookendScaleRange * velocityInterpolated + config.lowerBookendScale
+
+        val vibration =
+            VibrationEffect.startComposition()
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, bookendsHitScale)
+                .compose()
+        vibratorHelper.vibrate(vibration, VIBRATION_ATTRIBUTES_PIPELINING)
+    }
+
+    /**
+     * Create a drag texture vibration based on velocity and slider progress.
+     *
+     * @param[absoluteVelocity] Absolute velocity of the handle.
+     * @param[normalizedSliderProgress] Progress of the slider handled normalized to the range from
+     *   0F to 1F (inclusive).
+     */
+    private fun vibrateDragTexture(
+        absoluteVelocity: Float,
+        @FloatRange(from = 0.0, to = 1.0) normalizedSliderProgress: Float
+    ) {
+        // Check if its time to vibrate
+        val currentTime = clock.elapsedRealtime()
+        val elapsedSinceLastDrag = currentTime - dragTextureLastTime
+        if (elapsedSinceLastDrag < thresholdUntilNextDragCallMillis) return
+
+        val velocityInterpolated =
+            velocityAccelerateInterpolator.getInterpolation(
+                min(absoluteVelocity / config.maxVelocityToScale, 1f)
+            )
+
+        // Scaling of vibration due to the position of the slider
+        val positionScaleRange = config.progressBasedDragMaxScale - config.progressBasedDragMinScale
+        val sliderProgressInterpolated =
+            positionAccelerateInterpolator.getInterpolation(normalizedSliderProgress)
+        val positionBasedScale =
+            positionScaleRange * sliderProgressInterpolated + config.progressBasedDragMinScale
+
+        // Scaling bump due to velocity
+        val velocityBasedScale = velocityInterpolated * config.additionalVelocityMaxBump
+
+        // Total scale
+        val scale = positionBasedScale + velocityBasedScale
+
+        // Trigger the vibration composition
+        val composition = VibrationEffect.startComposition()
+        repeat(config.numberOfLowTicks) {
+            composition.addPrimitive(VibrationEffect.Composition.PRIMITIVE_LOW_TICK, scale)
+        }
+        vibratorHelper.vibrate(composition.compose(), VIBRATION_ATTRIBUTES_PIPELINING)
+        dragTextureLastTime = currentTime
+    }
+
+    override fun onHandleAcquiredByTouch() {}
+
+    override fun onHandleReleasedFromTouch() {}
+
+    override fun onLowerBookend() {
+        if (!hasVibratedAtLowerBookend) {
+            velocityTracker.computeCurrentVelocity(UNITS_SECOND, config.maxVelocityToScale)
+            vibrateOnEdgeCollision(abs(velocityTracker.xVelocity))
+            hasVibratedAtLowerBookend = true
+        }
+    }
+
+    override fun onUpperBookend() {
+        if (!hasVibratedAtUpperBookend) {
+            velocityTracker.computeCurrentVelocity(UNITS_SECOND, config.maxVelocityToScale)
+            vibrateOnEdgeCollision(abs(velocityTracker.xVelocity))
+            hasVibratedAtUpperBookend = true
+        }
+    }
+
+    override fun onProgress(@FloatRange(from = 0.0, to = 1.0) progress: Float) {
+        velocityTracker.computeCurrentVelocity(UNITS_SECOND, config.maxVelocityToScale)
+        vibrateDragTexture(abs(velocityTracker.xVelocity), progress)
+        hasVibratedAtUpperBookend = false
+        hasVibratedAtLowerBookend = false
+    }
+
+    override fun onProgressJump(@FloatRange(from = 0.0, to = 1.0) progress: Float) {}
+
+    override fun onSelectAndArrow(@FloatRange(from = 0.0, to = 1.0) progress: Float) {}
+
+    private companion object {
+        private val VIBRATION_ATTRIBUTES_PIPELINING =
+            VibrationAttributes.Builder()
+                .setUsage(VibrationAttributes.USAGE_TOUCH)
+                .setFlags(VibrationAttributes.FLAG_PIPELINED_EFFECT)
+                .build()
+        private const val UNITS_SECOND = 1000
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderStateListener.kt b/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderStateListener.kt
new file mode 100644
index 000000000000..9c99c90bb910
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderStateListener.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2023 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.haptics.slider
+
+import androidx.annotation.FloatRange
+
+/** Listener of events from a slider (such as [android.widget.SeekBar]) */
+interface SliderStateListener {
+
+    /** Notification that the handle is acquired by touch */
+    fun onHandleAcquiredByTouch()
+
+    /** Notification that the handle was released from touch */
+    fun onHandleReleasedFromTouch()
+
+    /** Notification that the handle reached the lower bookend */
+    fun onLowerBookend()
+
+    /** Notification that the handle reached the upper bookend */
+    fun onUpperBookend()
+
+    /**
+     * Notification that the slider reached a certain progress on the slider track.
+     *
+     * This method is called in all intermediate steps of a continuous progress change as the slider
+     * moves through the slider track.
+     *
+     * @param[progress] The progress of the slider in the range from 0F to 1F (inclusive).
+     */
+    fun onProgress(@FloatRange(from = 0.0, to = 1.0) progress: Float)
+
+    /**
+     * Notification that the slider handle jumped to a selected progress on the slider track.
+     *
+     * This method is specific to the case when the handle performed a single jump to a position on
+     * the slider track and reached the corresponding progress. In this case, [onProgress] is not
+     * called and the new progress reached is represented by the [progress] parameter.
+     *
+     * @param[progress] The selected progress on the slider track that the handle jumps to. The
+     *   progress is in the range from 0F to 1F (inclusive).
+     */
+    fun onProgressJump(@FloatRange(from = 0.0, to = 1.0) progress: Float)
+
+    /**
+     * Notification that the slider handle was moved by a button press.
+     *
+     * @param[progress] The progress of the slider in the range from 0F to 1F (inclusive).
+     */
+    fun onSelectAndArrow(@FloatRange(from = 0.0, to = 1.0) progress: Float)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/VibratorHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/VibratorHelper.java
index 645595c1f7bf..d089252759c7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/VibratorHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/VibratorHelper.java
@@ -117,6 +117,16 @@ public class VibratorHelper {
         mExecutor.execute(() -> mVibrator.vibrate(effect));
     }
 
+    /**
+     * @see Vibrator#vibrate(VibrationEffect, VibrationAttributes)
+     */
+    public void vibrate(@NonNull VibrationEffect effect, @NonNull VibrationAttributes attributes) {
+        if (!hasVibrator()) {
+            return;
+        }
+        mExecutor.execute(() -> mVibrator.vibrate(effect, attributes));
+    }
+
     /**
      * @see Vibrator#hasVibrator()
      */
@@ -153,6 +163,17 @@ public class VibratorHelper {
                 HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES);
     }
 
+    /**
+     * @see Vibrator#getPrimitiveDurations(int...)
+     */
+    public int[] getPrimitiveDurations(int... primitiveIds) {
+        if (!hasVibrator()) {
+            return new int[]{0};
+        } else {
+            return mVibrator.getPrimitiveDurations(primitiveIds);
+        }
+    }
+
     /**
      * Perform a vibration using a view and the one-way API with flags
      * @see View#performHapticFeedback(int feedbackConstant, int flags)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/haptics/slider/SliderHapticFeedbackProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/haptics/slider/SliderHapticFeedbackProviderTest.kt
new file mode 100644
index 000000000000..0ee348e0d23d
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/haptics/slider/SliderHapticFeedbackProviderTest.kt
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2023 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.haptics.slider
+
+import android.os.VibrationAttributes
+import android.os.VibrationEffect
+import android.view.VelocityTracker
+import android.view.animation.AccelerateInterpolator
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.VibratorHelper
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.whenever
+import com.android.systemui.util.time.FakeSystemClock
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class SliderHapticFeedbackProviderTest : SysuiTestCase() {
+
+    @Mock private lateinit var velocityTracker: VelocityTracker
+    @Mock private lateinit var vibratorHelper: VibratorHelper
+
+    private val config = SliderHapticFeedbackConfig()
+    private val clock = FakeSystemClock()
+
+    private val lowTickDuration = 12 // Mocked duration of a low tick
+    private val dragTextureThresholdMillis =
+        lowTickDuration * config.numberOfLowTicks + config.deltaMillisForDragInterval
+    private val progressInterpolator = AccelerateInterpolator(config.progressInterpolatorFactor)
+    private val velocityInterpolator = AccelerateInterpolator(config.velocityInterpolatorFactor)
+    private lateinit var sliderHapticFeedbackProvider: SliderHapticFeedbackProvider
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+        whenever(vibratorHelper.getPrimitiveDurations(any()))
+            .thenReturn(intArrayOf(lowTickDuration))
+        whenever(velocityTracker.xVelocity).thenReturn(config.maxVelocityToScale)
+        sliderHapticFeedbackProvider =
+            SliderHapticFeedbackProvider(vibratorHelper, velocityTracker, config, clock)
+    }
+
+    @Test
+    fun playHapticAtLowerBookend_playsClick() {
+        val vibration =
+            VibrationEffect.startComposition()
+                .addPrimitive(
+                    VibrationEffect.Composition.PRIMITIVE_CLICK,
+                    scaleAtBookends(config.maxVelocityToScale)
+                )
+                .compose()
+
+        sliderHapticFeedbackProvider.onLowerBookend()
+
+        verify(vibratorHelper).vibrate(eq(vibration), any(VibrationAttributes::class.java))
+    }
+
+    @Test
+    fun playHapticAtLowerBookend_twoTimes_playsClickOnlyOnce() {
+        val vibration =
+            VibrationEffect.startComposition()
+                .addPrimitive(
+                    VibrationEffect.Composition.PRIMITIVE_CLICK,
+                    scaleAtBookends(config.maxVelocityToScale)
+                )
+                .compose()
+
+        sliderHapticFeedbackProvider.onLowerBookend()
+        sliderHapticFeedbackProvider.onLowerBookend()
+
+        verify(vibratorHelper).vibrate(eq(vibration), any(VibrationAttributes::class.java))
+    }
+
+    @Test
+    fun playHapticAtUpperBookend_playsClick() {
+        val vibration =
+            VibrationEffect.startComposition()
+                .addPrimitive(
+                    VibrationEffect.Composition.PRIMITIVE_CLICK,
+                    scaleAtBookends(config.maxVelocityToScale)
+                )
+                .compose()
+
+        sliderHapticFeedbackProvider.onUpperBookend()
+
+        verify(vibratorHelper).vibrate(eq(vibration), any(VibrationAttributes::class.java))
+    }
+
+    @Test
+    fun playHapticAtUpperBookend_twoTimes_playsClickOnlyOnce() {
+        val vibration =
+            VibrationEffect.startComposition()
+                .addPrimitive(
+                    VibrationEffect.Composition.PRIMITIVE_CLICK,
+                    scaleAtBookends(config.maxVelocityToScale)
+                )
+                .compose()
+
+        sliderHapticFeedbackProvider.onUpperBookend()
+        sliderHapticFeedbackProvider.onUpperBookend()
+
+        verify(vibratorHelper, times(1))
+            .vibrate(eq(vibration), any(VibrationAttributes::class.java))
+    }
+
+    @Test
+    fun playHapticAtProgress_onQuickSuccession_playsLowTicksOnce() {
+        // GIVEN max velocity and slider progress
+        val progress = 1f
+        val expectedScale = scaleAtProgressChange(config.maxVelocityToScale.toFloat(), progress)
+        val ticks = VibrationEffect.startComposition()
+        repeat(config.numberOfLowTicks) {
+            ticks.addPrimitive(VibrationEffect.Composition.PRIMITIVE_LOW_TICK, expectedScale)
+        }
+
+        // GIVEN system running for 1s
+        clock.advanceTime(1000)
+
+        // WHEN two calls to play occur immediately
+        sliderHapticFeedbackProvider.onProgress(progress)
+        sliderHapticFeedbackProvider.onProgress(progress)
+
+        // THEN the correct composition only plays once
+        verify(vibratorHelper, times(1))
+            .vibrate(eq(ticks.compose()), any(VibrationAttributes::class.java))
+    }
+
+    @Test
+    fun playHapticAtProgress_afterNextDragThreshold_playsLowTicksTwice() {
+        // GIVEN max velocity and slider progress
+        val progress = 1f
+        val expectedScale = scaleAtProgressChange(config.maxVelocityToScale.toFloat(), progress)
+        val ticks = VibrationEffect.startComposition()
+        repeat(config.numberOfLowTicks) {
+            ticks.addPrimitive(VibrationEffect.Composition.PRIMITIVE_LOW_TICK, expectedScale)
+        }
+
+        // GIVEN system running for 1s
+        clock.advanceTime(1000)
+
+        // WHEN two calls to play occur with the required threshold separation
+        sliderHapticFeedbackProvider.onProgress(progress)
+        clock.advanceTime(dragTextureThresholdMillis.toLong())
+        sliderHapticFeedbackProvider.onProgress(progress)
+
+        // THEN the correct composition plays two times
+        verify(vibratorHelper, times(2))
+            .vibrate(eq(ticks.compose()), any(VibrationAttributes::class.java))
+    }
+
+    @Test
+    fun playHapticAtLowerBookend_afterPlayingAtProgress_playsTwice() {
+        // GIVEN max velocity and slider progress
+        val progress = 1f
+        val expectedScale = scaleAtProgressChange(config.maxVelocityToScale.toFloat(), progress)
+        val ticks = VibrationEffect.startComposition()
+        repeat(config.numberOfLowTicks) {
+            ticks.addPrimitive(VibrationEffect.Composition.PRIMITIVE_LOW_TICK, expectedScale)
+        }
+        val bookendVibration =
+            VibrationEffect.startComposition()
+                .addPrimitive(
+                    VibrationEffect.Composition.PRIMITIVE_CLICK,
+                    scaleAtBookends(config.maxVelocityToScale)
+                )
+                .compose()
+
+        // GIVEN a vibration at the lower bookend followed by a request to vibrate at progress
+        sliderHapticFeedbackProvider.onLowerBookend()
+        sliderHapticFeedbackProvider.onProgress(progress)
+
+        // WHEN a vibration is to trigger again at the lower bookend
+        sliderHapticFeedbackProvider.onLowerBookend()
+
+        // THEN there are two bookend vibrations
+        verify(vibratorHelper, times(2))
+            .vibrate(eq(bookendVibration), any(VibrationAttributes::class.java))
+    }
+
+    @Test
+    fun playHapticAtUpperBookend_afterPlayingAtProgress_playsTwice() {
+        // GIVEN max velocity and slider progress
+        val progress = 1f
+        val expectedScale = scaleAtProgressChange(config.maxVelocityToScale.toFloat(), progress)
+        val ticks = VibrationEffect.startComposition()
+        repeat(config.numberOfLowTicks) {
+            ticks.addPrimitive(VibrationEffect.Composition.PRIMITIVE_LOW_TICK, expectedScale)
+        }
+        val bookendVibration =
+            VibrationEffect.startComposition()
+                .addPrimitive(
+                    VibrationEffect.Composition.PRIMITIVE_CLICK,
+                    scaleAtBookends(config.maxVelocityToScale)
+                )
+                .compose()
+
+        // GIVEN a vibration at the upper bookend followed by a request to vibrate at progress
+        sliderHapticFeedbackProvider.onUpperBookend()
+        sliderHapticFeedbackProvider.onProgress(progress)
+
+        // WHEN a vibration is to trigger again at the upper bookend
+        sliderHapticFeedbackProvider.onUpperBookend()
+
+        // THEN there are two bookend vibrations
+        verify(vibratorHelper, times(2))
+            .vibrate(eq(bookendVibration), any(VibrationAttributes::class.java))
+    }
+
+    private fun scaleAtBookends(velocity: Float): Float {
+        val range = config.upperBookendScale - config.lowerBookendScale
+        val interpolatedVelocity =
+            velocityInterpolator.getInterpolation(velocity / config.maxVelocityToScale)
+        return interpolatedVelocity * range + config.lowerBookendScale
+    }
+
+    private fun scaleAtProgressChange(velocity: Float, progress: Float): Float {
+        val range = config.progressBasedDragMaxScale - config.progressBasedDragMinScale
+        val interpolatedVelocity =
+            velocityInterpolator.getInterpolation(velocity / config.maxVelocityToScale)
+        val interpolatedProgress = progressInterpolator.getInterpolation(progress)
+        val bump = interpolatedVelocity * config.additionalVelocityMaxBump
+        return interpolatedProgress * range + config.progressBasedDragMinScale + bump
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/VibratorHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/VibratorHelperTest.kt
index aab4bc361d7b..b90582575970 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/VibratorHelperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/VibratorHelperTest.kt
@@ -74,6 +74,18 @@ class VibratorHelperTest : SysuiTestCase() {
         verifyAsync().vibrate(any(VibrationEffect::class.java))
     }
 
+    @Test
+    fun testVibrate5() {
+        vibratorHelper.vibrate(
+            mock(VibrationEffect::class.java),
+            mock(VibrationAttributes::class.java)
+        )
+        verifyAsync().vibrate(
+            any(VibrationEffect::class.java),
+            any(VibrationAttributes::class.java)
+        )
+    }
+
     @Test
     fun testPerformHapticFeedback() {
         val constant = HapticFeedbackConstants.CONFIRM
-- 
GitLab


From 91af11ff0d5e3d2dd67b931f62cc97b6a03dca00 Mon Sep 17 00:00:00 2001
From: Juan Sebastian Martinez <juansmartinez@google.com>
Date: Fri, 1 Sep 2023 16:23:19 -0700
Subject: [PATCH 89/95] Introducing Slider Tracker components for sliders in
 SysUI.

Components related to the state machine of a slider are introduced.
These include a SliderTracker, SliderState and the concrete
implementation of a tracker for the brightness slider in the system UI
(SeekableSliderTracker).

Test: atest SeekableSliderTrackerTest
Bug: 295932558
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:b2e4731cc439095c07ef9de06b612aa14f67efe1)

Change-Id: I04a3d3d38a9f43e7262ff419b183b1cb40177675
---
 .../haptics/slider/SeekableSliderTracker.kt   | 212 +++++++
 .../slider/SeekableSliderTrackerConfig.kt     |  37 ++
 .../systemui/haptics/slider/SliderState.kt    |  37 ++
 .../systemui/haptics/slider/SliderTracker.kt  |  93 +++
 .../haptics/slider/FakeSliderEventProducer.kt |  32 +
 .../slider/SeekableSliderTrackerTest.kt       | 547 ++++++++++++++++++
 6 files changed, 958 insertions(+)
 create mode 100644 packages/SystemUI/src/com/android/systemui/haptics/slider/SeekableSliderTracker.kt
 create mode 100644 packages/SystemUI/src/com/android/systemui/haptics/slider/SeekableSliderTrackerConfig.kt
 create mode 100644 packages/SystemUI/src/com/android/systemui/haptics/slider/SliderState.kt
 create mode 100644 packages/SystemUI/src/com/android/systemui/haptics/slider/SliderTracker.kt
 create mode 100644 packages/SystemUI/tests/src/com/android/systemui/haptics/slider/FakeSliderEventProducer.kt
 create mode 100644 packages/SystemUI/tests/src/com/android/systemui/haptics/slider/SeekableSliderTrackerTest.kt

diff --git a/packages/SystemUI/src/com/android/systemui/haptics/slider/SeekableSliderTracker.kt b/packages/SystemUI/src/com/android/systemui/haptics/slider/SeekableSliderTracker.kt
new file mode 100644
index 000000000000..cc51d21744e8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/haptics/slider/SeekableSliderTracker.kt
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2023 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.haptics.slider
+
+import androidx.annotation.VisibleForTesting
+import com.android.systemui.dagger.qualifiers.Main
+import kotlin.math.abs
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.isActive
+import kotlinx.coroutines.launch
+
+/**
+ * Slider tracker attached to a seekable slider.
+ *
+ * The tracker runs a state machine to execute actions on touch-based events typical of a seekable
+ * slider such as [android.widget.SeekBar]. Coroutines responsible for running the state machine,
+ * collecting slider events and maintaining waiting states are run on the main thread via the
+ * [com.android.systemui.dagger.qualifiers.Main] coroutine dispatcher.
+ *
+ * @param[sliderStateListener] Listener of the slider state.
+ * @param[sliderEventProducer] Producer of slider events arising from the slider.
+ * @property[scope] [CoroutineScope] where the collection of slider events and the launch of timer
+ *   jobs occur.
+ * @property[config] Configuration parameters of the slider tracker.
+ */
+class SeekableSliderTracker(
+    sliderStateListener: SliderStateListener,
+    sliderEventProducer: SliderEventProducer,
+    @Main mainDispatcher: CoroutineDispatcher,
+    private val config: SeekableSliderTrackerConfig = SeekableSliderTrackerConfig(),
+) : SliderTracker(CoroutineScope(mainDispatcher), sliderStateListener, sliderEventProducer) {
+
+    // History of the latest progress collected from slider events
+    private var latestProgress = 0f
+    // Timer job for the wait state
+    private var timerJob: Job? = null
+    // Indicator that there is waiting job active
+    var isWaiting = false
+        private set
+        get() = timerJob != null && timerJob?.isActive == true
+
+    override suspend fun iterateState(event: SliderEvent) {
+        when (currentState) {
+            SliderState.IDLE -> handleIdle(event.type)
+            SliderState.WAIT -> handleWait(event.type, event.currentProgress)
+            SliderState.DRAG_HANDLE_ACQUIRED_BY_TOUCH -> handleAcquired(event.type)
+            SliderState.DRAG_HANDLE_DRAGGING -> handleDragging(event.type, event.currentProgress)
+            SliderState.DRAG_HANDLE_REACHED_BOOKEND ->
+                handleReachedBookend(event.type, event.currentProgress)
+            SliderState.DRAG_HANDLE_RELEASED_FROM_TOUCH -> setState(SliderState.IDLE)
+            SliderState.JUMP_TRACK_LOCATION_SELECTED -> handleJumpToTrack(event.type)
+            SliderState.JUMP_BOOKEND_SELECTED -> handleJumpToBookend(event.type)
+        }
+        latestProgress = event.currentProgress
+    }
+
+    private fun handleIdle(newEventType: SliderEventType) {
+        if (newEventType == SliderEventType.STARTED_TRACKING_TOUCH) {
+            timerJob = launchTimer()
+            // The WAIT state will wait for the timer to complete or a slider progress to occur.
+            // This will disambiguate between an imprecise touch that acquires the slider handle,
+            // and a select and jump operation in the slider track.
+            setState(SliderState.WAIT)
+        }
+    }
+
+    private fun launchTimer() =
+        scope.launch {
+            delay(config.waitTimeMillis)
+            if (isActive && currentState == SliderState.WAIT) {
+                setState(SliderState.DRAG_HANDLE_ACQUIRED_BY_TOUCH)
+                // This transitory state must also trigger the corresponding action
+                executeOnState(currentState)
+            }
+        }
+
+    private fun handleWait(newEventType: SliderEventType, currentProgress: Float) {
+        // The timer may have completed and may have already modified the state
+        if (currentState != SliderState.WAIT) return
+
+        // The timer is still running but the state may be modified by the progress change
+        val deltaProgressIsJump = deltaProgressIsAboveThreshold(currentProgress)
+        if (newEventType == SliderEventType.PROGRESS_CHANGE_BY_USER) {
+            if (bookendReached(currentProgress)) {
+                setState(SliderState.JUMP_BOOKEND_SELECTED)
+            } else if (deltaProgressIsJump) {
+                setState(SliderState.JUMP_TRACK_LOCATION_SELECTED)
+            } else {
+                setState(SliderState.DRAG_HANDLE_ACQUIRED_BY_TOUCH)
+            }
+        } else if (newEventType == SliderEventType.STOPPED_TRACKING_TOUCH) {
+            setState(SliderState.IDLE)
+        }
+
+        // If the state changed, the timer does not need to complete. No further synchronization
+        // will be required onwards until WAIT is reached again.
+        if (currentState != SliderState.WAIT) {
+            timerJob?.cancel()
+            timerJob = null
+        }
+    }
+
+    private fun handleAcquired(newEventType: SliderEventType) {
+        if (newEventType == SliderEventType.STOPPED_TRACKING_TOUCH) {
+            setState(SliderState.DRAG_HANDLE_RELEASED_FROM_TOUCH)
+        } else if (newEventType == SliderEventType.PROGRESS_CHANGE_BY_USER) {
+            setState(SliderState.DRAG_HANDLE_DRAGGING)
+        }
+    }
+
+    private fun handleDragging(newEventType: SliderEventType, currentProgress: Float) {
+        if (newEventType == SliderEventType.STOPPED_TRACKING_TOUCH) {
+            setState(SliderState.DRAG_HANDLE_RELEASED_FROM_TOUCH)
+        } else if (
+            newEventType == SliderEventType.PROGRESS_CHANGE_BY_USER &&
+                bookendReached(currentProgress)
+        ) {
+            setState(SliderState.DRAG_HANDLE_REACHED_BOOKEND)
+        }
+    }
+
+    private fun handleReachedBookend(newEventType: SliderEventType, currentProgress: Float) {
+        if (newEventType == SliderEventType.PROGRESS_CHANGE_BY_USER) {
+            if (!bookendReached(currentProgress)) {
+                setState(SliderState.DRAG_HANDLE_DRAGGING)
+            }
+        } else if (newEventType == SliderEventType.STOPPED_TRACKING_TOUCH) {
+            setState(SliderState.DRAG_HANDLE_RELEASED_FROM_TOUCH)
+        }
+    }
+
+    private fun handleJumpToTrack(newEventType: SliderEventType) {
+        when (newEventType) {
+            SliderEventType.PROGRESS_CHANGE_BY_USER -> setState(SliderState.DRAG_HANDLE_DRAGGING)
+            SliderEventType.STOPPED_TRACKING_TOUCH ->
+                setState(SliderState.DRAG_HANDLE_RELEASED_FROM_TOUCH)
+            else -> {}
+        }
+    }
+
+    private fun handleJumpToBookend(newEventType: SliderEventType) {
+        when (newEventType) {
+            SliderEventType.PROGRESS_CHANGE_BY_USER -> setState(SliderState.DRAG_HANDLE_DRAGGING)
+            SliderEventType.STOPPED_TRACKING_TOUCH ->
+                setState(SliderState.DRAG_HANDLE_RELEASED_FROM_TOUCH)
+            else -> {}
+        }
+    }
+
+    override fun executeOnState(currentState: SliderState) {
+        when (currentState) {
+            SliderState.DRAG_HANDLE_ACQUIRED_BY_TOUCH -> sliderListener.onHandleAcquiredByTouch()
+            SliderState.DRAG_HANDLE_RELEASED_FROM_TOUCH -> {
+                sliderListener.onHandleReleasedFromTouch()
+                // This transitory state must also reset the state machine
+                resetState()
+            }
+            SliderState.DRAG_HANDLE_DRAGGING -> sliderListener.onProgress(latestProgress)
+            SliderState.DRAG_HANDLE_REACHED_BOOKEND -> executeOnBookend()
+            SliderState.JUMP_TRACK_LOCATION_SELECTED ->
+                sliderListener.onProgressJump(latestProgress)
+            SliderState.JUMP_BOOKEND_SELECTED -> executeOnBookend()
+            else -> {}
+        }
+    }
+
+    private fun executeOnBookend() {
+        if (latestProgress >= config.upperBookendThreshold) sliderListener.onUpperBookend()
+        else sliderListener.onLowerBookend()
+    }
+
+    override fun resetState() {
+        timerJob?.cancel()
+        timerJob = null
+        super.resetState()
+    }
+
+    private fun deltaProgressIsAboveThreshold(
+        currentProgress: Float,
+        epsilon: Float = 0.00001f,
+    ): Boolean {
+        val delta = abs(currentProgress - latestProgress)
+        return abs(delta - config.jumpThreshold) < epsilon
+    }
+
+    private fun bookendReached(currentProgress: Float): Boolean {
+        return currentProgress >= config.upperBookendThreshold ||
+            currentProgress <= config.lowerBookendThreshold
+    }
+
+    @VisibleForTesting
+    fun setState(state: SliderState) {
+        currentState = state
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/haptics/slider/SeekableSliderTrackerConfig.kt b/packages/SystemUI/src/com/android/systemui/haptics/slider/SeekableSliderTrackerConfig.kt
new file mode 100644
index 000000000000..cb0f43b8235a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/haptics/slider/SeekableSliderTrackerConfig.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2023 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.haptics.slider
+
+import androidx.annotation.FloatRange
+
+/**
+ * Configuration parameters of a seekable slider tracker.
+ *
+ * @property[waitTimeMillis] Wait period to determine if a touch event acquires the slider handle.
+ * @property[jumpThreshold] Threshold on the slider progress to detect if a touch event is qualified
+ *   as an imprecise acquisition of the slider handle.
+ * @property[lowerBookendThreshold] Threshold to determine the progress on the slider that qualifies
+ *   as reaching the lower bookend.
+ * @property[upperBookendThreshold] Threshold to determine the progress on the slider that qualifies
+ *   as reaching the upper bookend.
+ */
+data class SeekableSliderTrackerConfig(
+    val waitTimeMillis: Long = 100,
+    @FloatRange(from = 0.0, to = 1.0) val jumpThreshold: Float = 0.02f,
+    @FloatRange(from = 0.0, to = 1.0) val lowerBookendThreshold: Float = 0.05f,
+    @FloatRange(from = 0.0, to = 1.0) val upperBookendThreshold: Float = 0.95f,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderState.kt b/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderState.kt
new file mode 100644
index 000000000000..fe092e67036b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderState.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2023 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.haptics.slider
+
+/** State of a slider */
+enum class SliderState {
+    /* The slider is idle */
+    IDLE,
+    /* Waiting state to disambiguate between handle acquisition and select and jump operations */
+    WAIT,
+    /* The slider handle was acquired by touch. */
+    DRAG_HANDLE_ACQUIRED_BY_TOUCH,
+    /* The slider handle was released. */
+    DRAG_HANDLE_RELEASED_FROM_TOUCH,
+    /* The slider handle is being dragged by touch. */
+    DRAG_HANDLE_DRAGGING,
+    /* The slider handle reached a bookend. */
+    DRAG_HANDLE_REACHED_BOOKEND,
+    /* A location in the slider track has been selected. */
+    JUMP_TRACK_LOCATION_SELECTED,
+    /* The slider handled moved to a bookend after it was selected. */
+    JUMP_BOOKEND_SELECTED,
+}
diff --git a/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderTracker.kt b/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderTracker.kt
new file mode 100644
index 000000000000..e1f57089d792
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderTracker.kt
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2023 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.haptics.slider
+
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.cancel
+import kotlinx.coroutines.launch
+
+/**
+ * Tracker component for a slider.
+ *
+ * The tracker maintains a state machine operated by slider events coming from a
+ * [SliderEventProducer]. An action is executed in each state via a [SliderListener].
+ *
+ * @param[scope] [CoroutineScope] to launch the collection of [SliderEvent].
+ * @property[sliderListener] [SliderListener] to execute actions on a given [SliderState].
+ * @property[eventProducer] Producer of [SliderEvent] to iterate over a state machine.
+ */
+sealed class SliderTracker(
+    protected val scope: CoroutineScope,
+    protected val sliderListener: SliderStateListener,
+    protected val eventProducer: SliderEventProducer,
+) {
+
+    /* Reference to the current state of the internal state machine */
+    var currentState: SliderState = SliderState.IDLE
+        protected set
+
+    /**
+     * Job that launches and maintains the coroutine that collects events and operates the state
+     * machine.
+     */
+    protected var job: Job? = null
+
+    /** Indicator that the tracker is active and tracking */
+    var isTracking = false
+        get() = job != null && job?.isActive == true
+        private set
+
+    /** Starts the [Job] that collects slider events and runs the state machine */
+    fun startTracking() {
+        job =
+            scope.launch {
+                eventProducer.produceEvents().collect { event ->
+                    iterateState(event)
+                    executeOnState(currentState)
+                }
+            }
+    }
+
+    /** Stops the collection of slider events and the state machine */
+    fun stopTracking() {
+        job?.cancel("Stopped tracking slider state")
+        job = null
+        resetState()
+    }
+
+    /**
+     * Iterate through the state machine due to a new slider event. As a result, the current state
+     * is modified.
+     *
+     * @param[event] The slider event that is received.
+     */
+    protected abstract suspend fun iterateState(event: SliderEvent)
+
+    /**
+     * Execute an action based on the state of the state machine. This method should use the
+     * [SliderListener] to act on the current state.
+     *
+     * @param[currentState] A [SliderState] in the state machine
+     */
+    protected abstract fun executeOnState(currentState: SliderState)
+
+    /** Reset the state machine by setting the current state to [SliderState.IDLE] */
+    protected open fun resetState() {
+        currentState = SliderState.IDLE
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/haptics/slider/FakeSliderEventProducer.kt b/packages/SystemUI/tests/src/com/android/systemui/haptics/slider/FakeSliderEventProducer.kt
new file mode 100644
index 000000000000..9deabc76065c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/haptics/slider/FakeSliderEventProducer.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 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.haptics.slider
+
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
+
+/** Fake implementation of a slider event producer */
+class FakeSliderEventProducer : SliderEventProducer {
+
+    private val _currentEvent = MutableStateFlow(SliderEvent(SliderEventType.NOTHING, 0f))
+
+    fun sendEvent(event: SliderEvent) {
+        _currentEvent.value = event
+    }
+    override fun produceEvents(): Flow<SliderEvent> = _currentEvent.asStateFlow()
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/haptics/slider/SeekableSliderTrackerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/haptics/slider/SeekableSliderTrackerTest.kt
new file mode 100644
index 000000000000..add601c4b1b3
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/haptics/slider/SeekableSliderTrackerTest.kt
@@ -0,0 +1,547 @@
+/*
+ * Copyright (C) 2023 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.haptics.slider
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestCoroutineScheduler
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.advanceTimeBy
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.anyFloat
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.Mockito.verifyZeroInteractions
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class SeekableSliderTrackerTest : SysuiTestCase() {
+
+    @Mock private lateinit var sliderStateListener: SliderStateListener
+    private val sliderEventProducer = FakeSliderEventProducer()
+    private lateinit var mSeekableSliderTracker: SeekableSliderTracker
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+    }
+
+    @Test
+    fun initializeSliderTracker_startsTracking() = runTest {
+        // GIVEN Initialized tracker
+        initTracker(testScheduler)
+
+        // THEN the tracker job is active
+        assertThat(mSeekableSliderTracker.isTracking).isTrue()
+    }
+
+    @Test
+    fun stopTracking_onAnyState_resetsToIdle() = runTest {
+        enumValues<SliderState>().forEach {
+            // GIVEN Initialized tracker
+            initTracker(testScheduler)
+
+            // GIVEN a state in the state machine
+            mSeekableSliderTracker.setState(it)
+
+            // WHEN the tracker stops tracking the state and listening to events
+            mSeekableSliderTracker.stopTracking()
+
+            // THEN The state is idle and the tracker is not active
+            assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.IDLE)
+            assertThat(mSeekableSliderTracker.isTracking).isFalse()
+        }
+    }
+
+    // Tests on the IDLE state
+    @Test
+    fun initializeSliderTracker_isIdle() = runTest {
+        // GIVEN Initialized tracker
+        initTracker(testScheduler)
+
+        // THEN The state is idle and the listener is not called to play haptics
+        assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.IDLE)
+        verifyZeroInteractions(sliderStateListener)
+    }
+
+    @Test
+    fun startsTrackingTouch_onIdle_entersWaitState() = runTest {
+        initTracker(testScheduler)
+
+        // GIVEN a start of tracking touch event
+        val progress = 0f
+        sliderEventProducer.sendEvent(SliderEvent(SliderEventType.STARTED_TRACKING_TOUCH, progress))
+
+        // THEN the tracker moves to the wait state and the timer job begins
+        assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.WAIT)
+        verifyZeroInteractions(sliderStateListener)
+        assertThat(mSeekableSliderTracker.isWaiting).isTrue()
+    }
+
+    // Tests on the WAIT state
+
+    @OptIn(ExperimentalCoroutinesApi::class)
+    @Test
+    fun waitCompletes_onWait_movesToHandleAcquired() = runTest {
+        val config = SeekableSliderTrackerConfig()
+        initTracker(testScheduler, config)
+
+        // GIVEN a start of tracking touch event that moves the tracker to WAIT
+        val progress = 0f
+        sliderEventProducer.sendEvent(SliderEvent(SliderEventType.STARTED_TRACKING_TOUCH, progress))
+
+        // WHEN the wait time completes plus a small buffer time
+        advanceTimeBy(config.waitTimeMillis + 10L)
+
+        // THEN the tracker moves to the DRAG_HANDLE_ACQUIRED_BY_TOUCH state
+        assertThat(mSeekableSliderTracker.currentState)
+            .isEqualTo(SliderState.DRAG_HANDLE_ACQUIRED_BY_TOUCH)
+        assertThat(mSeekableSliderTracker.isWaiting).isFalse()
+        verify(sliderStateListener).onHandleAcquiredByTouch()
+        verifyNoMoreInteractions(sliderStateListener)
+    }
+
+    @Test
+    fun impreciseTouch_onWait_movesToHandleAcquired() = runTest {
+        val config = SeekableSliderTrackerConfig()
+        initTracker(testScheduler, config)
+
+        // GIVEN a start of tracking touch event that moves the tracker to WAIT at the middle of the
+        // slider
+        var progress = 0.5f
+        sliderEventProducer.sendEvent(SliderEvent(SliderEventType.STARTED_TRACKING_TOUCH, progress))
+
+        // GIVEN a progress event due to an imprecise touch with a progress below threshold
+        progress += (config.jumpThreshold - 0.01f)
+        sliderEventProducer.sendEvent(
+            SliderEvent(SliderEventType.PROGRESS_CHANGE_BY_USER, progress)
+        )
+
+        // THEN the tracker moves to the DRAG_HANDLE_ACQUIRED_BY_TOUCH state without the timer job
+        // being complete
+        assertThat(mSeekableSliderTracker.currentState)
+            .isEqualTo(SliderState.DRAG_HANDLE_ACQUIRED_BY_TOUCH)
+        assertThat(mSeekableSliderTracker.isWaiting).isFalse()
+        verify(sliderStateListener).onHandleAcquiredByTouch()
+        verifyNoMoreInteractions(sliderStateListener)
+    }
+
+    @Test
+    fun trackJump_onWait_movesToJumpTrackLocationSelected() = runTest {
+        val config = SeekableSliderTrackerConfig()
+        initTracker(testScheduler, config)
+
+        // GIVEN a start of tracking touch event that moves the tracker to WAIT at the middle of the
+        // slider
+        var progress = 0.5f
+        sliderEventProducer.sendEvent(SliderEvent(SliderEventType.STARTED_TRACKING_TOUCH, progress))
+
+        // GIVEN a progress event due to a touch on the slider track at threshold
+        progress += config.jumpThreshold
+        sliderEventProducer.sendEvent(
+            SliderEvent(SliderEventType.PROGRESS_CHANGE_BY_USER, progress)
+        )
+
+        // THEN the tracker moves to the jump-track location selected state
+        assertThat(mSeekableSliderTracker.currentState)
+            .isEqualTo(SliderState.JUMP_TRACK_LOCATION_SELECTED)
+        assertThat(mSeekableSliderTracker.isWaiting).isFalse()
+        verify(sliderStateListener).onProgressJump(anyFloat())
+        verifyNoMoreInteractions(sliderStateListener)
+    }
+
+    @Test
+    fun upperBookendSelection_onWait_movesToBookendSelected() = runTest {
+        val config = SeekableSliderTrackerConfig()
+        initTracker(testScheduler, config)
+
+        // GIVEN a start of tracking touch event that moves the tracker to WAIT at the middle of the
+        // slider
+        var progress = 0.5f
+        sliderEventProducer.sendEvent(SliderEvent(SliderEventType.STARTED_TRACKING_TOUCH, progress))
+
+        // GIVEN a progress event due to a touch on the slider upper bookend zone.
+        progress = (config.upperBookendThreshold + 0.01f)
+        sliderEventProducer.sendEvent(
+            SliderEvent(SliderEventType.PROGRESS_CHANGE_BY_USER, progress)
+        )
+
+        // THEN the tracker moves to the jump-track location selected state
+        assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.JUMP_BOOKEND_SELECTED)
+        assertThat(mSeekableSliderTracker.isWaiting).isFalse()
+        verify(sliderStateListener).onUpperBookend()
+        verifyNoMoreInteractions(sliderStateListener)
+    }
+
+    @Test
+    fun lowerBookendSelection_onWait_movesToBookendSelected() = runTest {
+        val config = SeekableSliderTrackerConfig()
+        initTracker(testScheduler, config)
+
+        // GIVEN a start of tracking touch event that moves the tracker to WAIT at the middle of the
+        // slider
+        var progress = 0.5f
+        sliderEventProducer.sendEvent(SliderEvent(SliderEventType.STARTED_TRACKING_TOUCH, progress))
+
+        // GIVEN a progress event due to a touch on the slider lower bookend zone
+        progress = (config.lowerBookendThreshold - 0.01f)
+        sliderEventProducer.sendEvent(
+            SliderEvent(SliderEventType.PROGRESS_CHANGE_BY_USER, progress)
+        )
+
+        // THEN the tracker moves to the JUMP_TRACK_LOCATION_SELECTED state
+        assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.JUMP_BOOKEND_SELECTED)
+        assertThat(mSeekableSliderTracker.isWaiting).isFalse()
+        verify(sliderStateListener).onLowerBookend()
+        verifyNoMoreInteractions(sliderStateListener)
+    }
+
+    @Test
+    fun stopTracking_onWait_whenWaitingJobIsActive_resetsToIdle() = runTest {
+        val config = SeekableSliderTrackerConfig()
+        initTracker(testScheduler, config)
+
+        // GIVEN a start of tracking touch event that moves the tracker to WAIT at the middle of the
+        // slider
+        sliderEventProducer.sendEvent(SliderEvent(SliderEventType.STARTED_TRACKING_TOUCH, 0.5f))
+        assertThat(mSeekableSliderTracker.isWaiting).isTrue()
+
+        // GIVEN that the tracker stops tracking the state and listening to events
+        mSeekableSliderTracker.stopTracking()
+
+        // THEN the tracker moves to the IDLE state without the timer job being complete
+        assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.IDLE)
+        assertThat(mSeekableSliderTracker.isWaiting).isFalse()
+        assertThat(mSeekableSliderTracker.isTracking).isFalse()
+        verifyNoMoreInteractions(sliderStateListener)
+    }
+
+    // Tests on the JUMP_TRACK_LOCATION_SELECTED state
+
+    @Test
+    fun progressChangeByUser_onJumpTrackLocationSelected_movesToDragHandleDragging() = runTest {
+        initTracker(testScheduler)
+
+        // GIVEN a JUMP_TRACK_LOCATION_SELECTED state
+        mSeekableSliderTracker.setState(SliderState.JUMP_TRACK_LOCATION_SELECTED)
+
+        // GIVEN a progress event due to dragging the handle
+        sliderEventProducer.sendEvent(SliderEvent(SliderEventType.PROGRESS_CHANGE_BY_USER, 0.5f))
+
+        // THEN the tracker moves to the DRAG_HANDLE_DRAGGING state
+        assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.DRAG_HANDLE_DRAGGING)
+        verify(sliderStateListener).onProgress(anyFloat())
+        verifyNoMoreInteractions(sliderStateListener)
+    }
+
+    @Test
+    fun touchRelease_onJumpTrackLocationSelected_movesToIdle() = runTest {
+        initTracker(testScheduler)
+
+        // GIVEN a JUMP_TRACK_LOCATION_SELECTED state
+        mSeekableSliderTracker.setState(SliderState.JUMP_TRACK_LOCATION_SELECTED)
+
+        // GIVEN that the slider stopped tracking touch
+        sliderEventProducer.sendEvent(SliderEvent(SliderEventType.STOPPED_TRACKING_TOUCH, 0.5f))
+
+        // THEN the tracker executes on onHandleReleasedFromTouch before moving to the IDLE state
+        verify(sliderStateListener).onHandleReleasedFromTouch()
+        assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.IDLE)
+        verifyNoMoreInteractions(sliderStateListener)
+    }
+
+    @Test
+    fun progressChangeByUser_onJumpBookendSelected_movesToDragHandleDragging() = runTest {
+        initTracker(testScheduler)
+
+        // GIVEN a JUMP_BOOKEND_SELECTED state
+        mSeekableSliderTracker.setState(SliderState.JUMP_BOOKEND_SELECTED)
+
+        // GIVEN that the slider stopped tracking touch
+        sliderEventProducer.sendEvent(SliderEvent(SliderEventType.PROGRESS_CHANGE_BY_USER, 0.5f))
+
+        // THEN the tracker moves to the DRAG_HANDLE_DRAGGING state
+        assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.DRAG_HANDLE_DRAGGING)
+        verify(sliderStateListener).onProgress(anyFloat())
+        verifyNoMoreInteractions(sliderStateListener)
+    }
+
+    @Test
+    fun touchRelease_onJumpBookendSelected_movesToIdle() = runTest {
+        initTracker(testScheduler)
+
+        // GIVEN a JUMP_BOOKEND_SELECTED state
+        mSeekableSliderTracker.setState(SliderState.JUMP_BOOKEND_SELECTED)
+
+        // GIVEN that the slider stopped tracking touch
+        sliderEventProducer.sendEvent(SliderEvent(SliderEventType.STOPPED_TRACKING_TOUCH, 0.5f))
+
+        // THEN the tracker executes on onHandleReleasedFromTouch before moving to the IDLE state
+        verify(sliderStateListener).onHandleReleasedFromTouch()
+        assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.IDLE)
+        verifyNoMoreInteractions(sliderStateListener)
+    }
+
+    // Tests on the DRAG_HANDLE_ACQUIRED state
+
+    @Test
+    fun progressChangeByUser_onHandleAcquired_movesToDragHandleDragging() = runTest {
+        initTracker(testScheduler)
+
+        // GIVEN a DRAG_HANDLE_ACQUIRED_BY_TOUCH state
+        mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_ACQUIRED_BY_TOUCH)
+
+        // GIVEN a progress change by the user
+        val progress = 0.5f
+        sliderEventProducer.sendEvent(
+            SliderEvent(SliderEventType.PROGRESS_CHANGE_BY_USER, progress)
+        )
+
+        // THEN the tracker moves to the DRAG_HANDLE_DRAGGING state
+        verify(sliderStateListener).onProgress(progress)
+        assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.DRAG_HANDLE_DRAGGING)
+        verifyNoMoreInteractions(sliderStateListener)
+    }
+
+    @Test
+    fun touchRelease_onHandleAcquired_movesToIdle() = runTest {
+        initTracker(testScheduler)
+
+        // GIVEN a DRAG_HANDLE_ACQUIRED_BY_TOUCH state
+        mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_ACQUIRED_BY_TOUCH)
+
+        // GIVEN that the handle stops tracking touch
+        sliderEventProducer.sendEvent(SliderEvent(SliderEventType.STOPPED_TRACKING_TOUCH, 0.5f))
+
+        // THEN the tracker executes on onHandleReleasedFromTouch before moving to the IDLE state
+        verify(sliderStateListener).onHandleReleasedFromTouch()
+        assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.IDLE)
+        verifyNoMoreInteractions(sliderStateListener)
+    }
+
+    // Tests on DRAG_HANDLE_DRAGGING
+
+    @Test
+    fun progressChangeByUser_onHandleDragging_progressOutsideOfBookends_doesNotChangeState() =
+        runTest {
+            initTracker(testScheduler)
+
+            // GIVEN a DRAG_HANDLE_DRAGGING state
+            mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_DRAGGING)
+
+            // GIVEN a progress change by the user outside of bookend bounds
+            val progress = 0.5f
+            sliderEventProducer.sendEvent(
+                SliderEvent(SliderEventType.PROGRESS_CHANGE_BY_USER, progress)
+            )
+
+            // THEN the tracker does not change state and executes the onProgress call
+            assertThat(mSeekableSliderTracker.currentState)
+                .isEqualTo(SliderState.DRAG_HANDLE_DRAGGING)
+            verify(sliderStateListener).onProgress(progress)
+            verifyNoMoreInteractions(sliderStateListener)
+        }
+
+    @Test
+    fun progressChangeByUser_onHandleDragging_reachesLowerBookend_movesToHandleReachedBookend() =
+        runTest {
+            val config = SeekableSliderTrackerConfig()
+            initTracker(testScheduler, config)
+
+            // GIVEN a DRAG_HANDLE_DRAGGING state
+            mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_DRAGGING)
+
+            // GIVEN a progress change by the user reaching the lower bookend
+            val progress = config.lowerBookendThreshold - 0.01f
+            sliderEventProducer.sendEvent(
+                SliderEvent(SliderEventType.PROGRESS_CHANGE_BY_USER, progress)
+            )
+
+            // THEN the tracker moves to the DRAG_HANDLE_REACHED_BOOKEND state and executes the
+            // corresponding callback
+            assertThat(mSeekableSliderTracker.currentState)
+                .isEqualTo(SliderState.DRAG_HANDLE_REACHED_BOOKEND)
+            verify(sliderStateListener).onLowerBookend()
+            verifyNoMoreInteractions(sliderStateListener)
+        }
+
+    @Test
+    fun progressChangeByUser_onHandleDragging_reachesUpperBookend_movesToHandleReachedBookend() =
+        runTest {
+            val config = SeekableSliderTrackerConfig()
+            initTracker(testScheduler, config)
+
+            // GIVEN a DRAG_HANDLE_DRAGGING state
+            mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_DRAGGING)
+
+            // GIVEN a progress change by the user reaching the upper bookend
+            val progress = config.upperBookendThreshold + 0.01f
+            sliderEventProducer.sendEvent(
+                SliderEvent(SliderEventType.PROGRESS_CHANGE_BY_USER, progress)
+            )
+
+            // THEN the tracker moves to the DRAG_HANDLE_REACHED_BOOKEND state and executes the
+            // corresponding callback
+            assertThat(mSeekableSliderTracker.currentState)
+                .isEqualTo(SliderState.DRAG_HANDLE_REACHED_BOOKEND)
+            verify(sliderStateListener).onUpperBookend()
+            verifyNoMoreInteractions(sliderStateListener)
+        }
+
+    @Test
+    fun touchRelease_onHandleDragging_movesToIdle() = runTest {
+        initTracker(testScheduler)
+
+        // GIVEN a DRAG_HANDLE_DRAGGING state
+        mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_DRAGGING)
+
+        // GIVEN that the slider stops tracking touch
+        sliderEventProducer.sendEvent(SliderEvent(SliderEventType.STOPPED_TRACKING_TOUCH, 0.5f))
+
+        // THEN the tracker executes on onHandleReleasedFromTouch before moving to the IDLE state
+        verify(sliderStateListener).onHandleReleasedFromTouch()
+        assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.IDLE)
+        verifyNoMoreInteractions(sliderStateListener)
+    }
+
+    // Tests on the DRAG_HANDLE_REACHED_BOOKEND state
+
+    @Test
+    fun progressChangeByUser_outsideOfBookendRange_onLowerBookend_movesToDragHandleDragging() =
+        runTest {
+            val config = SeekableSliderTrackerConfig()
+            initTracker(testScheduler, config)
+
+            // GIVEN a DRAG_HANDLE_REACHED_BOOKEND state
+            mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_REACHED_BOOKEND)
+
+            // GIVEN a progress event that falls outside of the lower bookend range
+            val progress = config.lowerBookendThreshold + 0.01f
+            sliderEventProducer.sendEvent(
+                SliderEvent(SliderEventType.PROGRESS_CHANGE_BY_USER, progress)
+            )
+
+            // THEN the tracker moves to the DRAG_HANDLE_DRAGGING state and executes accordingly
+            verify(sliderStateListener).onProgress(progress)
+            assertThat(mSeekableSliderTracker.currentState)
+                .isEqualTo(SliderState.DRAG_HANDLE_DRAGGING)
+            verifyNoMoreInteractions(sliderStateListener)
+        }
+
+    @Test
+    fun progressChangeByUser_insideOfBookendRange_onLowerBookend_doesNotChangeState() = runTest {
+        val config = SeekableSliderTrackerConfig()
+        initTracker(testScheduler, config)
+
+        // GIVEN a DRAG_HANDLE_REACHED_BOOKEND state
+        mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_REACHED_BOOKEND)
+
+        // GIVEN a progress event that falls inside of the lower bookend range
+        val progress = config.lowerBookendThreshold - 0.01f
+        sliderEventProducer.sendEvent(
+            SliderEvent(SliderEventType.PROGRESS_CHANGE_BY_USER, progress)
+        )
+
+        // THEN the tracker stays in the current state and executes accordingly
+        verify(sliderStateListener).onLowerBookend()
+        assertThat(mSeekableSliderTracker.currentState)
+            .isEqualTo(SliderState.DRAG_HANDLE_REACHED_BOOKEND)
+        verifyNoMoreInteractions(sliderStateListener)
+    }
+
+    @Test
+    fun progressChangeByUser_outsideOfBookendRange_onUpperBookend_movesToDragHandleDragging() =
+        runTest {
+            val config = SeekableSliderTrackerConfig()
+            initTracker(testScheduler, config)
+
+            // GIVEN a DRAG_HANDLE_REACHED_BOOKEND state
+            mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_REACHED_BOOKEND)
+
+            // GIVEN a progress event that falls outside of the upper bookend range
+            val progress = config.upperBookendThreshold - 0.01f
+            sliderEventProducer.sendEvent(
+                SliderEvent(SliderEventType.PROGRESS_CHANGE_BY_USER, progress)
+            )
+
+            // THEN the tracker moves to the DRAG_HANDLE_DRAGGING state and executes accordingly
+            verify(sliderStateListener).onProgress(progress)
+            assertThat(mSeekableSliderTracker.currentState)
+                .isEqualTo(SliderState.DRAG_HANDLE_DRAGGING)
+            verifyNoMoreInteractions(sliderStateListener)
+        }
+
+    @Test
+    fun progressChangeByUser_insideOfBookendRange_onUpperBookend_doesNotChangeState() = runTest {
+        val config = SeekableSliderTrackerConfig()
+        initTracker(testScheduler, config)
+
+        // GIVEN a DRAG_HANDLE_REACHED_BOOKEND state
+        mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_REACHED_BOOKEND)
+
+        // GIVEN a progress event that falls inside of the upper bookend range
+        val progress = config.upperBookendThreshold + 0.01f
+        sliderEventProducer.sendEvent(
+            SliderEvent(SliderEventType.PROGRESS_CHANGE_BY_USER, progress)
+        )
+
+        // THEN the tracker stays in the current state and executes accordingly
+        verify(sliderStateListener).onUpperBookend()
+        assertThat(mSeekableSliderTracker.currentState)
+            .isEqualTo(SliderState.DRAG_HANDLE_REACHED_BOOKEND)
+        verifyNoMoreInteractions(sliderStateListener)
+    }
+
+    @Test
+    fun touchRelease_onHandleReachedBookend_movesToIdle() = runTest {
+        initTracker(testScheduler)
+
+        // GIVEN a DRAG_HANDLE_REACHED_BOOKEND state
+        mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_REACHED_BOOKEND)
+
+        // GIVEN that the handle stops tracking touch
+        sliderEventProducer.sendEvent(SliderEvent(SliderEventType.STOPPED_TRACKING_TOUCH, 0.5f))
+
+        // THEN the tracker executes on onHandleReleasedFromTouch before moving to the IDLE state
+        verify(sliderStateListener).onHandleReleasedFromTouch()
+        assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.IDLE)
+        verifyNoMoreInteractions(sliderStateListener)
+    }
+
+    @OptIn(ExperimentalCoroutinesApi::class)
+    private fun initTracker(
+        scheduler: TestCoroutineScheduler,
+        config: SeekableSliderTrackerConfig = SeekableSliderTrackerConfig(),
+    ) {
+        mSeekableSliderTracker =
+            SeekableSliderTracker(
+                sliderStateListener,
+                sliderEventProducer,
+                UnconfinedTestDispatcher(scheduler),
+                config
+            )
+        mSeekableSliderTracker.startTracking()
+    }
+}
-- 
GitLab


From 3068b00e43c538d72db77036173c1cce51152250 Mon Sep 17 00:00:00 2001
From: Juan Sebastian Martinez <juansmartinez@google.com>
Date: Wed, 6 Sep 2023 14:30:02 -0700
Subject: [PATCH 90/95] Introducing haptic components to the brightness slider.

The components come in the form of a slider state tracker, a slider
event producer, and a slider state listener with concrete
implementations for the purpose of haptic feedback based on the slider
progress and velocity. The components are incorporated as a bundle
inside a BrightnessSliderHaptic plugin added to the
BrightnessSliderController. The new feature is protected by a flag.

Test: atest BrightnessSliderHapticPluginImplTest
Test: atest BrightnessSlidercontrollerTest
Bug: 295932558
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:9f288982db8e863b49c6d249c168202516874a2f)

Change-Id: I52b954b8a108a66feee524e152bcc1f882669dd0
---
 .../BrightnessSliderController.java           |  68 +++++++++++-
 .../BrightnessSliderHapticPlugin.kt           |  46 ++++++++
 .../BrightnessSliderHapticPluginImpl.kt       |  69 ++++++++++++
 .../BrightnessSliderControllerTest.kt         |  12 ++-
 .../BrightnessSliderHapticPluginImplTest.kt   | 102 ++++++++++++++++++
 5 files changed, 292 insertions(+), 5 deletions(-)
 create mode 100644 packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPlugin.kt
 create mode 100644 packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPluginImpl.kt
 create mode 100644 packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPluginImplTest.kt

diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderController.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderController.java
index d0d37c4e685f..516d19298b4b 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderController.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderController.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.settings.brightness;
 
+import static com.android.systemui.flags.Flags.HAPTIC_BRIGHTNESS_SLIDER;
+
 import android.content.Context;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
@@ -30,12 +32,19 @@ import com.android.settingslib.RestrictedLockUtils;
 import com.android.systemui.Gefingerpoken;
 import com.android.systemui.R;
 import com.android.systemui.classifier.Classifier;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.flags.FeatureFlagsClassic;
+import com.android.systemui.haptics.slider.SeekableSliderEventProducer;
 import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.statusbar.VibratorHelper;
 import com.android.systemui.statusbar.policy.BrightnessMirrorController;
 import com.android.systemui.util.ViewController;
+import com.android.systemui.util.time.SystemClock;
 
 import javax.inject.Inject;
 
+import kotlinx.coroutines.CoroutineDispatcher;
+
 /**
  * {@code ViewController} for a {@code BrightnessSliderView}
  *
@@ -55,12 +64,21 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV
     private final FalsingManager mFalsingManager;
     private final UiEventLogger mUiEventLogger;
 
+    private final BrightnessSliderHapticPlugin mBrightnessSliderHapticPlugin;
+
     private final Gefingerpoken mOnInterceptListener = new Gefingerpoken() {
         @Override
         public boolean onInterceptTouchEvent(MotionEvent ev) {
             int action = ev.getActionMasked();
             if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
                 mFalsingManager.isFalseTouch(Classifier.BRIGHTNESS_SLIDER);
+                if (mBrightnessSliderHapticPlugin.getVelocityTracker() != null) {
+                    mBrightnessSliderHapticPlugin.getVelocityTracker().clear();
+                }
+            } else if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE) {
+                if (mBrightnessSliderHapticPlugin.getVelocityTracker() != null) {
+                    mBrightnessSliderHapticPlugin.getVelocityTracker().addMovement(ev);
+                }
             }
 
             return false;
@@ -75,10 +93,12 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV
     BrightnessSliderController(
             BrightnessSliderView brightnessSliderView,
             FalsingManager falsingManager,
-            UiEventLogger uiEventLogger) {
+            UiEventLogger uiEventLogger,
+            BrightnessSliderHapticPlugin brightnessSliderHapticPlugin) {
         super(brightnessSliderView);
         mFalsingManager = falsingManager;
         mUiEventLogger = uiEventLogger;
+        mBrightnessSliderHapticPlugin = brightnessSliderHapticPlugin;
     }
 
     /**
@@ -93,6 +113,7 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV
     protected void onViewAttached() {
         mView.setOnSeekBarChangeListener(mSeekListener);
         mView.setOnInterceptListener(mOnInterceptListener);
+        mBrightnessSliderHapticPlugin.start();
     }
 
     @Override
@@ -100,6 +121,7 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV
         mView.setOnSeekBarChangeListener(null);
         mView.setOnDispatchTouchEventListener(null);
         mView.setOnInterceptListener(null);
+        mBrightnessSliderHapticPlugin.stop();
     }
 
     @Override
@@ -204,6 +226,11 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV
         public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
             if (mListener != null) {
                 mListener.onChanged(mTracking, progress, false);
+                SeekableSliderEventProducer eventProducer =
+                        mBrightnessSliderHapticPlugin.getSeekableSliderEventProducer();
+                if (eventProducer != null) {
+                    eventProducer.onProgressChanged(seekBar, progress, fromUser);
+                }
             }
         }
 
@@ -213,6 +240,11 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV
             mUiEventLogger.log(BrightnessSliderEvent.SLIDER_STARTED_TRACKING_TOUCH);
             if (mListener != null) {
                 mListener.onChanged(mTracking, getValue(), false);
+                SeekableSliderEventProducer eventProducer =
+                        mBrightnessSliderHapticPlugin.getSeekableSliderEventProducer();
+                if (eventProducer != null) {
+                    eventProducer.onStartTrackingTouch(seekBar);
+                }
             }
 
             if (mMirrorController != null) {
@@ -227,6 +259,11 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV
             mUiEventLogger.log(BrightnessSliderEvent.SLIDER_STOPPED_TRACKING_TOUCH);
             if (mListener != null) {
                 mListener.onChanged(mTracking, getValue(), true);
+                SeekableSliderEventProducer eventProducer =
+                        mBrightnessSliderHapticPlugin.getSeekableSliderEventProducer();
+                if (eventProducer != null) {
+                    eventProducer.onStopTrackingTouch(seekBar);
+                }
             }
 
             if (mMirrorController != null) {
@@ -242,11 +279,26 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV
 
         private final FalsingManager mFalsingManager;
         private final UiEventLogger mUiEventLogger;
+        private final FeatureFlagsClassic mFeatureFlags;
+        private final VibratorHelper mVibratorHelper;
+        private final SystemClock mSystemClock;
+        private final CoroutineDispatcher mMainDispatcher;
 
         @Inject
-        public Factory(FalsingManager falsingManager, UiEventLogger uiEventLogger) {
+        public Factory(
+                FalsingManager falsingManager,
+                UiEventLogger uiEventLogger,
+                VibratorHelper vibratorHelper,
+                SystemClock clock,
+                FeatureFlagsClassic featureFlags,
+                @Main CoroutineDispatcher mainDispatcher
+        ) {
             mFalsingManager = falsingManager;
             mUiEventLogger = uiEventLogger;
+            mFeatureFlags = featureFlags;
+            mVibratorHelper = vibratorHelper;
+            mSystemClock = clock;
+            mMainDispatcher = mainDispatcher;
         }
 
         /**
@@ -262,7 +314,17 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV
             int layout = getLayout();
             BrightnessSliderView root = (BrightnessSliderView) LayoutInflater.from(context)
                     .inflate(layout, viewRoot, false);
-            return new BrightnessSliderController(root, mFalsingManager, mUiEventLogger);
+            BrightnessSliderHapticPlugin plugin;
+            if (mFeatureFlags.isEnabled(HAPTIC_BRIGHTNESS_SLIDER)) {
+                plugin = new BrightnessSliderHapticPluginImpl(
+                    mVibratorHelper,
+                    mSystemClock,
+                    mMainDispatcher
+                );
+            } else {
+                plugin = new BrightnessSliderHapticPlugin() {};
+            }
+            return new BrightnessSliderController(root, mFalsingManager, mUiEventLogger, plugin);
         }
 
         /** Get the layout to inflate based on what slider to use */
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPlugin.kt b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPlugin.kt
new file mode 100644
index 000000000000..f77511420491
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPlugin.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 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.settings.brightness
+
+import android.view.VelocityTracker
+import com.android.systemui.haptics.slider.SeekableSliderEventProducer
+
+/** Plugin component for the System UI brightness slider to incorporate dynamic haptics */
+interface BrightnessSliderHapticPlugin {
+
+    /** Finger velocity tracker */
+    val velocityTracker: VelocityTracker?
+        get() = null
+
+    /** Producer of slider events from the underlying [android.widget.SeekBar] */
+    val seekableSliderEventProducer: SeekableSliderEventProducer?
+        get() = null
+
+    /**
+     * Start the plugin.
+     *
+     * This starts the tracking of slider states, events and triggering of haptic feedback.
+     */
+    fun start() {}
+
+    /**
+     * Stop the plugin
+     *
+     * This stops the tracking of slider states, events and triggers of haptic feedback.
+     */
+    fun stop() {}
+}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPluginImpl.kt b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPluginImpl.kt
new file mode 100644
index 000000000000..32561f0b4c4f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPluginImpl.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2023 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.settings.brightness
+
+import android.view.VelocityTracker
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.haptics.slider.SeekableSliderEventProducer
+import com.android.systemui.haptics.slider.SeekableSliderTracker
+import com.android.systemui.haptics.slider.SliderHapticFeedbackProvider
+import com.android.systemui.haptics.slider.SliderTracker
+import com.android.systemui.statusbar.VibratorHelper
+import com.android.systemui.util.time.SystemClock
+import kotlinx.coroutines.CoroutineDispatcher
+
+/**
+ * Implementation of the [BrightnessSliderHapticPlugin].
+ *
+ * For the specifics of the brightness slider in System UI, a [SeekableSliderEventProducer] is used
+ * as the producer of slider events, a [SliderHapticFeedbackProvider] is used as the listener of
+ * slider states to play haptic feedback depending on the state, and a [SeekableSliderTracker] is
+ * used as the state machine handler that tracks and manipulates the slider state.
+ */
+class BrightnessSliderHapticPluginImpl
+@JvmOverloads
+constructor(
+    vibratorHelper: VibratorHelper,
+    systemClock: SystemClock,
+    @Main mainDispatcher: CoroutineDispatcher,
+    override val velocityTracker: VelocityTracker = VelocityTracker.obtain(),
+    override val seekableSliderEventProducer: SeekableSliderEventProducer =
+        SeekableSliderEventProducer(),
+) : BrightnessSliderHapticPlugin {
+
+    private val sliderHapticFeedbackProvider: SliderHapticFeedbackProvider =
+        SliderHapticFeedbackProvider(vibratorHelper, velocityTracker, clock = systemClock)
+    private val sliderTracker: SliderTracker =
+        SeekableSliderTracker(
+            sliderHapticFeedbackProvider,
+            seekableSliderEventProducer,
+            mainDispatcher,
+        )
+
+    val isTracking: Boolean
+        get() = sliderTracker.isTracking
+
+    override fun start() {
+        if (!sliderTracker.isTracking) {
+            sliderTracker.startTracking()
+        }
+    }
+
+    override fun stop() {
+        sliderTracker.stopTracking()
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderControllerTest.kt
index d75405fe503f..707a2971b1eb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderControllerTest.kt
@@ -40,7 +40,6 @@ import org.mockito.Mock
 import org.mockito.Mockito.isNull
 import org.mockito.Mockito.never
 import org.mockito.Mockito.notNull
-import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 import org.mockito.Mockito.`when` as whenever
@@ -61,6 +60,8 @@ class BrightnessSliderControllerTest : SysuiTestCase() {
     private lateinit var motionEvent: MotionEvent
     @Mock
     private lateinit var listener: ToggleSlider.Listener
+    @Mock
+    private lateinit var mBrightnessSliderHapticPlugin: BrightnessSliderHapticPlugin
 
     @Captor
     private lateinit var seekBarChangeCaptor: ArgumentCaptor<SeekBar.OnSeekBarChangeListener>
@@ -79,7 +80,12 @@ class BrightnessSliderControllerTest : SysuiTestCase() {
         whenever(motionEvent.copy()).thenReturn(motionEvent)
 
         mController =
-            BrightnessSliderController(brightnessSliderView, mFalsingManager, uiEventLogger)
+            BrightnessSliderController(
+                brightnessSliderView,
+                mFalsingManager,
+                uiEventLogger,
+                mBrightnessSliderHapticPlugin,
+            )
         mController.init()
         mController.setOnChangedListener(listener)
     }
@@ -94,6 +100,7 @@ class BrightnessSliderControllerTest : SysuiTestCase() {
         mController.onViewAttached()
 
         verify(brightnessSliderView).setOnSeekBarChangeListener(notNull())
+        verify(mBrightnessSliderHapticPlugin).start()
     }
 
     @Test
@@ -103,6 +110,7 @@ class BrightnessSliderControllerTest : SysuiTestCase() {
 
         verify(brightnessSliderView).setOnSeekBarChangeListener(isNull())
         verify(brightnessSliderView).setOnDispatchTouchEventListener(isNull())
+        verify(mBrightnessSliderHapticPlugin).stop()
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPluginImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPluginImplTest.kt
new file mode 100644
index 000000000000..51629b5c01e3
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPluginImplTest.kt
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2023 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.settings.brightness
+
+import android.view.VelocityTracker
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.haptics.slider.SeekableSliderEventProducer
+import com.android.systemui.statusbar.VibratorHelper
+import com.android.systemui.util.mockito.whenever
+import com.android.systemui.util.time.FakeSystemClock
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class BrightnessSliderHapticPluginImplTest : SysuiTestCase() {
+
+    @Mock private lateinit var vibratorHelper: VibratorHelper
+    @Mock private lateinit var velocityTracker: VelocityTracker
+    @Mock private lateinit var mainDispatcher: CoroutineDispatcher
+
+    private val systemClock = FakeSystemClock()
+    private val sliderEventProducer = SeekableSliderEventProducer()
+
+    private lateinit var plugin: BrightnessSliderHapticPluginImpl
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+        whenever(vibratorHelper.getPrimitiveDurations(anyInt())).thenReturn(intArrayOf(0))
+    }
+
+    @Test
+    fun start_beginsTrackingSlider() = runTest {
+        createPlugin(UnconfinedTestDispatcher(testScheduler))
+        plugin.start()
+
+        assertThat(plugin.isTracking).isTrue()
+    }
+
+    @Test
+    fun stop_stopsTrackingSlider() = runTest {
+        createPlugin(UnconfinedTestDispatcher(testScheduler))
+        // GIVEN that the plugin started the tracking component
+        plugin.start()
+
+        // WHEN called to stop
+        plugin.stop()
+
+        // THEN the tracking component stops
+        assertThat(plugin.isTracking).isFalse()
+    }
+
+    @Test
+    fun start_afterStop_startsTheTrackingAgain() = runTest {
+        createPlugin(UnconfinedTestDispatcher(testScheduler))
+        // GIVEN that the plugin started the tracking component
+        plugin.start()
+
+        // WHEN the plugin is restarted
+        plugin.stop()
+        plugin.start()
+
+        // THEN the tracking begins again
+        assertThat(plugin.isTracking).isTrue()
+    }
+
+    private fun createPlugin(dispatcher: CoroutineDispatcher) {
+        plugin =
+            BrightnessSliderHapticPluginImpl(
+                vibratorHelper,
+                systemClock,
+                dispatcher,
+                velocityTracker,
+                sliderEventProducer,
+            )
+    }
+}
-- 
GitLab


From 8c464b95c3ae6e8b976b5ac379320a54f08435f3 Mon Sep 17 00:00:00 2001
From: Melody Hsu <melodymhsu@google.com>
Date: Thu, 21 Sep 2023 18:30:42 +0000
Subject: [PATCH 91/95] Revert "Delete ScreenCapture#captureDisplay and
 DisplayCaptureArgs."

This reverts commit 8b04d81ffa7c458953f6d940f5007531639f42b7.

Bug: b/301083608
Reason for revert: investigating causes for b/301083608

Change-Id: I24e0387ccd360c22dee7e4a3e35057c986d4fd2b
---
 core/java/android/window/ScreenCapture.java | 125 +++++++++++++++++++-
 core/jni/android_window_ScreenCapture.cpp   |  53 +++++++++
 2 files changed, 177 insertions(+), 1 deletion(-)

diff --git a/core/java/android/window/ScreenCapture.java b/core/java/android/window/ScreenCapture.java
index e42193d45949..95e9e861bea2 100644
--- a/core/java/android/window/ScreenCapture.java
+++ b/core/java/android/window/ScreenCapture.java
@@ -24,6 +24,7 @@ import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.hardware.HardwareBuffer;
 import android.os.Build;
+import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.Log;
@@ -34,6 +35,7 @@ import libcore.util.NativeAllocationRegistry;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.function.ObjIntConsumer;
+
 /**
  * Handles display and layer captures for the system.
  *
@@ -43,6 +45,8 @@ public class ScreenCapture {
     private static final String TAG = "ScreenCapture";
     private static final int SCREENSHOT_WAIT_TIME_S = 4 * Build.HW_TIMEOUT_MULTIPLIER;
 
+    private static native int nativeCaptureDisplay(DisplayCaptureArgs captureArgs,
+            long captureListener);
     private static native int nativeCaptureLayers(LayerCaptureArgs captureArgs,
             long captureListener);
     private static native long nativeCreateScreenCaptureListener(
@@ -51,6 +55,37 @@ public class ScreenCapture {
     private static native long nativeReadListenerFromParcel(Parcel in);
     private static native long getNativeListenerFinalizer();
 
+    /**
+     * @param captureArgs     Arguments about how to take the screenshot
+     * @param captureListener A listener to receive the screenshot callback
+     * @hide
+     */
+    public static int captureDisplay(@NonNull DisplayCaptureArgs captureArgs,
+            @NonNull ScreenCaptureListener captureListener) {
+        return nativeCaptureDisplay(captureArgs, captureListener.mNativeObject);
+    }
+
+    /**
+     * Captures all the surfaces in a display and returns a {@link ScreenshotHardwareBuffer} with
+     * the content.
+     *
+     * @hide
+     */
+    public static ScreenshotHardwareBuffer captureDisplay(
+            DisplayCaptureArgs captureArgs) {
+        SynchronousScreenCaptureListener syncScreenCapture = createSyncCaptureListener();
+        int status = captureDisplay(captureArgs, syncScreenCapture);
+        if (status != 0) {
+            return null;
+        }
+
+        try {
+            return syncScreenCapture.getBuffer();
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
     /**
      * Captures a layer and its children and returns a {@link HardwareBuffer} with the content.
      *
@@ -483,6 +518,92 @@ public class ScreenCapture {
                 };
     }
 
+    /**
+     * The arguments class used to make display capture requests.
+     *
+     * @hide
+     * @see #nativeCaptureDisplay(DisplayCaptureArgs, long)
+     */
+    public static class DisplayCaptureArgs extends CaptureArgs {
+        private final IBinder mDisplayToken;
+        private final int mWidth;
+        private final int mHeight;
+        private final boolean mUseIdentityTransform;
+
+        private DisplayCaptureArgs(Builder builder) {
+            super(builder);
+            mDisplayToken = builder.mDisplayToken;
+            mWidth = builder.mWidth;
+            mHeight = builder.mHeight;
+            mUseIdentityTransform = builder.mUseIdentityTransform;
+        }
+
+        /**
+         * The Builder class used to construct {@link DisplayCaptureArgs}
+         */
+        public static class Builder extends CaptureArgs.Builder<Builder> {
+            private IBinder mDisplayToken;
+            private int mWidth;
+            private int mHeight;
+            private boolean mUseIdentityTransform;
+
+            /**
+             * Construct a new {@link LayerCaptureArgs} with the set parameters. The builder
+             * remains valid.
+             */
+            public DisplayCaptureArgs build() {
+                if (mDisplayToken == null) {
+                    throw new IllegalStateException(
+                            "Can't take screenshot with null display token");
+                }
+                return new DisplayCaptureArgs(this);
+            }
+
+            public Builder(IBinder displayToken) {
+                setDisplayToken(displayToken);
+            }
+
+            /**
+             * The display to take the screenshot of.
+             */
+            public Builder setDisplayToken(IBinder displayToken) {
+                mDisplayToken = displayToken;
+                return this;
+            }
+
+            /**
+             * Set the desired size of the returned buffer. The raw screen  will be  scaled down to
+             * this size
+             *
+             * @param width  The desired width of the returned buffer. Caller may pass in 0 if no
+             *               scaling is desired.
+             * @param height The desired height of the returned buffer. Caller may pass in 0 if no
+             *               scaling is desired.
+             */
+            public Builder setSize(int width, int height) {
+                mWidth = width;
+                mHeight = height;
+                return this;
+            }
+
+            /**
+             * Replace the rotation transform of the display with the identity transformation while
+             * taking the screenshot. This ensures the screenshot is taken in the ROTATION_0
+             * orientation. Set this value to false if the screenshot should be taken in the
+             * current screen orientation.
+             */
+            public Builder setUseIdentityTransform(boolean useIdentityTransform) {
+                mUseIdentityTransform = useIdentityTransform;
+                return this;
+            }
+
+            @Override
+            Builder getThis() {
+                return this;
+            }
+        }
+    }
+
     /**
      * The arguments class used to make layer capture requests.
      *
@@ -561,6 +682,7 @@ public class ScreenCapture {
 
     /**
      * The object used to receive the results when invoking screen capture requests via
+     * {@link #captureDisplay(DisplayCaptureArgs, ScreenCaptureListener)} or
      * {@link #captureLayers(LayerCaptureArgs, ScreenCaptureListener)}
      *
      * This listener can only be used for a single call to capture content call.
@@ -662,7 +784,8 @@ public class ScreenCapture {
 
     /**
      * Helper class to synchronously get the {@link ScreenshotHardwareBuffer} when calling
-     * {@link #captureLayers(LayerCaptureArgs, ScreenCaptureListener)}
+     * {@link #captureLayers(LayerCaptureArgs, ScreenCaptureListener)} or
+     * {@link #captureDisplay(DisplayCaptureArgs, ScreenCaptureListener)}
      */
     public abstract static class SynchronousScreenCaptureListener extends ScreenCaptureListener {
         SynchronousScreenCaptureListener(ObjIntConsumer<ScreenshotHardwareBuffer> consumer) {
diff --git a/core/jni/android_window_ScreenCapture.cpp b/core/jni/android_window_ScreenCapture.cpp
index beb8c9b2d12f..bdf7eaa8aace 100644
--- a/core/jni/android_window_ScreenCapture.cpp
+++ b/core/jni/android_window_ScreenCapture.cpp
@@ -49,6 +49,13 @@ static struct {
     jfieldID hintForSeamlessTransition;
 } gCaptureArgsClassInfo;
 
+static struct {
+    jfieldID displayToken;
+    jfieldID width;
+    jfieldID height;
+    jfieldID useIdentityTransform;
+} gDisplayCaptureArgsClassInfo;
+
 static struct {
     jfieldID layer;
     jfieldID childrenOnly;
@@ -174,6 +181,39 @@ static void getCaptureArgs(JNIEnv* env, jobject captureArgsObject, CaptureArgs&
                                  gCaptureArgsClassInfo.hintForSeamlessTransition);
 }
 
+static DisplayCaptureArgs displayCaptureArgsFromObject(JNIEnv* env,
+                                                       jobject displayCaptureArgsObject) {
+    DisplayCaptureArgs captureArgs;
+    getCaptureArgs(env, displayCaptureArgsObject, captureArgs);
+
+    captureArgs.displayToken =
+            ibinderForJavaObject(env,
+                                 env->GetObjectField(displayCaptureArgsObject,
+                                                     gDisplayCaptureArgsClassInfo.displayToken));
+    captureArgs.width =
+            env->GetIntField(displayCaptureArgsObject, gDisplayCaptureArgsClassInfo.width);
+    captureArgs.height =
+            env->GetIntField(displayCaptureArgsObject, gDisplayCaptureArgsClassInfo.height);
+    captureArgs.useIdentityTransform =
+            env->GetBooleanField(displayCaptureArgsObject,
+                                 gDisplayCaptureArgsClassInfo.useIdentityTransform);
+    return captureArgs;
+}
+
+static jint nativeCaptureDisplay(JNIEnv* env, jclass clazz, jobject displayCaptureArgsObject,
+                                 jlong screenCaptureListenerObject) {
+    const DisplayCaptureArgs captureArgs =
+            displayCaptureArgsFromObject(env, displayCaptureArgsObject);
+
+    if (captureArgs.displayToken == nullptr) {
+        return BAD_VALUE;
+    }
+
+    sp<gui::IScreenCaptureListener> captureListener =
+            reinterpret_cast<gui::IScreenCaptureListener*>(screenCaptureListenerObject);
+    return ScreenshotClient::captureDisplay(captureArgs, captureListener);
+}
+
 static jint nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerCaptureArgsObject,
                                 jlong screenCaptureListenerObject) {
     LayerCaptureArgs captureArgs;
@@ -243,6 +283,8 @@ static jlong getNativeListenerFinalizer(JNIEnv* env, jclass clazz) {
 
 static const JNINativeMethod sScreenCaptureMethods[] = {
         // clang-format off
+    {"nativeCaptureDisplay", "(Landroid/window/ScreenCapture$DisplayCaptureArgs;J)I",
+            (void*)nativeCaptureDisplay },
     {"nativeCaptureLayers",  "(Landroid/window/ScreenCapture$LayerCaptureArgs;J)I",
             (void*)nativeCaptureLayers },
     {"nativeCreateScreenCaptureListener", "(Ljava/util/function/ObjIntConsumer;)J",
@@ -275,6 +317,17 @@ int register_android_window_ScreenCapture(JNIEnv* env) {
     gCaptureArgsClassInfo.hintForSeamlessTransition =
             GetFieldIDOrDie(env, captureArgsClazz, "mHintForSeamlessTransition", "Z");
 
+    jclass displayCaptureArgsClazz =
+            FindClassOrDie(env, "android/window/ScreenCapture$DisplayCaptureArgs");
+    gDisplayCaptureArgsClassInfo.displayToken =
+            GetFieldIDOrDie(env, displayCaptureArgsClazz, "mDisplayToken", "Landroid/os/IBinder;");
+    gDisplayCaptureArgsClassInfo.width =
+            GetFieldIDOrDie(env, displayCaptureArgsClazz, "mWidth", "I");
+    gDisplayCaptureArgsClassInfo.height =
+            GetFieldIDOrDie(env, displayCaptureArgsClazz, "mHeight", "I");
+    gDisplayCaptureArgsClassInfo.useIdentityTransform =
+            GetFieldIDOrDie(env, displayCaptureArgsClazz, "mUseIdentityTransform", "Z");
+
     jclass layerCaptureArgsClazz =
             FindClassOrDie(env, "android/window/ScreenCapture$LayerCaptureArgs");
     gLayerCaptureArgsClassInfo.layer =
-- 
GitLab


From 080aa5144236b361da8e4a0cb645876eb9ecb14e Mon Sep 17 00:00:00 2001
From: Alejandro Nijamkin <nijamkin@google.com>
Date: Fri, 22 Sep 2023 10:05:00 -0700
Subject: [PATCH 92/95] [flexiglass] Updates SceneContainerFlags.

Adds to new secondary flag dependencies, matching go/flexiglass-script.

Bug: 283121968
Test: not tested
Change-Id: I2c7b30cf0fd96c5ad855b200e5f22a357c33b465
---
 .../android/systemui/scene/shared/flag/SceneContainerFlags.kt   | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt
index 291d273d611f..f0650d34fc9d 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt
@@ -60,6 +60,8 @@ constructor(
                 Flags.MIGRATE_LOCK_ICON,
                 Flags.MIGRATE_NSSL,
                 Flags.MIGRATE_KEYGUARD_STATUS_VIEW,
+                Flags.NOTIFICATION_SHELF_REFACTOR,
+                Flags.MIGRATE_KEYGUARD_STATUS_BAR_VIEW,
             )
     }
 
-- 
GitLab


From e52958999c001486f421cdc874b4727a2994ff53 Mon Sep 17 00:00:00 2001
From: Diego Vela <diegovela@google.com>
Date: Mon, 11 Sep 2023 22:06:41 +0000
Subject: [PATCH 93/95] Report folding features to letterboxed apps.

Letterboxed apps lost support for Folding Features. We are enabling
reporting folding features to letterboxed apps again.
Report folding features if an Activity is embedded or not in
PiP.

Bug: 295785410
Test: atest CtsWindowManagerJetpackTestCases
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:b1deb55446c3b5a2d46cc2751ac0200ef5986fa2)
Merged-In: Ib964b22278c31982a3d6bf66abaab3dac0c4093b
Change-Id: Ib964b22278c31982a3d6bf66abaab3dac0c4093b
---
 .../extensions/WindowExtensionsImpl.java      |  9 +---
 .../layout/WindowLayoutComponentImpl.java     | 45 +++----------------
 2 files changed, 6 insertions(+), 48 deletions(-)

diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java
index 55eabb039c01..9da6c10c6d74 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java
@@ -19,7 +19,6 @@ package androidx.window.extensions;
 import android.app.ActivityThread;
 import android.app.Application;
 import android.content.Context;
-import android.window.TaskFragmentOrganizer;
 
 import androidx.annotation.NonNull;
 import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
@@ -81,13 +80,7 @@ public class WindowExtensionsImpl implements WindowExtensions {
                     Context context = getApplication();
                     DeviceStateManagerFoldingFeatureProducer producer =
                             getFoldingFeatureProducer();
-                    // TODO(b/263263909) Use the organizer to tell if an Activity is embededed.
-                    // Need to improve our Dependency Injection and centralize the logic.
-                    TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(command -> {
-                        throw new RuntimeException("Not allowed!");
-                    });
-                    mWindowLayoutComponent = new WindowLayoutComponentImpl(context, organizer,
-                            producer);
+                    mWindowLayoutComponent = new WindowLayoutComponentImpl(context, producer);
                 }
             }
         }
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
index 6db2ae4d2141..69c1d294eab0 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
@@ -24,7 +24,6 @@ import static androidx.window.util.ExtensionHelper.rotateRectToDisplayRotation;
 import static androidx.window.util.ExtensionHelper.transformToWindowSpaceRect;
 
 import android.app.Activity;
-import android.app.ActivityClient;
 import android.app.Application;
 import android.app.WindowConfiguration;
 import android.content.ComponentCallbacks;
@@ -34,8 +33,6 @@ import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.util.ArrayMap;
-import android.view.WindowManager;
-import android.window.TaskFragmentOrganizer;
 
 import androidx.annotation.GuardedBy;
 import androidx.annotation.NonNull;
@@ -51,7 +48,6 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
 import java.util.Set;
 
 /**
@@ -85,16 +81,12 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
     private final Map<java.util.function.Consumer<WindowLayoutInfo>, Consumer<WindowLayoutInfo>>
             mJavaToExtConsumers = new ArrayMap<>();
 
-    private final TaskFragmentOrganizer mTaskFragmentOrganizer;
-
     public WindowLayoutComponentImpl(@NonNull Context context,
-            @NonNull TaskFragmentOrganizer taskFragmentOrganizer,
             @NonNull DeviceStateManagerFoldingFeatureProducer foldingFeatureProducer) {
         ((Application) context.getApplicationContext())
                 .registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged());
         mFoldingFeatureProducer = foldingFeatureProducer;
         mFoldingFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
-        mTaskFragmentOrganizer = taskFragmentOrganizer;
     }
 
     /** Registers to listen to {@link CommonFoldingFeature} changes */
@@ -382,38 +374,11 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
             // Display features are not supported on secondary displays.
             return false;
         }
-        final int windowingMode;
-        IBinder activityToken = context.getActivityToken();
-        if (activityToken != null) {
-            final Configuration taskConfig = ActivityClient.getInstance().getTaskConfiguration(
-                    activityToken);
-            if (taskConfig == null) {
-                // If we cannot determine the task configuration for any reason, it is likely that
-                // we won't be able to determine its position correctly as well. DisplayFeatures'
-                // bounds in this case can't be computed correctly, so we should skip.
-                return false;
-            }
-            final Rect taskBounds = taskConfig.windowConfiguration.getBounds();
-            final WindowManager windowManager = Objects.requireNonNull(
-                    context.getSystemService(WindowManager.class));
-            final Rect maxBounds = windowManager.getMaximumWindowMetrics().getBounds();
-            boolean isTaskExpanded = maxBounds.equals(taskBounds);
-            /*
-             * We need to proxy being in full screen because when a user enters PiP and exits PiP
-             * the task windowingMode will report multi-window/pinned until the transition is
-             * finished in WM Shell.
-             * maxBounds == taskWindowBounds is a proxy check to verify the window is full screen
-             */
-            return isTaskExpanded;
-        } else {
-            // TODO(b/242674941): use task windowing mode for window context that associates with
-            //  activity.
-            windowingMode = context.getResources().getConfiguration().windowConfiguration
-                    .getWindowingMode();
-        }
-        // It is recommended not to report any display features in multi-window mode, since it
-        // won't be possible to synchronize the display feature positions with window movement.
-        return !WindowConfiguration.inMultiWindowMode(windowingMode);
+
+        // We do not report folding features for Activities in PiP because the bounds are
+        // not updated fast enough and the window is too small for the UI to adapt.
+        return context.getResources().getConfiguration().windowConfiguration
+                .getWindowingMode() != WindowConfiguration.WINDOWING_MODE_PINNED;
     }
 
     @GuardedBy("mLock")
-- 
GitLab


From 84c5a997f4b7a94fa84a8df4f92c777b80452ad4 Mon Sep 17 00:00:00 2001
From: Peter Kalauskas <peskal@google.com>
Date: Wed, 23 Aug 2023 13:39:23 -0700
Subject: [PATCH 94/95] Enable use_resource_processor for all sysui deps

This will make the build faster

Test: m checkbuild
Bug: 295208392
Change-Id: I675bea822a46fa9adda6c13589a20aa4d32db6f3
---
 .../SettingsLib/ActionBarShadow/Android.bp    |  1 +
 .../ActionBarShadow/AndroidManifest.xml       |  2 +-
 .../ActionButtonsPreference/Android.bp        |  1 +
 .../AndroidManifest.xml                       |  2 +-
 .../widget/ActionButtonsPreference.java       |  3 +-
 .../SettingsLib/ActivityEmbedding/Android.bp  |  1 +
 .../ActivityEmbedding/AndroidManifest.xml     |  2 +-
 packages/SettingsLib/AdaptiveIcon/Android.bp  |  1 +
 .../AdaptiveIcon/AndroidManifest.xml          |  2 +-
 .../settingslib/widget/AdaptiveIcon.java      |  1 +
 .../widget/AdaptiveOutlineDrawable.java       |  2 +
 packages/SettingsLib/AppPreference/Android.bp |  1 +
 .../AppPreference/AndroidManifest.xml         |  2 +-
 .../widget/AppHeaderPreference.java           |  2 +
 .../settingslib/widget/AppPreference.java     |  2 +
 .../widget/AppSwitchPreference.java           |  2 +-
 .../BannerMessagePreference/Android.bp        |  1 +
 .../AndroidManifest.xml                       |  2 +-
 .../widget/BannerMessagePreference.java       |  2 +-
 .../settingslib/widget/BannerMessageView.java |  4 +-
 .../SettingsLib/BarChartPreference/Android.bp |  1 +
 .../BarChartPreference/AndroidManifest.xml    |  2 +-
 .../settingslib/widget/BarChartInfo.java      |  2 +-
 .../widget/BarChartPreference.java            |  2 +-
 .../android/settingslib/widget/BarView.java   |  2 +-
 .../settingslib/widget/BarViewInfo.java       |  2 +-
 .../SettingsLib/ButtonPreference/Android.bp   |  1 +
 .../ButtonPreference/AndroidManifest.xml      |  2 +-
 .../settingslib/widget/ButtonPreference.java  |  2 +
 .../CollapsingToolbarBaseActivity/Android.bp  |  1 +
 .../AndroidManifest.xml                       |  2 +-
 .../BasePreferencesFragment.java              |  1 -
 .../CollapsingToolbarAppCompatActivity.java   |  3 +-
 .../CollapsingToolbarBaseActivity.java        |  1 -
 .../CollapsingToolbarDelegate.java            |  2 -
 .../widget/CollapsingCoordinatorLayout.java   |  2 +-
 .../DeviceStateRotationLock/Android.bp        |  1 +
 packages/SettingsLib/DisplayUtils/Android.bp  |  1 +
 .../SettingsLib/EmergencyNumber/Android.bp    |  1 +
 .../EntityHeaderWidgets/Android.bp            |  1 +
 .../EntityHeaderWidgets/AndroidManifest.xml   |  2 +-
 .../widget/AppEntitiesHeaderController.java   |  2 +
 .../settingslib/widget/AppEntityInfo.java     |  2 +
 .../SettingsLib/FooterPreference/Android.bp   |  1 +
 .../FooterPreference/AndroidManifest.xml      |  2 +-
 .../settingslib/widget/FooterPreference.java  |  4 +-
 .../settingslib/widget/LinkTextView.java      |  2 +
 packages/SettingsLib/HelpUtils/Android.bp     |  1 +
 .../SettingsLib/HelpUtils/AndroidManifest.xml |  2 +-
 .../com/android/settingslib/HelpUtils.java    |  2 +-
 .../IllustrationPreference/Android.bp         |  1 +
 .../AndroidManifest.xml                       |  2 +-
 .../widget/IllustrationPreference.java        |  7 +-
 .../SettingsLib/LayoutPreference/Android.bp   |  1 +
 .../LayoutPreference/AndroidManifest.xml      |  2 +-
 .../settingslib/widget/LayoutPreference.java  | 16 ++--
 .../MainSwitchPreference/AndroidManifest.xml  |  2 +-
 .../settingslib/widget/MainSwitchBar.java     |  2 +
 .../widget/MainSwitchPreference.java          |  2 +
 .../widget/OnMainSwitchChangeListener.java    |  2 +
 .../SettingsLib/ProfileSelector/Android.bp    |  1 +
 .../ProfileSelector/AndroidManifest.xml       |  2 +-
 .../widget/ProfileSelectFragment.java         |  1 +
 .../widget/ProfileViewPagerAdapter.java       |  1 +
 packages/SettingsLib/ProgressBar/Android.bp   |  1 +
 .../ProgressBar/AndroidManifest.xml           |  2 +-
 .../RadioButtonPreference/Android.bp          |  1 +
 .../RadioButtonPreference/AndroidManifest.xml |  2 +-
 .../widget/RadioButtonPreference.java         |  2 +
 .../RestrictedLockUtils/Android.bp            |  1 +
 .../RestrictedLockUtils/AndroidManifest.xml   |  2 +-
 .../SettingsLib/SchedulesProvider/Android.bp  |  1 +
 .../SettingsLib/SearchProvider/Android.bp     |  1 +
 .../SearchProvider/AndroidManifest.xml        |  2 +-
 packages/SettingsLib/SearchWidget/Android.bp  |  1 +
 .../SearchWidget/AndroidManifest.xml          |  2 +-
 .../SelectorWithWidgetPreference/Android.bp   |  1 +
 .../AndroidManifest.xml                       |  2 +-
 .../widget/SelectorWithWidgetPreference.java  |  2 +
 .../SettingsLib/SettingsSpinner/Android.bp    |  1 +
 .../SettingsSpinner/AndroidManifest.xml       |  2 +-
 .../widget/SettingsSpinnerAdapter.java        |  2 +-
 .../widget/SettingsSpinnerPreference.java     |  1 +
 packages/SettingsLib/SettingsTheme/Android.bp |  1 +
 .../SettingsTheme/AndroidManifest.xml         |  2 +-
 .../SettingsLib/SettingsTransition/Android.bp |  1 +
 .../SettingsTransition/AndroidManifest.xml    |  2 +-
 .../SettingsLib/Spa/screenshot/Android.bp     |  1 +
 .../model/enterprise/RestrictionsProvider.kt  |  2 +-
 .../spaprivileged/template/app/AppInfo.kt     |  2 +-
 packages/SettingsLib/Tile/Android.bp          |  1 +
 .../SettingsLib/TopIntroPreference/Android.bp |  1 +
 .../TopIntroPreference/AndroidManifest.xml    |  2 +-
 .../widget/TopIntroPreference.java            |  2 +
 .../TwoTargetPreference/Android.bp            |  1 +
 .../TwoTargetPreference/AndroidManifest.xml   |  2 +-
 .../widget/TwoTargetPreference.java           |  2 +
 .../UsageProgressBarPreference/Android.bp     |  1 +
 .../AndroidManifest.xml                       |  2 +-
 .../widget/UsageProgressBarPreference.java    |  2 +
 packages/SettingsLib/Utils/Android.bp         |  1 +
 packages/SettingsLib/search/Android.bp        |  1 +
 .../RestrictedSwitchPreference.java           |  4 +-
 .../bluetooth/BroadcastDialog.java            |  2 +-
 .../inputmethod/InputMethodPreference.java    |  2 +-
 .../wifi/AccessPointPreference.java           |  4 +-
 packages/SettingsLib/tests/integ/Android.bp   |  1 +
 .../tests/integ/AndroidManifest.xml           |  2 +-
 .../widget/SettingsSpinnerPreferenceTest.java |  2 +
 .../UsageProgressBarPreferenceTest.java       |  2 +
 .../SettingsLib/tests/robotests/Android.bp    |  1 +
 .../android/settingslib/HelpUtilsTest.java    |  8 +-
 .../PrimarySwitchPreferenceTest.java          |  3 +-
 .../CollapsingCoordinatorLayoutTest.java      |  8 +-
 .../widget/ActionButtonsPreferenceTest.java   | 82 ++++++++++---------
 .../settingslib/widget/AdaptiveIconTest.java  |  8 +-
 .../widget/AdaptiveOutlineDrawableTest.java   |  2 +
 .../AppEntitiesHeaderControllerTest.java      | 14 ++--
 .../widget/AppHeaderPreferenceTest.java       |  2 +-
 .../settingslib/widget/AppPreferenceTest.java |  4 +-
 .../widget/BannerMessagePreferenceTest.java   |  4 +-
 .../widget/BarChartPreferenceTest.java        | 34 ++++----
 .../widget/ButtonPreferenceTest.java          |  4 +-
 .../widget/FooterPreferenceTest.java          |  4 +-
 .../widget/IllustrationPreferenceTest.java    |  3 +
 .../widget/LayoutPreferenceTest.java          |  2 +
 .../settingslib/widget/MainSwitchBarTest.java |  2 +
 .../widget/MainSwitchPreferenceTest.java      |  2 +
 .../widget/RadioButtonPreferenceTest.java     |  2 +
 .../SelectorWithWidgetPreferenceTest.java     |  2 +
 .../widget/TwoTargetPreferenceTest.java       |  2 +
 packages/SettingsLib/tests/unit/Android.bp    |  1 +
 packages/SystemUI/Android.bp                  | 14 ++--
 .../accessibilitymenu/Android.bp              |  1 +
 .../accessibilitymenu/tests/Android.bp        |  1 +
 packages/SystemUI/animation/Android.bp        |  2 +
 packages/SystemUI/common/Android.bp           |  1 +
 packages/SystemUI/compose/core/Android.bp     |  1 +
 .../SystemUI/compose/core/tests/Android.bp    |  1 +
 packages/SystemUI/compose/features/Android.bp |  1 +
 .../bouncer/ui/composable/BouncerScene.kt     |  2 +-
 .../bouncer/ui/composable/PinBouncer.kt       |  2 +-
 .../bouncer/ui/composable/PinInputDisplay.kt  |  2 +-
 .../keyguard/ui/composable/LockscreenScene.kt |  2 +-
 .../people/ui/compose/PeopleScreen.kt         |  2 +-
 .../people/ui/compose/PeopleScreenEmpty.kt    |  2 +-
 .../qs/footer/ui/compose/FooterActions.kt     |  2 +-
 .../shade/ui/composable/ShadeHeader.kt        |  2 +-
 .../compose/features/tests/Android.bp         |  1 +
 packages/SystemUI/customization/Android.bp    |  1 +
 packages/SystemUI/log/Android.bp              |  1 +
 packages/SystemUI/plugin/Android.bp           |  1 +
 .../SystemUI/plugin/ExamplePlugin/Android.bp  |  1 +
 packages/SystemUI/shared/Android.bp           |  1 +
 .../src/com/android/keyguard/CarrierText.java |  2 +-
 .../android/keyguard/CarrierTextManager.java  |  2 +-
 .../ConnectedDisplayKeyguardPresentation.kt   |  2 +-
 .../keyguard/EmergencyCarrierArea.java        |  2 +-
 .../keyguard/FaceWakeUpTriggersConfig.kt      |  2 +-
 .../keyguard/KeyguardAbsKeyInputView.java     |  2 +-
 .../KeyguardAbsKeyInputViewController.java    |  2 +-
 .../KeyguardClockAccessibilityDelegate.java   |  2 +-
 .../android/keyguard/KeyguardClockSwitch.java |  2 +-
 .../KeyguardClockSwitchController.java        |  4 +-
 .../keyguard/KeyguardDisplayManager.java      |  2 +-
 .../android/keyguard/KeyguardEsimArea.java    |  2 +-
 .../android/keyguard/KeyguardInputView.java   |  2 +-
 .../keyguard/KeyguardInputViewController.java |  2 +-
 .../android/keyguard/KeyguardMessageArea.java |  2 +-
 .../com/android/keyguard/KeyguardPINView.java |  2 +-
 .../keyguard/KeyguardPasswordView.java        |  2 +-
 .../KeyguardPasswordViewController.java       |  2 +-
 .../android/keyguard/KeyguardPatternView.java |  2 +-
 .../KeyguardPatternViewController.java        |  2 +-
 .../keyguard/KeyguardPinBasedInputView.java   |  2 +-
 .../KeyguardPinBasedInputViewController.java  |  2 +-
 .../keyguard/KeyguardPinViewController.java   |  2 +-
 .../keyguard/KeyguardSecurityContainer.java   |  2 +-
 .../KeyguardSecurityContainerController.java  |  2 +-
 .../keyguard/KeyguardSecurityViewFlipper.java |  2 +-
 ...KeyguardSecurityViewFlipperController.java |  2 +-
 .../KeyguardSecurityViewTransition.kt         |  2 +-
 .../android/keyguard/KeyguardSimInputView.kt  |  2 +-
 .../android/keyguard/KeyguardSimPinView.java  |  2 +-
 .../KeyguardSimPinViewController.java         |  4 +-
 .../android/keyguard/KeyguardSimPukView.java  |  2 +-
 .../KeyguardSimPukViewController.java         | 14 ++--
 .../android/keyguard/KeyguardSliceView.java   |  2 +-
 .../keyguard/KeyguardStatusAreaView.kt        |  2 +-
 .../android/keyguard/KeyguardStatusView.java  |  2 +-
 .../KeyguardStatusViewController.java         |  2 +-
 .../keyguard/KeyguardUnfoldTransition.kt      |  2 +-
 .../keyguard/KeyguardUpdateMonitor.java       |  2 +-
 .../keyguard/KeyguardUserSwitcherAnchor.kt    |  2 +-
 .../KeyguardUserSwitcherPopupMenu.java        |  2 +-
 .../com/android/keyguard/LockIconView.java    |  2 +-
 .../keyguard/LockIconViewController.java      |  2 +-
 .../com/android/keyguard/NumPadButton.java    |  2 +-
 .../src/com/android/keyguard/NumPadKey.java   |  2 +-
 .../android/keyguard/PasswordTextView.java    |  2 +-
 .../com/android/keyguard/PinShapeAdapter.kt   |  2 +-
 .../android/keyguard/PinShapeHintingView.java |  2 +-
 .../keyguard/PinShapeNonHintingView.java      |  2 +-
 .../keyguard/dagger/ClockRegistryModule.java  |  2 +-
 .../dagger/KeyguardBouncerModule.java         |  2 +-
 .../dagger/KeyguardStatusBarViewModule.java   |  2 +-
 .../dagger/KeyguardStatusViewModule.java      |  2 +-
 .../systemui/AutoReinflateContainer.java      |  2 +
 .../systemui/CameraAvailabilityListener.kt    |  2 +-
 .../com/android/systemui/DessertCaseView.java |  2 +
 .../com/android/systemui/DualToneHandler.kt   |  1 +
 .../com/android/systemui/ExpandHelper.java    |  2 +
 .../systemui/ForegroundServicesDialog.java    |  1 +
 .../systemui/GuestResumeSessionReceiver.java  |  1 +
 .../systemui/GuestSessionNotification.java    |  1 +
 .../android/systemui/HardwareBgDrawable.java  |  1 +
 .../systemui/PluginInflateContainer.java      |  1 +
 .../android/systemui/ScreenDecorations.java   |  5 +-
 .../systemui/SlicePermissionActivity.java     |  2 +
 .../src/com/android/systemui/SwipeHelper.java |  1 +
 .../android/systemui/SystemUIApplication.java |  1 +
 .../android/systemui/SystemUIInitializer.java |  1 +
 .../com/android/systemui/SystemUIService.java |  1 +
 .../MagnificationModeSwitch.java              |  2 +-
 .../MagnificationSettingsController.java      |  2 +-
 .../accessibility/MirrorWindowControl.java    |  2 +-
 .../SimpleMirrorWindowControl.java            |  2 +-
 .../accessibility/WindowMagnification.java    |  4 +-
 ...indowMagnificationAnimationController.java |  2 +-
 .../WindowMagnificationController.java        |  2 +-
 .../WindowMagnificationSettings.java          |  2 +-
 .../AccessibilityTargetAdapter.java           |  2 +-
 .../floatingmenu/MenuEduTooltipView.java      |  2 +-
 .../MenuItemAccessibilityDelegate.java        |  2 +-
 .../floatingmenu/MenuMessageView.java         |  2 +-
 .../floatingmenu/MenuViewAppearance.java      |  2 +-
 .../floatingmenu/MenuViewLayer.java           |  2 +-
 .../fontscaling/FontScalingDialog.kt          |  2 +-
 .../systemui/assist/AssistDisclosure.java     |  2 +-
 .../systemui/assist/AssistManager.java        |  2 +-
 .../assist/ui/DefaultUiController.java        |  2 +-
 .../systemui/assist/ui/DisplayUtils.java      |  2 +-
 .../assist/ui/InvocationLightsView.java       |  2 +-
 .../assist/ui/PathSpecCornerPathRenderer.java |  2 +-
 .../battery/AccessorizedBatteryDrawable.kt    |  2 +-
 .../systemui/battery/BatteryMeterView.java    |  2 +-
 .../battery/BatteryMeterViewController.java   |  2 +-
 .../AuthBiometricFaceIconController.kt        |  2 +-
 ...ometricFingerprintAndFaceIconController.kt |  2 +-
 .../AuthBiometricFingerprintIconController.kt |  2 +-
 .../biometrics/AuthContainerView.java         |  2 +-
 .../systemui/biometrics/AuthController.java   |  6 +-
 .../biometrics/AuthPanelController.java       |  2 +-
 .../biometrics/AuthRippleController.kt        |  2 +-
 .../BiometricNotificationDialogFactory.java   |  2 +-
 .../BiometricNotificationService.java         |  2 +-
 .../FaceAuthAccessibilityDelegate.kt          |  2 +-
 .../biometrics/FaceHelpMessageDeferral.kt     |  2 +-
 .../systemui/biometrics/SideFpsController.kt  |  2 +-
 .../biometrics/UdfpsControllerOverlay.kt      |  2 +-
 .../biometrics/UdfpsDialogMeasureAdapter.java |  2 +-
 .../systemui/biometrics/UdfpsDrawable.kt      |  2 +-
 .../systemui/biometrics/UdfpsFpmEmptyView.kt  |  2 +-
 .../UdfpsKeyguardAccessibilityDelegate.kt     |  2 +-
 .../UdfpsKeyguardViewControllerLegacy.kt      |  2 +-
 .../biometrics/UdfpsKeyguardViewLegacy.java   |  2 +-
 .../android/systemui/biometrics/UdfpsView.kt  |  2 +-
 .../domain/interactor/CredentialInteractor.kt |  2 +-
 .../biometrics/ui/BiometricPromptLayout.java  |  2 +-
 .../biometrics/ui/CredentialPasswordView.kt   |  2 +-
 .../ui/binder/BiometricViewBinder.kt          |  2 +-
 .../ui/binder/BiometricViewSizeBinder.kt      |  2 +-
 .../ui/binder/CredentialPasswordViewBinder.kt |  2 +-
 .../ui/binder/CredentialPatternViewBinder.kt  |  2 +-
 .../ui/binder/CredentialViewBinder.kt         |  2 +-
 .../biometrics/ui/binder/PinPadViewBinder.kt  |  2 +-
 .../ui/viewmodel/CredentialViewModel.kt       |  2 +-
 .../PromptFingerprintIconViewModel.kt         |  2 +-
 .../systemui/bluetooth/BroadcastDialog.java   |  2 +-
 .../data/factory/BouncerMessageFactory.kt     | 80 +++++++++---------
 .../domain/interactor/BouncerInteractor.kt    |  2 +-
 .../interactor/PrimaryBouncerInteractor.kt    |  2 +-
 .../systemui/bouncer/ui/BouncerMessageView.kt |  2 +-
 .../bouncer/ui/viewmodel/BouncerViewModel.kt  |  2 +-
 .../android/systemui/camera/CameraIntents.kt  |  2 +-
 .../charging/WiredChargingRippleController.kt |  2 +-
 .../charging/WirelessChargingLayout.java      |  2 +-
 .../systemui/classifier/FalsingModule.java    |  2 +-
 .../clipboardoverlay/ClipboardImageLoader.kt  |  2 +-
 .../clipboardoverlay/ClipboardModel.kt        |  2 +-
 .../ClipboardOverlayController.java           |  2 +-
 .../ClipboardOverlayUtils.java                |  2 +-
 .../ClipboardOverlayView.java                 |  2 +-
 .../clipboardoverlay/ClipboardToast.java      |  2 +-
 .../clipboardoverlay/EditTextActivity.java    |  2 +-
 .../clipboardoverlay/IntentCreator.java       |  2 +-
 .../dagger/ClipboardOverlayModule.java        |  2 +-
 .../ui/view/SeekBarWithIconButtonsView.java   |  2 +-
 .../ui/binder/CommunalWidgetViewBinder.kt     |  2 +-
 .../communal/ui/view/CommunalWidgetWrapper.kt |  2 +-
 .../sections/DefaultCommunalWidgetSection.kt  |  2 +-
 .../ComplicationLayoutEngine.java             |  2 +-
 .../dagger/ComplicationHostViewModule.java    |  2 +-
 .../DreamClockTimeComplicationComponent.kt    |  2 +-
 ...reamHomeControlsComplicationComponent.java |  2 +-
 .../DreamMediaEntryComplicationComponent.java |  2 +-
 .../dagger/RegisteredComplicationsModule.java |  2 +-
 .../systemui/contrast/ContrastDialog.kt       |  2 +-
 .../systemui/controls/ControlsServiceInfo.kt  |  2 +-
 .../systemui/controls/TooltipManager.kt       |  2 +-
 .../ControlsTileResourceConfigurationImpl.kt  |  2 +-
 .../controls/management/AppAdapter.kt         |  2 +-
 .../controls/management/ControlAdapter.kt     |  2 +-
 .../controls/management/ControlsAnimations.kt |  2 +-
 .../management/ControlsEditingActivity.kt     |  2 +-
 .../management/ControlsFavoritingActivity.kt  |  2 +-
 .../ControlsProviderSelectorActivity.kt       |  2 +-
 .../management/ControlsRequestDialog.kt       |  2 +-
 .../PanelConfirmationDialogFactory.kt         |  2 +-
 .../controls/management/StructureAdapter.kt   |  2 +-
 .../panels/AuthorizedPanelsRepositoryImpl.kt  |  2 +-
 .../settings/ControlsSettingsDialogManager.kt |  2 +-
 .../systemui/controls/ui/ChallengeDialogs.kt  |  2 +-
 .../systemui/controls/ui/ControlViewHolder.kt |  2 +-
 .../systemui/controls/ui/ControlsActivity.kt  |  2 +-
 .../controls/ui/ControlsDialogsFactory.kt     |  2 +-
 .../systemui/controls/ui/ControlsPopupMenu.kt |  2 +-
 .../controls/ui/ControlsUiControllerImpl.kt   |  2 +-
 .../systemui/controls/ui/DetailDialog.kt      |  2 +-
 .../controls/ui/PanelTaskViewController.kt    |  2 +-
 .../systemui/controls/ui/RenderInfo.kt        |  2 +-
 .../systemui/controls/ui/StatusBehavior.kt    |  2 +-
 .../controls/ui/TemperatureControlBehavior.kt |  2 +-
 .../systemui/controls/ui/ThumbnailBehavior.kt |  2 +-
 .../systemui/controls/ui/ToggleBehavior.kt    |  2 +-
 .../controls/ui/ToggleRangeBehavior.kt        |  2 +-
 .../systemui/controls/ui/TouchBehavior.kt     |  2 +-
 .../systemui/decor/CutoutDecorProviderImpl.kt |  2 +-
 .../decor/FaceScanningProviderFactory.kt      |  2 +-
 .../decor/PrivacyDotDecorProviderFactory.kt   |  2 +-
 .../RoundedCornerDecorProviderFactory.kt      |  2 +-
 .../decor/RoundedCornerDecorProviderImpl.kt   |  2 +-
 .../decor/RoundedCornerResDelegate.kt         |  2 +-
 .../ui/view/MirroringConfirmationDialog.kt    |  2 +-
 .../systemui/doze/AlwaysOnDisplayPolicy.java  |  2 +-
 .../systemui/doze/dagger/DozeModule.java      |  2 +-
 .../DreamOverlayAnimationsController.kt       |  2 +-
 .../DreamOverlayContainerViewController.java  |  2 +-
 .../dreams/DreamOverlayDotImageView.java      |  2 +-
 .../dreams/DreamOverlayStatusBarView.java     |  2 +-
 .../DreamOverlayStatusBarViewController.java  |  2 +-
 .../complication/dagger/ComplicationModule.kt |  2 +-
 .../systemui/dreams/dagger/DreamModule.java   |  2 +-
 .../dreams/dagger/DreamOverlayModule.java     |  2 +-
 .../touch/dagger/BouncerSwipeModule.java      |  2 +-
 .../dreams/touch/dagger/ShadeModule.java      |  2 +-
 .../systemui/dump/SystemUIConfigDumpable.kt   |  2 +-
 .../src/com/android/systemui/flags/Flags.kt   |  2 +-
 .../GlobalActionsColumnLayout.java            |  2 +-
 .../GlobalActionsDialogLite.java              | 42 +++++-----
 .../GlobalActionsFlatLayout.java              |  4 +-
 .../GlobalActionsGridLayout.java              |  2 +-
 .../globalactions/GlobalActionsLayout.java    |  2 +-
 .../GlobalActionsLayoutLite.java              |  4 +-
 .../globalactions/GlobalActionsPopupMenu.java |  2 +-
 .../GlobalActionsPowerDialog.java             |  4 +-
 .../systemui/globalactions/ShutdownUi.java    | 10 +--
 .../android/systemui/keyboard/KeyboardUI.java |  2 +-
 .../ui/view/KeyboardBacklightDialog.kt        |  2 +-
 .../keyguard/KeyguardSliceProvider.java       |  2 +-
 .../keyguard/KeyguardViewConfigurator.kt      |  2 +-
 .../keyguard/KeyguardViewMediator.java        |  2 +-
 .../keyguard/WakefulnessLifecycle.java        |  2 +-
 .../systemui/keyguard/WorkLockActivity.java   |  2 +-
 .../CameraQuickAffordanceConfig.kt            |  2 +-
 .../DoNotDisturbQuickAffordanceConfig.kt      |  2 +-
 .../FlashlightQuickAffordanceConfig.kt        |  2 +-
 ...meControlsKeyguardQuickAffordanceConfig.kt |  2 +-
 .../KeyguardQuickAffordanceConfig.kt          |  2 +-
 ...uickAffordanceLocalUserSelectionManager.kt |  2 +-
 .../MuteQuickAffordanceConfig.kt              |  2 +-
 ...odeScannerKeyguardQuickAffordanceConfig.kt |  2 +-
 ...cessWalletKeyguardQuickAffordanceConfig.kt |  2 +-
 .../VideoCameraQuickAffordanceConfig.kt       |  2 +-
 .../repository/BiometricSettingsRepository.kt |  2 +-
 .../DeviceEntryFaceAuthRepository.kt          |  2 +-
 .../KeyguardQuickAffordanceRepository.kt      |  2 +-
 .../repository/LightRevealScrimRepository.kt  |  2 +-
 .../domain/interactor/BurnInInteractor.kt     |  2 +-
 .../domain/interactor/KeyguardInteractor.kt   |  2 +-
 .../interactor/KeyguardLongPressInteractor.kt |  2 +-
 .../KeyguardQuickAffordanceInteractor.kt      |  2 +-
 .../SystemUIKeyguardFaceAuthInteractor.kt     |  2 +-
 ...KeyguardAmbientIndicationAreaViewBinder.kt |  2 +-
 .../ui/binder/KeyguardBottomAreaViewBinder.kt |  2 +-
 .../ui/binder/KeyguardIndicationAreaBinder.kt |  2 +-
 .../KeyguardQuickAffordanceOnTouchListener.kt |  2 +-
 .../KeyguardQuickAffordanceViewBinder.kt      |  2 +-
 .../ui/binder/KeyguardRootViewBinder.kt       |  2 +-
 .../ui/binder/KeyguardSettingsViewBinder.kt   |  2 +-
 .../binder/UdfpsKeyguardInternalViewBinder.kt |  2 +-
 .../ui/binder/UdfpsKeyguardViewBinder.kt      |  2 +-
 .../ui/preview/KeyguardPreviewRenderer.kt     |  2 +-
 .../ui/view/KeyguardIndicationArea.kt         |  2 +-
 .../sections/AlignShortcutsToUdfpsSection.kt  |  2 +-
 .../sections/AodNotificationIconsSection.kt   |  2 +-
 .../layout/sections/BaseShortcutSection.kt    |  2 +-
 .../DefaultAmbientIndicationAreaSection.kt    |  2 +-
 .../sections/DefaultIndicationAreaSection.kt  |  2 +-
 .../layout/sections/DefaultLockIconSection.kt |  2 +-
 ...ultNotificationStackScrollLayoutSection.kt |  2 +-
 .../DefaultSettingsPopupMenuSection.kt        |  2 +-
 .../sections/DefaultShortcutsSection.kt       |  2 +-
 .../sections/DefaultStatusBarSection.kt       |  2 +-
 .../sections/DefaultStatusViewSection.kt      |  2 +-
 .../layout/sections/SplitShadeGuidelines.kt   |  2 +-
 .../KeyguardPreviewSmartspaceViewModel.kt     |  2 +-
 .../KeyguardSettingsMenuViewModel.kt          |  2 +-
 .../ui/viewmodel/UdfpsAodViewModel.kt         |  2 +-
 .../ui/viewmodel/UdfpsLockscreenViewModel.kt  |  2 +-
 .../logcat/LogAccessDialogActivity.java       |  2 +-
 .../MediaProjectionAppSelectorActivity.kt     |  2 +-
 .../MediaProjectionPermissionActivity.java    |  2 +-
 .../media/controls/models/GutsViewHolder.kt   |  2 +-
 .../media/controls/models/player/MediaData.kt |  2 +-
 .../controls/models/player/MediaViewHolder.kt |  2 +-
 .../controls/models/player/SeekBarObserver.kt |  2 +-
 .../RecommendationViewHolder.kt               |  2 +-
 .../controls/pipeline/MediaDataManager.kt     |  2 +-
 .../controls/pipeline/MediaDeviceManager.kt   |  2 +-
 .../media/controls/ui/IlluminationDrawable.kt |  2 +-
 .../media/controls/ui/LightSourceDrawable.kt  |  2 +-
 .../controls/ui/MediaCarouselController.kt    |  2 +-
 .../controls/ui/MediaCarouselScrollHandler.kt |  2 +-
 .../media/controls/ui/MediaControlPanel.java  |  2 +-
 .../controls/ui/MediaHierarchyManager.kt      |  2 +-
 .../media/controls/ui/MediaViewController.kt  |  2 +-
 .../media/controls/util/MediaUiEventLogger.kt |  2 +-
 .../systemui/media/dialog/MediaItem.java      |  2 +-
 .../media/dialog/MediaOutputAdapter.java      |  2 +-
 .../media/dialog/MediaOutputBaseAdapter.java  |  2 +-
 .../media/dialog/MediaOutputBaseDialog.java   |  2 +-
 .../dialog/MediaOutputBroadcastDialog.java    |  2 +-
 .../media/dialog/MediaOutputController.java   |  2 +-
 .../media/dialog/MediaOutputDialog.java       |  2 +-
 .../dialog/MediaSessionReleaseDialog.java     |  2 +-
 .../HomeSoundEffectController.java            |  2 +-
 .../taptotransfer/common/MediaTttUtils.kt     |  2 +-
 .../MediaTttChipControllerReceiver.kt         |  2 +-
 .../MediaTttReceiverRippleController.kt       |  2 +-
 .../taptotransfer/sender/ChipStateSender.kt   |  2 +-
 .../sender/MediaTttSenderCoordinator.kt       |  2 +-
 ...ediaProjectionBlockerEmptyStateProvider.kt |  2 +-
 .../MediaProjectionRecentsViewController.kt   |  2 +-
 .../view/MediaProjectionTaskView.kt           |  2 +-
 .../appselector/view/RecentTaskViewHolder.kt  |  2 +-
 .../appselector/view/RecentTasksAdapter.kt    |  2 +-
 .../ScreenCaptureDisabledDialog.kt            |  2 +-
 .../ui/TaskSwitcherNotificationCoordinator.kt |  2 +-
 .../systemui/navigationbar/NavigationBar.java |  2 +-
 .../NavigationBarInflaterView.java            |  2 +-
 .../navigationbar/NavigationBarModule.java    |  2 +-
 .../NavigationBarTransitions.java             |  2 +-
 .../navigationbar/NavigationBarView.java      |  2 +-
 .../navigationbar/ScreenPinningNotify.java    |  2 +-
 .../navigationbar/buttons/DeadZone.java       |  2 +-
 .../buttons/KeyButtonDrawable.java            |  2 +-
 .../navigationbar/buttons/KeyButtonView.java  |  2 +-
 .../buttons/NearestTouchFrame.java            |  2 +-
 .../gestural/EdgeBackGestureHandler.java      |  2 +-
 .../navigationbar/gestural/EdgePanelParams.kt |  2 +-
 .../gestural/NavigationBarEdgePanel.java      |  2 +-
 .../gestural/NavigationHandle.java            |  2 +-
 .../QuickswitchOrientedNavHandle.java         |  2 +-
 .../net/NetworkOverLimitActivity.java         |  2 +-
 .../systemui/notetask/NoteTaskController.kt   |  2 +-
 .../notetask/NoteTaskRoleManagerExt.kt        |  2 +-
 .../NoteTaskQuickAffordanceConfig.kt          |  2 +-
 .../systemui/people/PeopleSpaceTileView.java  |  2 +-
 .../systemui/people/PeopleSpaceUtils.java     |  2 +-
 .../systemui/people/PeopleTileViewHelper.java |  2 +-
 .../people/ui/view/PeopleViewBinder.kt        |  2 +-
 .../people/ui/viewmodel/PeopleViewModel.kt    |  2 +-
 .../systemui/plugins/PluginsModule.java       |  2 +-
 .../power/InattentiveSleepWarningView.java    |  2 +-
 .../power/PowerNotificationWarnings.java      |  2 +-
 .../com/android/systemui/power/PowerUI.java   |  2 +-
 .../systemui/privacy/OngoingPrivacyChip.kt    |  2 +-
 .../systemui/privacy/PrivacyChipBuilder.kt    |  2 +-
 .../android/systemui/privacy/PrivacyDialog.kt |  2 +-
 .../systemui/privacy/PrivacyDialogV2.kt       |  2 +-
 .../android/systemui/privacy/PrivacyItem.kt   |  2 +-
 .../android/systemui/qs/DataUsageGraph.java   |  2 +-
 .../systemui/qs/FgsManagerController.kt       |  2 +-
 .../android/systemui/qs/PageIndicator.java    |  2 +-
 .../android/systemui/qs/PagedTileLayout.java  |  2 +-
 .../android/systemui/qs/PseudoGridView.java   |  2 +-
 .../android/systemui/qs/QSContainerImpl.java  |  2 +-
 .../android/systemui/qs/QSDualTileLabel.java  |  2 +-
 .../com/android/systemui/qs/QSFooterView.java |  2 +-
 .../systemui/qs/QSFooterViewController.java   |  2 +-
 .../com/android/systemui/qs/QSFragment.java   |  2 +-
 .../src/com/android/systemui/qs/QSHost.java   |  2 +-
 .../src/com/android/systemui/qs/QSPanel.java  |  2 +-
 .../android/systemui/qs/QSScrollLayout.java   |  2 +-
 .../systemui/qs/QSSecurityFooterUtils.java    |  2 +-
 .../com/android/systemui/qs/QSTileHost.java   |  2 +-
 .../com/android/systemui/qs/QuickQSPanel.java |  2 +-
 .../systemui/qs/QuickQSPanelController.java   |  2 +-
 .../systemui/qs/QuickStatusBarHeader.java     |  2 +-
 .../systemui/qs/SideLabelTileLayout.kt        |  2 +-
 .../com/android/systemui/qs/TileLayout.java   |  2 +-
 .../systemui/qs/customize/QSCustomizer.java   |  2 +-
 .../qs/customize/QSCustomizerController.java  |  2 +-
 .../systemui/qs/customize/TileAdapter.java    |  2 +-
 .../qs/customize/TileAdapterDelegate.java     |  2 +-
 .../qs/customize/TileQueryHelper.java         |  2 +-
 .../systemui/qs/dagger/QSFragmentModule.java  |  2 +-
 .../systemui/qs/external/TileColorPicker.java |  2 +-
 .../systemui/qs/external/TileRequestDialog.kt |  2 +-
 .../external/TileServiceRequestController.kt  |  2 +-
 .../data/repository/UserSwitcherRepository.kt |  2 +-
 .../ui/binder/FooterActionsViewBinder.kt      |  2 +-
 .../ui/viewmodel/FooterActionsViewModel.kt    |  2 +-
 .../data/repository/TileSpecRepository.kt     |  2 +-
 .../autoaddable/AutoAddableSettingList.kt     |  2 +-
 .../autoaddable/SafetyCenterAutoAddable.kt    |  2 +-
 .../systemui/qs/tileimpl/QSIconViewImpl.java  |  2 +-
 .../systemui/qs/tileimpl/QSTileViewImpl.kt    |  2 +-
 .../qs/tileimpl/SubtitleArrayMapping.kt       |  2 +-
 .../systemui/qs/tiles/AirplaneModeTile.java   |  2 +-
 .../android/systemui/qs/tiles/AlarmTile.kt    |  2 +-
 .../systemui/qs/tiles/BatterySaverTile.java   |  2 +-
 .../systemui/qs/tiles/BluetoothTile.java      |  2 +-
 .../systemui/qs/tiles/CameraToggleTile.java   |  2 +-
 .../android/systemui/qs/tiles/CastTile.java   |  2 +-
 .../qs/tiles/ColorCorrectionTile.java         |  4 +-
 .../systemui/qs/tiles/ColorInversionTile.java |  4 +-
 .../systemui/qs/tiles/DataSaverTile.java      |  2 +-
 .../qs/tiles/DataUsageDetailView.java         |  2 +-
 .../systemui/qs/tiles/DeviceControlsTile.kt   |  2 +-
 .../android/systemui/qs/tiles/DndTile.java    |  2 +-
 .../android/systemui/qs/tiles/DreamTile.java  |  2 +-
 .../systemui/qs/tiles/FlashlightTile.java     |  2 +-
 .../systemui/qs/tiles/FontScalingTile.kt      |  2 +-
 .../systemui/qs/tiles/HotspotTile.java        |  2 +-
 .../systemui/qs/tiles/InternetTile.java       |  2 +-
 .../systemui/qs/tiles/InternetTileNewImpl.kt  |  2 +-
 .../systemui/qs/tiles/LocationTile.java       |  2 +-
 .../qs/tiles/MicrophoneToggleTile.java        |  2 +-
 .../android/systemui/qs/tiles/NfcTile.java    |  2 +-
 .../systemui/qs/tiles/NightDisplayTile.java   |  2 +-
 .../systemui/qs/tiles/OneHandedModeTile.java  |  2 +-
 .../systemui/qs/tiles/QRCodeScannerTile.java  |  2 +-
 .../qs/tiles/QuickAccessWalletTile.java       |  2 +-
 .../qs/tiles/ReduceBrightColorsTile.java      |  2 +-
 .../systemui/qs/tiles/RotationLockTile.java   |  2 +-
 .../systemui/qs/tiles/ScreenRecordTile.java   |  2 +-
 .../qs/tiles/SensorPrivacyToggleTile.java     |  2 +-
 .../systemui/qs/tiles/UiModeNightTile.java    |  2 +-
 .../systemui/qs/tiles/UserDetailItemView.java |  2 +-
 .../systemui/qs/tiles/UserDetailView.java     |  2 +-
 .../systemui/qs/tiles/WorkModeTile.java       |  2 +-
 .../qs/tiles/dialog/InternetAdapter.java      |  2 +-
 .../qs/tiles/dialog/InternetDialog.java       |  2 +-
 .../dialog/InternetDialogController.java      |  2 +-
 .../qs/user/UserSwitchDialogController.kt     |  2 +-
 .../RearDisplayDialogController.java          |  2 +-
 .../systemui/recents/RecentsModule.java       |  2 +-
 .../recents/ScreenPinningRequest.java         |  2 +-
 .../ui/view/SceneWindowRootViewBinder.kt      |  2 +-
 .../systemui/scene/ui/view/WindowRootView.kt  |  2 +-
 .../BaseScreenSharePermissionDialog.kt        |  2 +-
 .../MediaProjectionPermissionDialog.kt        |  2 +-
 .../screenrecord/RecordingService.java        |  2 +-
 .../screenrecord/ScreenRecordDialog.java      |  2 +-
 .../ScreenRecordPermissionDialog.kt           |  2 +-
 .../screenrecord/ScreenRecordingAdapter.java  |  2 +-
 .../screenshot/ActionIntentCreator.kt         |  2 +-
 .../android/systemui/screenshot/CropView.java |  2 +-
 .../screenshot/DraggableConstraintLayout.java |  2 +-
 .../screenshot/LongScreenshotActivity.java    |  2 +-
 .../systemui/screenshot/MagnifierView.java    |  2 +-
 .../screenshot/MessageContainerController.kt  |  2 +-
 .../screenshot/OverlayActionChip.java         |  2 +-
 .../screenshot/SaveImageInBackgroundTask.java |  2 +-
 .../screenshot/ScreenshotController.java      |  2 +-
 .../ScreenshotDetectionController.kt          |  2 +-
 .../ScreenshotNotificationsController.java    |  2 +-
 .../ScreenshotServiceErrorReceiver.java       |  2 +-
 .../systemui/screenshot/ScreenshotView.java   |  2 +-
 .../screenshot/TakeScreenshotService.java     |  2 +-
 .../WorkProfileMessageController.kt           |  2 +-
 .../screenshot/appclips/AppClipsActivity.java |  2 +-
 .../screenshot/appclips/AppClipsService.java  |  2 +-
 .../appclips/AppClipsTrampolineActivity.java  |  2 +-
 .../systemui/sensorprivacy/SensorUseDialog.kt |  2 +-
 .../settings/brightness/BrightnessDialog.java |  2 +-
 .../BrightnessSliderController.java           |  2 +-
 .../brightness/BrightnessSliderView.java      |  2 +-
 ...mbinedShadeHeadersConstraintManagerImpl.kt |  2 +-
 ...ificationPanelUnfoldAnimationController.kt |  2 +-
 .../NotificationPanelViewController.java      |  2 +-
 ...NotificationShadeWindowControllerImpl.java |  2 +-
 ...NotificationShadeWindowViewController.java |  2 +-
 .../NotificationsQSContainerController.kt     |  2 +-
 .../NotificationsQuickSettingsContainer.java  |  2 +-
 .../systemui/shade/QsBatteryModeController.kt |  2 +-
 .../shade/QuickSettingsController.java        |  2 +-
 .../systemui/shade/ShadeHeaderController.kt   |  2 +-
 .../systemui/shade/ShadeViewProviderModule.kt |  2 +-
 .../systemui/shade/carrier/ShadeCarrier.java  |  2 +-
 .../shade/carrier/ShadeCarrierGroup.java      |  2 +-
 .../carrier/ShadeCarrierGroupController.java  |  2 +-
 .../ui/viewmodel/ShadeHeaderViewModel.kt      |  2 +-
 .../systemui/statusbar/AnimatedImageView.java |  2 +-
 .../systemui/statusbar/BatteryStatusChip.kt   |  2 +-
 .../android/systemui/statusbar/BlurUtils.kt   |  2 +-
 .../systemui/statusbar/CastDrawable.java      |  2 +-
 .../statusbar/ConnectedDisplayChip.kt         |  2 +-
 .../systemui/statusbar/CrossFadeHelper.java   |  2 +-
 .../systemui/statusbar/EmptyShadeView.java    |  2 +-
 .../statusbar/HeadsUpStatusBarView.java       |  2 +-
 .../statusbar/ImmersiveModeConfirmation.java  |  2 +-
 .../KeyboardShortcutAppItemLayout.java        |  2 +-
 .../statusbar/KeyboardShortcutListSearch.java |  2 +-
 .../systemui/statusbar/KeyboardShortcuts.java |  2 +-
 .../statusbar/KeyguardAffordanceView.java     |  2 +-
 .../KeyguardIndicationController.java         |  6 +-
 ...screenShadeKeyguardTransitionController.kt |  2 +-
 .../LockscreenShadeQsTransitionController.kt  |  2 +-
 ...ockscreenShadeScrimTransitionController.kt |  2 +-
 .../LockscreenShadeTransitionController.kt    |  2 +-
 .../NotificationRemoteInputManager.java       |  2 +-
 .../systemui/statusbar/NotificationShelf.java |  2 +-
 .../statusbar/PulseExpansionHandler.kt        |  2 +-
 .../statusbar/ScreenRecordDrawable.java       |  2 +-
 .../SingleShadeLockScreenOverScroller.kt      |  2 +-
 .../SplitShadeLockScreenOverScroller.kt       |  2 +-
 .../systemui/statusbar/StatusBarIconView.java |  2 +-
 .../StatusBarStateControllerImpl.java         |  2 +-
 .../statusbar/ViewTransformationHelper.java   |  2 +-
 .../statusbar/connectivity/EthernetIcons.java |  2 +-
 .../connectivity/MobileSignalController.java  |  2 +-
 .../connectivity/NetworkControllerImpl.java   |  2 +-
 .../connectivity/WifiSignalController.java    |  2 +-
 .../statusbar/core/StatusBarInitializer.kt    |  2 +-
 .../events/PrivacyDotViewController.kt        |  2 +-
 .../SystemEventChipAnimationController.kt     |  2 +-
 .../events/SystemEventCoordinator.kt          |  2 +-
 .../LockscreenSmartspaceController.kt         |  2 +-
 .../notification/AnimatableProperty.java      |  2 +-
 .../AssistantFeedbackController.java          | 10 +--
 .../notification/FakeShadowView.java          |  2 +-
 .../notification/ImageTransformState.java     |  2 +-
 .../notification/InstantAppNotifier.java      |  2 +-
 .../MessagingImageTransformState.java         |  2 +-
 .../notification/NotificationDozeHelper.java  |  2 +-
 .../NotificationIconDozeHelper.java           |  2 +-
 .../notification/NotificationUtils.java       |  2 +-
 .../statusbar/notification/Roundable.kt       |  2 +-
 .../notification/TransformState.java          |  2 +-
 .../notification/ViewGroupFadeHelper.kt       |  2 +-
 .../coordinator/RowAppearanceCoordinator.kt   |  2 +-
 .../SectionHeaderVisibilityProvider.kt        |  2 +-
 .../render/MediaContainerController.kt        |  2 +-
 .../render/SectionHeaderController.kt         |  2 +-
 .../NotificationSectionHeadersModule.kt       |  2 +-
 .../dagger/NotificationsModule.java           |  2 +-
 .../notification/icon/IconManager.kt          |  2 +-
 ...IconAreaControllerViewBinderWrapperImpl.kt |  2 +-
 .../row/ActivatableNotificationView.java      |  2 +-
 .../row/ChannelEditorDialogController.kt      |  2 +-
 .../notification/row/ChannelEditorListView.kt |  2 +-
 .../row/ExpandableNotificationRow.java        |  2 +-
 ...pandableNotificationRowDragController.java |  2 +-
 .../row/ExpandableOutlineView.java            |  2 +-
 .../notification/row/ExpandableView.java      |  2 +-
 .../notification/row/FeedbackInfo.java        |  2 +-
 .../notification/row/FooterView.java          |  2 +-
 .../HybridConversationNotificationView.java   |  2 +-
 .../notification/row/HybridGroupManager.java  |  2 +-
 .../row/HybridNotificationView.java           |  2 +-
 .../row/NotificationBackgroundView.java       |  2 +-
 .../row/NotificationContentInflater.java      |  2 +-
 .../row/NotificationContentView.java          |  2 +-
 .../row/NotificationConversationInfo.java     |  2 +-
 .../notification/row/NotificationGuts.java    |  2 +-
 .../row/NotificationGutsManager.java          |  2 +-
 .../notification/row/NotificationInfo.java    |  2 +-
 .../notification/row/NotificationMenuRow.java |  2 +-
 .../notification/row/NotificationSnooze.java  |  2 +-
 .../row/PartialConversationInfo.java          |  2 +-
 .../notification/row/RowInflaterTask.java     |  2 +-
 .../NotificationCallTemplateViewWrapper.kt    |  2 +-
 ...ficationConversationTemplateViewWrapper.kt |  2 +-
 .../NotificationCustomViewWrapper.java        |  2 +-
 .../NotificationHeaderViewWrapper.java        |  2 +-
 ...ificationMessagingTemplateViewWrapper.java |  2 +-
 .../NotificationTemplateViewWrapper.java      |  2 +-
 .../notification/stack/AmbientState.java      |  2 +-
 .../stack/ExpandableViewState.java            |  2 +-
 .../notification/stack/MediaContainerView.kt  |  2 +-
 .../stack/NotificationChildrenContainer.java  |  2 +-
 .../stack/NotificationStackScrollLayout.java  |  2 +-
 .../stack/NotificationStackSizeCalculator.kt  |  2 +-
 .../notification/stack/SectionHeaderView.java |  2 +-
 .../stack/StackScrollAlgorithm.java           |  2 +-
 .../stack/StackStateAnimator.java             |  2 +-
 .../notification/stack/ViewState.java         |  2 +-
 .../SharedNotificationContainerInteractor.kt  |  2 +-
 .../ui/view/SharedNotificationContainer.kt    |  2 +-
 .../viewbinder/NotificationListViewBinder.kt  |  2 +-
 .../statusbar/phone/ActivityStarterImpl.kt    |  2 +-
 .../statusbar/phone/AutoTileManager.java      |  2 +-
 .../statusbar/phone/BarTransitions.java       |  2 +-
 .../phone/BiometricUnlockController.java      |  2 +-
 .../CentralSurfacesCommandQueueCallbacks.java |  2 +-
 .../statusbar/phone/CentralSurfacesImpl.java  |  4 +-
 .../statusbar/phone/DemoStatusIcons.java      |  2 +-
 .../statusbar/phone/DozeParameters.java       |  2 +-
 .../statusbar/phone/ExpandableIndicator.java  |  2 +-
 .../phone/HeadsUpAppearanceController.java    |  2 +-
 .../statusbar/phone/HeadsUpManagerPhone.java  |  2 +-
 .../statusbar/phone/KeyguardBottomAreaView.kt |  2 +-
 .../phone/KeyguardBypassController.kt         |  2 +-
 .../phone/KeyguardClockPositionAlgorithm.java |  2 +-
 .../phone/KeyguardIndicationTextView.java     |  4 +-
 .../phone/KeyguardStatusBarView.java          |  2 +-
 .../KeyguardStatusBarViewController.java      |  2 +-
 ...acyNotificationIconAreaControllerImpl.java |  2 +-
 .../systemui/statusbar/phone/LockIcon.java    |  2 +-
 .../statusbar/phone/MultiUserSwitch.java      |  2 +-
 .../phone/NotificationIconContainer.java      |  2 +-
 .../statusbar/phone/PhoneStatusBarPolicy.java |  2 +-
 .../phone/PhoneStatusBarTransitions.java      |  2 +-
 .../statusbar/phone/PhoneStatusBarView.java   |  2 +-
 .../phone/PhoneStatusBarViewController.kt     |  2 +-
 .../statusbar/phone/ScrimController.java      |  2 +-
 .../phone/StatusBarContentInsetsProvider.kt   |  2 +-
 .../phone/StatusBarIconController.java        |  2 +-
 .../phone/StatusBarNotificationPresenter.java |  2 +-
 .../phone/StatusBarSignalPolicy.java          |  2 +-
 .../StatusBarTouchableRegionManager.java      |  2 +-
 .../statusbar/phone/StatusIconContainer.java  |  2 +-
 .../phone/StatusOverlayHoverListener.kt       |  2 +-
 .../statusbar/phone/SystemUIDialog.java       |  2 +-
 .../statusbar/phone/TapAgainView.java         |  4 +-
 .../statusbar/phone/UserAvatarView.java       |  2 +-
 .../fragment/CollapsedStatusBarFragment.java  |  2 +-
 .../phone/fragment/StatusBarIconBlocklist.kt  |  2 +-
 .../fragment/StatusBarSystemEventAnimator.kt  |  2 +-
 .../dagger/StatusBarFragmentModule.java       |  2 +-
 .../ongoingcall/OngoingCallController.kt      |  2 +-
 .../StatusBarUserSwitcherContainer.kt         |  2 +-
 .../ethernet/domain/EthernetInteractor.kt     |  2 +-
 .../prod/MobileConnectionsRepositoryImpl.kt   |  2 +-
 .../mobile/ui/binder/MobileIconBinder.kt      |  2 +-
 .../view/ModernShadeCarrierGroupMobileView.kt |  2 +-
 .../ui/view/ModernStatusBarMobileView.kt      |  2 +-
 .../pipeline/shared/ConnectivityConstants.kt  |  2 +-
 .../data/repository/ConnectivityRepository.kt |  2 +-
 .../shared/ui/view/ModernStatusBarView.kt     |  2 +-
 .../ui/viewmodel/InternetTileViewModel.kt     |  2 +-
 .../pipeline/wifi/shared/WifiConstants.kt     |  2 +-
 .../pipeline/wifi/ui/binder/WifiViewBinder.kt |  2 +-
 .../pipeline/wifi/ui/model/WifiIcon.kt        |  2 +-
 .../wifi/ui/view/ModernStatusBarWifiView.kt   |  2 +-
 .../statusbar/policy/BatteryStateNotifier.kt  |  2 +-
 .../policy/BrightnessMirrorController.java    |  2 +-
 .../statusbar/policy/CastControllerImpl.java  |  2 +-
 .../systemui/statusbar/policy/Clock.java      |  2 +-
 .../systemui/statusbar/policy/DateView.java   |  2 +-
 .../policy/DeviceControlsControllerImpl.kt    |  2 +-
 .../statusbar/policy/HeadsUpManager.java      |  2 +-
 .../statusbar/policy/HeadsUpUtil.java         |  2 +-
 .../policy/HotspotControllerImpl.java         |  2 +-
 .../KeyguardQsUserSwitchController.java       |  2 +-
 .../policy/KeyguardStateControllerImpl.java   |  2 +-
 .../policy/KeyguardUserDetailItemView.java    |  2 +-
 .../KeyguardUserSwitcherController.java       |  2 +-
 .../policy/KeyguardUserSwitcherScrim.java     |  2 +-
 .../statusbar/policy/RemoteInputView.java     |  2 +-
 .../policy/RemoteInputViewController.kt       |  2 +-
 .../ResourcesSplitShadeStateController.kt     |  2 +-
 .../policy/SecurityControllerImpl.java        |  2 +-
 .../statusbar/policy/SmartReplyConstants.java |  2 +-
 .../policy/SmartReplyStateInflater.kt         |  2 +-
 .../statusbar/policy/SmartReplyView.java      |  2 +-
 .../statusbar/policy/SplitClockView.java      |  2 +-
 .../policy/SplitShadeStateControllerImpl.kt   |  2 +-
 .../policy/UserInfoControllerImpl.java        |  2 +-
 .../statusbar/policy/VariableDateView.kt      |  2 +-
 .../window/StatusBarWindowController.java     |  2 +-
 .../statusbar/window/StatusBarWindowModule.kt |  2 +-
 .../systemui/stylus/StylusUsiPowerUI.kt       |  2 +-
 .../SwitchToManagedProfileForCallActivity.kt  |  2 +-
 .../chipbar/ChipbarCoordinator.kt             |  2 +-
 .../temporarydisplay/chipbar/ChipbarInfo.kt   |  2 +-
 .../android/systemui/theme/ThemeModule.java   |  2 +-
 .../android/systemui/toast/SystemUIToast.java |  8 +-
 .../systemui/toast/ToastDefaultAnimation.kt   |  8 +-
 .../android/systemui/tuner/ClipboardView.java |  2 +-
 .../systemui/tuner/DemoModeFragment.java      |  2 +-
 .../systemui/tuner/LockscreenFragment.java    |  2 +-
 .../android/systemui/tuner/NavBarTuner.java   |  2 +-
 .../android/systemui/tuner/OtherPrefs.java    |  2 +-
 .../systemui/tuner/PluginFragment.java        |  2 +-
 .../PowerNotificationControlsFragment.java    |  2 +-
 .../systemui/tuner/RadioListPreference.java   |  2 +-
 .../systemui/tuner/SelectablePreference.java  |  2 +-
 .../systemui/tuner/ShortcutPicker.java        |  2 +-
 .../android/systemui/tuner/TunerActivity.java |  2 +-
 .../android/systemui/tuner/TunerFragment.java |  2 +-
 .../systemui/tuner/TunerServiceImpl.java      |  2 +-
 .../android/systemui/tuner/TunerSwitch.java   |  2 +-
 .../systemui/usb/UsbAccessoryUriActivity.java |  2 +-
 .../usb/UsbAudioWarningDialogMessage.java     |  2 +-
 .../systemui/usb/UsbContaminantActivity.java  |  2 +-
 .../systemui/usb/UsbDebuggingActivity.java    |  2 +-
 .../UsbDebuggingSecondaryUserActivity.java    |  2 +-
 .../systemui/usb/UsbDialogActivity.java       |  2 +-
 .../systemui/usb/UsbResolverActivity.java     |  2 +-
 .../systemui/user/CreateUserActivity.java     |  2 +-
 .../user/UserSwitcherFullscreenDialog.kt      |  2 +-
 .../systemui/user/UserSwitcherPopupMenu.kt    |  2 +-
 .../user/data/repository/UserRepository.kt    |  2 +-
 .../user/domain/interactor/UserInteractor.kt  |  2 +-
 .../legacyhelper/data/LegacyUserDataHelper.kt |  2 +-
 .../legacyhelper/ui/LegacyUserUiHelper.kt     |  2 +-
 .../user/ui/binder/UserSwitcherViewBinder.kt  |  2 +-
 .../systemui/user/ui/binder/UserViewBinder.kt |  2 +-
 .../systemui/user/ui/dialog/AddUserDialog.kt  |  2 +-
 .../user/ui/dialog/UserSwitchDialog.kt        |  2 +-
 .../ui/viewmodel/UserSwitcherViewModel.kt     |  2 +-
 .../util/AlphaTintDrawableWrapper.java        |  2 +-
 .../systemui/util/DelayableMarqueeTextView.kt |  2 +-
 .../android/systemui/util/LargeScreenUtils.kt |  2 +-
 .../systemui/util/NotificationChannels.java   |  2 +-
 .../src/com/android/systemui/util/Utils.java  |  2 +-
 .../util/animation/UniqueObjectHostView.kt    |  2 +-
 .../systemui/util/leak/GarbageMonitor.java    |  2 +-
 .../systemui/util/sensors/SensorModule.java   |  2 +-
 .../dagger/ObservableServiceModule.java       |  2 +-
 .../volume/CaptionsToggleImageButton.java     |  2 +-
 .../systemui/volume/CsdWarningDialog.java     |  2 +-
 .../systemui/volume/SegmentedButtons.java     |  2 +-
 .../volume/VolumeDialogControllerImpl.java    |  2 +-
 .../systemui/volume/VolumeDialogImpl.java     |  2 +-
 .../systemui/volume/VolumePanelDialog.java    |  2 +-
 .../volume/VolumePanelSlicesAdapter.java      |  2 +-
 .../systemui/volume/VolumeToolTipView.java    |  2 +-
 .../com/android/systemui/volume/VolumeUI.java |  2 +-
 .../QuickAccessWalletController.java          |  2 +-
 .../wallet/ui/DotIndicatorDecoration.java     |  2 +-
 .../systemui/wallet/ui/WalletActivity.java    |  2 +-
 .../wallet/ui/WalletCardCarousel.java         |  2 +-
 .../systemui/wallet/ui/WalletCardView.java    |  2 +-
 .../wallet/ui/WalletCardViewHolder.java       |  2 +-
 .../wallet/ui/WalletScreenController.java     |  2 +-
 .../systemui/wallet/ui/WalletView.java        |  2 +-
 .../systemui/wifi/WifiDebuggingActivity.java  |  2 +-
 .../WifiDebuggingSecondaryUserActivity.java   |  2 +-
 packages/SystemUI/tests/Android.bp            |  1 +
 .../robotests/SysuiResourceLoadingTest.java   |  2 +-
 .../keyguard/CarrierTextManagerTest.java      |  2 +-
 .../keyguard/FaceWakeUpTriggersConfigTest.kt  |  2 +-
 ...KeyguardAbsKeyInputViewControllerTest.java |  2 +-
 ...eyguardClockAccessibilityDelegateTest.java |  2 +-
 ...KeyguardClockSwitchControllerBaseTest.java |  4 +-
 .../keyguard/KeyguardClockSwitchTest.java     |  2 +-
 .../KeyguardPasswordViewControllerTest.kt     |  2 +-
 .../KeyguardPatternViewControllerTest.kt      |  2 +-
 ...yguardPinBasedInputViewControllerTest.java |  2 +-
 .../keyguard/KeyguardPinViewControllerTest.kt |  2 +-
 .../keyguard/KeyguardPresentationTest.java    |  2 +-
 ...KeyguardSecurityContainerControllerTest.kt |  2 +-
 .../KeyguardSecurityContainerTest.java        |  2 +-
 ...uardSecurityViewFlipperControllerTest.java |  2 +-
 .../KeyguardSimPinViewControllerTest.kt       |  2 +-
 .../KeyguardSimPukViewControllerTest.kt       |  2 +-
 .../keyguard/KeyguardSliceViewTest.java       |  2 +-
 .../keyguard/KeyguardStatusViewTest.kt        |  2 +-
 .../keyguard/KeyguardUnfoldTransitionTest.kt  |  2 +-
 .../keyguard/KeyguardUpdateMonitorTest.java   |  4 +-
 .../KeyguardUserSwitcherAnchorTest.kt         |  2 +-
 .../LockIconViewControllerBaseTest.java       |  2 +-
 .../keyguard/PinShapeHintingViewTest.kt       |  2 +-
 .../keyguard/PinShapeNonHintingViewTest.kt    |  2 +-
 .../systemui/BatteryMeterDrawableTest.java    |  1 +
 .../systemui/ScreenDecorationsTest.java       |  1 +
 .../MagnificationModeSwitchTest.java          |  2 +-
 ...wMagnificationAnimationControllerTest.java |  2 +-
 .../WindowMagnificationControllerTest.java    |  2 +-
 .../WindowMagnificationSettingsTest.java      |  2 +-
 .../AccessibilityTargetAdapterTest.java       |  2 +-
 .../floatingmenu/AnnotationLinkSpanTest.java  |  2 +-
 .../floatingmenu/MenuEduTooltipViewTest.java  |  2 +-
 .../MenuItemAccessibilityDelegateTest.java    |  2 +-
 .../fontscaling/FontScalingDialogTest.kt      |  2 +-
 .../systemui/assist/ui/DisplayUtilsTest.java  |  2 +-
 .../BatteryMeterViewControllerTest.java       |  2 +-
 .../systemui/battery/BatteryMeterViewTest.kt  |  2 +-
 ...hBiometricFingerprintIconControllerTest.kt |  2 +-
 .../biometrics/AuthContainerViewTest.kt       |  2 +-
 .../biometrics/AuthControllerTest.java        |  4 +-
 .../biometrics/SideFpsControllerTest.kt       |  2 +-
 .../biometrics/UdfpsControllerOverlayTest.kt  |  2 +-
 .../biometrics/UdfpsControllerTest.java       |  2 +-
 .../systemui/biometrics/UdfpsViewTest.kt      |  4 +-
 .../bluetooth/BroadcastDialogTest.java        |  2 +-
 .../data/repo/BouncerMessageRepositoryTest.kt | 18 ++--
 .../interactor/BouncerInteractorTest.kt       |  2 +-
 .../BouncerMessageInteractorTest.kt           |  4 +-
 .../PrimaryBouncerInteractorTest.kt           |  2 +-
 .../viewmodel/PasswordBouncerViewModelTest.kt |  2 +-
 .../viewmodel/PatternBouncerViewModelTest.kt  |  2 +-
 .../ui/viewmodel/PinBouncerViewModelTest.kt   |  2 +-
 .../WiredChargingRippleControllerTest.kt      |  2 +-
 .../ClipboardOverlayUtilsTest.java            |  2 +-
 .../clipboardoverlay/IntentCreatorTest.java   |  2 +-
 .../view/SeekBarWithIconButtonsViewTest.java  |  2 +-
 .../ComplicationLayoutEngineTest.java         |  2 +-
 ...ntrolsTileResourceConfigurationImplTest.kt |  2 +-
 .../management/ControlsEditingActivityTest.kt |  2 +-
 .../ControlsFavoritingActivityTest.kt         |  2 +-
 .../ControlsListingControllerImplTest.kt      |  2 +-
 .../PanelConfirmationDialogFactoryTest.kt     |  2 +-
 .../AuthorizedPanelsRepositoryImplTest.kt     |  2 +-
 .../controls/ui/ControlViewHolderTest.kt      |  2 +-
 .../controls/ui/ControlsDialogsFactoryTest.kt |  2 +-
 .../controls/ui/ControlsPopupMenuTest.kt      |  2 +-
 .../ui/ControlsUiControllerImplTest.kt        |  2 +-
 .../ui/TemperatureControlBehaviorTest.kt      |  2 +-
 .../systemui/decor/OverlayWindowTest.kt       |  2 +-
 .../PrivacyDotDecorProviderFactoryTest.kt     |  2 +-
 .../RoundedCornerDecorProviderFactoryTest.kt  |  2 +-
 .../decor/RoundedCornerResDelegateTest.kt     |  2 +-
 .../view/MirroringConfirmationDialogTest.kt   |  2 +-
 .../doze/AlwaysOnDisplayPolicyTest.java       |  2 +-
 ...eamOverlayStatusBarViewControllerTest.java |  2 +-
 .../GlobalActionsColumnLayoutTest.java        |  2 +-
 .../GlobalActionsGridLayoutTest.java          |  2 +-
 .../globalactions/ListGridLayoutTest.java     |  2 +-
 .../systemui/graphics/ImageLoaderTest.kt      |  2 +-
 .../keyguard/CustomizationProviderTest.kt     |  2 +-
 .../DoNotDisturbQuickAffordanceConfigTest.kt  |  2 +-
 .../FlashlightQuickAffordanceConfigTest.kt    |  2 +-
 ...kAffordanceConfigParameterizedStateTest.kt |  2 +-
 ...ntrolsKeyguardQuickAffordanceConfigTest.kt |  2 +-
 .../KeyguardQuickAffordanceConfigTest.kt      |  2 +-
 ...dQuickAffordanceLegacySettingSyncerTest.kt |  2 +-
 ...AffordanceLocalUserSelectionManagerTest.kt |  2 +-
 ...WalletKeyguardQuickAffordanceConfigTest.kt |  2 +-
 .../BiometricSettingsRepositoryTest.kt        |  2 +-
 .../DeviceEntryFaceAuthRepositoryTest.kt      |  2 +-
 .../KeyguardQuickAffordanceRepositoryTest.kt  |  2 +-
 .../KeyguardLongPressInteractorTest.kt        |  2 +-
 .../KeyguardQuickAffordanceInteractorTest.kt  |  2 +-
 .../DefaultIndicationAreaSectionTest.kt       |  2 +-
 .../sections/DefaultLockIconSectionTest.kt    |  2 +-
 .../KeyguardBottomAreaViewModelTest.kt        |  2 +-
 ...rdQuickAffordancesCombinedViewModelTest.kt |  2 +-
 .../ui/viewmodel/UdfpsAodViewModelTest.kt     |  2 +-
 .../UdfpsFingerprintViewModelTest.kt          |  2 +-
 .../logcat/LogAccessDialogActivityTest.java   |  2 +-
 .../models/player/SeekBarObserverTest.kt      |  2 +-
 .../recommendation/SmartspaceMediaDataTest.kt |  2 +-
 .../controls/pipeline/MediaDataManagerTest.kt |  2 +-
 .../pipeline/MediaDeviceManagerTest.kt        |  2 +-
 .../ui/MediaCarouselControllerTest.kt         |  2 +-
 .../controls/ui/MediaControlPanelTest.kt      | 22 ++---
 .../controls/ui/MediaHierarchyManagerTest.kt  |  2 +-
 .../controls/ui/MediaViewControllerTest.kt    |  2 +-
 .../media/dialog/MediaOutputAdapterTest.java  |  6 +-
 .../dialog/MediaOutputBaseDialogTest.java     |  2 +-
 .../MediaOutputBroadcastDialogTest.java       |  2 +-
 .../dialog/MediaOutputControllerTest.java     |  2 +-
 .../media/dialog/MediaOutputDialogTest.java   |  2 +-
 .../MediaMuteAwaitConnectionManagerTest.kt    |  2 +-
 .../taptotransfer/common/MediaTttUtilsTest.kt |  2 +-
 .../MediaTttChipControllerReceiverTest.kt     |  2 +-
 .../sender/MediaTttSenderCoordinatorTest.kt   |  2 +-
 ...TaskSwitcherNotificationCoordinatorTest.kt |  2 +-
 .../notetask/NoteTaskBubblesServiceTest.kt    |  2 +-
 .../notetask/NoteTaskControllerTest.kt        |  2 +-
 .../NoteTaskQuickAffordanceConfigTest.kt      |  2 +-
 .../systemui/people/PeopleSpaceUtilsTest.java |  2 +-
 .../people/PeopleTileViewHelperTest.java      |  2 +-
 .../widget/PeopleSpaceWidgetManagerTest.java  |  2 +-
 .../android/systemui/power/PowerUITest.java   |  2 +-
 .../systemui/privacy/PrivacyDialogTest.kt     |  2 +-
 .../systemui/privacy/PrivacyDialogV2Test.kt   |  2 +-
 .../systemui/qs/QSContainerImplTest.kt        |  2 +-
 .../qs/QSFooterViewControllerTest.java        |  2 +-
 .../android/systemui/qs/QSFragmentTest.java   |  2 +-
 .../qs/QSPanelControllerBaseTest.java         |  2 +-
 .../systemui/qs/QSPanelControllerTest.kt      |  2 +-
 .../com/android/systemui/qs/QSPanelTest.kt    |  2 +-
 .../systemui/qs/QSSecurityFooterTest.java     |  2 +-
 .../android/systemui/qs/QSTileHostTest.java   |  2 +-
 .../systemui/qs/QuickQSPanelControllerTest.kt |  2 +-
 .../android/systemui/qs/TileLayoutTest.java   |  2 +-
 .../qs/customize/TileAdapterDelegateTest.java |  2 +-
 .../qs/customize/TileQueryHelperTest.java     |  2 +-
 .../systemui/qs/external/CustomTileTest.kt    |  2 +-
 .../qs/external/TileColorPickerTest.java      |  2 +-
 .../qs/external/TileRequestDialogTest.kt      |  2 +-
 .../viewmodel/FooterActionsViewModelTest.kt   |  2 +-
 .../TileSpecSettingsRepositoryTest.kt         |  2 +-
 .../autoaddable/AutoAddableSettingListTest.kt |  2 +-
 .../SafetyCenterAutoAddableTest.kt            |  2 +-
 .../qs/tileimpl/QSTileViewImplTest.kt         |  2 +-
 .../qs/tileimpl/TilesStatesTextTest.kt        |  2 +-
 .../systemui/qs/tiles/AirplaneModeTileTest.kt |  2 +-
 .../systemui/qs/tiles/BatterySaverTileTest.kt |  2 +-
 .../systemui/qs/tiles/BluetoothTileTest.kt    |  2 +-
 .../systemui/qs/tiles/CameraToggleTileTest.kt |  2 +-
 .../qs/tiles/ColorInversionTileTest.java      |  2 +-
 .../systemui/qs/tiles/DataSaverTileTest.kt    |  2 +-
 .../qs/tiles/DeviceControlsTileTest.kt        |  2 +-
 .../android/systemui/qs/tiles/DndTileTest.kt  |  2 +-
 .../systemui/qs/tiles/DreamTileTest.java      |  2 +-
 .../systemui/qs/tiles/FlashlightTileTest.kt   |  2 +-
 .../systemui/qs/tiles/HotspotTileTest.java    |  6 +-
 .../qs/tiles/InternetTileNewImplTest.kt       |  2 +-
 .../systemui/qs/tiles/InternetTileTest.java   |  2 +-
 .../systemui/qs/tiles/LocationTileTest.kt     |  2 +-
 .../qs/tiles/MicrophoneToggleTileTest.kt      |  2 +-
 .../systemui/qs/tiles/NfcTileTest.java        |  2 +-
 .../systemui/qs/tiles/NightDisplayTileTest.kt |  2 +-
 .../qs/tiles/QRCodeScannerTileTest.java       |  2 +-
 .../qs/tiles/QuickAccessWalletTileTest.java   |  2 +-
 .../qs/tiles/ReduceBrightColorsTileTest.java  |  2 +-
 .../qs/tiles/RotationLockTileTest.java        |  2 +-
 .../qs/tiles/ScreenRecordTileTest.java        |  2 +-
 .../systemui/qs/tiles/UiModeNightTileTest.kt  |  2 +-
 .../qs/tiles/UserDetailViewAdapterTest.kt     |  2 +-
 .../qs/tiles/dialog/InternetAdapterTest.java  |  2 +-
 .../dialog/InternetDialogControllerTest.java  |  4 +-
 .../qs/tiles/dialog/InternetDialogTest.java   |  2 +-
 .../RearDisplayDialogControllerTest.java      |  2 +-
 .../ScreenRecordPermissionDialogTest.kt       |  2 +-
 .../screenshot/ActionIntentCreatorTest.kt     |  2 +-
 .../MessageContainerControllerTest.kt         |  8 +-
 .../WorkProfileMessageControllerTest.java     |  2 +-
 .../appclips/AppClipsActivityTest.java        |  2 +-
 .../AppClipsTrampolineActivityTest.java       |  2 +-
 .../brightness/BrightnessDialogTest.kt        |  2 +-
 .../CombinedShadeHeaderConstraintsTest.kt     |  2 +-
 ...ationPanelUnfoldAnimationControllerTest.kt |  2 +-
 ...tificationPanelViewControllerBaseTest.java |  2 +-
 .../NotificationPanelViewControllerTest.java  |  2 +-
 ...onPanelViewControllerWithCoroutinesTest.kt |  2 +-
 ...ficationShadeWindowControllerImplTest.java |  2 +-
 ...tificationShadeWindowViewControllerTest.kt |  2 +-
 .../shade/NotificationShadeWindowViewTest.kt  |  2 +-
 ...icationsQSContainerControllerLegacyTest.kt |  2 +-
 .../NotificationsQSContainerControllerTest.kt |  2 +-
 ...NotificationsQuickSettingsContainerTest.kt |  2 +-
 .../shade/QsBatteryModeControllerTest.kt      |  2 +-
 .../QuickSettingsControllerBaseTest.java      |  2 +-
 .../shade/QuickSettingsControllerTest.java    |  2 +-
 .../shade/ShadeHeaderControllerTest.kt        |  2 +-
 .../shade/carrier/ShadeCarrierTest.java       |  2 +-
 .../data/repository/ShadeInteractorTest.kt    |  2 +-
 .../LargeScreenShadeInterpolatorImplTest.kt   |  2 +-
 .../shadow/DoubleShadowTextClockTest.kt       |  2 +-
 .../shared/clocks/AnimatableClockViewTest.kt  |  2 +-
 .../shared/clocks/DefaultClockProviderTest.kt |  2 +-
 .../AlertingNotificationManagerTest.java      |  2 +-
 .../KeyguardIndicationControllerBaseTest.java |  2 +-
 .../KeyguardIndicationControllerTest.java     |  2 +-
 ...ckscreenShadeQsTransitionControllerTest.kt |  2 +-
 ...LockscreenShadeTransitionControllerTest.kt |  2 +-
 .../NotificationShadeDepthControllerTest.kt   |  2 +-
 .../statusbar/SmartReplyControllerTest.java   |  2 +-
 .../statusbar/StatusBarIconViewTest.java      |  2 +-
 .../connectivity/CallbackHandlerTest.java     |  4 +-
 .../NetworkControllerSignalTest.java          |  2 +-
 .../repository/DisableFlagsRepositoryTest.kt  |  2 +-
 .../DynamicChildBindControllerTest.java       |  2 +-
 ...otificationLaunchAnimatorControllerTest.kt |  2 +-
 .../notification/PropertyAnimatorTest.java    |  2 +-
 .../collection/NotificationEntryTest.java     |  2 +-
 ...icationInterruptStateProviderImplTest.java |  2 +-
 .../row/ActivatableNotificationViewTest.kt    |  2 +-
 .../row/BigPictureIconManagerTest.kt          |  2 +-
 .../notification/row/FeedbackInfoTest.java    |  2 +-
 .../notification/row/FooterViewTest.java      |  2 +-
 .../row/NotificationContentInflaterTest.java  |  4 +-
 .../row/NotificationConversationInfoTest.java |  2 +-
 .../notification/row/NotificationGutsTest.kt  |  2 +-
 .../row/NotificationInfoTest.java             |  2 +-
 .../row/NotificationSnoozeTest.java           |  2 +-
 .../row/NotificationTestHelper.java           |  4 +-
 .../row/PartialConversationInfoTest.java      |  2 +-
 .../stack/MediaContainerViewTest.kt           |  2 +-
 .../stack/NotificationShelfTest.kt            |  2 +-
 .../NotificationStackScrollLayoutTest.java    |  2 +-
 .../NotificationStackSizeCalculatorTest.kt    |  2 +-
 .../stack/StackScrollAlgorithmTest.kt         |  2 +-
 ...aredNotificationContainerInteractorTest.kt |  2 +-
 ...haredNotificationContainerViewModelTest.kt |  2 +-
 .../statusbar/phone/AutoTileManagerTest.java  |  2 +-
 .../phone/CentralSurfacesImplTest.java        |  2 +-
 .../phone/HeadsUpManagerPhoneTest.java        |  2 +-
 .../phone/KeyguardBypassControllerTest.kt     |  2 +-
 .../KeyguardClockPositionAlgorithmTest.java   |  2 +-
 .../KeyguardStatusBarViewControllerTest.java  |  2 +-
 .../phone/KeyguardStatusBarViewTest.java      |  2 +-
 .../phone/NotificationGroupTestHelper.java    |  2 +-
 .../phone/NotificationTapHelperTest.java      |  2 +-
 .../phone/PhoneStatusBarTransitionsTest.kt    |  2 +-
 .../phone/PhoneStatusBarViewControllerTest.kt |  2 +-
 .../phone/StatusOverlayHoverListenerTest.kt   |  2 +-
 .../CollapsedStatusBarFragmentTest.java       |  2 +-
 .../OngoingCallBackgroundContainerTest.kt     |  2 +-
 .../ongoingcall/OngoingCallChronometerTest.kt |  2 +-
 .../ongoingcall/OngoingCallControllerTest.kt  |  2 +-
 .../ethernet/domain/EthernetInteractorTest.kt |  2 +-
 .../ui/view/ModernStatusBarMobileViewTest.kt  |  2 +-
 .../ui/viewmodel/InternetTileViewModelTest.kt |  2 +-
 .../ui/view/ModernStatusBarWifiViewTest.kt    |  2 +-
 .../DeviceControlsControllerImplTest.kt       |  2 +-
 .../statusbar/policy/HeadsUpManagerTest.java  |  2 +-
 .../policy/HotspotControllerImplTest.java     |  2 +-
 .../policy/InflatedSmartRepliesTest.java      |  2 +-
 .../KeyguardQsUserSwitchControllerTest.kt     |  2 +-
 .../policy/KeyguardUserSwitcherAdapterTest.kt |  2 +-
 .../RemoteInputQuickSettingsDisablerTest.kt   |  2 +-
 .../statusbar/policy/RemoteInputViewTest.java |  2 +-
 .../policy/SmartReplyConstantsTest.java       |  2 +-
 .../statusbar/policy/SmartReplyViewTest.java  |  2 +-
 .../systemui/stylus/StylusUsiPowerUiTest.kt   |  2 +-
 .../TemporaryViewDisplayControllerTest.kt     |  2 +-
 .../chipbar/ChipbarCoordinatorTest.kt         |  2 +-
 .../android/systemui/toast/ToastUITest.java   |  6 +-
 .../domain/interactor/UserInteractorTest.kt   |  4 +-
 .../systemui/volume/VolumeDialogImplTest.java |  2 +-
 .../QuickAccessWalletControllerTest.java      |  2 +-
 .../android/systemui/wmshell/BubblesTest.java |  8 +-
 .../systemui/SysuiTestableContext.java        |  1 +
 packages/SystemUI/unfold/Android.bp           |  1 +
 1144 files changed, 1410 insertions(+), 1271 deletions(-)

diff --git a/packages/SettingsLib/ActionBarShadow/Android.bp b/packages/SettingsLib/ActionBarShadow/Android.bp
index bf4c8587722a..6f9445874fce 100644
--- a/packages/SettingsLib/ActionBarShadow/Android.bp
+++ b/packages/SettingsLib/ActionBarShadow/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibActionBarShadow",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
 
diff --git a/packages/SettingsLib/ActionBarShadow/AndroidManifest.xml b/packages/SettingsLib/ActionBarShadow/AndroidManifest.xml
index 98c4cb4b2766..4ec6870e6c87 100644
--- a/packages/SettingsLib/ActionBarShadow/AndroidManifest.xml
+++ b/packages/SettingsLib/ActionBarShadow/AndroidManifest.xml
@@ -16,6 +16,6 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.widget">
+          package="com.android.settingslib.widget.actionbarshadow">
 
 </manifest>
diff --git a/packages/SettingsLib/ActionButtonsPreference/Android.bp b/packages/SettingsLib/ActionButtonsPreference/Android.bp
index b6e167717023..122855561751 100644
--- a/packages/SettingsLib/ActionButtonsPreference/Android.bp
+++ b/packages/SettingsLib/ActionButtonsPreference/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibActionButtonsPreference",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
     resource_dirs: ["res"],
diff --git a/packages/SettingsLib/ActionButtonsPreference/AndroidManifest.xml b/packages/SettingsLib/ActionButtonsPreference/AndroidManifest.xml
index 4b9f1ab8d6cc..01ad59814cc8 100644
--- a/packages/SettingsLib/ActionButtonsPreference/AndroidManifest.xml
+++ b/packages/SettingsLib/ActionButtonsPreference/AndroidManifest.xml
@@ -16,7 +16,7 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.widget">
+          package="com.android.settingslib.widget.preference.actionbuttons">
 
     <uses-sdk android:minSdkVersion="21" />
 
diff --git a/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java b/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java
index 4d3ca945f7e1..3e65d94e3323 100644
--- a/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java
+++ b/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java
@@ -32,10 +32,11 @@ import androidx.preference.Preference;
 import androidx.preference.PreferenceViewHolder;
 
 import com.android.settingslib.utils.BuildCompatUtils;
-
 import java.util.ArrayList;
 import java.util.List;
 
+import com.android.settingslib.widget.preference.actionbuttons.R;
+
 /**
  * This preference provides a four buttons layout with Settings style.
  * It looks like below
diff --git a/packages/SettingsLib/ActivityEmbedding/Android.bp b/packages/SettingsLib/ActivityEmbedding/Android.bp
index 0cd9fe387a22..41de29a93e51 100644
--- a/packages/SettingsLib/ActivityEmbedding/Android.bp
+++ b/packages/SettingsLib/ActivityEmbedding/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibActivityEmbedding",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
 
diff --git a/packages/SettingsLib/ActivityEmbedding/AndroidManifest.xml b/packages/SettingsLib/ActivityEmbedding/AndroidManifest.xml
index 0949e1defc2f..c67f51c0d7e7 100644
--- a/packages/SettingsLib/ActivityEmbedding/AndroidManifest.xml
+++ b/packages/SettingsLib/ActivityEmbedding/AndroidManifest.xml
@@ -16,7 +16,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.widget">
+          package="com.android.settingslib.widget.activityembedding">
 
     <uses-sdk android:minSdkVersion="21" />
 
diff --git a/packages/SettingsLib/AdaptiveIcon/Android.bp b/packages/SettingsLib/AdaptiveIcon/Android.bp
index 934aacfddfb9..df72a921544d 100644
--- a/packages/SettingsLib/AdaptiveIcon/Android.bp
+++ b/packages/SettingsLib/AdaptiveIcon/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibAdaptiveIcon",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
     resource_dirs: ["res"],
diff --git a/packages/SettingsLib/AdaptiveIcon/AndroidManifest.xml b/packages/SettingsLib/AdaptiveIcon/AndroidManifest.xml
index 256b8f3ea477..7709ad3cba4d 100644
--- a/packages/SettingsLib/AdaptiveIcon/AndroidManifest.xml
+++ b/packages/SettingsLib/AdaptiveIcon/AndroidManifest.xml
@@ -16,7 +16,7 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.widget">
+          package="com.android.settingslib.widget.adaptiveicon">
 
     <uses-sdk android:minSdkVersion="21" />
 
diff --git a/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveIcon.java b/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveIcon.java
index 723caf2ce0a1..fc41c93587c4 100644
--- a/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveIcon.java
+++ b/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveIcon.java
@@ -32,6 +32,7 @@ import android.util.Log;
 import androidx.annotation.VisibleForTesting;
 
 import com.android.settingslib.drawer.Tile;
+import com.android.settingslib.widget.adaptiveicon.R;
 
 /**
  * Adaptive icon that can set background color
diff --git a/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java b/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java
index e82997431290..12c234ecd739 100644
--- a/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java
+++ b/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java
@@ -34,6 +34,8 @@ import android.view.WindowManagerGlobal;
 import androidx.annotation.IntDef;
 import androidx.annotation.VisibleForTesting;
 
+import com.android.settingslib.widget.adaptiveicon.R;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
diff --git a/packages/SettingsLib/AppPreference/Android.bp b/packages/SettingsLib/AppPreference/Android.bp
index 0ba47a8156e3..69b9d44fe16f 100644
--- a/packages/SettingsLib/AppPreference/Android.bp
+++ b/packages/SettingsLib/AppPreference/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibAppPreference",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
     resource_dirs: ["res"],
diff --git a/packages/SettingsLib/AppPreference/AndroidManifest.xml b/packages/SettingsLib/AppPreference/AndroidManifest.xml
index 4b9f1ab8d6cc..9d014977da8f 100644
--- a/packages/SettingsLib/AppPreference/AndroidManifest.xml
+++ b/packages/SettingsLib/AppPreference/AndroidManifest.xml
@@ -16,7 +16,7 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.widget">
+          package="com.android.settingslib.widget.preference.app">
 
     <uses-sdk android:minSdkVersion="21" />
 
diff --git a/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/AppHeaderPreference.java b/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/AppHeaderPreference.java
index 60d00da29755..b1d311080b86 100644
--- a/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/AppHeaderPreference.java
+++ b/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/AppHeaderPreference.java
@@ -28,6 +28,8 @@ import androidx.annotation.StringRes;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceViewHolder;
 
+import com.android.settingslib.widget.preference.app.R;
+
 /**
  * The Preference for the pages need to show big apps icon and name in the header of the page.
  */
diff --git a/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/AppPreference.java b/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/AppPreference.java
index cfe701353787..f1d162e116b5 100644
--- a/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/AppPreference.java
+++ b/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/AppPreference.java
@@ -24,6 +24,8 @@ import android.widget.ProgressBar;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceViewHolder;
 
+import com.android.settingslib.widget.preference.app.R;
+
 /**
  * The Preference for the pages need to show apps icon.
  */
diff --git a/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/AppSwitchPreference.java b/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/AppSwitchPreference.java
index 781bfcdbc75e..87bfc8111a4b 100644
--- a/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/AppSwitchPreference.java
+++ b/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/AppSwitchPreference.java
@@ -22,7 +22,7 @@ import android.view.View;
 
 import androidx.preference.PreferenceViewHolder;
 import androidx.preference.SwitchPreference;
-
+import com.android.settingslib.widget.preference.app.R;
 /**
  * The SwitchPreference for the pages need to show apps icon.
  */
diff --git a/packages/SettingsLib/BannerMessagePreference/Android.bp b/packages/SettingsLib/BannerMessagePreference/Android.bp
index 0f7a451e7c8b..da91344242a1 100644
--- a/packages/SettingsLib/BannerMessagePreference/Android.bp
+++ b/packages/SettingsLib/BannerMessagePreference/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibBannerMessagePreference",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
     resource_dirs: ["res"],
diff --git a/packages/SettingsLib/BannerMessagePreference/AndroidManifest.xml b/packages/SettingsLib/BannerMessagePreference/AndroidManifest.xml
index dd51ea38a1fe..a93a1fec8135 100644
--- a/packages/SettingsLib/BannerMessagePreference/AndroidManifest.xml
+++ b/packages/SettingsLib/BannerMessagePreference/AndroidManifest.xml
@@ -16,7 +16,7 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.widget">
+          package="com.android.settingslib.widget.preference.banner">
 
     <uses-sdk android:minSdkVersion="28"/>
 
diff --git a/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessagePreference.java b/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessagePreference.java
index afeb24ad3b61..33775a64aa82 100644
--- a/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessagePreference.java
+++ b/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessagePreference.java
@@ -39,7 +39,7 @@ import androidx.preference.Preference;
 import androidx.preference.PreferenceViewHolder;
 
 import com.android.settingslib.utils.BuildCompatUtils;
-
+import com.android.settingslib.widget.preference.banner.R;
 /**
  * Banner message is a banner displaying important information (permission request, page error etc),
  * and provide actions for user to address. It requires a user action to be dismissed.
diff --git a/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessageView.java b/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessageView.java
index 5ca6fb64db2d..ff4e79ddaaa1 100644
--- a/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessageView.java
+++ b/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessageView.java
@@ -25,6 +25,8 @@ import android.widget.LinearLayout;
 
 import androidx.annotation.Nullable;
 
+import com.android.settingslib.widget.preference.banner.R;
+
 /**
  * The view providing {@link BannerMessagePreference}.
  *
@@ -75,7 +77,7 @@ public class BannerMessageView extends LinearLayout {
 
         int minimum =
                 getResources()
-                        .getDimensionPixelSize(R.dimen.settingslib_preferred_minimum_touch_target);
+                        .getDimensionPixelSize(com.android.settingslib.widget.theme.R.dimen.settingslib_preferred_minimum_touch_target);
         int width = dismissButton.getWidth();
         int height = dismissButton.getHeight();
         int widthIncrease = width < minimum ? minimum - width : 0;
diff --git a/packages/SettingsLib/BarChartPreference/Android.bp b/packages/SettingsLib/BarChartPreference/Android.bp
index 5c5da9827e61..be1e0cf8ab4f 100644
--- a/packages/SettingsLib/BarChartPreference/Android.bp
+++ b/packages/SettingsLib/BarChartPreference/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibBarChartPreference",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
     resource_dirs: ["res"],
diff --git a/packages/SettingsLib/BarChartPreference/AndroidManifest.xml b/packages/SettingsLib/BarChartPreference/AndroidManifest.xml
index 4b9f1ab8d6cc..fda4e1d2e232 100644
--- a/packages/SettingsLib/BarChartPreference/AndroidManifest.xml
+++ b/packages/SettingsLib/BarChartPreference/AndroidManifest.xml
@@ -16,7 +16,7 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.widget">
+          package="com.android.settingslib.widget.preference.barchart">
 
     <uses-sdk android:minSdkVersion="21" />
 
diff --git a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarChartInfo.java b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarChartInfo.java
index eeaf2737a2fd..a32a24d825ba 100644
--- a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarChartInfo.java
+++ b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarChartInfo.java
@@ -24,7 +24,7 @@ import androidx.annotation.StringRes;
 
 import java.util.ArrayList;
 import java.util.List;
-
+import com.android.settingslib.widget.preference.barchart.R;
 /**
  * BarChartInfo is responsible for storing information about {@link BarChartPreference}.
  */
diff --git a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarChartPreference.java b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarChartPreference.java
index 20e0a3b20b8c..d63fc3c34728 100644
--- a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarChartPreference.java
+++ b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarChartPreference.java
@@ -28,7 +28,7 @@ import androidx.preference.Preference;
 import androidx.preference.PreferenceViewHolder;
 
 import java.util.Arrays;
-
+import com.android.settingslib.widget.preference.barchart.R;
 /**
  * This BarChartPreference shows up to four bar views in this preference at most.
  *
diff --git a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarView.java b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarView.java
index 93a34c03bf92..7c749716942d 100644
--- a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarView.java
+++ b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarView.java
@@ -29,7 +29,7 @@ import android.widget.TextView;
 
 import androidx.annotation.ColorInt;
 import androidx.annotation.VisibleForTesting;
-
+import com.android.settingslib.widget.preference.barchart.R;
 /**
  * {@link View} for a single vertical bar with icon and summary.
  */
diff --git a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarViewInfo.java b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarViewInfo.java
index 922337a92f18..4b6ca4ad48ca 100644
--- a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarViewInfo.java
+++ b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarViewInfo.java
@@ -23,7 +23,7 @@ import androidx.annotation.IntRange;
 import androidx.annotation.Nullable;
 
 import java.util.Comparator;
-
+import com.android.settingslib.widget.preference.barchart.R;
 /**
  * A class responsible for saving bar view information.
  */
diff --git a/packages/SettingsLib/ButtonPreference/Android.bp b/packages/SettingsLib/ButtonPreference/Android.bp
index 39f804fa9ae5..35572fad55a2 100644
--- a/packages/SettingsLib/ButtonPreference/Android.bp
+++ b/packages/SettingsLib/ButtonPreference/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibButtonPreference",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
     resource_dirs: ["res"],
diff --git a/packages/SettingsLib/ButtonPreference/AndroidManifest.xml b/packages/SettingsLib/ButtonPreference/AndroidManifest.xml
index 2d35c331cd82..f867707e8e08 100644
--- a/packages/SettingsLib/ButtonPreference/AndroidManifest.xml
+++ b/packages/SettingsLib/ButtonPreference/AndroidManifest.xml
@@ -16,7 +16,7 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.widget">
+          package="com.android.settingslib.widget.preference.button">
 
     <uses-sdk android:minSdkVersion="21" />
 
diff --git a/packages/SettingsLib/ButtonPreference/src/com/android/settingslib/widget/ButtonPreference.java b/packages/SettingsLib/ButtonPreference/src/com/android/settingslib/widget/ButtonPreference.java
index 5364783b4c68..16ba96265751 100644
--- a/packages/SettingsLib/ButtonPreference/src/com/android/settingslib/widget/ButtonPreference.java
+++ b/packages/SettingsLib/ButtonPreference/src/com/android/settingslib/widget/ButtonPreference.java
@@ -30,6 +30,8 @@ import androidx.annotation.GravityInt;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceViewHolder;
 
+import com.android.settingslib.widget.preference.button.R;
+
 /**
  * A preference handled a button
  */
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp b/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp
index df43863fdd84..70f7554d5e53 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibCollapsingToolbarBaseActivity",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
     resource_dirs: ["res"],
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/AndroidManifest.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/AndroidManifest.xml
index 51fc7ed64660..dabba6832134 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/AndroidManifest.xml
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/AndroidManifest.xml
@@ -16,7 +16,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.widget">
+          package="com.android.settingslib.collapsingtoolbar">
 
     <uses-sdk android:minSdkVersion="21" />
 
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/BasePreferencesFragment.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/BasePreferencesFragment.java
index 3582897014ff..8ebbac39d1d0 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/BasePreferencesFragment.java
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/BasePreferencesFragment.java
@@ -20,7 +20,6 @@ import androidx.fragment.app.FragmentActivity;
 import androidx.preference.PreferenceFragmentCompat;
 
 import com.android.settingslib.utils.BuildCompatUtils;
-import com.android.settingslib.widget.R;
 
 import com.google.android.material.appbar.AppBarLayout;
 
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarAppCompatActivity.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarAppCompatActivity.java
index dcc6e5a37246..04c44e6d11be 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarAppCompatActivity.java
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarAppCompatActivity.java
@@ -27,7 +27,6 @@ import androidx.annotation.Nullable;
 import androidx.appcompat.app.AppCompatActivity;
 
 import com.android.settingslib.utils.BuildCompatUtils;
-import com.android.settingslib.widget.R;
 
 import com.google.android.material.appbar.AppBarLayout;
 import com.google.android.material.appbar.CollapsingToolbarLayout;
@@ -70,7 +69,7 @@ public class CollapsingToolbarAppCompatActivity extends AppCompatActivity {
         if (BuildCompatUtils.isAtLeastS()) {
             DynamicColors.applyToActivityIfAvailable(this);
         }
-        setTheme(R.style.Theme_SubSettingsBase);
+        setTheme(com.android.settingslib.widget.theme.R.style.Theme_SubSettingsBase);
 
         if (mCustomizeLayoutResId > 0 && !BuildCompatUtils.isAtLeastS()) {
             super.setContentView(mCustomizeLayoutResId);
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
index 19b7e8546805..143101f76977 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
@@ -28,7 +28,6 @@ import androidx.annotation.Nullable;
 import androidx.fragment.app.FragmentActivity;
 
 import com.android.settingslib.utils.BuildCompatUtils;
-import com.android.settingslib.widget.R;
 
 import com.google.android.material.appbar.AppBarLayout;
 import com.google.android.material.appbar.CollapsingToolbarLayout;
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarDelegate.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarDelegate.java
index 1c2288acd358..155cfbbc6677 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarDelegate.java
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarDelegate.java
@@ -35,8 +35,6 @@ import androidx.annotation.Nullable;
 import androidx.appcompat.app.AppCompatActivity;
 import androidx.coordinatorlayout.widget.CoordinatorLayout;
 
-import com.android.settingslib.widget.R;
-
 import com.google.android.material.appbar.AppBarLayout;
 import com.google.android.material.appbar.CollapsingToolbarLayout;
 
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/widget/CollapsingCoordinatorLayout.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/widget/CollapsingCoordinatorLayout.java
index e4e34f8cae1e..f70add9cc62d 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/widget/CollapsingCoordinatorLayout.java
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/widget/CollapsingCoordinatorLayout.java
@@ -38,7 +38,7 @@ import androidx.annotation.RequiresApi;
 import androidx.appcompat.app.AppCompatActivity;
 import androidx.coordinatorlayout.widget.CoordinatorLayout;
 
-import com.android.settingslib.widget.R;
+import com.android.settingslib.collapsingtoolbar.R;
 
 import com.google.android.material.appbar.AppBarLayout;
 import com.google.android.material.appbar.CollapsingToolbarLayout;
diff --git a/packages/SettingsLib/DeviceStateRotationLock/Android.bp b/packages/SettingsLib/DeviceStateRotationLock/Android.bp
index 103309a43bb8..72df6cd58af5 100644
--- a/packages/SettingsLib/DeviceStateRotationLock/Android.bp
+++ b/packages/SettingsLib/DeviceStateRotationLock/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibDeviceStateRotationLock",
+    use_resource_processor: true,
 
     srcs: [
         "src/**/*.java",
diff --git a/packages/SettingsLib/DisplayUtils/Android.bp b/packages/SettingsLib/DisplayUtils/Android.bp
index 136f883ca70d..eab35a11d7d6 100644
--- a/packages/SettingsLib/DisplayUtils/Android.bp
+++ b/packages/SettingsLib/DisplayUtils/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibDisplayUtils",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
 
diff --git a/packages/SettingsLib/EmergencyNumber/Android.bp b/packages/SettingsLib/EmergencyNumber/Android.bp
index 25b4905c438f..986baf70fa44 100644
--- a/packages/SettingsLib/EmergencyNumber/Android.bp
+++ b/packages/SettingsLib/EmergencyNumber/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibEmergencyNumber",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
     static_libs: [
diff --git a/packages/SettingsLib/EntityHeaderWidgets/Android.bp b/packages/SettingsLib/EntityHeaderWidgets/Android.bp
index bd83cdce0078..17b662c60227 100644
--- a/packages/SettingsLib/EntityHeaderWidgets/Android.bp
+++ b/packages/SettingsLib/EntityHeaderWidgets/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibEntityHeaderWidgets",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
     resource_dirs: ["res"],
diff --git a/packages/SettingsLib/EntityHeaderWidgets/AndroidManifest.xml b/packages/SettingsLib/EntityHeaderWidgets/AndroidManifest.xml
index 4b9f1ab8d6cc..ad4d22d0e276 100644
--- a/packages/SettingsLib/EntityHeaderWidgets/AndroidManifest.xml
+++ b/packages/SettingsLib/EntityHeaderWidgets/AndroidManifest.xml
@@ -16,7 +16,7 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.widget">
+          package="com.android.settingslib.widget.entityheader">
 
     <uses-sdk android:minSdkVersion="21" />
 
diff --git a/packages/SettingsLib/EntityHeaderWidgets/src/com/android/settingslib/widget/AppEntitiesHeaderController.java b/packages/SettingsLib/EntityHeaderWidgets/src/com/android/settingslib/widget/AppEntitiesHeaderController.java
index 6e95a0ed106a..d802e5b7a145 100644
--- a/packages/SettingsLib/EntityHeaderWidgets/src/com/android/settingslib/widget/AppEntitiesHeaderController.java
+++ b/packages/SettingsLib/EntityHeaderWidgets/src/com/android/settingslib/widget/AppEntitiesHeaderController.java
@@ -30,6 +30,8 @@ import androidx.annotation.Nullable;
 import androidx.annotation.StringRes;
 import androidx.annotation.VisibleForTesting;
 
+import com.android.settingslib.widget.entityheader.R;
+
 /**
  * This class is used to initialize view which was inflated
  * from {@link R.xml.app_entities_header.xml}.
diff --git a/packages/SettingsLib/EntityHeaderWidgets/src/com/android/settingslib/widget/AppEntityInfo.java b/packages/SettingsLib/EntityHeaderWidgets/src/com/android/settingslib/widget/AppEntityInfo.java
index 1e55f2e99bfc..0439ff5dab96 100644
--- a/packages/SettingsLib/EntityHeaderWidgets/src/com/android/settingslib/widget/AppEntityInfo.java
+++ b/packages/SettingsLib/EntityHeaderWidgets/src/com/android/settingslib/widget/AppEntityInfo.java
@@ -22,6 +22,8 @@ import android.view.View;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.android.settingslib.widget.entityheader.R;
+
 /**
  * AppEntityInfo is responsible for storing app information shown in {@link R.xml.app_view.xml}.
  */
diff --git a/packages/SettingsLib/FooterPreference/Android.bp b/packages/SettingsLib/FooterPreference/Android.bp
index 8b976bbb2c56..b45cd65467d2 100644
--- a/packages/SettingsLib/FooterPreference/Android.bp
+++ b/packages/SettingsLib/FooterPreference/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibFooterPreference",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
     resource_dirs: ["res"],
diff --git a/packages/SettingsLib/FooterPreference/AndroidManifest.xml b/packages/SettingsLib/FooterPreference/AndroidManifest.xml
index 96d9e518663f..9046b109bb75 100644
--- a/packages/SettingsLib/FooterPreference/AndroidManifest.xml
+++ b/packages/SettingsLib/FooterPreference/AndroidManifest.xml
@@ -16,7 +16,7 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.widget">
+          package="com.android.settingslib.widget.preference.footer">
 
     <uses-sdk android:minSdkVersion="21" />
 
diff --git a/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/FooterPreference.java b/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/FooterPreference.java
index bf24c86b8d8b..5b2fa1d2a1bb 100644
--- a/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/FooterPreference.java
+++ b/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/FooterPreference.java
@@ -30,6 +30,8 @@ import androidx.annotation.VisibleForTesting;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceViewHolder;
 
+import com.android.settingslib.widget.preference.footer.R;
+
 /**
  * A custom preference acting as "footer" of a page. It has a field for icon and text. It is added
  * to screen as the last preference.
@@ -47,7 +49,7 @@ public class FooterPreference extends Preference {
     private FooterLearnMoreSpan mLearnMoreSpan;
 
     public FooterPreference(Context context, AttributeSet attrs) {
-        super(context, attrs, R.attr.footerPreferenceStyle);
+        super(context, attrs, com.android.settingslib.widget.theme.R.attr.footerPreferenceStyle);
         init();
     }
 
diff --git a/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/LinkTextView.java b/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/LinkTextView.java
index 868feadf6b35..16d4475aaa07 100644
--- a/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/LinkTextView.java
+++ b/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/LinkTextView.java
@@ -22,6 +22,8 @@ import android.text.style.ClickableSpan;
 import android.util.AttributeSet;
 import android.widget.TextView;
 
+import com.android.settingslib.widget.preference.footer.R;
+
 /**
  * Copied from setup wizard. This TextView performed two functions. The first is to make it so the
  * link behaves properly and becomes clickable. The second was that it made the link visible to
diff --git a/packages/SettingsLib/HelpUtils/Android.bp b/packages/SettingsLib/HelpUtils/Android.bp
index 13fcf8c7cbe3..041fce254b72 100644
--- a/packages/SettingsLib/HelpUtils/Android.bp
+++ b/packages/SettingsLib/HelpUtils/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibHelpUtils",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
     resource_dirs: ["res"],
diff --git a/packages/SettingsLib/HelpUtils/AndroidManifest.xml b/packages/SettingsLib/HelpUtils/AndroidManifest.xml
index ccad6e49ff8c..35c7515b60a0 100644
--- a/packages/SettingsLib/HelpUtils/AndroidManifest.xml
+++ b/packages/SettingsLib/HelpUtils/AndroidManifest.xml
@@ -16,6 +16,6 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.settingslib.widget">
+    package="com.android.settingslib.widget.help">
 
 </manifest>
diff --git a/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java b/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java
index 70c8658a7f55..2c13695eb892 100644
--- a/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java
+++ b/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java
@@ -36,7 +36,7 @@ import android.view.MenuItem.OnMenuItemClickListener;
 import androidx.annotation.RequiresApi;
 import androidx.annotation.VisibleForTesting;
 
-import com.android.settingslib.widget.R;
+import com.android.settingslib.widget.help.R;
 
 import java.net.URISyntaxException;
 import java.util.Locale;
diff --git a/packages/SettingsLib/IllustrationPreference/Android.bp b/packages/SettingsLib/IllustrationPreference/Android.bp
index 24ccab235fa1..4d4759b99f15 100644
--- a/packages/SettingsLib/IllustrationPreference/Android.bp
+++ b/packages/SettingsLib/IllustrationPreference/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibIllustrationPreference",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
     resource_dirs: ["res"],
diff --git a/packages/SettingsLib/IllustrationPreference/AndroidManifest.xml b/packages/SettingsLib/IllustrationPreference/AndroidManifest.xml
index 73163fca5362..a0d10c383445 100644
--- a/packages/SettingsLib/IllustrationPreference/AndroidManifest.xml
+++ b/packages/SettingsLib/IllustrationPreference/AndroidManifest.xml
@@ -16,7 +16,7 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.widget">
+          package="com.android.settingslib.widget.preference.illustration">
 
     <uses-sdk android:minSdkVersion="28" />
 
diff --git a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java
index 37ae2d45e614..f4d4dbadb37f 100644
--- a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java
+++ b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java
@@ -42,6 +42,7 @@ import com.airbnb.lottie.LottieDrawable;
 
 import java.io.FileNotFoundException;
 import java.io.InputStream;
+import com.android.settingslib.widget.preference.illustration.R;
 
 /**
  * IllustrationPreference is a preference that can play lottie format animation
@@ -427,10 +428,10 @@ public class IllustrationPreference extends Preference {
         mIsAutoScale = false;
         if (attrs != null) {
             TypedArray a = context.obtainStyledAttributes(attrs,
-                    R.styleable.LottieAnimationView, 0 /*defStyleAttr*/, 0 /*defStyleRes*/);
-            mImageResId = a.getResourceId(R.styleable.LottieAnimationView_lottie_rawRes, 0);
+                    com.airbnb.lottie.R.styleable.LottieAnimationView, 0 /*defStyleAttr*/, 0 /*defStyleRes*/);
+            mImageResId = a.getResourceId(com.airbnb.lottie.R.styleable.LottieAnimationView_lottie_rawRes, 0);
             mCacheComposition = a.getBoolean(
-                    R.styleable.LottieAnimationView_lottie_cacheComposition, true);
+                    com.airbnb.lottie.R.styleable.LottieAnimationView_lottie_cacheComposition, true);
 
             a = context.obtainStyledAttributes(attrs,
                     R.styleable.IllustrationPreference, 0 /*defStyleAttr*/, 0 /*defStyleRes*/);
diff --git a/packages/SettingsLib/LayoutPreference/Android.bp b/packages/SettingsLib/LayoutPreference/Android.bp
index c29e1f789fd3..53ded2385634 100644
--- a/packages/SettingsLib/LayoutPreference/Android.bp
+++ b/packages/SettingsLib/LayoutPreference/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibLayoutPreference",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
     resource_dirs: ["res"],
diff --git a/packages/SettingsLib/LayoutPreference/AndroidManifest.xml b/packages/SettingsLib/LayoutPreference/AndroidManifest.xml
index 4b9f1ab8d6cc..a8427a1cbfb1 100644
--- a/packages/SettingsLib/LayoutPreference/AndroidManifest.xml
+++ b/packages/SettingsLib/LayoutPreference/AndroidManifest.xml
@@ -16,7 +16,7 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.widget">
+          package="com.android.settingslib.widget.preference.layout">
 
     <uses-sdk android:minSdkVersion="21" />
 
diff --git a/packages/SettingsLib/LayoutPreference/src/com/android/settingslib/widget/LayoutPreference.java b/packages/SettingsLib/LayoutPreference/src/com/android/settingslib/widget/LayoutPreference.java
index 2a635b0996e6..49f045f4423c 100644
--- a/packages/SettingsLib/LayoutPreference/src/com/android/settingslib/widget/LayoutPreference.java
+++ b/packages/SettingsLib/LayoutPreference/src/com/android/settingslib/widget/LayoutPreference.java
@@ -102,16 +102,16 @@ public class LayoutPreference extends Preference {
     }
 
     private void init(Context context, AttributeSet attrs, int defStyleAttr) {
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Preference);
-        mAllowDividerAbove = TypedArrayUtils.getBoolean(a, R.styleable.Preference_allowDividerAbove,
-                R.styleable.Preference_allowDividerAbove, false);
-        mAllowDividerBelow = TypedArrayUtils.getBoolean(a, R.styleable.Preference_allowDividerBelow,
-                R.styleable.Preference_allowDividerBelow, false);
+        TypedArray a = context.obtainStyledAttributes(attrs, androidx.preference.R.styleable.Preference);
+        mAllowDividerAbove = TypedArrayUtils.getBoolean(a, androidx.preference.R.styleable.Preference_allowDividerAbove,
+                androidx.preference.R.styleable.Preference_allowDividerAbove, false);
+        mAllowDividerBelow = TypedArrayUtils.getBoolean(a, androidx.preference.R.styleable.Preference_allowDividerBelow,
+                androidx.preference.R.styleable.Preference_allowDividerBelow, false);
         a.recycle();
 
         a = context.obtainStyledAttributes(
-                attrs, R.styleable.Preference, defStyleAttr, 0);
-        int layoutResource = a.getResourceId(R.styleable.Preference_android_layout, 0);
+                attrs, androidx.preference.R.styleable.Preference, defStyleAttr, 0);
+        int layoutResource = a.getResourceId(androidx.preference.R.styleable.Preference_android_layout, 0);
         if (layoutResource == 0) {
             throw new IllegalArgumentException("LayoutPreference requires a layout to be defined");
         }
@@ -124,7 +124,7 @@ public class LayoutPreference extends Preference {
     }
 
     private void setView(View view) {
-        setLayoutResource(R.layout.layout_preference_frame);
+        setLayoutResource(com.android.settingslib.widget.preference.layout.R.layout.layout_preference_frame);
         mRootView = view;
         setShouldDisableView(false);
     }
diff --git a/packages/SettingsLib/MainSwitchPreference/AndroidManifest.xml b/packages/SettingsLib/MainSwitchPreference/AndroidManifest.xml
index 6e0d82768148..4b3acbf2c394 100644
--- a/packages/SettingsLib/MainSwitchPreference/AndroidManifest.xml
+++ b/packages/SettingsLib/MainSwitchPreference/AndroidManifest.xml
@@ -16,6 +16,6 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.widget">
+          package="com.android.settingslib.widget.mainswitch">
 
 </manifest>
diff --git a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
index d1703c31627d..56b3eacf6c1f 100644
--- a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
+++ b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
@@ -35,6 +35,8 @@ import com.android.settingslib.utils.BuildCompatUtils;
 import java.util.ArrayList;
 import java.util.List;
 
+import com.android.settingslib.widget.mainswitch.R;
+
 /**
  * MainSwitchBar is a View with a customized Switch.
  * This component is used as the main switch of the page
diff --git a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java
index 53cc268851e7..11a680466ecf 100644
--- a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java
+++ b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java
@@ -27,6 +27,8 @@ import androidx.preference.TwoStatePreference;
 import java.util.ArrayList;
 import java.util.List;
 
+import com.android.settingslib.widget.mainswitch.R;
+
 /**
  * MainSwitchPreference is a Preference with a customized Switch.
  * This component is used as the main switch of the page
diff --git a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/OnMainSwitchChangeListener.java b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/OnMainSwitchChangeListener.java
index 1c610d9995f6..03868f99663d 100644
--- a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/OnMainSwitchChangeListener.java
+++ b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/OnMainSwitchChangeListener.java
@@ -18,6 +18,8 @@ package com.android.settingslib.widget;
 
 import android.widget.Switch;
 
+import com.android.settingslib.widget.mainswitch.R;
+
 /**
  * Called when the checked state of the Switch has changed.
  */
diff --git a/packages/SettingsLib/ProfileSelector/Android.bp b/packages/SettingsLib/ProfileSelector/Android.bp
index 250cd755a6a6..155ed2e091f8 100644
--- a/packages/SettingsLib/ProfileSelector/Android.bp
+++ b/packages/SettingsLib/ProfileSelector/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibProfileSelector",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
     resource_dirs: ["res"],
diff --git a/packages/SettingsLib/ProfileSelector/AndroidManifest.xml b/packages/SettingsLib/ProfileSelector/AndroidManifest.xml
index a57469e39eb6..80f6b7683269 100644
--- a/packages/SettingsLib/ProfileSelector/AndroidManifest.xml
+++ b/packages/SettingsLib/ProfileSelector/AndroidManifest.xml
@@ -16,7 +16,7 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.widget">
+          package="com.android.settingslib.widget.profileselector">
 
     <uses-sdk android:minSdkVersion="23" />
 </manifest>
diff --git a/packages/SettingsLib/ProfileSelector/src/com/android/settingslib/widget/ProfileSelectFragment.java b/packages/SettingsLib/ProfileSelector/src/com/android/settingslib/widget/ProfileSelectFragment.java
index ac426ed8b5d4..be5753beea4e 100644
--- a/packages/SettingsLib/ProfileSelector/src/com/android/settingslib/widget/ProfileSelectFragment.java
+++ b/packages/SettingsLib/ProfileSelector/src/com/android/settingslib/widget/ProfileSelectFragment.java
@@ -27,6 +27,7 @@ import androidx.viewpager2.widget.ViewPager2;
 
 import com.google.android.material.tabs.TabLayout;
 import com.google.android.material.tabs.TabLayoutMediator;
+import com.android.settingslib.widget.profileselector.R;
 
 /**
  * Base fragment class for profile settings.
diff --git a/packages/SettingsLib/ProfileSelector/src/com/android/settingslib/widget/ProfileViewPagerAdapter.java b/packages/SettingsLib/ProfileSelector/src/com/android/settingslib/widget/ProfileViewPagerAdapter.java
index daf2564a674e..f5ab64742992 100644
--- a/packages/SettingsLib/ProfileSelector/src/com/android/settingslib/widget/ProfileViewPagerAdapter.java
+++ b/packages/SettingsLib/ProfileSelector/src/com/android/settingslib/widget/ProfileViewPagerAdapter.java
@@ -18,6 +18,7 @@ package com.android.settingslib.widget;
 
 import androidx.fragment.app.Fragment;
 import androidx.viewpager2.adapter.FragmentStateAdapter;
+import com.android.settingslib.widget.profileselector.R;
 
 /**
  * ViewPager Adapter to handle between TabLayout and ViewPager2
diff --git a/packages/SettingsLib/ProgressBar/Android.bp b/packages/SettingsLib/ProgressBar/Android.bp
index fb3c4e6efd90..d876573a7728 100644
--- a/packages/SettingsLib/ProgressBar/Android.bp
+++ b/packages/SettingsLib/ProgressBar/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibProgressBar",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
     resource_dirs: ["res"],
diff --git a/packages/SettingsLib/ProgressBar/AndroidManifest.xml b/packages/SettingsLib/ProgressBar/AndroidManifest.xml
index 256b8f3ea477..fbd6eb00feb6 100644
--- a/packages/SettingsLib/ProgressBar/AndroidManifest.xml
+++ b/packages/SettingsLib/ProgressBar/AndroidManifest.xml
@@ -16,7 +16,7 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.widget">
+          package="com.android.settingslib.widget.progressbar">
 
     <uses-sdk android:minSdkVersion="21" />
 
diff --git a/packages/SettingsLib/RadioButtonPreference/Android.bp b/packages/SettingsLib/RadioButtonPreference/Android.bp
index 1387daa959be..505ba05c5f59 100644
--- a/packages/SettingsLib/RadioButtonPreference/Android.bp
+++ b/packages/SettingsLib/RadioButtonPreference/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibRadioButtonPreference",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
     resource_dirs: ["res"],
diff --git a/packages/SettingsLib/RadioButtonPreference/AndroidManifest.xml b/packages/SettingsLib/RadioButtonPreference/AndroidManifest.xml
index fda7fde29404..8b5c3b1b5652 100644
--- a/packages/SettingsLib/RadioButtonPreference/AndroidManifest.xml
+++ b/packages/SettingsLib/RadioButtonPreference/AndroidManifest.xml
@@ -16,7 +16,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.widget">
+          package="com.android.settingslib.widget.preference.radio">
 
     <uses-sdk android:minSdkVersion="21" />
 
diff --git a/packages/SettingsLib/RadioButtonPreference/src/com/android/settingslib/widget/RadioButtonPreference.java b/packages/SettingsLib/RadioButtonPreference/src/com/android/settingslib/widget/RadioButtonPreference.java
index 02d3c06dcea2..fc4b71430c5f 100644
--- a/packages/SettingsLib/RadioButtonPreference/src/com/android/settingslib/widget/RadioButtonPreference.java
+++ b/packages/SettingsLib/RadioButtonPreference/src/com/android/settingslib/widget/RadioButtonPreference.java
@@ -25,6 +25,8 @@ import android.widget.ImageView;
 import androidx.preference.CheckBoxPreference;
 import androidx.preference.PreferenceViewHolder;
 
+import com.android.settingslib.widget.preference.radio.R;
+
 /**
  * DEPRECATED. Please use SelectorWithWidgetPreference instead.
  *
diff --git a/packages/SettingsLib/RestrictedLockUtils/Android.bp b/packages/SettingsLib/RestrictedLockUtils/Android.bp
index 6a8fef36a969..028489d22bdb 100644
--- a/packages/SettingsLib/RestrictedLockUtils/Android.bp
+++ b/packages/SettingsLib/RestrictedLockUtils/Android.bp
@@ -15,6 +15,7 @@ filegroup {
 
 android_library {
     name: "SettingsLibRestrictedLockUtils",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
     resource_dirs: ["res"],
diff --git a/packages/SettingsLib/RestrictedLockUtils/AndroidManifest.xml b/packages/SettingsLib/RestrictedLockUtils/AndroidManifest.xml
index 09756400b736..50a55a79fb3e 100644
--- a/packages/SettingsLib/RestrictedLockUtils/AndroidManifest.xml
+++ b/packages/SettingsLib/RestrictedLockUtils/AndroidManifest.xml
@@ -16,6 +16,6 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.widget">
+          package="com.android.settingslib.widget.restricted">
 
 </manifest>
\ No newline at end of file
diff --git a/packages/SettingsLib/SchedulesProvider/Android.bp b/packages/SettingsLib/SchedulesProvider/Android.bp
index c4373bb2dc1f..2d93e4e3a925 100644
--- a/packages/SettingsLib/SchedulesProvider/Android.bp
+++ b/packages/SettingsLib/SchedulesProvider/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibSchedulesProvider",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
 
diff --git a/packages/SettingsLib/SearchProvider/Android.bp b/packages/SettingsLib/SearchProvider/Android.bp
index f96011ad5d09..c07a802f3ed5 100644
--- a/packages/SettingsLib/SearchProvider/Android.bp
+++ b/packages/SettingsLib/SearchProvider/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibSearchProvider",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
 
diff --git a/packages/SettingsLib/SearchProvider/AndroidManifest.xml b/packages/SettingsLib/SearchProvider/AndroidManifest.xml
index 2c06673a56ad..7e2c47f420bd 100644
--- a/packages/SettingsLib/SearchProvider/AndroidManifest.xml
+++ b/packages/SettingsLib/SearchProvider/AndroidManifest.xml
@@ -16,7 +16,7 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.search">
+          package="com.android.settingslib.search.provider">
 
     <uses-sdk android:minSdkVersion="21" />
 
diff --git a/packages/SettingsLib/SearchWidget/Android.bp b/packages/SettingsLib/SearchWidget/Android.bp
index 5aaee2afc069..ad9e16738e18 100644
--- a/packages/SettingsLib/SearchWidget/Android.bp
+++ b/packages/SettingsLib/SearchWidget/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibSearchWidget",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
     resource_dirs: ["res"],
diff --git a/packages/SettingsLib/SearchWidget/AndroidManifest.xml b/packages/SettingsLib/SearchWidget/AndroidManifest.xml
index 5798801fe5fa..5982b02902cc 100644
--- a/packages/SettingsLib/SearchWidget/AndroidManifest.xml
+++ b/packages/SettingsLib/SearchWidget/AndroidManifest.xml
@@ -16,6 +16,6 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.search">
+          package="com.android.settingslib.search.widget">
 
 </manifest>
diff --git a/packages/SettingsLib/SelectorWithWidgetPreference/Android.bp b/packages/SettingsLib/SelectorWithWidgetPreference/Android.bp
index b5a21bdae606..702387ecadab 100644
--- a/packages/SettingsLib/SelectorWithWidgetPreference/Android.bp
+++ b/packages/SettingsLib/SelectorWithWidgetPreference/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibSelectorWithWidgetPreference",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
     resource_dirs: ["res"],
diff --git a/packages/SettingsLib/SelectorWithWidgetPreference/AndroidManifest.xml b/packages/SettingsLib/SelectorWithWidgetPreference/AndroidManifest.xml
index 51fc7ed64660..919d1a934ca0 100644
--- a/packages/SettingsLib/SelectorWithWidgetPreference/AndroidManifest.xml
+++ b/packages/SettingsLib/SelectorWithWidgetPreference/AndroidManifest.xml
@@ -16,7 +16,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.widget">
+          package="com.android.settingslib.widget.preference.selector">
 
     <uses-sdk android:minSdkVersion="21" />
 
diff --git a/packages/SettingsLib/SelectorWithWidgetPreference/src/com/android/settingslib/widget/SelectorWithWidgetPreference.java b/packages/SettingsLib/SelectorWithWidgetPreference/src/com/android/settingslib/widget/SelectorWithWidgetPreference.java
index 1d1316a48fd3..f2ce8a965dfa 100644
--- a/packages/SettingsLib/SelectorWithWidgetPreference/src/com/android/settingslib/widget/SelectorWithWidgetPreference.java
+++ b/packages/SettingsLib/SelectorWithWidgetPreference/src/com/android/settingslib/widget/SelectorWithWidgetPreference.java
@@ -25,6 +25,8 @@ import android.widget.ImageView;
 import androidx.preference.CheckBoxPreference;
 import androidx.preference.PreferenceViewHolder;
 
+import com.android.settingslib.widget.preference.selector.R;
+
 /**
  * Selector preference (checkbox or radio button) with an optional additional widget.
  *
diff --git a/packages/SettingsLib/SettingsSpinner/Android.bp b/packages/SettingsLib/SettingsSpinner/Android.bp
index cbb570ece8b0..0eec50563a75 100644
--- a/packages/SettingsLib/SettingsSpinner/Android.bp
+++ b/packages/SettingsLib/SettingsSpinner/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibSettingsSpinner",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
     resource_dirs: ["res"],
diff --git a/packages/SettingsLib/SettingsSpinner/AndroidManifest.xml b/packages/SettingsLib/SettingsSpinner/AndroidManifest.xml
index 4b9f1ab8d6cc..123175c91cbc 100644
--- a/packages/SettingsLib/SettingsSpinner/AndroidManifest.xml
+++ b/packages/SettingsLib/SettingsSpinner/AndroidManifest.xml
@@ -16,7 +16,7 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.widget">
+          package="com.android.settingslib.widget.spinner">
 
     <uses-sdk android:minSdkVersion="21" />
 
diff --git a/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/SettingsSpinnerAdapter.java b/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/SettingsSpinnerAdapter.java
index 7288494beb21..f33cacd36c6d 100644
--- a/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/SettingsSpinnerAdapter.java
+++ b/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/SettingsSpinnerAdapter.java
@@ -22,7 +22,7 @@ import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ArrayAdapter;
-
+import com.android.settingslib.widget.spinner.R;
 /**
  * An ArrayAdapter which was used by Spinner with settings style.
  * @param <T> the data type to be loaded.
diff --git a/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/SettingsSpinnerPreference.java b/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/SettingsSpinnerPreference.java
index 69528757c0e3..63fe1b509751 100644
--- a/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/SettingsSpinnerPreference.java
+++ b/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/SettingsSpinnerPreference.java
@@ -25,6 +25,7 @@ import android.widget.Spinner;
 import androidx.preference.Preference;
 import androidx.preference.Preference.OnPreferenceClickListener;
 import androidx.preference.PreferenceViewHolder;
+import com.android.settingslib.widget.spinner.R;
 
 /**
  * This preference uses Spinner & SettingsSpinnerAdapter which provide default layouts for
diff --git a/packages/SettingsLib/SettingsTheme/Android.bp b/packages/SettingsLib/SettingsTheme/Android.bp
index e6fb720ba27f..996477cf7960 100644
--- a/packages/SettingsLib/SettingsTheme/Android.bp
+++ b/packages/SettingsLib/SettingsTheme/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibSettingsTheme",
+    use_resource_processor: true,
     resource_dirs: ["res"],
     static_libs: ["androidx.preference_preference"],
     sdk_version: "system_current",
diff --git a/packages/SettingsLib/SettingsTheme/AndroidManifest.xml b/packages/SettingsLib/SettingsTheme/AndroidManifest.xml
index fda7fde29404..56d137a8927a 100644
--- a/packages/SettingsLib/SettingsTheme/AndroidManifest.xml
+++ b/packages/SettingsLib/SettingsTheme/AndroidManifest.xml
@@ -16,7 +16,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.widget">
+          package="com.android.settingslib.widget.theme">
 
     <uses-sdk android:minSdkVersion="21" />
 
diff --git a/packages/SettingsLib/SettingsTransition/Android.bp b/packages/SettingsLib/SettingsTransition/Android.bp
index 48cc75d41285..06493c056203 100644
--- a/packages/SettingsLib/SettingsTransition/Android.bp
+++ b/packages/SettingsLib/SettingsTransition/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibSettingsTransition",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
 
diff --git a/packages/SettingsLib/SettingsTransition/AndroidManifest.xml b/packages/SettingsLib/SettingsTransition/AndroidManifest.xml
index 244b367423a4..3e64d560c96c 100644
--- a/packages/SettingsLib/SettingsTransition/AndroidManifest.xml
+++ b/packages/SettingsLib/SettingsTransition/AndroidManifest.xml
@@ -16,7 +16,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.widget">
+          package="com.android.settingslib.widget.transition">
 
     <uses-sdk android:minSdkVersion="29" />
 
diff --git a/packages/SettingsLib/Spa/screenshot/Android.bp b/packages/SettingsLib/Spa/screenshot/Android.bp
index 4e6b646da819..bd508cbb9e2f 100644
--- a/packages/SettingsLib/Spa/screenshot/Android.bp
+++ b/packages/SettingsLib/Spa/screenshot/Android.bp
@@ -20,6 +20,7 @@ package {
 
 android_test {
     name: "SpaScreenshotTests",
+    use_resource_processor: true,
     test_suites: ["device-tests"],
 
     asset_dirs: ["assets"],
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictionsProvider.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictionsProvider.kt
index a370ebfe21d5..f54de1514fcf 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictionsProvider.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictionsProvider.kt
@@ -26,10 +26,10 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import com.android.settingslib.RestrictedLockUtils
 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin
 import com.android.settingslib.RestrictedLockUtilsInternal
-import com.android.settingslib.widget.R
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.flow.flow
 import kotlinx.coroutines.flow.flowOn
+import com.android.settingslib.widget.restricted.R
 
 data class Restrictions(
     val userId: Int,
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppInfo.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppInfo.kt
index ea83e1d0d3d1..fc10a27cfa5b 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppInfo.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppInfo.kt
@@ -72,7 +72,7 @@ class AppInfoProvider(private val packageInfo: PackageInfo) {
     private fun InstallType(app: ApplicationInfo) {
         if (!app.isInstantApp) return
         Spacer(modifier = Modifier.height(4.dp))
-        SettingsBody(stringResource(com.android.settingslib.widget.R.string.install_type_instant))
+        SettingsBody(stringResource(com.android.settingslib.widget.preference.app.R.string.install_type_instant))
     }
 
     @Composable
diff --git a/packages/SettingsLib/Tile/Android.bp b/packages/SettingsLib/Tile/Android.bp
index cc570ccbb506..eb9e329b6a59 100644
--- a/packages/SettingsLib/Tile/Android.bp
+++ b/packages/SettingsLib/Tile/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibTile",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
 
diff --git a/packages/SettingsLib/TopIntroPreference/Android.bp b/packages/SettingsLib/TopIntroPreference/Android.bp
index 5d09a1a926d8..77b7ac1246bd 100644
--- a/packages/SettingsLib/TopIntroPreference/Android.bp
+++ b/packages/SettingsLib/TopIntroPreference/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibTopIntroPreference",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
     resource_dirs: ["res"],
diff --git a/packages/SettingsLib/TopIntroPreference/AndroidManifest.xml b/packages/SettingsLib/TopIntroPreference/AndroidManifest.xml
index 96d9e518663f..6cf643f7c708 100644
--- a/packages/SettingsLib/TopIntroPreference/AndroidManifest.xml
+++ b/packages/SettingsLib/TopIntroPreference/AndroidManifest.xml
@@ -16,7 +16,7 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.widget">
+          package="com.android.settingslib.widget.preference.topintro">
 
     <uses-sdk android:minSdkVersion="21" />
 
diff --git a/packages/SettingsLib/TopIntroPreference/src/com/android/settingslib/widget/TopIntroPreference.java b/packages/SettingsLib/TopIntroPreference/src/com/android/settingslib/widget/TopIntroPreference.java
index 5a5a9b8ffada..1bbd76d86b7f 100644
--- a/packages/SettingsLib/TopIntroPreference/src/com/android/settingslib/widget/TopIntroPreference.java
+++ b/packages/SettingsLib/TopIntroPreference/src/com/android/settingslib/widget/TopIntroPreference.java
@@ -22,6 +22,8 @@ import android.util.AttributeSet;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceViewHolder;
 
+import com.android.settingslib.widget.preference.topintro.R;
+
 /**
  * The TopIntroPreference shows a text which describe a feature. Gernerally, we expect this
  * preference always shows on the top of screen.
diff --git a/packages/SettingsLib/TwoTargetPreference/Android.bp b/packages/SettingsLib/TwoTargetPreference/Android.bp
index a3e50a92c0af..5aa906ec0ab3 100644
--- a/packages/SettingsLib/TwoTargetPreference/Android.bp
+++ b/packages/SettingsLib/TwoTargetPreference/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibTwoTargetPreference",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
     resource_dirs: ["res"],
diff --git a/packages/SettingsLib/TwoTargetPreference/AndroidManifest.xml b/packages/SettingsLib/TwoTargetPreference/AndroidManifest.xml
index 120b0859a70a..15e9368b52cd 100644
--- a/packages/SettingsLib/TwoTargetPreference/AndroidManifest.xml
+++ b/packages/SettingsLib/TwoTargetPreference/AndroidManifest.xml
@@ -16,7 +16,7 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.widget">
+          package="com.android.settingslib.widget.preference.twotarget">
 
     <uses-sdk android:minSdkVersion="21" />
 
diff --git a/packages/SettingsLib/TwoTargetPreference/src/com/android/settingslib/widget/TwoTargetPreference.java b/packages/SettingsLib/TwoTargetPreference/src/com/android/settingslib/widget/TwoTargetPreference.java
index 9130662021d5..b125f716fe52 100644
--- a/packages/SettingsLib/TwoTargetPreference/src/com/android/settingslib/widget/TwoTargetPreference.java
+++ b/packages/SettingsLib/TwoTargetPreference/src/com/android/settingslib/widget/TwoTargetPreference.java
@@ -26,6 +26,8 @@ import androidx.annotation.IntDef;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceViewHolder;
 
+import com.android.settingslib.widget.preference.twotarget.R;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
diff --git a/packages/SettingsLib/UsageProgressBarPreference/Android.bp b/packages/SettingsLib/UsageProgressBarPreference/Android.bp
index ad6e7ab9f564..4cc90ccbfe80 100644
--- a/packages/SettingsLib/UsageProgressBarPreference/Android.bp
+++ b/packages/SettingsLib/UsageProgressBarPreference/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibUsageProgressBarPreference",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
     resource_dirs: ["res"],
diff --git a/packages/SettingsLib/UsageProgressBarPreference/AndroidManifest.xml b/packages/SettingsLib/UsageProgressBarPreference/AndroidManifest.xml
index 51fc7ed64660..1e9df9c3e303 100644
--- a/packages/SettingsLib/UsageProgressBarPreference/AndroidManifest.xml
+++ b/packages/SettingsLib/UsageProgressBarPreference/AndroidManifest.xml
@@ -16,7 +16,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.widget">
+          package="com.android.settingslib.widget.preference.usage">
 
     <uses-sdk android:minSdkVersion="21" />
 
diff --git a/packages/SettingsLib/UsageProgressBarPreference/src/com/android/settingslib/widget/UsageProgressBarPreference.java b/packages/SettingsLib/UsageProgressBarPreference/src/com/android/settingslib/widget/UsageProgressBarPreference.java
index 4eedab2f417c..712f6f03a441 100644
--- a/packages/SettingsLib/UsageProgressBarPreference/src/com/android/settingslib/widget/UsageProgressBarPreference.java
+++ b/packages/SettingsLib/UsageProgressBarPreference/src/com/android/settingslib/widget/UsageProgressBarPreference.java
@@ -31,6 +31,8 @@ import android.widget.TextView;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceViewHolder;
 
+import com.android.settingslib.widget.preference.usage.R;
+
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
diff --git a/packages/SettingsLib/Utils/Android.bp b/packages/SettingsLib/Utils/Android.bp
index dc2b52d24462..c7ad24c6148c 100644
--- a/packages/SettingsLib/Utils/Android.bp
+++ b/packages/SettingsLib/Utils/Android.bp
@@ -9,6 +9,7 @@ package {
 
 android_library {
     name: "SettingsLibUtils",
+    use_resource_processor: true,
 
     srcs: ["src/**/*.java"],
     resource_dirs: ["res"],
diff --git a/packages/SettingsLib/search/Android.bp b/packages/SettingsLib/search/Android.bp
index 918d696fa481..202e7fe219de 100644
--- a/packages/SettingsLib/search/Android.bp
+++ b/packages/SettingsLib/search/Android.bp
@@ -16,6 +16,7 @@ java_library {
 
 android_library {
     name: "SettingsLib-search",
+    use_resource_processor: true,
     static_libs: [
         "SettingsLib-search-interface",
     ],
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
index b1d1ea5eda42..758f090118ad 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
@@ -126,10 +126,10 @@ public class RestrictedSwitchPreference extends SwitchPreference {
             switchSummary = isChecked()
                     ? getUpdatableEnterpriseString(
                             getContext(), ENABLED_BY_ADMIN_SWITCH_SUMMARY,
-                            com.android.settingslib.widget.R.string.enabled_by_admin)
+                            com.android.settingslib.widget.restricted.R.string.enabled_by_admin)
                     : getUpdatableEnterpriseString(
                             getContext(), DISABLED_BY_ADMIN_SWITCH_SUMMARY,
-                            com.android.settingslib.widget.R.string.disabled_by_admin);
+                            com.android.settingslib.widget.restricted.R.string.disabled_by_admin);
         } else {
             switchSummary = mRestrictedSwitchSummary;
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BroadcastDialog.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BroadcastDialog.java
index f5257b070392..8c0dc41f18af 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BroadcastDialog.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BroadcastDialog.java
@@ -47,7 +47,7 @@ public class BroadcastDialog extends AlertDialog {
         final Window window = getWindow();
         window.setContentView(layout);
         window.setWindowAnimations(
-                com.android.settingslib.widget.R.style.Theme_AlertDialog_SettingsLib);
+                com.android.settingslib.widget.theme.R.style.Theme_AlertDialog_SettingsLib);
 
         TextView title = layout.findViewById(R.id.dialog_title);
         TextView subTitle = layout.findViewById(R.id.dialog_subtitle);
diff --git a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java
index d53c3a7aafa6..2999c838a866 100644
--- a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java
@@ -153,7 +153,7 @@ public class InputMethodPreference extends PrimarySwitchPreference
         }
         final ImageView icon = holder.itemView.findViewById(android.R.id.icon);
         final int iconSize = getContext().getResources().getDimensionPixelSize(
-                com.android.settingslib.widget.R.dimen.secondary_app_icon_size);
+                com.android.settingslib.widget.theme.R.dimen.secondary_app_icon_size);
         if (icon != null && iconSize > 0) {
             ViewGroup.LayoutParams params = icon.getLayoutParams();
             params.height = iconSize;
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
index 2d6f0587fbf7..98272cc1dabd 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
@@ -167,8 +167,8 @@ public class AccessPointPreference extends Preference {
         ImageView frictionImageView = (ImageView) view.findViewById(R.id.friction_icon);
         bindFrictionImage(frictionImageView);
 
-        final View divider =
-                view.findViewById(com.android.settingslib.widget.R.id.two_target_divider);
+        final View divider = view.findViewById(
+                com.android.settingslib.widget.preference.twotarget.R.id.two_target_divider);
         divider.setVisibility(shouldShowDivider() ? View.VISIBLE : View.INVISIBLE);
     }
 
diff --git a/packages/SettingsLib/tests/integ/Android.bp b/packages/SettingsLib/tests/integ/Android.bp
index 8970debb3e2f..b03c43cbdee5 100644
--- a/packages/SettingsLib/tests/integ/Android.bp
+++ b/packages/SettingsLib/tests/integ/Android.bp
@@ -23,6 +23,7 @@ package {
 
 android_test {
     name: "SettingsLibTests",
+    use_resource_processor: true,
     defaults: [
         "SettingsLibDefaults",
         "framework-wifi-test-defaults",
diff --git a/packages/SettingsLib/tests/integ/AndroidManifest.xml b/packages/SettingsLib/tests/integ/AndroidManifest.xml
index 2a4dfdd84c63..a95da3033eae 100644
--- a/packages/SettingsLib/tests/integ/AndroidManifest.xml
+++ b/packages/SettingsLib/tests/integ/AndroidManifest.xml
@@ -15,7 +15,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.settingslib">
+    package="com.android.settingslib.tests.integ">
 
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
     <uses-permission android:name="android.permission.MANAGE_USERS" />
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/SettingsSpinnerPreferenceTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/SettingsSpinnerPreferenceTest.java
index b81d13d985e4..c8b20c1753b9 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/SettingsSpinnerPreferenceTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/SettingsSpinnerPreferenceTest.java
@@ -28,6 +28,8 @@ import androidx.preference.PreferenceViewHolder;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.settingslib.widget.spinner.R;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/UsageProgressBarPreferenceTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/UsageProgressBarPreferenceTest.java
index a9ad00d90ab8..a66d3fbee77c 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/UsageProgressBarPreferenceTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/UsageProgressBarPreferenceTest.java
@@ -35,6 +35,8 @@ import androidx.preference.PreferenceViewHolder;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.settingslib.widget.preference.usage.R;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
diff --git a/packages/SettingsLib/tests/robotests/Android.bp b/packages/SettingsLib/tests/robotests/Android.bp
index c037c400948f..dd9cb9cf7abe 100644
--- a/packages/SettingsLib/tests/robotests/Android.bp
+++ b/packages/SettingsLib/tests/robotests/Android.bp
@@ -27,6 +27,7 @@ package {
 
 android_app {
     name: "SettingsLibShell",
+    use_resource_processor: true,
     defaults: ["SettingsLibDefaults"],
     platform_apis: true,
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/HelpUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/HelpUtilsTest.java
index 4811d9507c8d..e1577e03ab5f 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/HelpUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/HelpUtilsTest.java
@@ -182,14 +182,14 @@ public class HelpUtilsTest {
         final Menu item = mock(Menu.class);
         when(item.findItem(MENU_HELP)).thenReturn(null);
         when(item.add(0, MENU_HELP, 0,
-                com.android.settingslib.widget.R.string.help_feedback_label)).thenReturn(
+                com.android.settingslib.widget.help.R.string.help_feedback_label)).thenReturn(
                 mock(MenuItem.class));
 
         HelpUtils.prepareHelpMenuItem(mActivity, item, TEST_HELP_URL, "backup_url");
         HelpUtils.prepareHelpMenuItem(mActivity, item, 0, "backup_url");
 
         verify(item, times(2)).add(0, MENU_HELP, 0,
-                com.android.settingslib.widget.R.string.help_feedback_label);
+                com.android.settingslib.widget.help.R.string.help_feedback_label);
     }
 
     @Test
@@ -197,13 +197,13 @@ public class HelpUtilsTest {
         final Menu item = mock(Menu.class);
         when(item.findItem(MENU_HELP)).thenReturn(mock(MenuItem.class));
         when(item.add(0, MENU_HELP, 0,
-                com.android.settingslib.widget.R.string.help_feedback_label)).thenReturn(
+                com.android.settingslib.widget.help.R.string.help_feedback_label)).thenReturn(
                 mock(MenuItem.class));
 
         HelpUtils.prepareHelpMenuItem(mActivity, item, TEST_HELP_URL, "backup_url");
         HelpUtils.prepareHelpMenuItem(mActivity, item, 0, "backup_url");
 
         verify(item, never()).add(0, MENU_HELP, 0,
-                com.android.settingslib.widget.R.string.help_feedback_label);
+                com.android.settingslib.widget.help.R.string.help_feedback_label);
     }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/PrimarySwitchPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/PrimarySwitchPreferenceTest.java
index 32a16716d9f9..d9cf9f285164 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/PrimarySwitchPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/PrimarySwitchPreferenceTest.java
@@ -54,7 +54,8 @@ public class PrimarySwitchPreferenceTest {
         mPreference = new PrimarySwitchPreference(mContext);
         LayoutInflater inflater = LayoutInflater.from(mContext);
         mHolder = PreferenceViewHolder.createInstanceForTests(inflater.inflate(
-                com.android.settingslib.widget.R.layout.preference_two_target, null));
+                com.android.settingslib.widget.preference.twotarget.R.layout.preference_two_target,
+                null));
         mWidgetView = mHolder.itemView.findViewById(android.R.id.widget_frame);
         inflater.inflate(R.layout.preference_widget_primary_switch, mWidgetView, true);
     }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/collapsingtoolbar/widget/CollapsingCoordinatorLayoutTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/collapsingtoolbar/widget/CollapsingCoordinatorLayoutTest.java
index ff84dc92037f..2b1e8080d389 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/collapsingtoolbar/widget/CollapsingCoordinatorLayoutTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/collapsingtoolbar/widget/CollapsingCoordinatorLayoutTest.java
@@ -24,7 +24,7 @@ import android.widget.TextView;
 
 import androidx.annotation.Nullable;
 
-import com.android.settingslib.R;
+import com.android.settingslib.collapsingtoolbar.R;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -58,7 +58,7 @@ public class CollapsingCoordinatorLayoutTest {
         View contentFrameView =
                 layout.findViewById(com.android.settingslib.widget.R.id.content_frame);
 
-        TextView textView = contentFrameView.findViewById(R.id.text_hello_world);
+        TextView textView = contentFrameView.findViewById(com.android.settingslib.robotests.R.id.text_hello_world);
 
         assertThat(textView).isNotNull();
         assertThat(textView.getText().toString()).isEqualTo(TEXT_HELLO_WORLD);
@@ -80,8 +80,8 @@ public class CollapsingCoordinatorLayoutTest {
         protected void onCreate(@Nullable Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             setTheme(android.R.style.Theme_Light_NoTitleBar);
-            setContentView(R.layout.collapsing_test_layout);
-            mCollapsingCoordinatorLayout = findViewById(R.id.id_collapsing_test);
+            setContentView(com.android.settingslib.robotests.R.layout.collapsing_test_layout);
+            mCollapsingCoordinatorLayout = findViewById(com.android.settingslib.robotests.R.id.id_collapsing_test);
         }
 
         public CollapsingCoordinatorLayout getCollapsingCoordinatorLayout() {
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ActionButtonsPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ActionButtonsPreferenceTest.java
index 9f31ceff7230..6d9261d81cd6 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ActionButtonsPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ActionButtonsPreferenceTest.java
@@ -31,6 +31,8 @@ import android.widget.Button;
 
 import androidx.preference.PreferenceViewHolder;
 
+import com.android.settingslib.widget.preference.actionbuttons.R;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -55,10 +57,10 @@ public class ActionButtonsPreferenceTest {
 
     @Test
     public void onBindViewHolder_setTitle_shouldShowButtonByDefault() {
-        mPref.setButton1Text(R.string.install_other_apps);
-        mPref.setButton2Text(R.string.install_other_apps);
-        mPref.setButton3Text(R.string.install_other_apps);
-        mPref.setButton4Text(R.string.install_other_apps);
+        mPref.setButton1Text(com.android.settingslib.R.string.install_other_apps);
+        mPref.setButton2Text(com.android.settingslib.R.string.install_other_apps);
+        mPref.setButton3Text(com.android.settingslib.R.string.install_other_apps);
+        mPref.setButton4Text(com.android.settingslib.R.string.install_other_apps);
 
         mPref.onBindViewHolder(mHolder);
 
@@ -107,10 +109,10 @@ public class ActionButtonsPreferenceTest {
 
     @Test
     public void onBindViewHolder_setVisibleIsGoneAndSetTitle_shouldNotShowButton() {
-        mPref.setButton1Text(R.string.install_other_apps).setButton1Visible(false);
-        mPref.setButton2Text(R.string.install_other_apps).setButton2Visible(false);
-        mPref.setButton3Text(R.string.install_other_apps).setButton3Visible(false);
-        mPref.setButton4Text(R.string.install_other_apps).setButton4Visible(false);
+        mPref.setButton1Text(com.android.settingslib.R.string.install_other_apps).setButton1Visible(false);
+        mPref.setButton2Text(com.android.settingslib.R.string.install_other_apps).setButton2Visible(false);
+        mPref.setButton3Text(com.android.settingslib.R.string.install_other_apps).setButton3Visible(false);
+        mPref.setButton4Text(com.android.settingslib.R.string.install_other_apps).setButton4Visible(false);
 
         mPref.onBindViewHolder(mHolder);
 
@@ -145,10 +147,10 @@ public class ActionButtonsPreferenceTest {
 
     @Test
     public void onBindViewHolder_setVisibility_shouldUpdateButtonVisibility() {
-        mPref.setButton1Text(R.string.install_other_apps).setButton1Visible(false);
-        mPref.setButton2Text(R.string.install_other_apps).setButton2Visible(false);
-        mPref.setButton3Text(R.string.install_other_apps).setButton3Visible(false);
-        mPref.setButton4Text(R.string.install_other_apps).setButton4Visible(false);
+        mPref.setButton1Text(com.android.settingslib.R.string.install_other_apps).setButton1Visible(false);
+        mPref.setButton2Text(com.android.settingslib.R.string.install_other_apps).setButton2Visible(false);
+        mPref.setButton3Text(com.android.settingslib.R.string.install_other_apps).setButton3Visible(false);
+        mPref.setButton4Text(com.android.settingslib.R.string.install_other_apps).setButton4Visible(false);
 
         mPref.onBindViewHolder(mHolder);
 
@@ -195,26 +197,26 @@ public class ActionButtonsPreferenceTest {
 
     @Test
     public void onBindViewHolder_setText_shouldShowSameText() {
-        mPref.setButton1Text(R.string.install_other_apps);
-        mPref.setButton2Text(R.string.install_other_apps);
-        mPref.setButton3Text(R.string.install_other_apps);
-        mPref.setButton4Text(R.string.install_other_apps);
+        mPref.setButton1Text(com.android.settingslib.R.string.install_other_apps);
+        mPref.setButton2Text(com.android.settingslib.R.string.install_other_apps);
+        mPref.setButton3Text(com.android.settingslib.R.string.install_other_apps);
+        mPref.setButton4Text(com.android.settingslib.R.string.install_other_apps);
 
         mPref.onBindViewHolder(mHolder);
 
         assertThat(((Button) mRootView.findViewById(R.id.button1)).getText())
-                .isEqualTo(mContext.getText(R.string.install_other_apps));
+                .isEqualTo(mContext.getText(com.android.settingslib.R.string.install_other_apps));
         assertThat(((Button) mRootView.findViewById(R.id.button2)).getText())
-                .isEqualTo(mContext.getText(R.string.install_other_apps));
+                .isEqualTo(mContext.getText(com.android.settingslib.R.string.install_other_apps));
         assertThat(((Button) mRootView.findViewById(R.id.button3)).getText())
-                .isEqualTo(mContext.getText(R.string.install_other_apps));
+                .isEqualTo(mContext.getText(com.android.settingslib.R.string.install_other_apps));
         assertThat(((Button) mRootView.findViewById(R.id.button4)).getText())
-                .isEqualTo(mContext.getText(R.string.install_other_apps));
+                .isEqualTo(mContext.getText(com.android.settingslib.R.string.install_other_apps));
     }
 
     @Test
     public void onBindViewHolder_setButtonIcon_iconMustDisplayAboveText() {
-        mPref.setButton1Text(R.string.install_other_apps);
+        mPref.setButton1Text(com.android.settingslib.R.string.install_other_apps);
         mPref.setButton1Icon(com.android.internal.R.drawable.ic_plus);
 
         mPref.onBindViewHolder(mHolder);
@@ -227,7 +229,7 @@ public class ActionButtonsPreferenceTest {
 
     @Test
     public void setButtonIcon_iconResourceIdIsZero_shouldNotDisplayIcon() {
-        mPref.setButton1Text(R.string.install_other_apps);
+        mPref.setButton1Text(com.android.settingslib.R.string.install_other_apps);
         mPref.setButton1Icon(0);
 
         mPref.onBindViewHolder(mHolder);
@@ -240,7 +242,7 @@ public class ActionButtonsPreferenceTest {
 
     @Test
     public void setButtonIcon_iconResourceIdNotExisting_shouldNotDisplayIconAndCrash() {
-        mPref.setButton1Text(R.string.install_other_apps);
+        mPref.setButton1Text(com.android.settingslib.R.string.install_other_apps);
         mPref.setButton1Icon(999999999 /* not existing id */);
         // Should not crash here
         mPref.onBindViewHolder(mHolder);
@@ -253,10 +255,10 @@ public class ActionButtonsPreferenceTest {
 
     @Test
     public void onBindViewHolder_setAllButton_shouldShowAllDivider() {
-        mPref.setButton1Text(R.string.install_other_apps);
-        mPref.setButton2Text(R.string.install_other_apps);
-        mPref.setButton3Text(R.string.install_other_apps);
-        mPref.setButton4Text(R.string.install_other_apps);
+        mPref.setButton1Text(com.android.settingslib.R.string.install_other_apps);
+        mPref.setButton2Text(com.android.settingslib.R.string.install_other_apps);
+        mPref.setButton3Text(com.android.settingslib.R.string.install_other_apps);
+        mPref.setButton4Text(com.android.settingslib.R.string.install_other_apps);
 
         mPref.onBindViewHolder(mHolder);
 
@@ -270,9 +272,9 @@ public class ActionButtonsPreferenceTest {
 
     @Test
     public void onBindViewHolder_setAllButtonWithoutButton2_shouldHideDivider1() {
-        mPref.setButton1Text(R.string.install_other_apps);
-        mPref.setButton3Text(R.string.install_other_apps);
-        mPref.setButton4Text(R.string.install_other_apps);
+        mPref.setButton1Text(com.android.settingslib.R.string.install_other_apps);
+        mPref.setButton3Text(com.android.settingslib.R.string.install_other_apps);
+        mPref.setButton4Text(com.android.settingslib.R.string.install_other_apps);
 
         mPref.onBindViewHolder(mHolder);
 
@@ -286,9 +288,9 @@ public class ActionButtonsPreferenceTest {
 
     @Test
     public void onBindViewHolder_setAllButtonWithoutButton3_shouldHideDivider2() {
-        mPref.setButton1Text(R.string.install_other_apps);
-        mPref.setButton2Text(R.string.install_other_apps);
-        mPref.setButton4Text(R.string.install_other_apps);
+        mPref.setButton1Text(com.android.settingslib.R.string.install_other_apps);
+        mPref.setButton2Text(com.android.settingslib.R.string.install_other_apps);
+        mPref.setButton4Text(com.android.settingslib.R.string.install_other_apps);
 
         mPref.onBindViewHolder(mHolder);
 
@@ -302,8 +304,8 @@ public class ActionButtonsPreferenceTest {
 
     @Test
     public void onBindViewHolder_setButton1And4_shouldShowDivider3Only() {
-        mPref.setButton1Text(R.string.install_other_apps);
-        mPref.setButton4Text(R.string.install_other_apps);
+        mPref.setButton1Text(com.android.settingslib.R.string.install_other_apps);
+        mPref.setButton4Text(com.android.settingslib.R.string.install_other_apps);
 
         mPref.onBindViewHolder(mHolder);
 
@@ -317,7 +319,7 @@ public class ActionButtonsPreferenceTest {
 
     @Test
     public void onBindViewHolder_setOneButtonOnly_noDivider() {
-        mPref.setButton4Text(R.string.install_other_apps);
+        mPref.setButton4Text(com.android.settingslib.R.string.install_other_apps);
 
         mPref.onBindViewHolder(mHolder);
 
@@ -331,8 +333,8 @@ public class ActionButtonsPreferenceTest {
 
     @Test
     public void onBindViewHolder_setButton1And2_shouldShowDivider1Only() {
-        mPref.setButton1Text(R.string.install_other_apps);
-        mPref.setButton2Text(R.string.install_other_apps);
+        mPref.setButton1Text(com.android.settingslib.R.string.install_other_apps);
+        mPref.setButton2Text(com.android.settingslib.R.string.install_other_apps);
 
         mPref.onBindViewHolder(mHolder);
 
@@ -346,8 +348,8 @@ public class ActionButtonsPreferenceTest {
 
     @Test
     public void onBindViewHolder_setButton1And3_shouldShowDivider2Only() {
-        mPref.setButton1Text(R.string.install_other_apps);
-        mPref.setButton3Text(R.string.install_other_apps);
+        mPref.setButton1Text(com.android.settingslib.R.string.install_other_apps);
+        mPref.setButton3Text(com.android.settingslib.R.string.install_other_apps);
 
         mPref.onBindViewHolder(mHolder);
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveIconTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveIconTest.java
index 10862403ae70..6195d754f8f0 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveIconTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveIconTest.java
@@ -36,7 +36,7 @@ import android.graphics.drawable.Icon;
 import android.graphics.drawable.ShapeDrawable;
 import android.os.Bundle;
 
-import com.android.settingslib.R;
+import com.android.settingslib.widget.adaptiveicon.R;
 import com.android.settingslib.drawer.ActivityTile;
 import com.android.settingslib.drawer.CategoryKey;
 import com.android.settingslib.drawer.Tile;
@@ -87,7 +87,7 @@ public class AdaptiveIconTest {
     public void setBackgroundColor_externalTileWithBackgroundColorRawValue_shouldUpdateIcon() {
         final Tile tile = spy(new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE));
         mActivityInfo.metaData.putInt(META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB, 0xff0000);
-        doReturn(Icon.createWithResource(mContext, R.drawable.ic_system_update))
+        doReturn(Icon.createWithResource(mContext, com.android.settingslib.R.drawable.ic_system_update))
                 .when(tile).getIcon(mContext);
         final AdaptiveIcon icon =
                 new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK));
@@ -99,7 +99,7 @@ public class AdaptiveIconTest {
     @Test
     public void setBackgroundColor_tileWithoutBackgroundColor_shouldSetDefaultBackgroundColor() {
         final Tile tile = spy(new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE));
-        doReturn(Icon.createWithResource(mContext, R.drawable.ic_system_update))
+        doReturn(Icon.createWithResource(mContext, com.android.settingslib.R.drawable.ic_system_update))
             .when(tile).getIcon(mContext);
         final AdaptiveIcon icon = new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK));
 
@@ -114,7 +114,7 @@ public class AdaptiveIconTest {
         final Tile tile = spy(new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE));
         mActivityInfo.metaData.putInt(META_DATA_PREFERENCE_ICON_BACKGROUND_HINT,
                 com.android.settingslib.widget.R.color.bt_outline_color);
-        doReturn(Icon.createWithResource(mContext, R.drawable.ic_system_update))
+        doReturn(Icon.createWithResource(mContext, com.android.settingslib.R.drawable.ic_system_update))
                 .when(tile).getIcon(mContext);
 
         final AdaptiveIcon icon =
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveOutlineDrawableTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveOutlineDrawableTest.java
index b2bc53dda1fa..943b9944af40 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveOutlineDrawableTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveOutlineDrawableTest.java
@@ -21,6 +21,8 @@ import static com.google.common.truth.Truth.assertThat;
 import android.content.res.Resources;
 import android.graphics.Paint;
 
+import com.android.settingslib.widget.adaptiveicon.R;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.RobolectricTestRunner;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AppEntitiesHeaderControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AppEntitiesHeaderControllerTest.java
index c9b066a5768e..172c1785c01b 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AppEntitiesHeaderControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AppEntitiesHeaderControllerTest.java
@@ -24,6 +24,8 @@ import android.view.View;
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import com.android.settingslib.widget.entityheader.R;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -69,18 +71,18 @@ public class AppEntitiesHeaderControllerTest {
 
     @Test
     public void setHeaderTitleRes_setTextRes_shouldSetToTitleView() {
-        mController.setHeaderTitleRes(R.string.expand_button_title).apply();
+        mController.setHeaderTitleRes(androidx.preference.R.string.expand_button_title).apply();
         final TextView view = mAppEntitiesHeaderView.findViewById(R.id.header_title);
 
-        assertThat(view.getText()).isEqualTo(mContext.getText(R.string.expand_button_title));
+        assertThat(view.getText()).isEqualTo(mContext.getText(androidx.preference.R.string.expand_button_title));
     }
 
     @Test
     public void setHeaderDetailsRes_setTextRes_shouldSetToDetailsView() {
-        mController.setHeaderDetailsRes(R.string.expand_button_title).apply();
+        mController.setHeaderDetailsRes(androidx.preference.R.string.expand_button_title).apply();
         final TextView view = mAppEntitiesHeaderView.findViewById(R.id.header_details);
 
-        assertThat(view.getText()).isEqualTo(mContext.getText(R.string.expand_button_title));
+        assertThat(view.getText()).isEqualTo(mContext.getText(androidx.preference.R.string.expand_button_title));
     }
 
     @Test
@@ -93,7 +95,7 @@ public class AppEntitiesHeaderControllerTest {
 
     @Test
     public void setHeaderDetails_detailsTextAndResBothSet_shouldSetTextToDetailsView() {
-        mController.setHeaderDetailsRes(R.string.expand_button_title);
+        mController.setHeaderDetailsRes(androidx.preference.R.string.expand_button_title);
         mController.setHeaderDetails(TITLE).apply();
         final TextView view = mAppEntitiesHeaderView.findViewById(R.id.header_details);
 
@@ -206,7 +208,7 @@ public class AppEntitiesHeaderControllerTest {
 
     @Test
     public void apply_noAppEntitySet_shouldOnlyShowTitleAndEmptyView() {
-        mController.setHeaderTitleRes(R.string.expand_button_title)
+        mController.setHeaderTitleRes(androidx.preference.R.string.expand_button_title)
                 .setAppEntity(0, mAppEntityInfo)
                 .setAppEntity(1, mAppEntityInfo)
                 .setAppEntity(2, mAppEntityInfo).apply();
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AppHeaderPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AppHeaderPreferenceTest.java
index e2b242c97e0e..9112f6bc69a5 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AppHeaderPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AppHeaderPreferenceTest.java
@@ -24,7 +24,7 @@ import android.widget.TextView;
 
 import androidx.preference.PreferenceViewHolder;
 
-
+import com.android.settingslib.widget.preference.app.R;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AppPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AppPreferenceTest.java
index 9e265a45a8f2..6c8fd50d1896 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AppPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AppPreferenceTest.java
@@ -23,6 +23,8 @@ import android.view.View;
 
 import androidx.preference.PreferenceViewHolder;
 
+import com.android.settingslib.widget.preference.app.R;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -56,7 +58,7 @@ public class AppPreferenceTest {
 
     @Test
     public void foobar_testName() {
-        float iconSize = mContext.getResources().getDimension(R.dimen.secondary_app_icon_size);
+        float iconSize = mContext.getResources().getDimension(com.android.settingslib.widget.theme.R.dimen.secondary_app_icon_size);
         assertThat(Float.floatToIntBits(iconSize)).isEqualTo(Float.floatToIntBits(32));
     }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BannerMessagePreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BannerMessagePreferenceTest.java
index 0d889139e8b4..721e69d2eb8d 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BannerMessagePreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BannerMessagePreferenceTest.java
@@ -39,7 +39,7 @@ import android.widget.TextView;
 
 import androidx.annotation.ColorRes;
 import androidx.preference.PreferenceViewHolder;
-import androidx.preference.R;
+import com.android.settingslib.widget.preference.banner.R;
 
 import com.android.settingslib.testutils.OverpoweredReflectionHelper;
 
@@ -65,7 +65,7 @@ public class BannerMessagePreferenceTest {
     private final View.OnClickListener mClickListener = v -> mClickListenerCalled = true;
     private final int mMinimumTargetSize =
             RuntimeEnvironment.application.getResources()
-                    .getDimensionPixelSize(R.dimen.settingslib_preferred_minimum_touch_target);
+                    .getDimensionPixelSize(com.android.settingslib.widget.theme.R.dimen.settingslib_preferred_minimum_touch_target);
 
     private static final int TEST_STRING_RES_ID =
             R.string.accessibility_banner_message_dismiss;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartPreferenceTest.java
index 567d90fa8916..ae6573e599ce 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartPreferenceTest.java
@@ -26,6 +26,8 @@ import android.widget.TextView;
 
 import androidx.preference.PreferenceViewHolder;
 
+import com.android.settingslib.widget.preference.barchart.R;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -71,9 +73,9 @@ public class BarChartPreferenceTest {
         mDetailsView = mBarChartView.findViewById(R.id.bar_chart_details);
 
         mBarChartInfo = new BarChartInfo.Builder()
-                .setTitle(R.string.debug_app)
-                .setDetails(R.string.debug_app)
-                .setEmptyText(R.string.debug_app)
+                .setTitle(com.android.settingslib.R.string.debug_app)
+                .setDetails(com.android.settingslib.R.string.debug_app)
+                .setEmptyText(com.android.settingslib.R.string.debug_app)
                 .setDetailsOnClickListener(v -> {
                 })
                 .build();
@@ -82,21 +84,21 @@ public class BarChartPreferenceTest {
     @Test
     public void initializeBarChart_titleSet_shouldSetTitleInChartView() {
         final BarChartInfo barChartInfo = new BarChartInfo.Builder()
-                .setTitle(R.string.debug_app)
+                .setTitle(com.android.settingslib.R.string.debug_app)
                 .build();
 
         mPreference.initializeBarChart(barChartInfo);
         mPreference.onBindViewHolder(mHolder);
 
         assertThat(mTitleView.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mTitleView.getText()).isEqualTo(mContext.getText(R.string.debug_app));
+        assertThat(mTitleView.getText()).isEqualTo(mContext.getText(com.android.settingslib.R.string.debug_app));
     }
 
     @Test
     public void initializeBarChart_noBarViewSet_shouldShowTitleAndEmptyView() {
         final BarChartInfo barChartInfo = new BarChartInfo.Builder()
-                .setTitle(R.string.debug_app)
-                .setEmptyText(R.string.debug_app)
+                .setTitle(com.android.settingslib.R.string.debug_app)
+                .setEmptyText(com.android.settingslib.R.string.debug_app)
                 .build();
 
         mPreference.initializeBarChart(barChartInfo);
@@ -113,11 +115,11 @@ public class BarChartPreferenceTest {
     @Test
     public void initializeBarChart_detailsSet_shouldShowBarChartDetailsView() {
         final BarChartInfo barChartInfo = new BarChartInfo.Builder()
-                .setTitle(R.string.debug_app)
-                .setDetails(R.string.debug_app)
+                .setTitle(com.android.settingslib.R.string.debug_app)
+                .setDetails(com.android.settingslib.R.string.debug_app)
                 .addBarViewInfo(
                         new BarViewInfo(mIcon, 10, null /* title */,
-                                mContext.getText(R.string.debug_app) /* summary */,
+                                mContext.getText(com.android.settingslib.R.string.debug_app) /* summary */,
                                 null /* contentDescription */))
                 .build();
 
@@ -125,17 +127,17 @@ public class BarChartPreferenceTest {
         mPreference.onBindViewHolder(mHolder);
 
         assertThat(mDetailsView.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mDetailsView.getText()).isEqualTo(mContext.getText(R.string.debug_app));
+        assertThat(mDetailsView.getText()).isEqualTo(mContext.getText(com.android.settingslib.R.string.debug_app));
     }
 
     @Test
     public void initializeBarChart_detailsNotSet_shouldHideBarChartDetailsView() {
         // We don't call BarChartInfo.Builder#setDetails yet.
         final BarChartInfo barChartInfo = new BarChartInfo.Builder()
-                .setTitle(R.string.debug_app)
+                .setTitle(com.android.settingslib.R.string.debug_app)
                 .addBarViewInfo(
                         new BarViewInfo(mIcon, 10, null /* title */,
-                                mContext.getText(R.string.debug_app) /* summary */,
+                                mContext.getText(com.android.settingslib.R.string.debug_app) /* summary */,
                                 null /* contentDescription */))
                 .build();
 
@@ -148,13 +150,13 @@ public class BarChartPreferenceTest {
     @Test
     public void initializeBarChart_clickListenerSet_shouldSetClickListenerOnDetailsView() {
         final BarChartInfo barChartInfo = new BarChartInfo.Builder()
-                .setTitle(R.string.debug_app)
-                .setDetails(R.string.debug_app)
+                .setTitle(com.android.settingslib.R.string.debug_app)
+                .setDetails(com.android.settingslib.R.string.debug_app)
                 .setDetailsOnClickListener(v -> {
                 })
                 .addBarViewInfo(
                         new BarViewInfo(mIcon, 10, null /* title */,
-                                mContext.getText(R.string.debug_app) /* summary */,
+                                mContext.getText(com.android.settingslib.R.string.debug_app) /* summary */,
                                 null /* contentDescription */))
                 .build();
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ButtonPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ButtonPreferenceTest.java
index d78f8e7e4e9b..f3fe5172b46a 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ButtonPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ButtonPreferenceTest.java
@@ -68,14 +68,14 @@ public class ButtonPreferenceTest {
 
     @Test
     public void onBindViewHolder_whenIconSet_shouldSetIcon() {
-        mPreference.setIcon(R.drawable.settingslib_ic_cross);
+        mPreference.setIcon(com.android.settingslib.widget.preference.banner.R.drawable.settingslib_ic_cross);
 
         mPreference.onBindViewHolder(mHolder);
 
         final Button button = mPreference.getButton();
         final Drawable icon = button.getCompoundDrawablesRelative()[0];
         final ShadowDrawable shadowDrawable = shadowOf(icon);
-        assertThat(shadowDrawable.getCreatedFromResId()).isEqualTo(R.drawable.settingslib_ic_cross);
+        assertThat(shadowDrawable.getCreatedFromResId()).isEqualTo(com.android.settingslib.widget.preference.banner.R.drawable.settingslib_ic_cross);
     }
 
     @Test
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java
index a26f200ec603..ccbe4f03e80c 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java
@@ -28,7 +28,7 @@ import android.widget.TextView;
 
 import androidx.preference.PreferenceViewHolder;
 
-import com.android.settingslib.R;
+import com.android.settingslib.widget.preference.footer.R;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -96,7 +96,7 @@ public class FooterPreferenceTest {
     public void onBindViewHolder_whenTitleIsNull_shouldNotRaiseNpe() {
         PreferenceViewHolder viewHolder = spy(PreferenceViewHolder.createInstanceForTests(
                 LayoutInflater.from(mContext)
-                        .inflate(com.android.settingslib.widget.R.layout.preference_footer, null)));
+                        .inflate(R.layout.preference_footer, null)));
         when(viewHolder.findViewById(androidx.core.R.id.title)).thenReturn(null);
 
         Throwable actualThrowable = null;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java
index 21e119a48f7b..6590bbdcdae6 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java
@@ -39,6 +39,8 @@ import android.widget.ImageView;
 import androidx.preference.PreferenceViewHolder;
 import androidx.test.core.app.ApplicationProvider;
 
+import com.android.settingslib.widget.preference.illustration.R;
+
 import com.airbnb.lottie.LottieAnimationView;
 
 import org.junit.Before;
@@ -49,6 +51,7 @@ import org.mockito.MockitoAnnotations;
 import org.robolectric.Robolectric;
 import org.robolectric.RobolectricTestRunner;
 
+
 @RunWith(RobolectricTestRunner.class)
 public class IllustrationPreferenceTest {
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/LayoutPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/LayoutPreferenceTest.java
index 99261a38f73b..58817fbd272a 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/LayoutPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/LayoutPreferenceTest.java
@@ -27,6 +27,8 @@ import android.view.LayoutInflater;
 import androidx.preference.Preference.OnPreferenceClickListener;
 import androidx.preference.PreferenceViewHolder;
 
+import com.android.settingslib.widget.preference.layout.R;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchBarTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchBarTest.java
index 24037caf4e6c..942e91525f02 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchBarTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchBarTest.java
@@ -26,6 +26,8 @@ import android.view.View;
 import android.widget.Switch;
 import android.widget.TextView;
 
+import com.android.settingslib.widget.mainswitch.R;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchPreferenceTest.java
index e58c04a3b435..c2e81bd7d54c 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchPreferenceTest.java
@@ -24,6 +24,8 @@ import android.widget.TextView;
 
 import androidx.preference.PreferenceViewHolder;
 
+import com.android.settingslib.widget.mainswitch.R;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/RadioButtonPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/RadioButtonPreferenceTest.java
index a5028ff30d73..0f708cdb9992 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/RadioButtonPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/RadioButtonPreferenceTest.java
@@ -28,6 +28,8 @@ import android.view.View;
 
 import androidx.preference.PreferenceViewHolder;
 
+import com.android.settingslib.widget.preference.radio.R;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/SelectorWithWidgetPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/SelectorWithWidgetPreferenceTest.java
index 34efe82f2527..60885f1079d3 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/SelectorWithWidgetPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/SelectorWithWidgetPreferenceTest.java
@@ -28,6 +28,8 @@ import android.view.View;
 
 import androidx.preference.PreferenceViewHolder;
 
+import com.android.settingslib.widget.preference.selector.R;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/TwoTargetPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/TwoTargetPreferenceTest.java
index 23b4c2aec80f..3befddab2db5 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/TwoTargetPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/TwoTargetPreferenceTest.java
@@ -32,6 +32,8 @@ import android.widget.LinearLayout;
 
 import androidx.preference.PreferenceViewHolder;
 
+import com.android.settingslib.widget.preference.twotarget.R;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
diff --git a/packages/SettingsLib/tests/unit/Android.bp b/packages/SettingsLib/tests/unit/Android.bp
index a4558f1bd40b..19ab1c69e98c 100644
--- a/packages/SettingsLib/tests/unit/Android.bp
+++ b/packages/SettingsLib/tests/unit/Android.bp
@@ -20,6 +20,7 @@ package {
 
 android_test {
     name: "SettingsLibUnitTests",
+    use_resource_processor: true,
     test_suites: ["device-tests"],
 
     srcs: [
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 608010156fcf..5e7e044947fd 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -116,6 +116,7 @@ filegroup {
 //Create a library to expose SystemUI's resources to other modules.
 android_library {
     name: "SystemUI-res",
+    use_resource_processor: true,
     resource_dirs: [
         "res-product",
         "res-keyguard",
@@ -149,13 +150,9 @@ android_library {
             exclude_srcs: [":ReleaseJavaFiles"],
         },
     },
-    resource_dirs: [
-        "res-product",
-        "res-keyguard",
-        "res",
-    ],
     use_resource_processor: true,
     static_libs: [
+        "SystemUI-res",
         "WifiTrackerLib",
         "WindowManager-Shell",
         "SystemUIAnimationLib",
@@ -380,14 +377,13 @@ java_library {
 
 android_library {
     name: "SystemUI-tests-base",
+    use_resource_processor: true,
     manifest: "tests/AndroidManifest-base.xml",
     resource_dirs: [
         "tests/res",
-        "res-product",
-        "res-keyguard",
-        "res",
     ],
     static_libs: [
+        "SystemUI-res",
         "WifiTrackerLib",
         "SystemUIAnimationLib",
         "SystemUIPluginLib",
@@ -442,6 +438,7 @@ android_library {
 
 android_library {
     name: "SystemUI-tests",
+    use_resource_processor: true,
     defaults: [
         "SystemUI_compose_defaults",
     ],
@@ -485,6 +482,7 @@ android_library {
 
 android_app {
     name: "SystemUIRobo-stub",
+    use_resource_processor: true,
     defaults: [
         "platform_app_defaults",
         "SystemUI_optimized_defaults",
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/Android.bp b/packages/SystemUI/accessibility/accessibilitymenu/Android.bp
index ff723e34d6bc..8b12f3c738cc 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/Android.bp
+++ b/packages/SystemUI/accessibility/accessibilitymenu/Android.bp
@@ -29,6 +29,7 @@ filegroup {
 
 android_app {
     name: "AccessibilityMenu",
+    use_resource_processor: true,
 
     static_libs: [
         "androidx.coordinatorlayout_coordinatorlayout",
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp b/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp
index 1757dda84eef..538ecb3d438d 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp
+++ b/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp
@@ -20,6 +20,7 @@ package {
 
 android_test {
     name: "AccessibilityMenuServiceTests",
+    use_resource_processor: true,
     certificate: "platform",
     libs: [
         "android.test.runner",
diff --git a/packages/SystemUI/animation/Android.bp b/packages/SystemUI/animation/Android.bp
index 6f53b42371c6..8438051e3430 100644
--- a/packages/SystemUI/animation/Android.bp
+++ b/packages/SystemUI/animation/Android.bp
@@ -24,6 +24,7 @@ package {
 android_library {
 
     name: "SystemUIAnimationLib",
+    use_resource_processor: true,
 
     srcs: [
         "src/**/*.java",
@@ -52,6 +53,7 @@ android_library {
 
 android_library {
     name: "SystemUIShaderLib",
+    use_resource_processor: true,
 
     srcs: [
         "src/com/android/systemui/surfaceeffects/**/*.java",
diff --git a/packages/SystemUI/common/Android.bp b/packages/SystemUI/common/Android.bp
index e36ada89b207..482776a37327 100644
--- a/packages/SystemUI/common/Android.bp
+++ b/packages/SystemUI/common/Android.bp
@@ -24,6 +24,7 @@ package {
 android_library {
 
     name: "SystemUICommon",
+    use_resource_processor: true,
 
     srcs: [
         "src/**/*.java",
diff --git a/packages/SystemUI/compose/core/Android.bp b/packages/SystemUI/compose/core/Android.bp
index ab3efb886182..510fa1e1fa80 100644
--- a/packages/SystemUI/compose/core/Android.bp
+++ b/packages/SystemUI/compose/core/Android.bp
@@ -38,4 +38,5 @@ android_library {
     ],
 
     kotlincflags: ["-Xjvm-default=all"],
+    use_resource_processor: true,
 }
diff --git a/packages/SystemUI/compose/core/tests/Android.bp b/packages/SystemUI/compose/core/tests/Android.bp
index 5a8a374b4b7f..52c63854f62f 100644
--- a/packages/SystemUI/compose/core/tests/Android.bp
+++ b/packages/SystemUI/compose/core/tests/Android.bp
@@ -47,4 +47,5 @@ android_test {
     ],
 
     kotlincflags: ["-Xjvm-default=all"],
+    use_resource_processor: true,
 }
diff --git a/packages/SystemUI/compose/features/Android.bp b/packages/SystemUI/compose/features/Android.bp
index c6438c9ef955..e4426fe97859 100644
--- a/packages/SystemUI/compose/features/Android.bp
+++ b/packages/SystemUI/compose/features/Android.bp
@@ -23,6 +23,7 @@ package {
 
 android_library {
     name: "SystemUIComposeFeatures",
+    use_resource_processor: true,
     manifest: "AndroidManifest.xml",
 
     srcs: [
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
index 5505eaf8fd7e..46a9d42d0606 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
@@ -48,7 +48,7 @@ import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.unit.dp
 import com.android.compose.animation.scene.ElementKey
 import com.android.compose.animation.scene.SceneScope
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.bouncer.ui.viewmodel.AuthMethodBouncerViewModel
 import com.android.systemui.bouncer.ui.viewmodel.BouncerViewModel
 import com.android.systemui.bouncer.ui.viewmodel.PasswordBouncerViewModel
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinBouncer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinBouncer.kt
index e5c69777503c..6491b70db99b 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinBouncer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinBouncer.kt
@@ -55,7 +55,7 @@ import androidx.compose.ui.unit.dp
 import com.android.compose.animation.Easings
 import com.android.compose.grid.VerticalGrid
 import com.android.compose.modifiers.thenIf
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.bouncer.ui.viewmodel.ActionButtonAppearance
 import com.android.systemui.bouncer.ui.viewmodel.PinBouncerViewModel
 import com.android.systemui.common.shared.model.ContentDescription
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinInputDisplay.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinInputDisplay.kt
index 77065cfdeb76..055ece328fc3 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinInputDisplay.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinInputDisplay.kt
@@ -51,7 +51,7 @@ import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
 import com.android.compose.animation.Easings
 import com.android.keyguard.PinShapeAdapter
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.bouncer.ui.viewmodel.EntryToken.Digit
 import com.android.systemui.bouncer.ui.viewmodel.PinBouncerViewModel
 import com.android.systemui.bouncer.ui.viewmodel.PinInputViewModel
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
index 77daebb9b8a0..c3a3752db374 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
@@ -36,7 +36,7 @@ import androidx.compose.ui.input.pointer.pointerInput
 import androidx.compose.ui.viewinterop.AndroidView
 import androidx.core.view.isVisible
 import com.android.compose.animation.scene.SceneScope
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.keyguard.qualifiers.KeyguardRootView
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt b/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt
index 68f010e1c50d..e12b7eae96e7 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt
@@ -47,7 +47,7 @@ import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.text.style.TextAlign
 import androidx.compose.ui.unit.dp
 import com.android.compose.theme.LocalAndroidColorScheme
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.compose.modifiers.sysuiResTag
 import com.android.systemui.people.ui.viewmodel.PeopleTileViewModel
 import com.android.systemui.people.ui.viewmodel.PeopleViewModel
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreenEmpty.kt b/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreenEmpty.kt
index 1e6f4a2f5b23..26cc9b952e27 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreenEmpty.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreenEmpty.kt
@@ -42,7 +42,7 @@ import androidx.compose.ui.text.style.TextAlign
 import androidx.compose.ui.text.style.TextOverflow
 import androidx.compose.ui.unit.dp
 import com.android.compose.theme.LocalAndroidColorScheme
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 @Composable
 internal fun PeopleScreenEmpty(
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt
index 482220013e32..689a0a2815c5 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt
@@ -69,7 +69,7 @@ import com.android.compose.animation.Expandable
 import com.android.compose.modifiers.background
 import com.android.compose.theme.LocalAndroidColorScheme
 import com.android.compose.theme.colorAttr
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.common.ui.compose.Icon
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt
index 272e507d5d4a..8e3400872a9a 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt
@@ -47,7 +47,7 @@ import com.android.compose.animation.scene.SceneScope
 import com.android.compose.animation.scene.ValueKey
 import com.android.compose.animation.scene.animateSharedFloatAsState
 import com.android.settingslib.Utils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.battery.BatteryMeterView
 import com.android.systemui.battery.BatteryMeterViewController
 import com.android.systemui.shade.ui.viewmodel.ShadeHeaderViewModel
diff --git a/packages/SystemUI/compose/features/tests/Android.bp b/packages/SystemUI/compose/features/tests/Android.bp
index c7c9140b53ed..c85cd7bae41b 100644
--- a/packages/SystemUI/compose/features/tests/Android.bp
+++ b/packages/SystemUI/compose/features/tests/Android.bp
@@ -24,6 +24,7 @@ package {
 // TODO(b/230606318): Make those host tests instead of device tests.
 android_test {
     name: "SystemUIComposeFeaturesTests",
+    use_resource_processor: true,
     manifest: "AndroidManifest.xml",
     test_suites: ["device-tests"],
     sdk_version: "current",
diff --git a/packages/SystemUI/customization/Android.bp b/packages/SystemUI/customization/Android.bp
index fc37b355494f..927fd8ea6279 100644
--- a/packages/SystemUI/customization/Android.bp
+++ b/packages/SystemUI/customization/Android.bp
@@ -23,6 +23,7 @@ package {
 
 android_library {
     name: "SystemUICustomizationLib",
+    use_resource_processor: true,
     srcs: [
         "src/**/*.java",
         "src/**/*.kt",
diff --git a/packages/SystemUI/log/Android.bp b/packages/SystemUI/log/Android.bp
index 627ac4b7c381..2be22a65676b 100644
--- a/packages/SystemUI/log/Android.bp
+++ b/packages/SystemUI/log/Android.bp
@@ -23,6 +23,7 @@ package {
 
 android_library {
     name: "SystemUILogLib",
+    use_resource_processor: true,
     srcs: [
         "src/**/*.java",
         "src/**/*.kt",
diff --git a/packages/SystemUI/plugin/Android.bp b/packages/SystemUI/plugin/Android.bp
index bb47a2f4726e..c42895282440 100644
--- a/packages/SystemUI/plugin/Android.bp
+++ b/packages/SystemUI/plugin/Android.bp
@@ -50,6 +50,7 @@ android_app {
 
     // Dummy to generate .toc files.
     name: "PluginDummyLib",
+    use_resource_processor: true,
     platform_apis: true,
     srcs: ["src/**/*.java"],
 
diff --git a/packages/SystemUI/plugin/ExamplePlugin/Android.bp b/packages/SystemUI/plugin/ExamplePlugin/Android.bp
index 3f0fdedb57da..66951b5d9640 100644
--- a/packages/SystemUI/plugin/ExamplePlugin/Android.bp
+++ b/packages/SystemUI/plugin/ExamplePlugin/Android.bp
@@ -10,6 +10,7 @@ package {
 android_app {
 
     name: "ExamplePlugin",
+    use_resource_processor: true,
 
     libs: ["SystemUIPluginLib"],
 
diff --git a/packages/SystemUI/shared/Android.bp b/packages/SystemUI/shared/Android.bp
index 0415341c16b6..9c368eb0a978 100644
--- a/packages/SystemUI/shared/Android.bp
+++ b/packages/SystemUI/shared/Android.bp
@@ -38,6 +38,7 @@ java_library {
 
 android_library {
     name: "SystemUISharedLib",
+    use_resource_processor: true,
     srcs: [
         "src/**/*.java",
         "src/**/*.kt",
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierText.java b/packages/SystemUI/src/com/android/keyguard/CarrierText.java
index 87a9b0f17a1c..ae282c7e14bd 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierText.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierText.java
@@ -24,7 +24,7 @@ import android.util.AttributeSet;
 import android.view.View;
 import android.widget.TextView;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.util.Locale;
 
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java
index b52ee01bfa61..873c3d9105db 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java
@@ -39,7 +39,7 @@ import androidx.annotation.VisibleForTesting;
 
 import com.android.keyguard.logging.CarrierTextManagerLogger;
 import com.android.settingslib.WirelessUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
diff --git a/packages/SystemUI/src/com/android/keyguard/ConnectedDisplayKeyguardPresentation.kt b/packages/SystemUI/src/com/android/keyguard/ConnectedDisplayKeyguardPresentation.kt
index 006974c9fa92..d677a15862de 100644
--- a/packages/SystemUI/src/com/android/keyguard/ConnectedDisplayKeyguardPresentation.kt
+++ b/packages/SystemUI/src/com/android/keyguard/ConnectedDisplayKeyguardPresentation.kt
@@ -25,7 +25,7 @@ import android.view.LayoutInflater
 import android.view.View
 import android.view.WindowManager
 import com.android.keyguard.dagger.KeyguardStatusViewComponent
-import com.android.systemui.R
+import com.android.systemui.res.R
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyCarrierArea.java b/packages/SystemUI/src/com/android/keyguard/EmergencyCarrierArea.java
index 225bebe57128..b2ffccc5616d 100644
--- a/packages/SystemUI/src/com/android/keyguard/EmergencyCarrierArea.java
+++ b/packages/SystemUI/src/com/android/keyguard/EmergencyCarrierArea.java
@@ -21,7 +21,7 @@ import android.util.AttributeSet;
 import android.view.MotionEvent;
 import android.view.View;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 public class EmergencyCarrierArea extends AlphaOptimizedLinearLayout {
 
diff --git a/packages/SystemUI/src/com/android/keyguard/FaceWakeUpTriggersConfig.kt b/packages/SystemUI/src/com/android/keyguard/FaceWakeUpTriggersConfig.kt
index 5c57d4eaf7ca..6a170a506fc4 100644
--- a/packages/SystemUI/src/com/android/keyguard/FaceWakeUpTriggersConfig.kt
+++ b/packages/SystemUI/src/com/android/keyguard/FaceWakeUpTriggersConfig.kt
@@ -20,7 +20,7 @@ import android.content.res.Resources
 import android.os.Build
 import android.os.PowerManager
 import com.android.systemui.Dumpable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.dump.DumpManager
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
index c6d147108611..dfeb1f318081 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
@@ -25,7 +25,7 @@ import android.view.View;
 import androidx.annotation.CallSuper;
 
 import com.android.internal.widget.LockscreenCredential;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * Base class for PIN and password unlock screens.
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java
index e3f9de11bf98..167bd59d4e8d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java
@@ -34,7 +34,7 @@ import com.android.internal.widget.LockscreenCredential;
 import com.android.keyguard.EmergencyButtonController.EmergencyButtonCallback;
 import com.android.keyguard.KeyguardAbsKeyInputView.KeyDownListener;
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.classifier.FalsingClassifier;
 import com.android.systemui.classifier.FalsingCollector;
 import com.android.systemui.flags.FeatureFlags;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java
index a78c293a65ac..f7db48aefdaf 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java
@@ -23,7 +23,7 @@ import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.TextView;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * Replaces fancy colons with regular colons. Only works on TextViews.
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index 610df11ce12a..ba8e42752586 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -22,7 +22,7 @@ import androidx.core.content.res.ResourcesCompat;
 
 import com.android.app.animation.Interpolators;
 import com.android.keyguard.dagger.KeyguardStatusViewScope;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.log.LogBuffer;
 import com.android.systemui.log.core.LogLevel;
 import com.android.systemui.plugins.ClockController;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index 11f95895338a..29414ea7f4c0 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -37,7 +37,7 @@ import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
 
 import com.android.systemui.Dumpable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.flags.FeatureFlags;
@@ -527,7 +527,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
         if (!mFeatureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) {
             NotificationIconContainer nic = (NotificationIconContainer)
                     mView.findViewById(
-                            com.android.systemui.R.id.left_aligned_notification_icon_container);
+                            com.android.systemui.res.R.id.left_aligned_notification_icon_container);
             mNotificationIconAreaController.setupAodIcons(nic);
         }
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
index 1c5a5758c2a4..9c015fea5cf7 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
@@ -39,7 +39,7 @@ import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.keyguard.dagger.KeyguardStatusViewComponent;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dagger.qualifiers.UiBackground;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java b/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java
index ccbb0c5057cc..fc4e122d235b 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java
@@ -32,7 +32,7 @@ import android.view.View;
 import android.view.WindowManager;
 import android.widget.Button;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /***
  * This button is used by the device with embedded SIM card to disable current carrier to unlock
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardInputView.java
index 98f082f78a38..38c84954a76d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardInputView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardInputView.java
@@ -28,7 +28,7 @@ import androidx.annotation.CallSuper;
 import androidx.annotation.Nullable;
 
 import com.android.internal.jank.InteractionJankMonitor;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * A Base class for all Keyguard password/pattern/pin related inputs.
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
index abd1563ecc43..29ce18c60833 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
@@ -29,7 +29,7 @@ import android.view.inputmethod.InputMethodManager;
 import com.android.internal.util.LatencyTracker;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor;
 import com.android.systemui.bouncer.ui.BouncerMessageView;
 import com.android.systemui.bouncer.ui.binder.BouncerMessageViewBinder;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java
index fc66527998b9..7e44866f9473 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java
@@ -27,7 +27,7 @@ import android.widget.TextView;
 import androidx.annotation.Nullable;
 
 import com.android.internal.policy.SystemBarUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /***
  * Manages a number of views inside of the given layout. See below for a list of widgets.
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
index 72b4ae568397..1741e306c29f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
@@ -40,7 +40,7 @@ import androidx.constraintlayout.widget.ConstraintSet;
 
 import com.android.app.animation.Interpolators;
 import com.android.settingslib.animation.DisappearAnimationUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.policy.DevicePostureController.DevicePostureInt;
 
 /**
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
index 8d5fc0467e3b..51c0676876b9 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
@@ -56,7 +56,7 @@ import com.android.app.animation.Interpolators;
 import com.android.internal.widget.LockscreenCredential;
 import com.android.internal.widget.TextViewInputDisabler;
 import com.android.systemui.DejankUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.policy.DevicePostureController;
 
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
index ab8cd531c307..959cf6fb8565 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
@@ -39,7 +39,7 @@ import android.widget.TextView.OnEditorActionListener;
 import com.android.internal.util.LatencyTracker;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.classifier.FalsingCollector;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.flags.FeatureFlags;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
index 56706b5a7135..802e222b3897 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
@@ -42,7 +42,7 @@ import com.android.internal.widget.LockPatternView;
 import com.android.settingslib.animation.AppearAnimationCreator;
 import com.android.settingslib.animation.AppearAnimationUtils;
 import com.android.settingslib.animation.DisappearAnimationUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.policy.DevicePostureController.DevicePostureInt;
 
 public class KeyguardPatternView extends KeyguardInputView
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
index 98312b11e9d6..714ba81fc664 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
@@ -36,7 +36,7 @@ import com.android.internal.widget.LockPatternView.Cell;
 import com.android.internal.widget.LockscreenCredential;
 import com.android.keyguard.EmergencyButtonController.EmergencyButtonCallback;
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.classifier.FalsingClassifier;
 import com.android.systemui.classifier.FalsingCollector;
 import com.android.systemui.flags.FeatureFlags;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
index 38e5dc57d316..9d6d0332b96b 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
@@ -39,7 +39,7 @@ import androidx.annotation.CallSuper;
 
 import com.android.app.animation.Interpolators;
 import com.android.internal.widget.LockscreenCredential;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
index 31cbdde3452d..aacf8662b2b8 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
@@ -25,7 +25,7 @@ import android.view.View.OnTouchListener;
 import com.android.internal.util.LatencyTracker;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.classifier.FalsingCollector;
 import com.android.systemui.flags.FeatureFlags;
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
index 0af803fc84fe..9a788688c9d1 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
@@ -23,7 +23,7 @@ import android.view.View;
 import com.android.internal.util.LatencyTracker;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.classifier.FalsingCollector;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 3f3efe9c5ab1..f7a4d47be800 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -97,7 +97,7 @@ import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
 import com.android.settingslib.Utils;
 import com.android.settingslib.drawable.CircleFramedDrawable;
 import com.android.systemui.Gefingerpoken;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.classifier.FalsingA11yDelegate;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.shade.TouchLogger;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index e9dd08c67b99..625c1de0134d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -68,7 +68,7 @@ import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
 import com.android.keyguard.dagger.KeyguardBouncerScope;
 import com.android.settingslib.utils.ThreadUtils;
 import com.android.systemui.Gefingerpoken;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor;
 import com.android.systemui.biometrics.FaceAuthAccessibilityDelegate;
 import com.android.systemui.biometrics.SideFpsController;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java
index 74f90063096e..44db01e3c99e 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java
@@ -30,7 +30,7 @@ import android.view.ViewHierarchyEncoder;
 import android.widget.FrameLayout;
 import android.widget.ViewFlipper;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * Subclass of the current view flipper that allows us to overload dispatchTouchEvent() so
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java
index f18504c28609..9c4d224115b2 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java
@@ -30,7 +30,7 @@ import com.android.internal.annotations.VisibleForTesting;
 import com.android.keyguard.KeyguardInputViewController.Factory;
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
 import com.android.keyguard.dagger.KeyguardBouncerScope;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.util.ViewController;
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewTransition.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewTransition.kt
index e1c060f0e8cb..db191c6cb8f3 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewTransition.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewTransition.kt
@@ -28,7 +28,7 @@ import android.view.ViewGroup
 import android.view.animation.AnimationUtils
 import com.android.app.animation.Interpolators
 import com.android.internal.R.interpolator.fast_out_extra_slow_in
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 /** Animates constraint layout changes for the security view. */
 class KeyguardSecurityViewTransition : Transition() {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt
index 7c8d91fdaba8..392abf2aa82c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt
@@ -21,7 +21,7 @@ import android.util.AttributeSet
 import android.widget.ImageView
 import androidx.core.graphics.drawable.DrawableCompat
 import com.android.settingslib.Utils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.ColorId.EMERGENCY_BUTTON
 
 abstract class KeyguardSimInputView(context: Context, attrs: AttributeSet) :
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
index 9d170150a709..bacd0c2d1e34 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
@@ -20,7 +20,7 @@ import android.content.Context;
 import android.content.res.Configuration;
 import android.util.AttributeSet;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * Displays a PIN pad for unlocking.
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
index 1fc88ab16e83..8717a532b43d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
@@ -39,7 +39,7 @@ import android.widget.ImageView;
 import com.android.internal.util.LatencyTracker;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.classifier.FalsingCollector;
 import com.android.systemui.flags.FeatureFlags;
 
@@ -144,7 +144,7 @@ public class KeyguardSimPinViewController
             mView.resetPasswordText(true /* animate */, true /* announce */);
             getKeyguardSecurityCallback().userActivity();
             mMessageAreaController.setMessage(
-                    com.android.systemui.R.string.kg_invalid_sim_pin_hint);
+                    com.android.systemui.res.R.string.kg_invalid_sim_pin_hint);
             return;
         }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
index 5f45fe31a779..151ca8ade506 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
@@ -22,7 +22,7 @@ import android.content.Context;
 import android.util.AttributeSet;
 import android.util.Log;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 
 /**
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
index 49d786fdddd8..248b7afd7535 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
@@ -36,7 +36,7 @@ import android.widget.ImageView;
 import com.android.internal.util.LatencyTracker;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.classifier.FalsingCollector;
 import com.android.systemui.flags.FeatureFlags;
 
@@ -139,25 +139,25 @@ public class KeyguardSimPukViewController
             if (mState == ENTER_PUK) {
                 if (checkPuk()) {
                     mState = ENTER_PIN;
-                    msg = com.android.systemui.R.string.kg_puk_enter_pin_hint;
+                    msg = com.android.systemui.res.R.string.kg_puk_enter_pin_hint;
                 } else {
-                    msg = com.android.systemui.R.string.kg_invalid_sim_puk_hint;
+                    msg = com.android.systemui.res.R.string.kg_invalid_sim_puk_hint;
                 }
             } else if (mState == ENTER_PIN) {
                 if (checkPin()) {
                     mState = CONFIRM_PIN;
-                    msg = com.android.systemui.R.string.kg_enter_confirm_pin_hint;
+                    msg = com.android.systemui.res.R.string.kg_enter_confirm_pin_hint;
                 } else {
-                    msg = com.android.systemui.R.string.kg_invalid_sim_pin_hint;
+                    msg = com.android.systemui.res.R.string.kg_invalid_sim_pin_hint;
                 }
             } else if (mState == CONFIRM_PIN) {
                 if (confirmPin()) {
                     mState = DONE;
-                    msg = com.android.systemui.R.string.keyguard_sim_unlock_progress_dialog_message;
+                    msg = com.android.systemui.res.R.string.keyguard_sim_unlock_progress_dialog_message;
                     updateSim();
                 } else {
                     mState = ENTER_PIN; // try again?
-                    msg = com.android.systemui.R.string.kg_invalid_confirm_pin_hint;
+                    msg = com.android.systemui.res.R.string.kg_invalid_confirm_pin_hint;
                 }
             }
             mView.resetPasswordText(true /* animate */, true /* announce */);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
index b4f124aa598a..7b5325d4eaa6 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
@@ -48,7 +48,7 @@ import com.android.app.animation.Interpolators;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.graphics.ColorUtils;
 import com.android.settingslib.Utils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.util.wakelock.KeepAwakeAnimationListener;
 
 import java.io.PrintWriter;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusAreaView.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusAreaView.kt
index e7da2b977379..11b1a7d00056 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusAreaView.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusAreaView.kt
@@ -4,7 +4,7 @@ import android.content.Context
 import android.util.AttributeSet
 import android.util.FloatProperty
 import android.widget.LinearLayout
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.notification.AnimatableProperty
 
 class KeyguardStatusAreaView(
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index 5774e42d2425..d8486029a903 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -29,7 +29,7 @@ import android.view.ViewGroup;
 import android.view.ViewPropertyAnimator;
 import android.widget.GridLayout;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.shade.TouchLogger;
 import com.android.systemui.statusbar.CrossFadeHelper;
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
index c314586e4a21..8d0d299e56c2 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
@@ -49,7 +49,7 @@ import com.android.internal.jank.InteractionJankMonitor;
 import com.android.keyguard.KeyguardClockSwitch.ClockSize;
 import com.android.keyguard.logging.KeyguardLogger;
 import com.android.systemui.Dumpable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUnfoldTransition.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardUnfoldTransition.kt
index ca64ae059093..7170be6124d2 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUnfoldTransition.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUnfoldTransition.kt
@@ -18,7 +18,7 @@ package com.android.keyguard
 
 import android.content.Context
 import android.view.ViewGroup
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.statusbar.StatusBarState.KEYGUARD
 import com.android.systemui.shared.animation.UnfoldConstantTranslateAnimator
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index abab5e682478..51308b86a532 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -153,7 +153,7 @@ import com.android.settingslib.Utils;
 import com.android.settingslib.WirelessUtils;
 import com.android.settingslib.fuelgauge.BatteryStatus;
 import com.android.systemui.Dumpable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider;
 import com.android.systemui.broadcast.BroadcastDispatcher;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUserSwitcherAnchor.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardUserSwitcherAnchor.kt
index 5f3ba72d445b..04e8a970c50b 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUserSwitcherAnchor.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUserSwitcherAnchor.kt
@@ -20,7 +20,7 @@ import android.util.AttributeSet
 import android.view.accessibility.AccessibilityNodeInfo
 import android.widget.LinearLayout
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 /**
  * Custom View for the multi-user switcher pull-down menu anchor
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUserSwitcherPopupMenu.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUserSwitcherPopupMenu.java
index b793fd22aed1..f746459bf8dd 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUserSwitcherPopupMenu.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUserSwitcherPopupMenu.java
@@ -25,7 +25,7 @@ import android.view.View;
 import android.widget.ListPopupWindow;
 import android.widget.ListView;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.plugins.FalsingManager;
 
 /**
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconView.java b/packages/SystemUI/src/com/android/keyguard/LockIconView.java
index c52288190a7c..1d2d77f16b75 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconView.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconView.java
@@ -37,7 +37,7 @@ import androidx.annotation.NonNull;
 import com.android.internal.graphics.ColorUtils;
 import com.android.settingslib.Utils;
 import com.android.systemui.Dumpable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.io.PrintWriter;
 
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
index 214b1228b87a..165c4bb018d3 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -56,7 +56,7 @@ import androidx.annotation.VisibleForTesting;
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
 
 import com.android.systemui.Dumpable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.biometrics.AuthRippleController;
 import com.android.systemui.biometrics.UdfpsController;
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
index 5c2f3b368f96..76f93e18dda4 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
@@ -30,7 +30,7 @@ import android.view.MotionEvent;
 import androidx.annotation.Nullable;
 
 import com.android.settingslib.Utils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * Similar to the {@link NumPadKey}, but displays an image.
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
index 466d15474679..871d57da9b0d 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
@@ -36,7 +36,7 @@ import android.widget.TextView;
 import androidx.annotation.Nullable;
 
 import com.android.settingslib.Utils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * Viewgroup for the bouncer numpad button, specifically for digits.
diff --git a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
index 9a2ffe0ec68c..85f8b4824c99 100644
--- a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
+++ b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
@@ -37,7 +37,7 @@ import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 
 import com.android.settingslib.Utils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.util.ArrayList;
 
diff --git a/packages/SystemUI/src/com/android/keyguard/PinShapeAdapter.kt b/packages/SystemUI/src/com/android/keyguard/PinShapeAdapter.kt
index 4496dc311e92..8d1bbb29267b 100644
--- a/packages/SystemUI/src/com/android/keyguard/PinShapeAdapter.kt
+++ b/packages/SystemUI/src/com/android/keyguard/PinShapeAdapter.kt
@@ -17,7 +17,7 @@
 package com.android.keyguard
 
 import android.content.Context
-import com.android.systemui.R
+import com.android.systemui.res.R
 import kotlin.random.Random
 
 class PinShapeAdapter {
diff --git a/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java b/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java
index 7c129b4c8905..5e9eed98f97b 100644
--- a/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java
+++ b/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java
@@ -29,7 +29,7 @@ import android.widget.LinearLayout;
 import androidx.core.graphics.drawable.DrawableCompat;
 
 import com.android.settingslib.Utils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * This class contains implementation for methods that will be used when user has set a
diff --git a/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java b/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java
index 5f33ef91ed9c..8c987e3c3143 100644
--- a/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java
+++ b/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java
@@ -40,7 +40,7 @@ import androidx.core.graphics.drawable.DrawableCompat;
 
 import com.android.app.animation.Interpolators;
 import com.android.settingslib.Utils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * This class contains implementation for methods that will be used when user has set a
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java b/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java
index 83fc2789dc91..9716d98cf5e0 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java
@@ -20,7 +20,7 @@ import android.content.Context;
 import android.content.res.Resources;
 import android.view.LayoutInflater;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Application;
 import com.android.systemui.dagger.qualifiers.Background;
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java
index 893239ba7ecb..afea224f31eb 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java
@@ -25,7 +25,7 @@ import android.view.ViewGroup;
 
 import com.android.keyguard.KeyguardSecurityContainer;
 import com.android.keyguard.KeyguardSecurityViewFlipper;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.biometrics.SideFpsController;
 import com.android.systemui.dagger.qualifiers.RootView;
 import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor;
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewModule.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewModule.java
index 87627698597f..37600da3a4de 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewModule.java
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewModule.java
@@ -17,7 +17,7 @@
 package com.android.keyguard.dagger;
 
 import com.android.keyguard.CarrierText;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.battery.BatteryMeterView;
 import com.android.systemui.statusbar.phone.KeyguardStatusBarView;
 import com.android.systemui.statusbar.phone.StatusBarLocation;
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewModule.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewModule.java
index b8841eda1de4..7575f0e80d1c 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewModule.java
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewModule.java
@@ -19,7 +19,7 @@ package com.android.keyguard.dagger;
 import com.android.keyguard.KeyguardClockSwitch;
 import com.android.keyguard.KeyguardSliceView;
 import com.android.keyguard.KeyguardStatusView;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import dagger.Module;
 import dagger.Provides;
diff --git a/packages/SystemUI/src/com/android/systemui/AutoReinflateContainer.java b/packages/SystemUI/src/com/android/systemui/AutoReinflateContainer.java
index 4c16d41c8672..72fa2b0bcacb 100644
--- a/packages/SystemUI/src/com/android/systemui/AutoReinflateContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/AutoReinflateContainer.java
@@ -24,6 +24,8 @@ import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.FrameLayout;
 
+import com.android.systemui.res.R;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
diff --git a/packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt b/packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt
index eee705dea277..2d2ebe99d651 100644
--- a/packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt
@@ -22,8 +22,8 @@ import android.graphics.Rect
 import android.graphics.RectF
 import android.hardware.camera2.CameraManager
 import android.util.PathParser
+import com.android.systemui.res.R
 import java.util.concurrent.Executor
-
 import kotlin.math.roundToInt
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/DessertCaseView.java b/packages/SystemUI/src/com/android/systemui/DessertCaseView.java
index 5e963798b9a2..2010a706fad2 100644
--- a/packages/SystemUI/src/com/android/systemui/DessertCaseView.java
+++ b/packages/SystemUI/src/com/android/systemui/DessertCaseView.java
@@ -43,6 +43,8 @@ import android.view.animation.DecelerateInterpolator;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 
+import com.android.systemui.res.R;
+
 import java.util.HashSet;
 import java.util.Set;
 
diff --git a/packages/SystemUI/src/com/android/systemui/DualToneHandler.kt b/packages/SystemUI/src/com/android/systemui/DualToneHandler.kt
index 2b8d3e046ffa..22d0bc9e4b5c 100644
--- a/packages/SystemUI/src/com/android/systemui/DualToneHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/DualToneHandler.kt
@@ -20,6 +20,7 @@ import android.animation.ArgbEvaluator
 import android.content.Context
 import android.view.ContextThemeWrapper
 import com.android.settingslib.Utils
+import com.android.systemui.res.R
 
 /**
  * A color blender for `Theme.SystemUI` and other themes.
diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
index 7c377d2841e3..086713f49508 100644
--- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
@@ -36,6 +36,8 @@ import androidx.core.animation.Animator;
 import androidx.core.animation.AnimatorListenerAdapter;
 import androidx.core.animation.ObjectAnimator;
 
+import com.android.systemui.res.R;
+
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServicesDialog.java b/packages/SystemUI/src/com/android/systemui/ForegroundServicesDialog.java
index e6d5719e6fbd..ab431d03760e 100644
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServicesDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/ForegroundServicesDialog.java
@@ -37,6 +37,7 @@ import android.widget.ImageView;
 import android.widget.ListView;
 import android.widget.TextView;
 
+import com.android.systemui.res.R;
 import com.android.internal.app.AlertActivity;
 import com.android.internal.app.AlertController;
 import com.android.internal.logging.MetricsLogger;
diff --git a/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java b/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
index 104b71f29219..4541384aaa37 100644
--- a/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
+++ b/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
@@ -24,6 +24,7 @@ import android.os.UserHandle;
 
 import androidx.annotation.NonNull;
 
+import com.android.systemui.res.R;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.UiEventLogger;
 import com.android.systemui.broadcast.BroadcastDispatcher;
diff --git a/packages/SystemUI/src/com/android/systemui/GuestSessionNotification.java b/packages/SystemUI/src/com/android/systemui/GuestSessionNotification.java
index 7a6b1c372a24..161cb43e95ba 100644
--- a/packages/SystemUI/src/com/android/systemui/GuestSessionNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/GuestSessionNotification.java
@@ -26,6 +26,7 @@ import android.os.Bundle;
 import android.os.UserHandle;
 import android.provider.Settings;
 
+import com.android.systemui.res.R;
 import com.android.internal.messages.nano.SystemMessageProto;
 import com.android.systemui.util.NotificationChannels;
 
diff --git a/packages/SystemUI/src/com/android/systemui/HardwareBgDrawable.java b/packages/SystemUI/src/com/android/systemui/HardwareBgDrawable.java
index d631cf3551d9..0643d0243517 100644
--- a/packages/SystemUI/src/com/android/systemui/HardwareBgDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/HardwareBgDrawable.java
@@ -23,6 +23,7 @@ import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.LayerDrawable;
 
+import com.android.systemui.res.R;
 import com.android.settingslib.Utils;
 
 public class HardwareBgDrawable extends LayerDrawable {
diff --git a/packages/SystemUI/src/com/android/systemui/PluginInflateContainer.java b/packages/SystemUI/src/com/android/systemui/PluginInflateContainer.java
index 1bb03291996d..b9e412c5d00e 100644
--- a/packages/SystemUI/src/com/android/systemui/PluginInflateContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/PluginInflateContainer.java
@@ -20,6 +20,7 @@ import android.util.AttributeSet;
 import android.util.Log;
 import android.view.View;
 
+import com.android.systemui.res.R;
 import com.android.systemui.plugins.PluginListener;
 import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.plugins.ViewProvider;
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index ff395da54d18..4af2c740ddc9 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -84,6 +84,7 @@ import com.android.systemui.decor.RoundedCornerResDelegateImpl;
 import com.android.systemui.decor.ScreenDecorCommand;
 import com.android.systemui.log.ScreenDecorationsLogger;
 import com.android.systemui.qs.SettingObserver;
+import com.android.systemui.res.R;
 import com.android.systemui.settings.DisplayTracker;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.commandline.CommandRegistry;
@@ -334,7 +335,7 @@ public class ScreenDecorations implements CoreStartable, Dumpable {
         mThreadFactory = threadFactory;
         mDotFactory = dotFactory;
         mFaceScanningFactory = faceScanningFactory;
-        mFaceScanningViewId = com.android.systemui.R.id.face_scanning_anim;
+        mFaceScanningViewId = com.android.systemui.res.R.id.face_scanning_anim;
         mLogger = logger;
         mAuthController = authController;
     }
@@ -1195,7 +1196,7 @@ public class ScreenDecorations implements CoreStartable, Dumpable {
         if (faceScanningOverlay != null) {
             faceScanningOverlay.setFaceScanningAnimColor(
                     Utils.getColorAttrDefaultColor(faceScanningOverlay.getContext(),
-                            com.android.systemui.R.attr.wallpaperTextColorAccent));
+                            com.android.systemui.res.R.attr.wallpaperTextColorAccent));
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java b/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java
index 6f99a24b7312..67012cb0584f 100644
--- a/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java
@@ -35,6 +35,8 @@ import android.util.Log;
 import android.widget.CheckBox;
 import android.widget.TextView;
 
+import com.android.systemui.res.R;
+
 public class SlicePermissionActivity extends Activity implements OnClickListener,
         OnDismissListener {
 
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 3ca74acf2d66..954129ef78c8 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -51,6 +51,7 @@ import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.wm.shell.animation.FlingAnimationUtils;
 import com.android.wm.shell.animation.PhysicsAnimator;
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 38298cfac49a..bf445177f3f8 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -37,6 +37,7 @@ import android.view.SurfaceControl;
 import android.view.ThreadedRenderer;
 import android.view.View;
 
+import com.android.systemui.res.R;
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.systemui.dagger.GlobalRootComponent;
 import com.android.systemui.dagger.SysUIComponent;
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java b/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java
index 2b468cf7c16b..872b00518d62 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java
@@ -22,6 +22,7 @@ import android.os.Handler;
 import android.os.HandlerThread;
 import android.util.Log;
 
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.GlobalRootComponent;
 import com.android.systemui.dagger.SysUIComponent;
 import com.android.systemui.dagger.WMComponent;
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIService.java b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
index 6cf9eff1da2f..76c228252484 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIService.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
@@ -33,6 +33,7 @@ import com.android.systemui.dump.DumpHandler;
 import com.android.systemui.dump.LogBufferEulogizer;
 import com.android.systemui.dump.LogBufferFreezer;
 import com.android.systemui.dump.SystemUIAuxiliaryDumpService;
+import com.android.systemui.res.R;
 import com.android.systemui.shared.system.UncaughtExceptionPreHandlerManager;
 import com.android.systemui.statusbar.policy.BatteryStateNotifier;
 
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
index f817c3cb90a7..84f1395051eb 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
@@ -46,7 +46,7 @@ import android.widget.ImageView;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.util.Collections;
 
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationSettingsController.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationSettingsController.java
index 859e183d39fe..ee7781d8af20 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationSettingsController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationSettingsController.java
@@ -73,7 +73,7 @@ public class MagnificationSettingsController implements ComponentCallbacks {
                 context.getDisplay(),
                 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
                 null);
-        mContext.setTheme(com.android.systemui.R.style.Theme_SystemUI);
+        mContext.setTheme(com.android.systemui.res.R.style.Theme_SystemUI);
         mDisplayId = mContext.getDisplayId();
         mConfiguration = new Configuration(mContext.getResources().getConfiguration());
         mSettingsControllerCallback = settingsControllerCallback;
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MirrorWindowControl.java b/packages/SystemUI/src/com/android/systemui/accessibility/MirrorWindowControl.java
index 6de3e930cfa3..443441f1ef48 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/MirrorWindowControl.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/MirrorWindowControl.java
@@ -31,7 +31,7 @@ import android.view.LayoutInflater;
 import android.view.View;
 import android.view.WindowManager;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * Contains a movable control UI to manipulate mirrored window's position, size and scale. The
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/SimpleMirrorWindowControl.java b/packages/SystemUI/src/com/android/systemui/accessibility/SimpleMirrorWindowControl.java
index ed6fbecd19fe..bc469eed7359 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/SimpleMirrorWindowControl.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/SimpleMirrorWindowControl.java
@@ -28,7 +28,7 @@ import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * A basic control to move the mirror window.
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
index 69041d32f04a..59b85d112753 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
@@ -102,7 +102,7 @@ public class WindowMagnification implements CoreStartable, CommandQueue.Callback
         protected WindowMagnificationController createInstance(Display display) {
             final Context windowContext = mContext.createWindowContext(display,
                     TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY, /* options */ null);
-            windowContext.setTheme(com.android.systemui.R.style.Theme_SystemUI);
+            windowContext.setTheme(com.android.systemui.res.R.style.Theme_SystemUI);
             return new WindowMagnificationController(
                     windowContext,
                     mHandler,
@@ -141,7 +141,7 @@ public class WindowMagnification implements CoreStartable, CommandQueue.Callback
         protected MagnificationSettingsController createInstance(Display display) {
             final Context windowContext = mContext.createWindowContext(display,
                     TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY, /* options */ null);
-            windowContext.setTheme(com.android.systemui.R.style.Theme_SystemUI);
+            windowContext.setTheme(com.android.systemui.res.R.style.Theme_SystemUI);
             return new MagnificationSettingsController(
                     windowContext,
                     new SfVsyncFrameCallbackProvider(),
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java
index d061c8ef6e12..9dd1454d2528 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java
@@ -30,7 +30,7 @@ import android.view.accessibility.IRemoteMagnificationAnimationCallback;
 import android.view.animation.AccelerateInterpolator;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
index 773241ec57e3..c095aa8349b3 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
@@ -80,7 +80,7 @@ import androidx.core.math.MathUtils;
 import com.android.internal.accessibility.common.MagnificationConstants;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.model.SysUiState;
 import com.android.systemui.util.settings.SecureSettings;
 
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
index 7c11311373ab..c03e403b754b 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
@@ -59,7 +59,7 @@ import android.widget.TextView;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView;
 import com.android.systemui.util.settings.SecureSettings;
 
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java
index ecfe4caa5984..83ad3c23fda3 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java
@@ -29,7 +29,7 @@ import androidx.recyclerview.widget.RecyclerView.Adapter;
 
 import com.android.internal.accessibility.common.ShortcutConstants.AccessibilityFragmentType;
 import com.android.internal.accessibility.dialog.AccessibilityTarget;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.accessibility.floatingmenu.AccessibilityTargetAdapter.ViewHolder;
 
 import java.lang.annotation.Retention;
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuEduTooltipView.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuEduTooltipView.java
index 5ec024ebc917..1ff9eb4ef503 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuEduTooltipView.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuEduTooltipView.java
@@ -41,7 +41,7 @@ import android.widget.TextView;
 import androidx.annotation.NonNull;
 
 import com.android.settingslib.Utils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.recents.TriangleShape;
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegate.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegate.java
index 14517ba5bdb4..9c22a7738ad6 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegate.java
@@ -27,7 +27,7 @@ import androidx.annotation.NonNull;
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
 import androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * An accessibility item delegate for the individual items of the list view in the
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuMessageView.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuMessageView.java
index 3e2b06b39bad..bf121fb8c752 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuMessageView.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuMessageView.java
@@ -37,7 +37,7 @@ import android.widget.TextView;
 import androidx.annotation.NonNull;
 
 import com.android.settingslib.Utils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewAppearance.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewAppearance.java
index df2c05d9f53c..89ce06514e1c 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewAppearance.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewAppearance.java
@@ -35,7 +35,7 @@ import android.view.WindowMetrics;
 import androidx.annotation.DimenRes;
 
 import com.android.systemui.Flags;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
index 6ba40d6944e3..b6e8997c31e7 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
@@ -59,7 +59,7 @@ import androidx.lifecycle.Observer;
 import com.android.internal.accessibility.dialog.AccessibilityTarget;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.Preconditions;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.util.settings.SecureSettings;
 import com.android.wm.shell.bubbles.DismissViewUtils;
 import com.android.wm.shell.common.bubbles.DismissView;
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/fontscaling/FontScalingDialog.kt b/packages/SystemUI/src/com/android/systemui/accessibility/fontscaling/FontScalingDialog.kt
index 0ef256d41157..2d2f29564263 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/fontscaling/FontScalingDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/fontscaling/FontScalingDialog.kt
@@ -29,7 +29,7 @@ import android.widget.SeekBar
 import android.widget.TextView
 import androidx.annotation.MainThread
 import androidx.annotation.WorkerThread
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView
 import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView.OnSeekBarWithIconButtonsChangeListener
 import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView.OnSeekBarWithIconButtonsChangeListener.ControlUnitType
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java b/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java
index d49197557dc4..a5c5beccefd9 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java
@@ -33,7 +33,7 @@ import android.view.WindowManager;
 import android.view.accessibility.AccessibilityEvent;
 
 import com.android.app.animation.Interpolators;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * Visually discloses that contextual data was provided to an assistant.
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index 4416b1979524..0e339dd68b4f 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -29,7 +29,7 @@ import com.android.internal.app.IVoiceInteractionSessionListener;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.assist.ui.DefaultUiController;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java b/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java
index 1c980993f32a..1ee06cc8d757 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java
@@ -35,7 +35,7 @@ import android.widget.FrameLayout;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.assist.AssistLogger;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.assist.AssistantSessionEvent;
diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/DisplayUtils.java b/packages/SystemUI/src/com/android/systemui/assist/ui/DisplayUtils.java
index 9b441ad1d75c..5765f3a57c14 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/ui/DisplayUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/ui/DisplayUtils.java
@@ -21,7 +21,7 @@ import android.util.DisplayMetrics;
 import android.view.Display;
 import android.view.Surface;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * Utility class for determining screen and corner dimensions.
diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java b/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
index ac39ed501811..4d89231f0b15 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
@@ -32,7 +32,7 @@ import android.view.View;
 
 import com.android.settingslib.Utils;
 import com.android.systemui.Dependency;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.navigationbar.NavigationBarController;
 import com.android.systemui.navigationbar.NavigationBar;
 import com.android.systemui.navigationbar.NavigationBarTransitions;
diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/PathSpecCornerPathRenderer.java b/packages/SystemUI/src/com/android/systemui/assist/ui/PathSpecCornerPathRenderer.java
index 523378e97c94..fa9676b04f84 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/ui/PathSpecCornerPathRenderer.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/ui/PathSpecCornerPathRenderer.java
@@ -23,7 +23,7 @@ import android.graphics.RectF;
 import android.util.Log;
 import android.util.PathParser;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * Parses a path describing rounded corners from a string.
diff --git a/packages/SystemUI/src/com/android/systemui/battery/AccessorizedBatteryDrawable.kt b/packages/SystemUI/src/com/android/systemui/battery/AccessorizedBatteryDrawable.kt
index b81d7fced5e4..b8de117fcbe9 100644
--- a/packages/SystemUI/src/com/android/systemui/battery/AccessorizedBatteryDrawable.kt
+++ b/packages/SystemUI/src/com/android/systemui/battery/AccessorizedBatteryDrawable.kt
@@ -28,7 +28,7 @@ import android.graphics.Rect
 import android.graphics.drawable.DrawableWrapper
 import android.util.PathParser
 import com.android.settingslib.graph.ThemedBatteryDrawable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.battery.BatterySpecs.BATTERY_HEIGHT
 import com.android.systemui.battery.BatterySpecs.BATTERY_HEIGHT_WITH_SHIELD
 import com.android.systemui.battery.BatterySpecs.BATTERY_WIDTH
diff --git a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
index 6ca1c3de0b63..f25f994bf8f3 100644
--- a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
@@ -47,7 +47,7 @@ import androidx.annotation.VisibleForTesting;
 
 import com.android.app.animation.Interpolators;
 import com.android.systemui.DualToneHandler;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
 import com.android.systemui.statusbar.policy.BatteryController;
diff --git a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterViewController.java b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterViewController.java
index b6f47e9c907e..5b840b52bde6 100644
--- a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterViewController.java
@@ -30,7 +30,7 @@ import android.view.View;
 
 import androidx.annotation.NonNull;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.flags.FeatureFlags;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceIconController.kt
index ea8f5d376ba7..3f2da5e144c5 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceIconController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceIconController.kt
@@ -19,7 +19,7 @@ import android.content.Context
 import android.graphics.drawable.Drawable
 import android.util.Log
 import com.airbnb.lottie.LottieAnimationView
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.biometrics.ui.binder.Spaghetti.BiometricState
 
 private const val TAG = "AuthBiometricFaceIconController"
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceIconController.kt
index fb22c6b07db4..09eabf2aa430 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceIconController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceIconController.kt
@@ -19,7 +19,7 @@ package com.android.systemui.biometrics
 import android.annotation.RawRes
 import android.content.Context
 import com.airbnb.lottie.LottieAnimationView
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.biometrics.ui.binder.Spaghetti.BiometricState
 import com.android.systemui.biometrics.ui.binder.Spaghetti.BiometricState.STATE_AUTHENTICATED
 import com.android.systemui.biometrics.ui.binder.Spaghetti.BiometricState.STATE_ERROR
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
index 683541bd1b5b..0ad3848299f9 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
@@ -26,7 +26,7 @@ import android.view.View
 import androidx.annotation.VisibleForTesting
 import com.airbnb.lottie.LottieAnimationView
 import com.android.settingslib.widget.LottieColorUtils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.biometrics.ui.binder.Spaghetti.BiometricState
 import com.android.systemui.biometrics.ui.binder.Spaghetti.BiometricState.STATE_AUTHENTICATED
 import com.android.systemui.biometrics.ui.binder.Spaghetti.BiometricState.STATE_AUTHENTICATING
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index c7d7fe32be31..85122baa3fec 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -63,7 +63,7 @@ import com.android.app.animation.Interpolators;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.widget.LockPatternUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.biometrics.AuthController.ScaleFactorProvider;
 import com.android.systemui.biometrics.domain.interactor.PromptCredentialInteractor;
 import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index b752c3b80cae..a64e862000fc 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -627,7 +627,7 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
             int xFpLocation = mCachedDisplayInfo.getNaturalWidth() / 2;
             try {
                 xFpLocation = mContext.getResources().getDimensionPixelSize(
-                        com.android.systemui.R.dimen
+                        com.android.systemui.res.R.dimen
                                 .physical_fingerprint_sensor_center_screen_location_x);
             } catch (Resources.NotFoundException e) {
             }
@@ -635,7 +635,7 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
             return new Point(
                     (int) (xFpLocation * mScaleFactor),
                     (int) (mContext.getResources().getDimensionPixelSize(
-                            com.android.systemui.R.dimen
+                            com.android.systemui.res.R.dimen
                                     .physical_fingerprint_sensor_center_screen_location_y)
                             * mScaleFactor)
             );
@@ -815,7 +815,7 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
 
         mFaceProps = mFaceManager != null ? mFaceManager.getSensorPropertiesInternal() : null;
         int[] faceAuthLocation = context.getResources().getIntArray(
-                com.android.systemui.R.array.config_face_auth_props);
+                com.android.systemui.res.R.array.config_face_auth_props);
         if (faceAuthLocation == null || faceAuthLocation.length < 2) {
             mFaceSensorLocationDefault = null;
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthPanelController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthPanelController.java
index 167067e7d7e9..bc0c8c892be8 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthPanelController.java
@@ -27,7 +27,7 @@ import android.view.View;
 import android.view.ViewOutlineProvider;
 import android.view.animation.AccelerateDecelerateInterpolator;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
index 141983ba548d..c09e68d4ace6 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
@@ -31,7 +31,7 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback
 import com.android.keyguard.logging.KeyguardLogger
 import com.android.settingslib.Utils
 import com.android.systemui.CoreStartable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.flags.FeatureFlags
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationDialogFactory.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationDialogFactory.java
index 3e6508c6da70..2962be8e55a2 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationDialogFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationDialogFactory.java
@@ -27,7 +27,7 @@ import android.hardware.fingerprint.FingerprintManager;
 import android.provider.Settings;
 import android.util.Log;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java
index c2b9102cbcb2..d6a4cbb67487 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java
@@ -43,7 +43,7 @@ import android.util.Log;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.systemui.CoreStartable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FaceAuthAccessibilityDelegate.kt b/packages/SystemUI/src/com/android/systemui/biometrics/FaceAuthAccessibilityDelegate.kt
index a24a47bb44df..bbdcadbb19c6 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/FaceAuthAccessibilityDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/FaceAuthAccessibilityDelegate.kt
@@ -22,7 +22,7 @@ import android.view.View
 import android.view.accessibility.AccessibilityNodeInfo
 import com.android.keyguard.FaceAuthApiRequestReason
 import com.android.keyguard.KeyguardUpdateMonitor
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.keyguard.domain.interactor.KeyguardFaceAuthInteractor
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FaceHelpMessageDeferral.kt b/packages/SystemUI/src/com/android/systemui/biometrics/FaceHelpMessageDeferral.kt
index 320e362dd9c7..b015f7078a83 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/FaceHelpMessageDeferral.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/FaceHelpMessageDeferral.kt
@@ -20,7 +20,7 @@ import android.content.res.Resources
 import com.android.keyguard.logging.BiometricMessageDeferralLogger
 import com.android.keyguard.logging.FaceMessageDeferralLogger
 import com.android.systemui.Dumpable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.dump.DumpManager
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
index 017ac6019b65..c1f6259d94f7 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
@@ -54,7 +54,7 @@ import com.android.app.animation.Interpolators
 import com.android.internal.annotations.VisibleForTesting
 import com.android.keyguard.KeyguardPINView
 import com.android.systemui.Dumpable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor
 import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor
 import com.android.systemui.dagger.SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
index 941df687ead9..34a0d8a46e52 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
@@ -46,7 +46,7 @@ import android.view.accessibility.AccessibilityManager.TouchExplorationStateChan
 import androidx.annotation.LayoutRes
 import androidx.annotation.VisibleForTesting
 import com.android.keyguard.KeyguardUpdateMonitor
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.ActivityLaunchAnimator
 import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams
 import com.android.systemui.biometrics.ui.controller.UdfpsKeyguardViewController
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java
index 16dc42acde46..abbfa017c13e 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java
@@ -35,7 +35,7 @@ import android.view.WindowMetrics;
 import android.widget.FrameLayout;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * Adapter that remeasures an auth dialog view to ensure that it matches the location of a physical
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDrawable.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDrawable.kt
index 511b4e34fa0e..c16dfb1ea1a8 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDrawable.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDrawable.kt
@@ -24,7 +24,7 @@ import android.graphics.drawable.Drawable
 import android.graphics.drawable.ShapeDrawable
 import android.graphics.drawable.shapes.PathShape
 import android.util.PathParser
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 private const val DEFAULT_STROKE_WIDTH = 3f
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyView.kt
index 5dafa61f9a27..0838855f4756 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyView.kt
@@ -20,7 +20,7 @@ import android.graphics.Rect
 import android.util.AttributeSet
 import android.view.View
 import android.view.ViewGroup
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 /**
  * View corresponding with udfps_fpm_empty_view.xml
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardAccessibilityDelegate.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardAccessibilityDelegate.kt
index 84978790f49c..99da660d1fda 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardAccessibilityDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardAccessibilityDelegate.kt
@@ -20,7 +20,7 @@ import android.content.res.Resources
 import android.os.Bundle
 import android.view.View
 import android.view.accessibility.AccessibilityNodeInfo
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt
index 84a746ca2b8f..8ce98a92adbd 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt
@@ -27,7 +27,7 @@ import androidx.lifecycle.repeatOnLifecycle
 import com.android.app.animation.Interpolators
 import com.android.keyguard.BouncerPanelExpansionCalculator.aboutToShowBouncerProgress
 import com.android.keyguard.KeyguardUpdateMonitor
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.ActivityLaunchAnimator
 import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor
 import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacy.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacy.java
index b916810c57d0..36a42f945235 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacy.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacy.java
@@ -42,7 +42,7 @@ import androidx.asynclayoutinflater.view.AsyncLayoutInflater;
 
 import com.android.app.animation.Interpolators;
 import com.android.settingslib.Utils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import com.airbnb.lottie.LottieAnimationView;
 import com.airbnb.lottie.LottieProperty;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt
index 54e62154bca3..6ce6172c9faa 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt
@@ -26,7 +26,7 @@ import android.util.AttributeSet
 import android.util.Log
 import android.view.MotionEvent
 import android.widget.FrameLayout
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams
 import com.android.systemui.doze.DozeReceiver
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/CredentialInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/CredentialInteractor.kt
index 2a026675adcb..191533c8f377 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/CredentialInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/CredentialInteractor.kt
@@ -7,7 +7,7 @@ import android.os.UserManager
 import com.android.internal.widget.LockPatternUtils
 import com.android.internal.widget.LockscreenCredential
 import com.android.internal.widget.VerifyCredentialResponse
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.biometrics.domain.model.BiometricPromptRequest
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.util.time.SystemClock
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/BiometricPromptLayout.java b/packages/SystemUI/src/com/android/systemui/biometrics/ui/BiometricPromptLayout.java
index fb246cd51d8a..cef0be09d3ce 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/BiometricPromptLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/BiometricPromptLayout.java
@@ -29,7 +29,7 @@ import android.widget.FrameLayout;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.biometrics.AuthBiometricFingerprintIconController;
 import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.biometrics.AuthDialog;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPasswordView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPasswordView.kt
index a7ecf38ef598..56e3f3995d1c 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPasswordView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPasswordView.kt
@@ -10,7 +10,7 @@ import android.view.WindowInsets.Type.ime
 import android.view.accessibility.AccessibilityManager
 import android.widget.LinearLayout
 import android.widget.TextView
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.biometrics.AuthPanelController
 import com.android.systemui.biometrics.ui.binder.CredentialViewBinder
 import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
index 02847c283738..c29efc0fcab9 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
@@ -38,7 +38,7 @@ import androidx.lifecycle.LifecycleOwner
 import androidx.lifecycle.lifecycleScope
 import androidx.lifecycle.repeatOnLifecycle
 import com.airbnb.lottie.LottieAnimationView
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.biometrics.AuthBiometricFaceIconController
 import com.android.systemui.biometrics.AuthBiometricFingerprintAndFaceIconController
 import com.android.systemui.biometrics.AuthBiometricFingerprintIconController
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
index b9af03166fed..7e16d1e1d668 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
@@ -30,7 +30,7 @@ import androidx.core.animation.addListener
 import androidx.core.view.doOnLayout
 import androidx.core.view.isGone
 import androidx.lifecycle.lifecycleScope
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.biometrics.AuthPanelController
 import com.android.systemui.biometrics.Utils
 import com.android.systemui.biometrics.ui.BiometricPromptLayout
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPasswordViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPasswordViewBinder.kt
index 996b62e084cb..0ad07ba924a0 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPasswordViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPasswordViewBinder.kt
@@ -12,7 +12,7 @@ import android.window.OnBackInvokedDispatcher
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.lifecycleScope
 import androidx.lifecycle.repeatOnLifecycle
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.biometrics.ui.CredentialPasswordView
 import com.android.systemui.biometrics.ui.CredentialView
 import com.android.systemui.biometrics.ui.IPinPad
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPatternViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPatternViewBinder.kt
index b692ad35caee..eff698705042 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPatternViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPatternViewBinder.kt
@@ -4,7 +4,7 @@ import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
 import com.android.internal.widget.LockPatternUtils
 import com.android.internal.widget.LockPatternView
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.biometrics.ui.CredentialPatternView
 import com.android.systemui.biometrics.ui.CredentialView
 import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialViewBinder.kt
index 931946aaa382..ce52e1d78fda 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialViewBinder.kt
@@ -8,7 +8,7 @@ import android.widget.TextView
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
 import com.android.app.animation.Interpolators
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.biometrics.AuthPanelController
 import com.android.systemui.biometrics.ui.CredentialPasswordView
 import com.android.systemui.biometrics.ui.CredentialPatternView
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PinPadViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PinPadViewBinder.kt
index 906206c27455..05fdb2f22a9f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PinPadViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PinPadViewBinder.kt
@@ -20,7 +20,7 @@ package com.android.systemui.biometrics.ui.binder
 import android.view.KeyEvent
 import android.widget.ImeAwareEditText
 import com.android.internal.widget.LockscreenCredential
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.biometrics.ui.CredentialPasswordView
 import com.android.systemui.biometrics.ui.IPinPad
 import com.android.systemui.biometrics.ui.PinPadClickListener
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt
index 6212ef000ff1..03c5c5354ad7 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt
@@ -4,7 +4,7 @@ import android.content.Context
 import android.graphics.drawable.Drawable
 import android.text.InputType
 import com.android.internal.widget.LockPatternView
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.biometrics.Utils
 import com.android.systemui.biometrics.domain.interactor.CredentialStatus
 import com.android.systemui.biometrics.domain.interactor.PromptCredentialInteractor
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptFingerprintIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptFingerprintIconViewModel.kt
index b406ea41eff0..a95e257188dc 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptFingerprintIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptFingerprintIconViewModel.kt
@@ -20,7 +20,7 @@ package com.android.systemui.biometrics.ui.viewmodel
 import android.annotation.RawRes
 import android.content.res.Configuration
 import android.view.Surface
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor
 import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor
 import com.android.systemui.biometrics.shared.model.FingerprintSensorType
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialog.java b/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialog.java
index 83e61d69e4f3..00e952718436 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialog.java
@@ -38,7 +38,7 @@ import com.android.internal.logging.UiEventLogger;
 import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.media.MediaOutputConstants;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.broadcast.BroadcastSender;
 import com.android.systemui.media.controls.util.MediaDataUtils;
 import com.android.systemui.media.dialog.MediaOutputDialogFactory;
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/data/factory/BouncerMessageFactory.kt b/packages/SystemUI/src/com/android/systemui/bouncer/data/factory/BouncerMessageFactory.kt
index 64bf688b3c5d..f93337c993c8 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/data/factory/BouncerMessageFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/data/factory/BouncerMessageFactory.kt
@@ -36,46 +36,46 @@ import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_RESTART_FOR_MAINL
 import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_TIMEOUT
 import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_TRUSTAGENT_EXPIRED
 import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_USER_REQUEST
-import com.android.systemui.R.string.bouncer_face_not_recognized
-import com.android.systemui.R.string.keyguard_enter_password
-import com.android.systemui.R.string.keyguard_enter_pattern
-import com.android.systemui.R.string.keyguard_enter_pin
-import com.android.systemui.R.string.kg_bio_too_many_attempts_password
-import com.android.systemui.R.string.kg_bio_too_many_attempts_pattern
-import com.android.systemui.R.string.kg_bio_too_many_attempts_pin
-import com.android.systemui.R.string.kg_bio_try_again_or_password
-import com.android.systemui.R.string.kg_bio_try_again_or_pattern
-import com.android.systemui.R.string.kg_bio_try_again_or_pin
-import com.android.systemui.R.string.kg_face_locked_out
-import com.android.systemui.R.string.kg_fp_locked_out
-import com.android.systemui.R.string.kg_fp_not_recognized
-import com.android.systemui.R.string.kg_primary_auth_locked_out_password
-import com.android.systemui.R.string.kg_primary_auth_locked_out_pattern
-import com.android.systemui.R.string.kg_primary_auth_locked_out_pin
-import com.android.systemui.R.string.kg_prompt_after_dpm_lock
-import com.android.systemui.R.string.kg_prompt_after_update_password
-import com.android.systemui.R.string.kg_prompt_after_update_pattern
-import com.android.systemui.R.string.kg_prompt_after_update_pin
-import com.android.systemui.R.string.kg_prompt_after_user_lockdown_password
-import com.android.systemui.R.string.kg_prompt_after_user_lockdown_pattern
-import com.android.systemui.R.string.kg_prompt_after_user_lockdown_pin
-import com.android.systemui.R.string.kg_prompt_auth_timeout
-import com.android.systemui.R.string.kg_prompt_password_auth_timeout
-import com.android.systemui.R.string.kg_prompt_pattern_auth_timeout
-import com.android.systemui.R.string.kg_prompt_pin_auth_timeout
-import com.android.systemui.R.string.kg_prompt_reason_restart_password
-import com.android.systemui.R.string.kg_prompt_reason_restart_pattern
-import com.android.systemui.R.string.kg_prompt_reason_restart_pin
-import com.android.systemui.R.string.kg_prompt_unattended_update
-import com.android.systemui.R.string.kg_too_many_failed_attempts_countdown
-import com.android.systemui.R.string.kg_trust_agent_disabled
-import com.android.systemui.R.string.kg_unlock_with_password_or_fp
-import com.android.systemui.R.string.kg_unlock_with_pattern_or_fp
-import com.android.systemui.R.string.kg_unlock_with_pin_or_fp
-import com.android.systemui.R.string.kg_wrong_input_try_fp_suggestion
-import com.android.systemui.R.string.kg_wrong_password_try_again
-import com.android.systemui.R.string.kg_wrong_pattern_try_again
-import com.android.systemui.R.string.kg_wrong_pin_try_again
+import com.android.systemui.res.R.string.bouncer_face_not_recognized
+import com.android.systemui.res.R.string.keyguard_enter_password
+import com.android.systemui.res.R.string.keyguard_enter_pattern
+import com.android.systemui.res.R.string.keyguard_enter_pin
+import com.android.systemui.res.R.string.kg_bio_too_many_attempts_password
+import com.android.systemui.res.R.string.kg_bio_too_many_attempts_pattern
+import com.android.systemui.res.R.string.kg_bio_too_many_attempts_pin
+import com.android.systemui.res.R.string.kg_bio_try_again_or_password
+import com.android.systemui.res.R.string.kg_bio_try_again_or_pattern
+import com.android.systemui.res.R.string.kg_bio_try_again_or_pin
+import com.android.systemui.res.R.string.kg_face_locked_out
+import com.android.systemui.res.R.string.kg_fp_locked_out
+import com.android.systemui.res.R.string.kg_fp_not_recognized
+import com.android.systemui.res.R.string.kg_primary_auth_locked_out_password
+import com.android.systemui.res.R.string.kg_primary_auth_locked_out_pattern
+import com.android.systemui.res.R.string.kg_primary_auth_locked_out_pin
+import com.android.systemui.res.R.string.kg_prompt_after_dpm_lock
+import com.android.systemui.res.R.string.kg_prompt_after_update_password
+import com.android.systemui.res.R.string.kg_prompt_after_update_pattern
+import com.android.systemui.res.R.string.kg_prompt_after_update_pin
+import com.android.systemui.res.R.string.kg_prompt_after_user_lockdown_password
+import com.android.systemui.res.R.string.kg_prompt_after_user_lockdown_pattern
+import com.android.systemui.res.R.string.kg_prompt_after_user_lockdown_pin
+import com.android.systemui.res.R.string.kg_prompt_auth_timeout
+import com.android.systemui.res.R.string.kg_prompt_password_auth_timeout
+import com.android.systemui.res.R.string.kg_prompt_pattern_auth_timeout
+import com.android.systemui.res.R.string.kg_prompt_pin_auth_timeout
+import com.android.systemui.res.R.string.kg_prompt_reason_restart_password
+import com.android.systemui.res.R.string.kg_prompt_reason_restart_pattern
+import com.android.systemui.res.R.string.kg_prompt_reason_restart_pin
+import com.android.systemui.res.R.string.kg_prompt_unattended_update
+import com.android.systemui.res.R.string.kg_too_many_failed_attempts_countdown
+import com.android.systemui.res.R.string.kg_trust_agent_disabled
+import com.android.systemui.res.R.string.kg_unlock_with_password_or_fp
+import com.android.systemui.res.R.string.kg_unlock_with_pattern_or_fp
+import com.android.systemui.res.R.string.kg_unlock_with_pin_or_fp
+import com.android.systemui.res.R.string.kg_wrong_input_try_fp_suggestion
+import com.android.systemui.res.R.string.kg_wrong_password_try_again
+import com.android.systemui.res.R.string.kg_wrong_pattern_try_again
+import com.android.systemui.res.R.string.kg_wrong_pin_try_again
 import com.android.systemui.bouncer.shared.model.BouncerMessageModel
 import com.android.systemui.bouncer.shared.model.Message
 import com.android.systemui.dagger.SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
index abddb0a322ea..199036f09e9a 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
@@ -17,7 +17,7 @@
 package com.android.systemui.bouncer.domain.interactor
 
 import android.content.Context
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
 import com.android.systemui.authentication.domain.model.AuthenticationMethodModel
 import com.android.systemui.authentication.shared.model.AuthenticationThrottlingModel
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractor.kt
index 3fd6617d5a81..6e26fe952749 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractor.kt
@@ -28,7 +28,7 @@ import com.android.keyguard.KeyguardSecurityModel
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.KeyguardUpdateMonitorCallback
 import com.android.systemui.DejankUtils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepository
 import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants
 import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.EXPANSION_HIDDEN
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/BouncerMessageView.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/BouncerMessageView.kt
index 648680293e3d..79a11ee88826 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/BouncerMessageView.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/BouncerMessageView.kt
@@ -22,7 +22,7 @@ import android.widget.LinearLayout
 import com.android.keyguard.BouncerKeyguardMessageArea
 import com.android.keyguard.KeyguardMessageArea
 import com.android.keyguard.KeyguardMessageAreaController
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 class BouncerMessageView : LinearLayout {
     constructor(context: Context?) : super(context)
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt
index f6794d4f40b3..15d1dae239a0 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt
@@ -17,7 +17,7 @@
 package com.android.systemui.bouncer.ui.viewmodel
 
 import android.content.Context
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
 import com.android.systemui.authentication.domain.model.AuthenticationMethodModel
 import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
diff --git a/packages/SystemUI/src/com/android/systemui/camera/CameraIntents.kt b/packages/SystemUI/src/com/android/systemui/camera/CameraIntents.kt
index cc43e7ed25a5..1e17059d20e4 100644
--- a/packages/SystemUI/src/com/android/systemui/camera/CameraIntents.kt
+++ b/packages/SystemUI/src/com/android/systemui/camera/CameraIntents.kt
@@ -20,7 +20,7 @@ import android.content.Context
 import android.content.Intent
 import android.provider.MediaStore
 import android.text.TextUtils
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 class CameraIntents {
     companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/charging/WiredChargingRippleController.kt b/packages/SystemUI/src/com/android/systemui/charging/WiredChargingRippleController.kt
index ddb097491988..718ef51aa161 100644
--- a/packages/SystemUI/src/com/android/systemui/charging/WiredChargingRippleController.kt
+++ b/packages/SystemUI/src/com/android/systemui/charging/WiredChargingRippleController.kt
@@ -27,7 +27,7 @@ import com.android.internal.annotations.VisibleForTesting
 import com.android.internal.logging.UiEvent
 import com.android.internal.logging.UiEventLogger
 import com.android.settingslib.Utils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
diff --git a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java
index 7bf8f4dac1fb..047d15daf6f8 100644
--- a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java
@@ -32,7 +32,7 @@ import android.widget.TextView;
 
 import com.android.app.animation.Interpolators;
 import com.android.settingslib.Utils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.shared.recents.utilities.Utilities;
 import com.android.systemui.surfaceeffects.ripple.RippleShader;
 import com.android.systemui.surfaceeffects.ripple.RippleShader.RippleShape;
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java
index 0a1aed65c205..2729b7b0a4fd 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java
@@ -19,7 +19,7 @@ package com.android.systemui.classifier;
 import android.content.res.Resources;
 import android.view.ViewConfiguration;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.scene.shared.flag.SceneContainerFlags;
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardImageLoader.kt b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardImageLoader.kt
index 0542e13ba6da..e83a825a0072 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardImageLoader.kt
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardImageLoader.kt
@@ -20,7 +20,7 @@ import android.graphics.Bitmap
 import android.net.Uri
 import android.util.Log
 import android.util.Size
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Background
 import java.io.IOException
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardModel.kt b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardModel.kt
index 789833c6d849..12597a7679fa 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardModel.kt
@@ -24,7 +24,7 @@ import android.text.TextUtils
 import android.util.Log
 import android.util.Size
 import android.view.textclassifier.TextLinks
-import com.android.systemui.R
+import com.android.systemui.res.R
 import java.io.IOException
 
 data class ClipboardModel(
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
index ffd836b3230f..70736ae3fcc1 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
@@ -61,7 +61,7 @@ import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.UiEventLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.broadcast.BroadcastSender;
 import com.android.systemui.clipboardoverlay.dagger.ClipboardOverlayModule.OverlayWindowContext;
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtils.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtils.java
index 758a6563323e..2406d6104c1a 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtils.java
@@ -30,7 +30,7 @@ import android.view.textclassifier.TextClassifier;
 import android.view.textclassifier.TextLinks;
 
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.util.ArrayList;
 import java.util.Optional;
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayView.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayView.java
index a76d2ea816a7..2af49cfbf1b1 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayView.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayView.java
@@ -54,7 +54,7 @@ import android.widget.TextView;
 import androidx.core.view.ViewCompat;
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.screenshot.DraggableConstraintLayout;
 import com.android.systemui.screenshot.FloatingWindowUtil;
 import com.android.systemui.screenshot.OverlayActionChip;
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardToast.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardToast.java
index e9daa462c022..0a4d76ef1a92 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardToast.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardToast.java
@@ -19,7 +19,7 @@ package com.android.systemui.clipboardoverlay;
 import android.content.Context;
 import android.widget.Toast;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import javax.inject.Inject;
 
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java
index 1ffbe3230bda..bb201b624a71 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java
@@ -31,7 +31,7 @@ import android.view.inputmethod.InputMethodManager;
 import android.widget.EditText;
 import android.widget.TextView;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * Lightweight activity for editing text clipboard contents
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/IntentCreator.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/IntentCreator.java
index d58fab45093d..a18b4c84b081 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/IntentCreator.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/IntentCreator.java
@@ -24,7 +24,7 @@ import android.content.Intent;
 import android.net.Uri;
 import android.text.TextUtils;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 class IntentCreator {
     private static final String EXTRA_EDIT_SOURCE = "edit_source";
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayModule.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayModule.java
index 09b2e44c1be1..0fd34bd757b0 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayModule.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayModule.java
@@ -25,7 +25,7 @@ import android.hardware.display.DisplayManager;
 import android.view.Display;
 import android.view.LayoutInflater;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.clipboardoverlay.ClipboardOverlayView;
 import com.android.systemui.settings.DisplayTracker;
 
diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsView.java b/packages/SystemUI/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsView.java
index f362831e8c88..7fe00322ef27 100644
--- a/packages/SystemUI/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsView.java
+++ b/packages/SystemUI/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsView.java
@@ -29,7 +29,7 @@ import android.widget.LinearLayout;
 import android.widget.SeekBar;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/binder/CommunalWidgetViewBinder.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/binder/CommunalWidgetViewBinder.kt
index 1b6d3a8095f0..65bf4b3e69cd 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/binder/CommunalWidgetViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/binder/CommunalWidgetViewBinder.kt
@@ -18,7 +18,7 @@ package com.android.systemui.communal.ui.binder
 
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.communal.ui.adapter.CommunalWidgetViewAdapter
 import com.android.systemui.communal.ui.view.CommunalWidgetWrapper
 import com.android.systemui.communal.ui.viewmodel.CommunalWidgetViewModel
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/view/CommunalWidgetWrapper.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/view/CommunalWidgetWrapper.kt
index 560f4fac048f..039078eb1f21 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/view/CommunalWidgetWrapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/view/CommunalWidgetWrapper.kt
@@ -20,7 +20,7 @@ package com.android.systemui.communal.ui.view
 import android.content.Context
 import android.util.AttributeSet
 import android.widget.LinearLayout
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 /** Wraps around a widget rendered in communal mode. */
 class CommunalWidgetWrapper(context: Context, attrs: AttributeSet? = null) :
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/view/layout/sections/DefaultCommunalWidgetSection.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/view/layout/sections/DefaultCommunalWidgetSection.kt
index 8640c97bb1e1..c3e8a96701ea 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/view/layout/sections/DefaultCommunalWidgetSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/view/layout/sections/DefaultCommunalWidgetSection.kt
@@ -22,7 +22,7 @@ import androidx.constraintlayout.widget.ConstraintSet
 import androidx.constraintlayout.widget.ConstraintSet.BOTTOM
 import androidx.constraintlayout.widget.ConstraintSet.END
 import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.communal.ui.adapter.CommunalWidgetViewAdapter
 import com.android.systemui.communal.ui.binder.CommunalWidgetViewBinder
 import com.android.systemui.communal.ui.viewmodel.CommunalWidgetViewModel
diff --git a/packages/SystemUI/src/com/android/systemui/complication/ComplicationLayoutEngine.java b/packages/SystemUI/src/com/android/systemui/complication/ComplicationLayoutEngine.java
index e1dd1a69158b..20b2494a6c29 100644
--- a/packages/SystemUI/src/com/android/systemui/complication/ComplicationLayoutEngine.java
+++ b/packages/SystemUI/src/com/android/systemui/complication/ComplicationLayoutEngine.java
@@ -40,7 +40,7 @@ import android.view.ViewGroup;
 import androidx.constraintlayout.widget.ConstraintLayout;
 import androidx.constraintlayout.widget.Constraints;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.complication.ComplicationLayoutParams.Direction;
 import com.android.systemui.complication.ComplicationLayoutParams.Position;
 import com.android.systemui.complication.dagger.ComplicationModule;
diff --git a/packages/SystemUI/src/com/android/systemui/complication/dagger/ComplicationHostViewModule.java b/packages/SystemUI/src/com/android/systemui/complication/dagger/ComplicationHostViewModule.java
index a7d017dda21e..712213ab0b12 100644
--- a/packages/SystemUI/src/com/android/systemui/complication/dagger/ComplicationHostViewModule.java
+++ b/packages/SystemUI/src/com/android/systemui/complication/dagger/ComplicationHostViewModule.java
@@ -22,7 +22,7 @@ import android.view.LayoutInflater;
 import androidx.constraintlayout.widget.ConstraintLayout;
 
 import com.android.internal.util.Preconditions;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Main;
 
 import dagger.Module;
diff --git a/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamClockTimeComplicationComponent.kt b/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamClockTimeComplicationComponent.kt
index 87c3b2f4117b..099e3fcf227d 100644
--- a/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamClockTimeComplicationComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamClockTimeComplicationComponent.kt
@@ -21,7 +21,7 @@ import android.view.LayoutInflater
 import android.view.View
 import android.widget.TextClock
 import com.android.internal.util.Preconditions
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.complication.DreamClockTimeComplication
 import com.android.systemui.complication.DreamClockTimeComplication.DreamClockTimeViewHolder
 import dagger.Module
diff --git a/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamHomeControlsComplicationComponent.java b/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamHomeControlsComplicationComponent.java
index 2b5aa7cd9c51..08d0595eba23 100644
--- a/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamHomeControlsComplicationComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamHomeControlsComplicationComponent.java
@@ -25,7 +25,7 @@ import android.view.LayoutInflater;
 import android.widget.ImageView;
 
 import com.android.settingslib.Utils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.complication.DreamHomeControlsComplication;
 import com.android.systemui.shared.shadow.DoubleShadowIconDrawable;
 import com.android.systemui.shared.shadow.DoubleShadowTextHelper;
diff --git a/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamMediaEntryComplicationComponent.java b/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamMediaEntryComplicationComponent.java
index f15a5862104f..c0a292cd0d33 100644
--- a/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamMediaEntryComplicationComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamMediaEntryComplicationComponent.java
@@ -21,7 +21,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
 import android.view.LayoutInflater;
 import android.view.View;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.complication.DreamMediaEntryComplication;
 
 import dagger.Module;
diff --git a/packages/SystemUI/src/com/android/systemui/complication/dagger/RegisteredComplicationsModule.java b/packages/SystemUI/src/com/android/systemui/complication/dagger/RegisteredComplicationsModule.java
index 776c9721aea5..92fdb1e69c83 100644
--- a/packages/SystemUI/src/com/android/systemui/complication/dagger/RegisteredComplicationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/complication/dagger/RegisteredComplicationsModule.java
@@ -19,7 +19,7 @@ package com.android.systemui.complication.dagger;
 import android.content.res.Resources;
 import android.view.ViewGroup;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.complication.ComplicationLayoutParams;
 import com.android.systemui.dagger.SystemUIBinder;
 import com.android.systemui.dagger.qualifiers.Main;
diff --git a/packages/SystemUI/src/com/android/systemui/contrast/ContrastDialog.kt b/packages/SystemUI/src/com/android/systemui/contrast/ContrastDialog.kt
index e627b68dc171..e9b59306c552 100644
--- a/packages/SystemUI/src/com/android/systemui/contrast/ContrastDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/contrast/ContrastDialog.kt
@@ -28,7 +28,7 @@ import android.view.LayoutInflater
 import android.view.View
 import android.widget.FrameLayout
 import com.android.internal.annotations.VisibleForTesting
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.statusbar.phone.SystemUIDialog
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ControlsServiceInfo.kt b/packages/SystemUI/src/com/android/systemui/controls/ControlsServiceInfo.kt
index adb0bf38b51f..97b4c94cb9a9 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ControlsServiceInfo.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ControlsServiceInfo.kt
@@ -32,7 +32,7 @@ import android.service.controls.ControlsProviderService
 import android.util.IconDrawableFactory
 import androidx.annotation.WorkerThread
 import com.android.settingslib.applications.DefaultAppInfo
-import com.android.systemui.R
+import com.android.systemui.res.R
 import java.util.Objects
 
 open class ControlsServiceInfo(
diff --git a/packages/SystemUI/src/com/android/systemui/controls/TooltipManager.kt b/packages/SystemUI/src/com/android/systemui/controls/TooltipManager.kt
index 6e17bc94b16b..21458e89583e 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/TooltipManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/TooltipManager.kt
@@ -28,7 +28,7 @@ import android.view.animation.AccelerateInterpolator
 import android.view.animation.DecelerateInterpolator
 import android.widget.TextView
 import com.android.systemui.Prefs
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.recents.TriangleShape
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsTileResourceConfigurationImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsTileResourceConfigurationImpl.kt
index 02490605fbb8..05ff7b71684c 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsTileResourceConfigurationImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsTileResourceConfigurationImpl.kt
@@ -16,7 +16,7 @@
 
 package com.android.systemui.controls.controller
 
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import javax.inject.Inject
 
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt
index 3fe0f03488d1..72483bbe135d 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt
@@ -26,7 +26,7 @@ import android.widget.TextView
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.LifecycleOwner
 import androidx.recyclerview.widget.RecyclerView
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.controls.ControlsServiceInfo
 import com.android.systemui.util.icuMessageFormat
 import java.text.Collator
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
index ec76f433b23b..f034851e5d80 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
@@ -36,7 +36,7 @@ import androidx.core.view.AccessibilityDelegateCompat
 import androidx.core.view.ViewCompat
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
 import androidx.recyclerview.widget.RecyclerView
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.controls.ControlInterface
 import com.android.systemui.controls.ui.CanUseIconPredicate
 import com.android.systemui.controls.ui.RenderInfo
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsAnimations.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsAnimations.kt
index b447d66c08dd..a534097458f7 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsAnimations.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsAnimations.kt
@@ -31,7 +31,7 @@ import android.view.Window
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.LifecycleObserver
 import androidx.lifecycle.OnLifecycleEvent
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.app.animation.Interpolators
 import com.android.systemui.controls.ui.ControlsUiController
 
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt
index 4c9dbe02fad8..41edb4a1ffaf 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt
@@ -34,7 +34,7 @@ import androidx.activity.ComponentActivity
 import androidx.recyclerview.widget.GridLayoutManager
 import androidx.recyclerview.widget.ItemTouchHelper
 import androidx.recyclerview.widget.RecyclerView
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.controls.CustomIconCache
 import com.android.systemui.controls.controller.ControlsControllerImpl
 import com.android.systemui.controls.controller.StructureInfo
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
index 8bae6674aa11..2ea4303e2290 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
@@ -39,7 +39,7 @@ import androidx.activity.ComponentActivity
 import androidx.annotation.VisibleForTesting
 import androidx.viewpager2.widget.ViewPager2
 import com.android.systemui.Prefs
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.controls.TooltipManager
 import com.android.systemui.controls.controller.ControlsControllerImpl
 import com.android.systemui.controls.controller.StructureInfo
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
index d5b8693af42d..10a0117f8757 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
@@ -35,7 +35,7 @@ import androidx.activity.ComponentActivity
 import androidx.annotation.VisibleForTesting
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.controls.ControlsServiceInfo
 import com.android.systemui.controls.controller.ControlsController
 import com.android.systemui.controls.panels.AuthorizedPanelsRepository
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestDialog.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestDialog.kt
index 86bde5c3cf4d..d7a68b317a61 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestDialog.kt
@@ -32,7 +32,7 @@ import android.view.View
 import android.widget.ImageView
 import android.widget.TextView
 import androidx.activity.ComponentActivity
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.controls.ControlsServiceInfo
 import com.android.systemui.controls.controller.ControlInfo
 import com.android.systemui.controls.controller.ControlsController
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/PanelConfirmationDialogFactory.kt b/packages/SystemUI/src/com/android/systemui/controls/management/PanelConfirmationDialogFactory.kt
index 6f87aa996f94..5df26b3176ff 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/PanelConfirmationDialogFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/PanelConfirmationDialogFactory.kt
@@ -20,7 +20,7 @@ package com.android.systemui.controls.management
 import android.app.Dialog
 import android.content.Context
 import android.content.DialogInterface
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.phone.SystemUIDialog
 import java.util.function.Consumer
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/StructureAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/StructureAdapter.kt
index 5977d379acde..7e56077dec29 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/StructureAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/StructureAdapter.kt
@@ -21,7 +21,7 @@ import android.view.View
 import android.view.ViewGroup
 import androidx.recyclerview.widget.GridLayoutManager
 import androidx.recyclerview.widget.RecyclerView
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 class StructureAdapter(
     private val models: List<StructureContainer>,
diff --git a/packages/SystemUI/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImpl.kt
index 4aef20928bb8..4e935df12ac1 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImpl.kt
@@ -19,7 +19,7 @@ package com.android.systemui.controls.panels
 
 import android.content.Context
 import android.content.SharedPreferences
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.settings.UserFileManager
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl
diff --git a/packages/SystemUI/src/com/android/systemui/controls/settings/ControlsSettingsDialogManager.kt b/packages/SystemUI/src/com/android/systemui/controls/settings/ControlsSettingsDialogManager.kt
index 501bcf054d20..4e391b7662e3 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/settings/ControlsSettingsDialogManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/settings/ControlsSettingsDialogManager.kt
@@ -24,7 +24,7 @@ import android.content.DialogInterface
 import android.content.SharedPreferences
 import android.provider.Settings
 import androidx.annotation.VisibleForTesting
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.controls.settings.ControlsSettingsDialogManager.Companion.MAX_NUMBER_ATTEMPTS_CONTROLS_DIALOG
 import com.android.systemui.controls.settings.ControlsSettingsDialogManager.Companion.PREFS_SETTINGS_DIALOG_ATTEMPTS
 import com.android.systemui.dagger.SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ChallengeDialogs.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ChallengeDialogs.kt
index a13f717bc77d..7e039cdcf204 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ChallengeDialogs.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ChallengeDialogs.kt
@@ -32,7 +32,7 @@ import android.view.inputmethod.InputMethodManager
 import android.widget.CheckBox
 import android.widget.EditText
 
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 /**
  * Creates all dialogs for challengeValues that can occur from a call to
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
index abe342320858..fdb9971a7d63 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
@@ -49,7 +49,7 @@ import android.widget.TextView
 import androidx.annotation.ColorInt
 import androidx.annotation.VisibleForTesting
 import com.android.internal.graphics.ColorUtils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.app.animation.Interpolators
 import com.android.systemui.controls.ControlsMetricsLogger
 import com.android.systemui.controls.controller.ControlsController
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt
index 8341964e1533..955a5a35d82f 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt
@@ -31,7 +31,7 @@ import android.view.WindowInsets
 import android.view.WindowInsets.Type
 import android.view.WindowManager
 import androidx.activity.ComponentActivity
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.controls.management.ControlsAnimations
 import com.android.systemui.controls.settings.ControlsSettingsDialogManager
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsDialogsFactory.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsDialogsFactory.kt
index d6cfb79101d7..2ad6014fd7cd 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsDialogsFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsDialogsFactory.kt
@@ -20,7 +20,7 @@ package com.android.systemui.controls.ui
 import android.app.Dialog
 import android.content.Context
 import android.content.DialogInterface
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.phone.SystemUIDialog
 import java.util.function.Consumer
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsPopupMenu.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsPopupMenu.kt
index f7c8e9652e4e..252f02ec2466 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsPopupMenu.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsPopupMenu.kt
@@ -30,7 +30,7 @@ import android.view.ViewGroup
 import android.widget.ListPopupWindow
 import android.widget.ListView
 import android.widget.PopupWindow
-import com.android.systemui.R
+import com.android.systemui.res.R
 import kotlin.math.max
 
 class ControlsPopupMenu(context: Context) : ListPopupWindow(context) {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
index 3cdf9ab69942..be9a2993dab1 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
@@ -51,7 +51,7 @@ import android.widget.Space
 import android.widget.TextView
 import androidx.annotation.VisibleForTesting
 import com.android.systemui.Dumpable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.controls.ControlsMetricsLogger
 import com.android.systemui.controls.ControlsServiceInfo
 import com.android.systemui.controls.CustomIconCache
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
index 98f17f409184..9b93522b2d5f 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
@@ -34,7 +34,7 @@ import android.view.WindowInsets.Type
 import android.view.WindowManager
 import android.widget.ImageView
 import com.android.internal.policy.ScreenDecorationsUtils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.broadcast.BroadcastSender
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.statusbar.policy.KeyguardStateController
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt
index db009dc46d89..1b0d03276415 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt
@@ -28,7 +28,7 @@ import android.graphics.drawable.ShapeDrawable
 import android.graphics.drawable.shapes.RoundRectShape
 import android.os.Trace
 import com.android.internal.annotations.VisibleForTesting
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.util.boundsOnScreen
 import com.android.wm.shell.taskview.TaskView
 import java.util.concurrent.Executor
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/RenderInfo.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/RenderInfo.kt
index dbbda9aad518..ac589eb900a3 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/RenderInfo.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/RenderInfo.kt
@@ -26,7 +26,7 @@ import android.service.controls.templates.TemperatureControlTemplate
 import android.util.ArrayMap
 import android.util.SparseArray
 
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 data class RenderInfo(
     val icon: Drawable,
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt
index 3c2bfa0efc39..0706a9670561 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt
@@ -26,7 +26,7 @@ import android.service.controls.Control
 import android.view.View
 import android.view.WindowManager
 
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 class StatusBehavior : Behavior {
     lateinit var cvh: ControlViewHolder
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/TemperatureControlBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/TemperatureControlBehavior.kt
index 39d69704d817..2c9eb3e058bd 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/TemperatureControlBehavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/TemperatureControlBehavior.kt
@@ -22,7 +22,7 @@ import android.service.controls.Control
 import android.service.controls.templates.ControlTemplate
 import android.service.controls.templates.TemperatureControlTemplate
 
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.controls.ui.ControlViewHolder.Companion.MIN_LEVEL
 import com.android.systemui.controls.ui.ControlViewHolder.Companion.MAX_LEVEL
 
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ThumbnailBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ThumbnailBehavior.kt
index d011dd421f7f..41907882a443 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ThumbnailBehavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ThumbnailBehavior.kt
@@ -26,7 +26,7 @@ import android.service.controls.templates.TemperatureControlTemplate
 import android.service.controls.templates.ThumbnailTemplate
 import android.util.TypedValue
 
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.controls.ui.ControlViewHolder.Companion.MAX_LEVEL
 import com.android.systemui.controls.ui.ControlViewHolder.Companion.MIN_LEVEL
 
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleBehavior.kt
index dc7247cd7096..4f47012b3e93 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleBehavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleBehavior.kt
@@ -23,7 +23,7 @@ import android.service.controls.templates.TemperatureControlTemplate
 import android.service.controls.templates.ToggleTemplate
 import android.util.Log
 import android.view.View
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.controls.ui.ControlViewHolder.Companion.MAX_LEVEL
 
 class ToggleBehavior : Behavior {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt
index 0d570d2dcc73..e34a94b6ccf7 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt
@@ -37,7 +37,7 @@ import android.view.View
 import android.view.ViewGroup
 import android.view.accessibility.AccessibilityEvent
 import android.view.accessibility.AccessibilityNodeInfo
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.app.animation.Interpolators
 import com.android.systemui.controls.ui.ControlViewHolder.Companion.MAX_LEVEL
 import com.android.systemui.controls.ui.ControlViewHolder.Companion.MIN_LEVEL
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/TouchBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/TouchBehavior.kt
index 9dd0f534e3a8..580a61556740 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/TouchBehavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/TouchBehavior.kt
@@ -23,7 +23,7 @@ import android.service.controls.Control
 import android.service.controls.templates.ControlTemplate
 import android.service.controls.templates.StatelessTemplate
 
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.controls.ui.ControlViewHolder.Companion.MAX_LEVEL
 import com.android.systemui.controls.ui.ControlViewHolder.Companion.MIN_LEVEL
 
diff --git a/packages/SystemUI/src/com/android/systemui/decor/CutoutDecorProviderImpl.kt b/packages/SystemUI/src/com/android/systemui/decor/CutoutDecorProviderImpl.kt
index ded0fb79cd6f..dbe6b0ba3719 100644
--- a/packages/SystemUI/src/com/android/systemui/decor/CutoutDecorProviderImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/decor/CutoutDecorProviderImpl.kt
@@ -21,7 +21,7 @@ import android.view.DisplayCutout
 import android.view.Surface
 import android.view.View
 import android.view.ViewGroup
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.ScreenDecorations.DisplayCutoutView
 
 class CutoutDecorProviderImpl(
diff --git a/packages/SystemUI/src/com/android/systemui/decor/FaceScanningProviderFactory.kt b/packages/SystemUI/src/com/android/systemui/decor/FaceScanningProviderFactory.kt
index ac0d3c8f3d36..31a5d37a4450 100644
--- a/packages/SystemUI/src/com/android/systemui/decor/FaceScanningProviderFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/decor/FaceScanningProviderFactory.kt
@@ -115,7 +115,7 @@ class FaceScanningOverlayProviderImpl(
     private val logger: ScreenDecorationsLogger,
     private val featureFlags: FeatureFlags,
 ) : BoundDecorProvider() {
-    override val viewId: Int = com.android.systemui.R.id.face_scanning_anim
+    override val viewId: Int = com.android.systemui.res.R.id.face_scanning_anim
 
     override fun onReloadResAndMeasure(
         view: View,
diff --git a/packages/SystemUI/src/com/android/systemui/decor/PrivacyDotDecorProviderFactory.kt b/packages/SystemUI/src/com/android/systemui/decor/PrivacyDotDecorProviderFactory.kt
index 8cfd39148f1c..14ecc66f555e 100644
--- a/packages/SystemUI/src/com/android/systemui/decor/PrivacyDotDecorProviderFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/decor/PrivacyDotDecorProviderFactory.kt
@@ -23,7 +23,7 @@ import android.view.LayoutInflater
 import android.view.Surface
 import android.view.View
 import android.view.ViewGroup
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderFactory.kt b/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderFactory.kt
index 0ffb4fb5b456..2f2c952fb778 100644
--- a/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderFactory.kt
@@ -17,7 +17,7 @@
 package com.android.systemui.decor
 
 import android.view.DisplayCutout
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 class RoundedCornerDecorProviderFactory(
     private val roundedCornerResDelegate: RoundedCornerResDelegate
diff --git a/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderImpl.kt b/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderImpl.kt
index 8156797c5a67..0ee11ae84e48 100644
--- a/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderImpl.kt
@@ -25,7 +25,7 @@ import android.view.View
 import android.view.ViewGroup
 import android.widget.FrameLayout
 import android.widget.ImageView
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 class RoundedCornerDecorProviderImpl(
     override val viewId: Int,
diff --git a/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt b/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt
index c64766a3eb3c..0314b0fe2ca3 100644
--- a/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt
@@ -24,7 +24,7 @@ import android.util.DisplayUtils
 import android.util.Size
 import android.view.RoundedCorners
 import com.android.systemui.Dumpable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import java.io.PrintWriter
 
 interface RoundedCornerResDelegate {
diff --git a/packages/SystemUI/src/com/android/systemui/display/ui/view/MirroringConfirmationDialog.kt b/packages/SystemUI/src/com/android/systemui/display/ui/view/MirroringConfirmationDialog.kt
index f730935e1b73..7510cf6ce04c 100644
--- a/packages/SystemUI/src/com/android/systemui/display/ui/view/MirroringConfirmationDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/ui/view/MirroringConfirmationDialog.kt
@@ -22,7 +22,7 @@ import android.view.Gravity
 import android.view.View
 import android.view.WindowManager
 import android.widget.TextView
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 /**
  * Dialog used to decide what to do with a connected display.
diff --git a/packages/SystemUI/src/com/android/systemui/doze/AlwaysOnDisplayPolicy.java b/packages/SystemUI/src/com/android/systemui/doze/AlwaysOnDisplayPolicy.java
index 55df7792e2e6..8e542b59a7cc 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/AlwaysOnDisplayPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/AlwaysOnDisplayPolicy.java
@@ -28,7 +28,7 @@ import android.text.format.DateUtils;
 import android.util.KeyValueListParser;
 import android.util.Log;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 
 import javax.inject.Inject;
diff --git a/packages/SystemUI/src/com/android/systemui/doze/dagger/DozeModule.java b/packages/SystemUI/src/com/android/systemui/doze/dagger/DozeModule.java
index d408472efca5..db0c3c68107a 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/dagger/DozeModule.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/dagger/DozeModule.java
@@ -20,7 +20,7 @@ import android.content.Context;
 import android.hardware.Sensor;
 import android.os.Handler;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dagger.qualifiers.UiBackground;
 import com.android.systemui.doze.DozeAuthRemover;
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt
index 01fb5227749f..4cfed33af95b 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt
@@ -27,7 +27,7 @@ import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
 import com.android.app.animation.Interpolators
 import com.android.dream.lowlight.util.TruncatedInterpolator
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.complication.ComplicationHostViewController
 import com.android.systemui.complication.ComplicationLayoutParams
 import com.android.systemui.complication.ComplicationLayoutParams.POSITION_BOTTOM
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
index 78ac45325072..d0f255943a84 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
@@ -33,7 +33,7 @@ import android.view.ViewGroup;
 
 import com.android.app.animation.Interpolators;
 import com.android.dream.lowlight.LowLightTransitionCoordinator;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.complication.ComplicationHostViewController;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dreams.dagger.DreamOverlayComponent;
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayDotImageView.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayDotImageView.java
index 02a8b39a106a..409b196fe525 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayDotImageView.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayDotImageView.java
@@ -31,7 +31,7 @@ import android.util.AttributeSet;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.AlphaOptimizedImageView;
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java
index 1865c38632e5..8e77079e0b5d 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java
@@ -26,7 +26,7 @@ import android.view.ViewGroup;
 
 import androidx.constraintlayout.widget.ConstraintLayout;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.shared.shadow.DoubleShadowIconDrawable;
 import com.android.systemui.shared.shadow.DoubleShadowTextHelper.ShadowInfo;
 import com.android.systemui.statusbar.AlphaOptimizedImageView;
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java
index a6401b6594ba..8d8702ebc6c7 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java
@@ -32,7 +32,7 @@ import android.view.View;
 
 import androidx.annotation.Nullable;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dreams.DreamOverlayStatusBarItemsProvider.StatusBarItem;
 import com.android.systemui.dreams.dagger.DreamOverlayComponent;
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationModule.kt b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationModule.kt
index 95c225de9598..6fd6f4e3d4eb 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationModule.kt
@@ -1,7 +1,7 @@
 package com.android.systemui.dreams.complication.dagger
 
 import android.content.res.Resources
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.qualifiers.Main
 import dagger.Module
 import dagger.Provides
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
index 4bafe325cda0..5ebb2ddcff36 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
@@ -23,7 +23,7 @@ import android.content.res.Resources;
 
 import com.android.dream.lowlight.dagger.LowLightDreamModule;
 import com.android.settingslib.dream.DreamBackend;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.complication.dagger.RegisteredComplicationsModule;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java
index 51eefd6bed37..34dd10084116 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java
@@ -25,7 +25,7 @@ import androidx.lifecycle.Lifecycle;
 import androidx.lifecycle.LifecycleOwner;
 
 import com.android.internal.util.Preconditions;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dreams.DreamOverlayContainerView;
 import com.android.systemui.dreams.DreamOverlayStatusBarView;
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/BouncerSwipeModule.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/BouncerSwipeModule.java
index 5f03743f48b8..8cf11a9817b7 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/BouncerSwipeModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/BouncerSwipeModule.java
@@ -21,7 +21,7 @@ import android.content.res.Resources;
 import android.util.TypedValue;
 import android.view.VelocityTracker;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dreams.touch.BouncerSwipeTouchHandler;
 import com.android.systemui.dreams.touch.DreamTouchHandler;
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/ShadeModule.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/ShadeModule.java
index 9e0ae4119f24..94fe4bd04dab 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/ShadeModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/ShadeModule.java
@@ -18,7 +18,7 @@ package com.android.systemui.dreams.touch.dagger;
 
 import android.content.res.Resources;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dreams.touch.DreamTouchHandler;
 import com.android.systemui.dreams.touch.ShadeTouchHandler;
diff --git a/packages/SystemUI/src/com/android/systemui/dump/SystemUIConfigDumpable.kt b/packages/SystemUI/src/com/android/systemui/dump/SystemUIConfigDumpable.kt
index b70edcc27254..7a441d6b4a6b 100644
--- a/packages/SystemUI/src/com/android/systemui/dump/SystemUIConfigDumpable.kt
+++ b/packages/SystemUI/src/com/android/systemui/dump/SystemUIConfigDumpable.kt
@@ -19,7 +19,7 @@ package com.android.systemui.dump
 import android.content.Context
 import com.android.systemui.CoreStartable
 import com.android.systemui.Dumpable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import java.io.PrintWriter
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index ab2ca690dd47..f97f6bd7613b 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -17,7 +17,7 @@ package com.android.systemui.flags
 
 import android.provider.DeviceConfig
 import com.android.internal.annotations.Keep
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.flags.FlagsFactory.releasedFlag
 import com.android.systemui.flags.FlagsFactory.resourceBooleanFlag
 import com.android.systemui.flags.FlagsFactory.sysPropBooleanFlag
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsColumnLayout.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsColumnLayout.java
index 59070287cc5c..a3065d3cca59 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsColumnLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsColumnLayout.java
@@ -26,7 +26,7 @@ import android.view.Gravity;
 import android.view.View;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * Grid-based implementation of the button layout created by the global actions dialog.
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
index 3eb17400446c..ac402303bf69 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
@@ -546,8 +546,8 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
      */
     @VisibleForTesting
     protected int getMaxShownPowerItems() {
-        return mResources.getInteger(com.android.systemui.R.integer.power_menu_lite_max_columns)
-                * mResources.getInteger(com.android.systemui.R.integer.power_menu_lite_max_rows);
+        return mResources.getInteger(com.android.systemui.res.R.integer.power_menu_lite_max_columns)
+                * mResources.getInteger(com.android.systemui.res.R.integer.power_menu_lite_max_rows);
     }
 
     /**
@@ -698,7 +698,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
 
         ActionsDialogLite dialog = new ActionsDialogLite(
                 mContext,
-                com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActionsLite,
+                com.android.systemui.res.R.style.Theme_SystemUI_Dialog_GlobalActionsLite,
                 mAdapter,
                 mOverflowAdapter,
                 mSysuiColorExtractor,
@@ -776,7 +776,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
     @VisibleForTesting
     protected final class PowerOptionsAction extends SinglePressAction {
         private PowerOptionsAction() {
-            super(com.android.systemui.R.drawable.ic_settings_power,
+            super(com.android.systemui.res.R.drawable.ic_settings_power,
                     R.string.global_action_power_options);
         }
 
@@ -884,17 +884,17 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
 
     protected int getEmergencyTextColor(Context context) {
         return context.getResources().getColor(
-                com.android.systemui.R.color.global_actions_lite_text);
+                com.android.systemui.res.R.color.global_actions_lite_text);
     }
 
     protected int getEmergencyIconColor(Context context) {
         return context.getResources().getColor(
-                com.android.systemui.R.color.global_actions_lite_emergency_icon);
+                com.android.systemui.res.R.color.global_actions_lite_emergency_icon);
     }
 
     protected int getEmergencyBackgroundColor(Context context) {
         return context.getResources().getColor(
-                com.android.systemui.R.color.global_actions_lite_emergency_background);
+                com.android.systemui.res.R.color.global_actions_lite_emergency_background);
     }
 
     private class EmergencyAffordanceAction extends EmergencyAction {
@@ -912,7 +912,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
     @VisibleForTesting
     class EmergencyDialerAction extends EmergencyAction {
         private EmergencyDialerAction() {
-            super(com.android.systemui.R.drawable.ic_emergency_star,
+            super(com.android.systemui.res.R.drawable.ic_emergency_star,
                     R.string.global_action_emergency);
         }
 
@@ -1482,7 +1482,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
                 Log.w(TAG, "No power options action found at position: " + position);
                 return null;
             }
-            int viewLayoutResource = com.android.systemui.R.layout.global_actions_power_item;
+            int viewLayoutResource = com.android.systemui.res.R.layout.global_actions_power_item;
             View view = convertView != null ? convertView
                     : LayoutInflater.from(mContext).inflate(viewLayoutResource, parent, false);
             view.setOnClickListener(v -> onClickItem(position));
@@ -1564,7 +1564,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
                 Log.w(TAG, "No overflow action found at position: " + position);
                 return null;
             }
-            int viewLayoutResource = com.android.systemui.R.layout.controls_more_item;
+            int viewLayoutResource = com.android.systemui.res.R.layout.controls_more_item;
             View view = convertView != null ? convertView
                     : LayoutInflater.from(mContext).inflate(viewLayoutResource, parent, false);
             TextView textView = (TextView) view;
@@ -1778,7 +1778,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
     }
 
     protected int getGridItemLayoutResource() {
-        return com.android.systemui.R.layout.global_actions_grid_item_lite;
+        return com.android.systemui.res.R.layout.global_actions_grid_item_lite;
     }
 
     private enum ToggleState {
@@ -1870,7 +1870,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
                 LayoutInflater inflater) {
             willCreate();
 
-            View v = inflater.inflate(com.android.systemui.R.layout.global_actions_grid_item_v2,
+            View v = inflater.inflate(com.android.systemui.res.R.layout.global_actions_grid_item_v2,
                     parent, false /* attach */);
             ViewGroup.LayoutParams p = v.getLayoutParams();
             p.width = WRAP_CONTENT;
@@ -2327,7 +2327,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
         protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             getWindow().setTitle(getContext().getString(
-                    com.android.systemui.R.string.accessibility_quick_settings_power_menu));
+                    com.android.systemui.res.R.string.accessibility_quick_settings_power_menu));
             initializeLayout();
             mWindowDimAmount = getWindow().getAttributes().dimAmount;
             getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
@@ -2379,14 +2379,14 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
             GlobalActionsPopupMenu popup = new GlobalActionsPopupMenu(
                     new ContextThemeWrapper(
                             mContext,
-                            com.android.systemui.R.style.Control_ListPopupWindow
+                            com.android.systemui.res.R.style.Control_ListPopupWindow
                     ), false /* isDropDownMode */);
             popup.setOnItemClickListener(
                     (parent, view, position, id) -> mOverflowAdapter.onClickItem(position));
             popup.setOnItemLongClickListener(
                     (parent, view, position, id) -> mOverflowAdapter.onLongClickItem(position));
             View overflowButton =
-                    findViewById(com.android.systemui.R.id.global_actions_overflow_button);
+                    findViewById(com.android.systemui.res.R.id.global_actions_overflow_button);
             popup.setAnchorView(overflowButton);
             popup.setAdapter(mOverflowAdapter);
             return popup;
@@ -2403,14 +2403,14 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
         }
 
         protected int getLayoutResource() {
-            return com.android.systemui.R.layout.global_actions_grid_lite;
+            return com.android.systemui.res.R.layout.global_actions_grid_lite;
         }
 
         protected void initializeLayout() {
             setContentView(getLayoutResource());
             fixNavBarClipping();
 
-            mGlobalActionsLayout = findViewById(com.android.systemui.R.id.global_actions_view);
+            mGlobalActionsLayout = findViewById(com.android.systemui.res.R.id.global_actions_view);
             mGlobalActionsLayout.setListViewAccessibilityDelegate(new View.AccessibilityDelegate() {
                 @Override
                 public boolean dispatchPopulateAccessibilityEvent(
@@ -2422,14 +2422,14 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
             });
             mGlobalActionsLayout.setRotationListener(this::onRotate);
             mGlobalActionsLayout.setAdapter(mAdapter);
-            mContainer = findViewById(com.android.systemui.R.id.global_actions_container);
+            mContainer = findViewById(com.android.systemui.res.R.id.global_actions_container);
             mContainer.setOnTouchListener((v, event) -> {
                 mGestureDetector.onTouchEvent(event);
                 return v.onTouchEvent(event);
             });
 
             View overflowButton = findViewById(
-                    com.android.systemui.R.id.global_actions_overflow_button);
+                    com.android.systemui.res.R.id.global_actions_overflow_button);
             if (overflowButton != null) {
                 if (mOverflowAdapter.getCount() > 0) {
                     overflowButton.setOnClickListener((view) -> showPowerOverflowMenu());
@@ -2442,7 +2442,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
                     LinearLayout.LayoutParams params =
                             (LinearLayout.LayoutParams) mGlobalActionsLayout.getLayoutParams();
                     params.setMarginEnd(mContext.getResources().getDimensionPixelSize(
-                            com.android.systemui.R.dimen.global_actions_side_margin));
+                            com.android.systemui.res.R.dimen.global_actions_side_margin));
                     mGlobalActionsLayout.setLayoutParams(params);
                 }
             }
@@ -2473,7 +2473,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
         private void showSmartLockDisabledMessage() {
             // Since power menu is the top window, make a Toast-like view that will show up
             View message = LayoutInflater.from(mContext)
-                    .inflate(com.android.systemui.R.layout.global_actions_toast, mContainer, false);
+                    .inflate(com.android.systemui.res.R.layout.global_actions_toast, mContainer, false);
 
             // Set up animation
             AccessibilityManager mAccessibilityManager =
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsFlatLayout.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsFlatLayout.java
index 83046ef450c3..bc1e13f772fa 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsFlatLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsFlatLayout.java
@@ -27,7 +27,7 @@ import android.view.ViewGroup;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.HardwareBgDrawable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * Flat, single-row implementation of the button layout created by the global actions dialog.
@@ -55,7 +55,7 @@ public class GlobalActionsFlatLayout extends GlobalActionsLayout {
     }
 
     private View getOverflowButton() {
-        return findViewById(com.android.systemui.R.id.global_actions_overflow_button);
+        return findViewById(com.android.systemui.res.R.id.global_actions_overflow_button);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java
index e1462d15c887..2272b8a888cd 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java
@@ -148,7 +148,7 @@ public class GlobalActionsGridLayout extends GlobalActionsLayout {
     protected float getAnimationDistance() {
         int rows = getListView().getRowCount();
         float gridItemSize = getContext().getResources().getDimension(
-                com.android.systemui.R.dimen.global_actions_grid_item_height);
+                com.android.systemui.res.R.dimen.global_actions_grid_item_height);
         return rows * gridItemSize / 2;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsLayout.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsLayout.java
index 183ee458acb4..6afefb040626 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsLayout.java
@@ -25,7 +25,7 @@ import android.view.ViewGroup;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.HardwareBgDrawable;
 import com.android.systemui.MultiListLayout;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.util.leak.RotationUtils;
 
 import java.util.Locale;
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsLayoutLite.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsLayoutLite.java
index 42230aed15d5..9b318a288caf 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsLayoutLite.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsLayoutLite.java
@@ -25,7 +25,7 @@ import androidx.constraintlayout.helper.widget.Flow;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.HardwareBgDrawable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * ConstraintLayout implementation of the button layout created by the global actions dialog.
@@ -53,7 +53,7 @@ public class GlobalActionsLayoutLite extends GlobalActionsLayout {
     public void onUpdateList() {
         super.onUpdateList();
         int nElementsWrap = getResources().getInteger(
-                com.android.systemui.R.integer.power_menu_lite_max_columns);
+                com.android.systemui.res.R.integer.power_menu_lite_max_columns);
         int nChildren = getListView().getChildCount() - 1; // don't count flow element
 
         // Avoid having just one action on the last row if there are more than 2 columns because
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPopupMenu.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPopupMenu.java
index 6d083f6c8bfd..b9a6a5515729 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPopupMenu.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPopupMenu.java
@@ -27,7 +27,7 @@ import android.widget.ListAdapter;
 import android.widget.ListPopupWindow;
 import android.widget.ListView;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * Customized widget for use in the GlobalActionsDialog. Ensures common positioning and user
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPowerDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPowerDialog.java
index caa88a372036..b8bf1428bb28 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPowerDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPowerDialog.java
@@ -36,7 +36,7 @@ public class GlobalActionsPowerDialog {
      */
     public static Dialog create(@NonNull Context context, ListAdapter adapter) {
         ViewGroup listView = (ViewGroup) LayoutInflater.from(context).inflate(
-                com.android.systemui.R.layout.global_actions_power_dialog, null);
+                com.android.systemui.res.R.layout.global_actions_power_dialog, null);
 
         for (int i = 0; i < adapter.getCount(); i++) {
             View action = adapter.getView(i, null, listView);
@@ -53,7 +53,7 @@ public class GlobalActionsPowerDialog {
         window.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
         window.setTitle(""); // prevent Talkback from speaking first item name twice
         window.setBackgroundDrawable(res.getDrawable(
-                com.android.systemui.R.drawable.control_background, context.getTheme()));
+                com.android.systemui.res.R.drawable.control_background, context.getTheme()));
         window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
 
         return dialog;
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/ShutdownUi.java b/packages/SystemUI/src/com/android/systemui/globalactions/ShutdownUi.java
index 68dc1b3dc7d7..51978ece14db 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/ShutdownUi.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/ShutdownUi.java
@@ -59,7 +59,7 @@ public class ShutdownUi {
         ScrimDrawable background = new ScrimDrawable();
 
         final Dialog d = new Dialog(mContext,
-                com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActions);
+                com.android.systemui.res.R.style.Theme_SystemUI_Dialog_GlobalActions);
 
         d.setOnShowListener(dialog -> {
             if (mBlurUtils.supportsBlursOnWindows()) {
@@ -69,7 +69,7 @@ public class ShutdownUi {
                         (int) mBlurUtils.blurRadiusOfRatio(1), backgroundAlpha == 255);
             } else {
                 float backgroundAlpha = mContext.getResources().getFloat(
-                        com.android.systemui.R.dimen.shutdown_scrim_behind_alpha);
+                        com.android.systemui.res.R.dimen.shutdown_scrim_behind_alpha);
                 background.setAlpha((int) (backgroundAlpha * 255));
             }
         });
@@ -96,7 +96,7 @@ public class ShutdownUi {
                         | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                         | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
         window.setBackgroundDrawable(background);
-        window.setWindowAnimations(com.android.systemui.R.style.Animation_ShutdownUi);
+        window.setWindowAnimations(com.android.systemui.res.R.style.Animation_ShutdownUi);
 
         d.setContentView(getShutdownDialogContent(isReboot));
         d.setCancelable(false);
@@ -104,10 +104,10 @@ public class ShutdownUi {
         int color;
         if (mBlurUtils.supportsBlursOnWindows()) {
             color = Utils.getColorAttrDefaultColor(mContext,
-                    com.android.systemui.R.attr.wallpaperTextColor);
+                    com.android.systemui.res.R.attr.wallpaperTextColor);
         } else {
             color = mContext.getResources().getColor(
-                    com.android.systemui.R.color.global_actions_shutdown_ui_text);
+                    com.android.systemui.res.R.color.global_actions_shutdown_ui_text);
         }
 
         ProgressBar bar = d.findViewById(R.id.progress);
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
index ad7973ed0b7a..1cdbe6fed58a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
@@ -50,7 +50,7 @@ import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
 import com.android.systemui.CoreStartable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.util.settings.SecureSettings;
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/view/KeyboardBacklightDialog.kt b/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/view/KeyboardBacklightDialog.kt
index 6f25f7c1921a..e16bb0bb8482 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/view/KeyboardBacklightDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/view/KeyboardBacklightDialog.kt
@@ -38,7 +38,7 @@ import android.widget.LinearLayout.LayoutParams.WRAP_CONTENT
 import androidx.annotation.IdRes
 import androidx.core.view.setPadding
 import com.android.settingslib.Utils
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 class KeyboardBacklightDialog(
     context: Context,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
index 732102e0cf9e..1f69cc0a8ec3 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
@@ -48,7 +48,7 @@ import androidx.slice.builders.SliceAction;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SystemUIAppComponentFactoryBase;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
index 22bcf0aa2799..fb02c7d68a9f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
@@ -26,7 +26,7 @@ import com.android.keyguard.LockIconView
 import com.android.keyguard.LockIconViewController
 import com.android.keyguard.dagger.KeyguardStatusViewComponent
 import com.android.systemui.CoreStartable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index a005b5ad6545..efd25d5d69e6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -128,7 +128,7 @@ import com.android.systemui.CoreStartable;
 import com.android.systemui.DejankUtils;
 import com.android.systemui.Dumpable;
 import com.android.systemui.EventLogTags;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.animation.LaunchAnimator;
 import com.android.systemui.broadcast.BroadcastDispatcher;
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java b/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java
index ffd8a0244a86..d5316cd40801 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java
@@ -30,7 +30,7 @@ import android.util.DisplayMetrics;
 import androidx.annotation.Nullable;
 
 import com.android.systemui.Dumpable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.util.time.SystemClock;
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java
index 82be009a7560..09875a52e07d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java
@@ -37,7 +37,7 @@ import android.window.OnBackInvokedCallback;
 import android.window.OnBackInvokedDispatcher;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 
 import javax.inject.Inject;
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt
index 5e5caba060ae..77e8179195a1 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt
@@ -21,7 +21,7 @@ import android.app.StatusBarManager
 import android.app.admin.DevicePolicyManager
 import android.content.Context
 import android.content.pm.PackageManager
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.Expandable
 import com.android.systemui.camera.CameraGestureHelper
 import com.android.systemui.common.shared.model.ContentDescription
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt
index 16385ec59aa7..9b5f4615a6d5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt
@@ -27,7 +27,7 @@ import android.provider.Settings.Secure.ZEN_DURATION_PROMPT
 import android.service.notification.ZenModeConfig
 import com.android.settingslib.notification.EnableZenModeDialog
 import com.android.settingslib.notification.ZenModeDialogMetricsLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt
index ed8823a53fe2..a7999c192643 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt
@@ -18,7 +18,7 @@
 package com.android.systemui.keyguard.data.quickaffordance
 
 import android.content.Context
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt
index f3fc8096f5d7..4e71ef4e34f2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt
@@ -21,7 +21,7 @@ import android.content.ComponentName
 import android.content.Context
 import android.content.Intent
 import androidx.annotation.DrawableRes
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt
index 320d158fb13e..1cf6183fec6c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt
@@ -21,7 +21,7 @@ import android.app.AlertDialog
 import android.content.Context
 import android.content.Intent
 import android.net.Uri
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.keyguard.shared.quickaffordance.ActivationState
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt
index 4dad17907aca..deedbdb9e72b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt
@@ -20,7 +20,7 @@ package com.android.systemui.keyguard.data.quickaffordance
 import android.content.Context
 import android.content.IntentFilter
 import android.content.SharedPreferences
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.backup.BackupHelper
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt
index 250356819baf..1fe94d5fa43b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt
@@ -21,7 +21,7 @@ import android.content.Context
 import android.media.AudioManager
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.Observer
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
 import com.android.systemui.common.shared.model.ContentDescription
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt
index 45277b833ea3..a503541dcf59 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt
@@ -18,7 +18,7 @@
 package com.android.systemui.keyguard.data.quickaffordance
 
 import android.content.Context
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
index 23f50eaba7e7..7337292a9ac5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
@@ -24,7 +24,7 @@ import android.service.quickaccesswallet.GetWalletCardsResponse
 import android.service.quickaccesswallet.QuickAccessWalletClient
 import android.service.quickaccesswallet.WalletCard
 import android.util.Log
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt
index 1ccc689da368..bbdd90375ece 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt
@@ -22,7 +22,7 @@ import android.app.admin.DevicePolicyManager
 import android.content.Context
 import android.content.Intent
 import com.android.systemui.ActivityIntentHelper
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.Expandable
 import com.android.systemui.camera.CameraIntents
 import com.android.systemui.camera.CameraIntentsWrapper
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepository.kt
index 682e841c3521..06cf7235ad2c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepository.kt
@@ -26,7 +26,7 @@ import android.os.UserHandle
 import android.util.Log
 import com.android.internal.widget.LockPatternUtils
 import com.android.systemui.Dumpable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.biometrics.AuthController
 import com.android.systemui.biometrics.data.repository.FacePropertyRepository
 import com.android.systemui.biometrics.data.repository.FingerprintPropertyRepository
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt
index 65cf0c9597d9..fd048ff11f14 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt
@@ -24,7 +24,7 @@ import com.android.internal.logging.InstanceId
 import com.android.internal.logging.UiEventLogger
 import com.android.keyguard.FaceAuthUiEvent
 import com.android.systemui.Dumpable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor
 import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor
 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt
index 34f6b4d74f2b..698328ecd7fb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt
@@ -22,7 +22,7 @@ import android.content.Intent
 import android.os.UserHandle
 import android.util.LayoutDirection
 import com.android.systemui.Dumpable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow
 import com.android.systemui.dagger.SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepository.kt
index 1c0b73fcfa2d..af01626c5c1d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepository.kt
@@ -22,7 +22,7 @@ import android.content.Context
 import android.graphics.Point
 import androidx.core.animation.Animator
 import androidx.core.animation.ValueAnimator
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.keyguard.shared.model.BiometricUnlockModel
 import com.android.systemui.keyguard.shared.model.BiometricUnlockSource
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractor.kt
index ac936b10fe43..b2e436cd2af6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractor.kt
@@ -19,7 +19,7 @@ package com.android.systemui.keyguard.domain.interactor
 
 import android.content.Context
 import androidx.annotation.DimenRes
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.common.ui.data.repository.ConfigurationRepository
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
index 572785721b4f..338f9945f5db 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
@@ -23,7 +23,7 @@ import android.app.StatusBarManager
 import android.graphics.Point
 import android.util.MathUtils
 import com.android.app.animation.Interpolators
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepository
 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractor.kt
index a257f529357f..299c8cf410cc 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractor.kt
@@ -24,7 +24,7 @@ import android.view.accessibility.AccessibilityManager
 import androidx.annotation.VisibleForTesting
 import com.android.internal.logging.UiEvent
 import com.android.internal.logging.UiEventLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
index 7f43cbc69fa2..de791aa23e22 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
@@ -23,7 +23,7 @@ import android.content.Context
 import android.content.Intent
 import android.util.Log
 import com.android.internal.widget.LockPatternUtils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.DialogLaunchAnimator
 import com.android.systemui.animation.Expandable
 import com.android.systemui.dagger.SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt
index 665e16db8abb..20e55e527fc2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt
@@ -22,7 +22,7 @@ import com.android.keyguard.FaceAuthUiEvent
 import com.android.keyguard.FaceWakeUpTriggersConfig
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.CoreStartable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.biometrics.data.repository.FacePropertyRepository
 import com.android.systemui.biometrics.shared.model.LockoutMode
 import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardAmbientIndicationAreaViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardAmbientIndicationAreaViewBinder.kt
index 5c072fbfdb01..5900a2467994 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardAmbientIndicationAreaViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardAmbientIndicationAreaViewBinder.kt
@@ -22,7 +22,7 @@ import android.view.ViewGroup
 import android.view.ViewPropertyAnimator
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardAmbientIndicationViewModel
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel
 import com.android.systemui.lifecycle.repeatWhenAttached
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
index a9c71adc095d..dd7eee924007 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
@@ -32,7 +32,7 @@ import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
 import com.android.app.animation.Interpolators
 import com.android.settingslib.Utils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.ActivityLaunchAnimator
 import com.android.systemui.animation.Expandable
 import com.android.systemui.animation.view.LaunchableLinearLayout
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardIndicationAreaBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardIndicationAreaBinder.kt
index dc51944ddc08..f20a66604ebf 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardIndicationAreaBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardIndicationAreaBinder.kt
@@ -22,7 +22,7 @@ import android.view.ViewGroup
 import android.widget.TextView
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardIndicationAreaViewModel
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceOnTouchListener.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceOnTouchListener.kt
index 7685345805f4..125e2dac7bb7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceOnTouchListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceOnTouchListener.kt
@@ -24,7 +24,7 @@ import android.view.ViewConfiguration
 import android.view.ViewPropertyAnimator
 import androidx.core.animation.CycleInterpolator
 import androidx.core.animation.ObjectAnimator
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.ui.view.rawDistanceFrom
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardQuickAffordanceViewModel
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt
index 83b5463ea19c..eeb4ac34bf37 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt
@@ -30,7 +30,7 @@ import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
 import com.android.app.animation.Interpolators
 import com.android.settingslib.Utils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.Expandable
 import com.android.systemui.animation.view.LaunchableImageView
 import com.android.systemui.common.shared.model.Icon
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
index 4b768211dc61..f564d0073e42 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
@@ -23,7 +23,7 @@ import android.view.ViewGroup
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
 import com.android.app.animation.Interpolators
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.common.shared.model.Text
 import com.android.systemui.common.shared.model.TintedIcon
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsViewBinder.kt
index 82610e6ea59d..6beef8ec1ff3 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsViewBinder.kt
@@ -22,7 +22,7 @@ import android.view.View
 import androidx.core.view.isVisible
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.ActivityLaunchAnimator
 import com.android.systemui.animation.view.LaunchableLinearLayout
 import com.android.systemui.common.ui.binder.IconViewBinder
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/UdfpsKeyguardInternalViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/UdfpsKeyguardInternalViewBinder.kt
index 3bb01f29aadf..aabb3f41e881 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/UdfpsKeyguardInternalViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/UdfpsKeyguardInternalViewBinder.kt
@@ -18,7 +18,7 @@
 package com.android.systemui.biometrics.ui.binder
 
 import android.view.View
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.keyguard.ui.binder.UdfpsAodFingerprintViewBinder
 import com.android.systemui.keyguard.ui.binder.UdfpsBackgroundViewBinder
 import com.android.systemui.keyguard.ui.binder.UdfpsFingerprintViewBinder
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/UdfpsKeyguardViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/UdfpsKeyguardViewBinder.kt
index 667abaea0b24..a0e0da452036 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/UdfpsKeyguardViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/UdfpsKeyguardViewBinder.kt
@@ -23,7 +23,7 @@ import android.widget.FrameLayout
 import androidx.asynclayoutinflater.view.AsyncLayoutInflater
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.biometrics.UdfpsKeyguardView
 import com.android.systemui.biometrics.ui.binder.UdfpsKeyguardInternalViewBinder
 import com.android.systemui.keyguard.ui.viewmodel.BackgroundViewModel
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
index 85a2fd5a6d01..2ad74fbc6674 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
@@ -38,7 +38,7 @@ import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.core.view.isInvisible
 import com.android.keyguard.ClockEventController
 import com.android.keyguard.KeyguardClockSwitch
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.view.LaunchableImageView
 import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor
 import com.android.systemui.broadcast.BroadcastDispatcher
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardIndicationArea.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardIndicationArea.kt
index 890d565b03a5..78099d9f5d90 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardIndicationArea.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardIndicationArea.kt
@@ -25,7 +25,7 @@ import android.view.View
 import android.view.ViewGroup.LayoutParams.MATCH_PARENT
 import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
 import android.widget.LinearLayout
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.phone.KeyguardIndicationTextView
 
 class KeyguardIndicationArea(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AlignShortcutsToUdfpsSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AlignShortcutsToUdfpsSection.kt
index 5aba229434d7..28e6a954a3d1 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AlignShortcutsToUdfpsSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AlignShortcutsToUdfpsSection.kt
@@ -25,7 +25,7 @@ import androidx.constraintlayout.widget.ConstraintSet.LEFT
 import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
 import androidx.constraintlayout.widget.ConstraintSet.RIGHT
 import androidx.constraintlayout.widget.ConstraintSet.TOP
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodNotificationIconsSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodNotificationIconsSection.kt
index ac11ba5b5ec6..669db34b97aa 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodNotificationIconsSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodNotificationIconsSection.kt
@@ -26,7 +26,7 @@ import androidx.constraintlayout.widget.ConstraintSet.END
 import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
 import androidx.constraintlayout.widget.ConstraintSet.START
 import androidx.constraintlayout.widget.ConstraintSet.TOP
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.shared.model.KeyguardSection
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/BaseShortcutSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/BaseShortcutSection.kt
index d046a196e94e..a4137ac934a1 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/BaseShortcutSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/BaseShortcutSection.kt
@@ -4,7 +4,7 @@ import android.view.View
 import android.widget.ImageView
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.core.content.res.ResourcesCompat
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.view.LaunchableImageView
 import com.android.systemui.keyguard.shared.model.KeyguardSection
 import com.android.systemui.keyguard.ui.binder.KeyguardQuickAffordanceViewBinder
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultAmbientIndicationAreaSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultAmbientIndicationAreaSection.kt
index ce86e9784180..9371d4e2d465 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultAmbientIndicationAreaSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultAmbientIndicationAreaSection.kt
@@ -29,7 +29,7 @@ import androidx.constraintlayout.widget.ConstraintSet.START
 import androidx.constraintlayout.widget.ConstraintSet.TOP
 import androidx.constraintlayout.widget.ConstraintSet.WRAP_CONTENT
 import com.android.keyguard.KeyguardUpdateMonitor
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.shared.model.KeyguardSection
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSection.kt
index a45223cbd449..623eac013a35 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSection.kt
@@ -21,7 +21,7 @@ import android.content.Context
 import android.view.ViewGroup
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.constraintlayout.widget.ConstraintSet
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.shared.model.KeyguardSection
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSection.kt
index 100099d3988e..9409036586e8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSection.kt
@@ -29,7 +29,7 @@ import androidx.constraintlayout.widget.ConstraintSet
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.LockIconView
 import com.android.keyguard.LockIconViewController
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.biometrics.AuthController
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultNotificationStackScrollLayoutSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultNotificationStackScrollLayoutSection.kt
index 7fff43b82e93..afa49bdd69d8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultNotificationStackScrollLayoutSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultNotificationStackScrollLayoutSection.kt
@@ -27,7 +27,7 @@ import androidx.constraintlayout.widget.ConstraintSet.END
 import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
 import androidx.constraintlayout.widget.ConstraintSet.START
 import androidx.constraintlayout.widget.ConstraintSet.TOP
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.shared.model.KeyguardSection
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultSettingsPopupMenuSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultSettingsPopupMenuSection.kt
index b25f9afc0d1e..6fd13e0931aa 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultSettingsPopupMenuSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultSettingsPopupMenuSection.kt
@@ -28,7 +28,7 @@ import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
 import androidx.constraintlayout.widget.ConstraintSet.START
 import androidx.constraintlayout.widget.ConstraintSet.WRAP_CONTENT
 import androidx.core.view.isVisible
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.view.LaunchableLinearLayout
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.flags.FeatureFlags
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt
index 13ef985287f6..a67912017e54 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt
@@ -24,7 +24,7 @@ import androidx.constraintlayout.widget.ConstraintSet.BOTTOM
 import androidx.constraintlayout.widget.ConstraintSet.LEFT
 import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
 import androidx.constraintlayout.widget.ConstraintSet.RIGHT
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusBarSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusBarSection.kt
index d6c69b3c442f..f713d5e312f1 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusBarSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusBarSection.kt
@@ -27,7 +27,7 @@ import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
 import androidx.constraintlayout.widget.ConstraintSet.START
 import androidx.constraintlayout.widget.ConstraintSet.TOP
 import com.android.keyguard.dagger.KeyguardStatusBarViewComponent
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.shared.model.KeyguardSection
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt
index 1cb10bd762a5..1a9f021a7622 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt
@@ -31,7 +31,7 @@ import androidx.constraintlayout.widget.ConstraintSet.START
 import androidx.constraintlayout.widget.ConstraintSet.TOP
 import com.android.keyguard.KeyguardStatusView
 import com.android.keyguard.dagger.KeyguardStatusViewComponent
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.KeyguardViewConfigurator
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeGuidelines.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeGuidelines.kt
index 5e3ea059ddd5..c8697717f1fd 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeGuidelines.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeGuidelines.kt
@@ -20,7 +20,7 @@ package com.android.systemui.keyguard.ui.view.layout.sections
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.constraintlayout.widget.ConstraintSet
 import androidx.constraintlayout.widget.ConstraintSet.VERTICAL
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.keyguard.shared.model.KeyguardSection
 import javax.inject.Inject
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt
index 63d165daa303..33718c410905 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt
@@ -18,7 +18,7 @@ package com.android.systemui.keyguard.ui.viewmodel
 
 import android.content.Context
 import android.content.res.Resources
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
 import com.android.systemui.keyguard.shared.model.SettingsClockSize
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSettingsMenuViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSettingsMenuViewModel.kt
index c36da9da58a5..66ceded2040d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSettingsMenuViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSettingsMenuViewModel.kt
@@ -17,7 +17,7 @@
 
 package com.android.systemui.keyguard.ui.viewmodel
 
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.common.shared.model.Text
 import com.android.systemui.keyguard.domain.interactor.KeyguardLongPressInteractor
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsAodViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsAodViewModel.kt
index 667c2f1bd998..c10a4635644f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsAodViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsAodViewModel.kt
@@ -17,7 +17,7 @@
 package com.android.systemui.keyguard.ui.viewmodel
 
 import android.content.Context
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.keyguard.domain.interactor.BurnInOffsets
 import com.android.systemui.keyguard.domain.interactor.UdfpsKeyguardInteractor
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsLockscreenViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsLockscreenViewModel.kt
index dd586076be83..54abc5bc695f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsLockscreenViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsLockscreenViewModel.kt
@@ -19,7 +19,7 @@ package com.android.systemui.keyguard.ui.viewmodel
 import android.content.Context
 import androidx.annotation.ColorInt
 import com.android.settingslib.Utils.getColorAttrDefaultColor
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.keyguard.domain.interactor.BurnInOffsets
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
diff --git a/packages/SystemUI/src/com/android/systemui/logcat/LogAccessDialogActivity.java b/packages/SystemUI/src/com/android/systemui/logcat/LogAccessDialogActivity.java
index 2cfe5a719f09..d01917a5d0fc 100644
--- a/packages/SystemUI/src/com/android/systemui/logcat/LogAccessDialogActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/logcat/LogAccessDialogActivity.java
@@ -43,7 +43,7 @@ import android.widget.TextView;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.ILogAccessDialogCallback;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
index be487561961c..88bc064c60f7 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
@@ -46,7 +46,7 @@ import com.android.internal.app.chooser.TargetInfo
 import com.android.internal.widget.RecyclerView
 import com.android.internal.widget.RecyclerViewAccessibilityDelegate
 import com.android.internal.widget.ResolverDrawerLayout
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorComponent
 import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorController
 import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorResultHandler
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
index d403788f2c66..4de6278400b3 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
@@ -51,7 +51,7 @@ import android.text.style.StyleSpan;
 import android.util.Log;
 import android.view.Window;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
 import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDevicePolicyResolver;
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/models/GutsViewHolder.kt b/packages/SystemUI/src/com/android/systemui/media/controls/models/GutsViewHolder.kt
index 531506771459..f5f5d388a278 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/models/GutsViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/models/GutsViewHolder.kt
@@ -22,7 +22,7 @@ import android.view.View
 import android.view.ViewGroup
 import android.widget.ImageButton
 import android.widget.TextView
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.media.controls.ui.accentPrimaryFromScheme
 import com.android.systemui.media.controls.ui.surfaceFromScheme
 import com.android.systemui.media.controls.ui.textPrimaryFromScheme
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/models/player/MediaData.kt b/packages/SystemUI/src/com/android/systemui/media/controls/models/player/MediaData.kt
index b7a2522037af..b98e9c232d58 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/models/player/MediaData.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/models/player/MediaData.kt
@@ -21,7 +21,7 @@ import android.graphics.drawable.Drawable
 import android.graphics.drawable.Icon
 import android.media.session.MediaSession
 import com.android.internal.logging.InstanceId
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 /** State of a media view. */
 data class MediaData(
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/models/player/MediaViewHolder.kt b/packages/SystemUI/src/com/android/systemui/media/controls/models/player/MediaViewHolder.kt
index 8b7426336b80..1b14f75d54ef 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/models/player/MediaViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/models/player/MediaViewHolder.kt
@@ -25,7 +25,7 @@ import android.widget.SeekBar
 import android.widget.TextView
 import androidx.constraintlayout.widget.Barrier
 import com.android.internal.widget.CachingIconView
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.media.controls.models.GutsViewHolder
 import com.android.systemui.surfaceeffects.ripple.MultiRippleView
 import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseView
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/models/player/SeekBarObserver.kt b/packages/SystemUI/src/com/android/systemui/media/controls/models/player/SeekBarObserver.kt
index 6eaff3fcb929..3f4f34745c4b 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/models/player/SeekBarObserver.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/models/player/SeekBarObserver.kt
@@ -23,7 +23,7 @@ import androidx.annotation.UiThread
 import androidx.lifecycle.Observer
 import com.android.app.animation.Interpolators
 import com.android.internal.annotations.VisibleForTesting
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.media.controls.ui.SquigglyProgress
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/models/recommendation/RecommendationViewHolder.kt b/packages/SystemUI/src/com/android/systemui/media/controls/models/recommendation/RecommendationViewHolder.kt
index 258284e8af51..8ac8a2da4478 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/models/recommendation/RecommendationViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/models/recommendation/RecommendationViewHolder.kt
@@ -23,7 +23,7 @@ import android.widget.ImageView
 import android.widget.SeekBar
 import android.widget.TextView
 import com.android.internal.widget.CachingIconView
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.media.controls.models.GutsViewHolder
 import com.android.systemui.media.controls.ui.IlluminationDrawable
 import com.android.systemui.util.animation.TransitionLayout
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
index e79fc74ffc86..0f3e0acd007d 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
@@ -60,7 +60,7 @@ import com.android.internal.annotations.Keep
 import com.android.internal.logging.InstanceId
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.Dumpable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDeviceManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDeviceManager.kt
index c90a3c10c6bd..1fe93ed5503d 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDeviceManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDeviceManager.kt
@@ -32,7 +32,7 @@ import com.android.settingslib.bluetooth.LocalBluetoothManager
 import com.android.settingslib.media.LocalMediaManager
 import com.android.settingslib.media.MediaDevice
 import com.android.systemui.Dumpable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.dump.DumpManager
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/IlluminationDrawable.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/IlluminationDrawable.kt
index b9cc772e7136..5aa6824a98b1 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/IlluminationDrawable.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/IlluminationDrawable.kt
@@ -37,7 +37,7 @@ import androidx.annotation.Keep
 import com.android.app.animation.Interpolators
 import com.android.internal.graphics.ColorUtils
 import com.android.internal.graphics.ColorUtils.blendARGB
-import com.android.systemui.R
+import com.android.systemui.res.R
 import org.xmlpull.v1.XmlPullParser
 
 private const val BACKGROUND_ANIM_DURATION = 370L
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/LightSourceDrawable.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/LightSourceDrawable.kt
index 646d1d0ff0fc..6ee072d41ecc 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/LightSourceDrawable.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/LightSourceDrawable.kt
@@ -37,7 +37,7 @@ import android.util.MathUtils.lerp
 import androidx.annotation.Keep
 import com.android.app.animation.Interpolators
 import com.android.internal.graphics.ColorUtils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import org.xmlpull.v1.XmlPullParser
 
 private const val RIPPLE_ANIM_DURATION = 800L
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
index 38a6a8f3470b..e59fc15c3876 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
@@ -38,7 +38,7 @@ import com.android.internal.logging.InstanceId
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.KeyguardUpdateMonitorCallback
 import com.android.systemui.Dumpable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.dump.DumpManager
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandler.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandler.kt
index ec0c40ec69a3..126115294e75 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandler.kt
@@ -29,7 +29,7 @@ import androidx.dynamicanimation.animation.SpringForce
 import com.android.internal.annotations.VisibleForTesting
 import com.android.settingslib.Utils
 import com.android.systemui.Gefingerpoken
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.classifier.Classifier.NOTIFICATION_DISMISS
 import com.android.systemui.media.controls.util.MediaUiEventLogger
 import com.android.systemui.plugins.FalsingManager
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
index a12bc2c99d63..cce4cda8af8a 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
@@ -81,7 +81,7 @@ import com.android.internal.logging.InstanceId;
 import com.android.internal.widget.CachingIconView;
 import com.android.settingslib.widget.AdaptiveIcon;
 import com.android.systemui.ActivityIntentHelper;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.animation.GhostedViewLaunchAnimatorController;
 import com.android.systemui.bluetooth.BroadcastDialogController;
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt
index 0b30e597ab1c..ae3c912d6d1b 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt
@@ -35,7 +35,7 @@ import android.view.ViewGroupOverlay
 import androidx.annotation.VisibleForTesting
 import com.android.app.animation.Interpolators
 import com.android.keyguard.KeyguardViewController
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.dreams.DreamOverlayStateController
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt
index 1dd969f9bea5..b436f5d5a1ef 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt
@@ -20,7 +20,7 @@ import android.content.Context
 import android.content.res.Configuration
 import androidx.annotation.VisibleForTesting
 import androidx.constraintlayout.widget.ConstraintSet
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.media.controls.models.GutsViewHolder
 import com.android.systemui.media.controls.models.player.MediaViewHolder
 import com.android.systemui.media.controls.models.recommendation.RecommendationViewHolder
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaUiEventLogger.kt b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaUiEventLogger.kt
index ea943be85f21..20ea60fa3a5f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaUiEventLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaUiEventLogger.kt
@@ -20,7 +20,7 @@ import com.android.internal.logging.InstanceId
 import com.android.internal.logging.InstanceIdSequence
 import com.android.internal.logging.UiEvent
 import com.android.internal.logging.UiEventLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.media.controls.models.player.MediaData
 import com.android.systemui.media.controls.ui.MediaHierarchyManager
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaItem.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaItem.java
index 875a01087908..fbb84defc372 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaItem.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaItem.java
@@ -19,7 +19,7 @@ package com.android.systemui.media.dialog;
 import androidx.annotation.IntDef;
 
 import com.android.settingslib.media.MediaDevice;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
index 26a7d048cf27..ff9495daaa22 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
@@ -41,7 +41,7 @@ import androidx.recyclerview.widget.RecyclerView;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settingslib.media.LocalMediaManager.MediaDeviceState;
 import com.android.settingslib.media.MediaDevice;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
index d88249830739..5958b0a24a5e 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
@@ -49,7 +49,7 @@ import androidx.recyclerview.widget.RecyclerView;
 
 import com.android.settingslib.media.MediaDevice;
 import com.android.settingslib.utils.ThreadUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.util.List;
 
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
index 3a1d8b0e238e..0c5a14f5720a 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
@@ -58,7 +58,7 @@ import androidx.core.graphics.drawable.IconCompat;
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.broadcast.BroadcastSender;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
 
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialog.java
index 11a16a427c6b..ac64300a6570 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialog.java
@@ -45,7 +45,7 @@ import com.android.internal.annotations.VisibleForTesting;
 import com.android.settingslib.media.BluetoothMediaDevice;
 import com.android.settingslib.media.MediaDevice;
 import com.android.settingslib.qrcode.QrCodeGenerator;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.broadcast.BroadcastSender;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
index 7011ad992a91..426a497fa329 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -78,7 +78,7 @@ import com.android.settingslib.media.InfoMediaManager;
 import com.android.settingslib.media.LocalMediaManager;
 import com.android.settingslib.media.MediaDevice;
 import com.android.settingslib.utils.ThreadUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.broadcast.BroadcastSender;
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
index e5a6bb523916..4640a5d4d801 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
@@ -27,7 +27,7 @@ import androidx.core.graphics.drawable.IconCompat;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.UiEvent;
 import com.android.internal.logging.UiEventLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.broadcast.BroadcastSender;
 import com.android.systemui.dagger.SysUISingleton;
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaSessionReleaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaSessionReleaseDialog.java
index 2680a2ff4567..87c9cd08abc3 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaSessionReleaseDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaSessionReleaseDialog.java
@@ -30,7 +30,7 @@ import android.view.WindowManager;
 import android.widget.Button;
 import android.widget.ImageView;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/media/systemsounds/HomeSoundEffectController.java b/packages/SystemUI/src/com/android/systemui/media/systemsounds/HomeSoundEffectController.java
index 0ba5f28c351f..9de2b4f4a97a 100644
--- a/packages/SystemUI/src/com/android/systemui/media/systemsounds/HomeSoundEffectController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/systemsounds/HomeSoundEffectController.java
@@ -26,7 +26,7 @@ import android.media.AudioManager;
 import android.util.Slog;
 
 import com.android.systemui.CoreStartable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.TaskStackChangeListener;
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt
index b29b5887545a..2f0e1298499c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt
@@ -21,7 +21,7 @@ import android.content.pm.PackageManager
 import android.graphics.drawable.Drawable
 import androidx.annotation.AttrRes
 import androidx.annotation.DrawableRes
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.common.shared.model.TintedIcon
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
index da8e106d3019..6e9485e5947c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
@@ -35,7 +35,7 @@ import android.view.accessibility.AccessibilityManager
 import android.view.View.ACCESSIBILITY_LIVE_REGION_ASSERTIVE
 import android.view.View.ACCESSIBILITY_LIVE_REGION_NONE
 import com.android.internal.widget.CachingIconView
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.app.animation.Interpolators
 import com.android.internal.logging.InstanceId
 import com.android.systemui.common.shared.model.ContentDescription
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverRippleController.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverRippleController.kt
index fbf7e25981da..fbd7fd3fe821 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverRippleController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverRippleController.kt
@@ -20,7 +20,7 @@ import android.content.res.ColorStateList
 import android.view.View
 import android.view.WindowManager
 import com.android.settingslib.Utils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import javax.inject.Inject
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt
index d3efae427cb0..339145c71215 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt
@@ -21,7 +21,7 @@ import android.content.Context
 import android.util.Log
 import androidx.annotation.StringRes
 import com.android.internal.logging.UiEventLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.common.shared.model.Text
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt
index 87d0098805b3..e827a1ec099d 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt
@@ -25,7 +25,7 @@ import com.android.internal.logging.UiEventLogger
 import com.android.internal.statusbar.IUndoMediaTransferCallback
 import com.android.systemui.CoreStartable
 import com.android.systemui.Dumpable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.common.shared.model.Text
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dump.DumpManager
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionBlockerEmptyStateProvider.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionBlockerEmptyStateProvider.kt
index 829b0ddbe3a8..950b695953ab 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionBlockerEmptyStateProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionBlockerEmptyStateProvider.kt
@@ -21,7 +21,7 @@ import com.android.internal.R as AndroidR
 import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyState
 import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyStateProvider
 import com.android.internal.app.ResolverListAdapter
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.mediaprojection.devicepolicy.PersonalProfile
 import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDevicePolicyResolver
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewController.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewController.kt
index cbb7e1d0ef83..fd1a683dc78f 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewController.kt
@@ -26,7 +26,7 @@ import android.view.View
 import android.view.ViewGroup
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorResultHandler
 import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorScope
 import com.android.systemui.mediaprojection.appselector.data.RecentTask
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionTaskView.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionTaskView.kt
index 0c7705467e10..412c006806bf 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionTaskView.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionTaskView.kt
@@ -28,7 +28,7 @@ import android.view.View
 import android.view.WindowManager
 import androidx.core.content.getSystemService
 import androidx.core.content.res.use
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.mediaprojection.appselector.data.RecentTask
 import com.android.systemui.shared.recents.model.ThumbnailData
 import com.android.systemui.shared.recents.utilities.PreviewPositionHelper
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RecentTaskViewHolder.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RecentTaskViewHolder.kt
index a09935b9fb6a..3fe040a0d715 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RecentTaskViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RecentTaskViewHolder.kt
@@ -21,7 +21,7 @@ import android.view.View
 import android.view.ViewGroup
 import android.widget.ImageView
 import androidx.recyclerview.widget.RecyclerView.ViewHolder
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelector
 import com.android.systemui.mediaprojection.appselector.data.AppIconLoader
 import com.android.systemui.mediaprojection.appselector.data.RecentTask
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RecentTasksAdapter.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RecentTasksAdapter.kt
index 6af50a0eb699..78dbd9245d8a 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RecentTasksAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RecentTasksAdapter.kt
@@ -20,7 +20,7 @@ import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import androidx.recyclerview.widget.RecyclerView
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.mediaprojection.appselector.data.RecentTask
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/devicepolicy/ScreenCaptureDisabledDialog.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/devicepolicy/ScreenCaptureDisabledDialog.kt
index a6b3da04ad80..fc452288f86d 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/devicepolicy/ScreenCaptureDisabledDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/devicepolicy/ScreenCaptureDisabledDialog.kt
@@ -16,7 +16,7 @@
 package com.android.systemui.mediaprojection.devicepolicy
 
 import android.content.Context
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.phone.SystemUIDialog
 
 /** Dialog that shows that screen capture is disabled on this device. */
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinator.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinator.kt
index a437139226de..7840da960a83 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinator.kt
@@ -21,7 +21,7 @@ import android.app.NotificationChannel
 import android.app.NotificationManager
 import android.content.Context
 import android.util.Log
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Main
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
index 62b22c50c1dc..cb52a5fb53fa 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
@@ -112,7 +112,7 @@ import com.android.internal.statusbar.LetterboxDetails;
 import com.android.internal.util.LatencyTracker;
 import com.android.internal.view.AppearanceRegion;
 import com.android.systemui.Gefingerpoken;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.DisplayId;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java
index 2a7704f13c3b..c1d98c9daf1d 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java
@@ -36,7 +36,7 @@ import android.widget.Space;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.Dependency;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
 import com.android.systemui.navigationbar.buttons.KeyButtonView;
 import com.android.systemui.navigationbar.buttons.ReverseLinearLayout;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java
index f6bfd6c8f9c5..3ef5094e55ed 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java
@@ -21,7 +21,7 @@ import android.view.LayoutInflater;
 import android.view.View;
 import android.view.WindowManager;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.DisplayId;
 import com.android.systemui.navigationbar.NavigationBarComponent.NavigationBarScope;
 import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java
index 1d73bc205dc4..3e34318a5fb5 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java
@@ -24,7 +24,7 @@ import android.graphics.Rect;
 import android.util.SparseArray;
 import android.view.View;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.navigationbar.NavigationBarComponent.NavigationBarScope;
 import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
 import com.android.systemui.settings.DisplayTracker;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
index 79e7b710c56e..4d6d95a05b1b 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
@@ -62,7 +62,7 @@ import com.android.app.animation.Interpolators;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settingslib.Utils;
 import com.android.systemui.Gefingerpoken;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.model.SysUiState;
 import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
 import com.android.systemui.navigationbar.buttons.ContextualButton;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/ScreenPinningNotify.java b/packages/SystemUI/src/com/android/systemui/navigationbar/ScreenPinningNotify.java
index ac7baf592599..939c09603c22 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/ScreenPinningNotify.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/ScreenPinningNotify.java
@@ -21,7 +21,7 @@ import android.os.SystemClock;
 import android.util.Slog;
 import android.widget.Toast;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysUIToast;
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/DeadZone.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/DeadZone.java
index 9305d0518732..bd3a0c1b0efa 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/DeadZone.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/DeadZone.java
@@ -26,7 +26,7 @@ import android.view.MotionEvent;
 import android.view.Surface;
 
 import com.android.systemui.Dependency;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.navigationbar.NavigationBarController;
 import com.android.systemui.navigationbar.NavigationBarView;
 
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonDrawable.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonDrawable.java
index 702be72ff4ed..686faccc639a 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonDrawable.java
@@ -40,7 +40,7 @@ import android.util.FloatProperty;
 import android.view.View;
 
 import com.android.settingslib.Utils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * Drawable for {@link KeyButtonView}s that supports tinting between two colors, rotation and shows
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java
index 3529142467d5..dcf1a8e98f1c 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java
@@ -58,7 +58,7 @@ import com.android.internal.logging.UiEventLogger;
 import com.android.internal.logging.UiEventLoggerImpl;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.Dependency;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.shared.system.QuickStepContract;
 
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java
index 8ff7b7ae8e59..d780f7c11608 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java
@@ -28,7 +28,7 @@ import android.widget.FrameLayout;
 
 import androidx.annotation.VisibleForTesting;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.util.ArrayList;
 import java.util.Comparator;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index b21b0017208c..3dfd2925a1b2 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -69,7 +69,7 @@ import androidx.annotation.DimenRes;
 
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.internal.policy.GestureNavigationSettingsObserver;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.flags.FeatureFlags;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
index 9ddb78ae19ee..439b7e18e0df 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
@@ -5,7 +5,7 @@ import android.util.TypedValue
 import androidx.core.animation.Interpolator
 import androidx.core.animation.PathInterpolator
 import androidx.dynamicanimation.animation.SpringForce
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 data class EdgePanelParams(private var resources: Resources) {
 
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java
index ff22398cc3be..380846e17a13 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java
@@ -51,7 +51,7 @@ import androidx.dynamicanimation.animation.SpringForce;
 import com.android.app.animation.Interpolators;
 import com.android.internal.util.LatencyTracker;
 import com.android.settingslib.Utils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.plugins.NavigationEdgeBackPlugin;
 import com.android.systemui.settings.DisplayTracker;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java
index 913b65289e12..5a22c385cb51 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java
@@ -28,7 +28,7 @@ import android.view.ContextThemeWrapper;
 import android.view.View;
 
 import com.android.settingslib.Utils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.navigationbar.buttons.ButtonInterface;
 
 public class NavigationHandle extends View implements ButtonInterface {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/QuickswitchOrientedNavHandle.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/QuickswitchOrientedNavHandle.java
index 88622aadd543..b55de279dc28 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/QuickswitchOrientedNavHandle.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/QuickswitchOrientedNavHandle.java
@@ -21,7 +21,7 @@ import android.graphics.Canvas;
 import android.graphics.RectF;
 import android.view.Surface;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /** Temporarily shown view when using QuickSwitch to switch between apps of different rotations */
 public class QuickswitchOrientedNavHandle extends NavigationHandle {
diff --git a/packages/SystemUI/src/com/android/systemui/net/NetworkOverLimitActivity.java b/packages/SystemUI/src/com/android/systemui/net/NetworkOverLimitActivity.java
index be3168c3b208..c2163370b4a1 100644
--- a/packages/SystemUI/src/com/android/systemui/net/NetworkOverLimitActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/net/NetworkOverLimitActivity.java
@@ -33,7 +33,7 @@ import android.os.ServiceManager;
 import android.util.Log;
 import android.view.WindowManager;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * Notify user that a {@link NetworkTemplate} is over its
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
index ea8eb363cc47..093d098de3e3 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
@@ -37,7 +37,7 @@ import android.os.UserManager
 import android.provider.Settings
 import android.widget.Toast
 import androidx.annotation.VisibleForTesting
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.devicepolicy.areKeyguardShortcutsDisabled
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskRoleManagerExt.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskRoleManagerExt.kt
index 63d463402655..9785446d7a43 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskRoleManagerExt.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskRoleManagerExt.kt
@@ -24,7 +24,7 @@ import android.content.pm.ShortcutInfo
 import android.graphics.drawable.Icon
 import android.os.PersistableBundle
 import android.os.UserHandle
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.notetask.shortcut.LaunchNoteTaskActivity
 
 /** Extension functions for [RoleManager] used **internally** by note task. */
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt
index f02d362501d5..6d55d0549d2e 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt
@@ -27,7 +27,7 @@ import android.os.UserManager
 import android.util.Log
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.KeyguardUpdateMonitorCallback
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceTileView.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceTileView.java
index 36b435b04fd6..59c76adb721b 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceTileView.java
@@ -27,7 +27,7 @@ import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * PeopleSpaceTileView renders an individual person's tile with associated status.
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
index c6c9aca0b161..188e8677e4ba 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
@@ -55,7 +55,7 @@ import com.android.internal.logging.UiEventLogger;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.widget.MessagingMessage;
 import com.android.settingslib.utils.ThreadUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
 import com.android.systemui.people.widget.PeopleTileKey;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
index 67e96645f9c5..733383e344b8 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
@@ -74,7 +74,7 @@ import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
 import androidx.core.math.MathUtils;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.people.data.model.PeopleTileModel;
 import com.android.systemui.people.widget.LaunchConversationActivity;
 import com.android.systemui.people.widget.PeopleSpaceWidgetProvider;
diff --git a/packages/SystemUI/src/com/android/systemui/people/ui/view/PeopleViewBinder.kt b/packages/SystemUI/src/com/android/systemui/people/ui/view/PeopleViewBinder.kt
index 46c8d358aaac..c567d56fd424 100644
--- a/packages/SystemUI/src/com/android/systemui/people/ui/view/PeopleViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/people/ui/view/PeopleViewBinder.kt
@@ -31,7 +31,7 @@ import androidx.lifecycle.Lifecycle.State.CREATED
 import androidx.lifecycle.LifecycleOwner
 import androidx.lifecycle.lifecycleScope
 import androidx.lifecycle.repeatOnLifecycle
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.people.PeopleSpaceTileView
 import com.android.systemui.people.ui.viewmodel.PeopleTileViewModel
 import com.android.systemui.people.ui.viewmodel.PeopleViewModel
diff --git a/packages/SystemUI/src/com/android/systemui/people/ui/viewmodel/PeopleViewModel.kt b/packages/SystemUI/src/com/android/systemui/people/ui/viewmodel/PeopleViewModel.kt
index e27bfb34ee3e..ed7c21b787ca 100644
--- a/packages/SystemUI/src/com/android/systemui/people/ui/viewmodel/PeopleViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/people/ui/viewmodel/PeopleViewModel.kt
@@ -23,7 +23,7 @@ import android.content.Intent
 import android.util.Log
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.ViewModelProvider
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.people.PeopleSpaceUtils
 import com.android.systemui.people.PeopleTileViewHelper
diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginsModule.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginsModule.java
index fbf1a0e46ce3..1f66b8407f9e 100644
--- a/packages/SystemUI/src/com/android/systemui/plugins/PluginsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginsModule.java
@@ -21,7 +21,7 @@ import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.Build;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.PluginModule;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.shared.plugins.PluginActionManager;
diff --git a/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningView.java b/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningView.java
index 03d1f15bf379..1cd5d91ef69e 100644
--- a/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningView.java
+++ b/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningView.java
@@ -29,7 +29,7 @@ import android.view.ViewGroup;
 import android.view.WindowManager;
 import android.widget.FrameLayout;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * View that shows a warning shortly before the device goes into sleep
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index a765702a95b2..38204ab1b6d9 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -65,7 +65,7 @@ import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.settingslib.Utils;
 import com.android.settingslib.fuelgauge.BatterySaverUtils;
 import com.android.settingslib.utils.PowerUtil;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SystemUIApplication;
 import com.android.systemui.animation.DialogCuj;
 import com.android.systemui.animation.DialogLaunchAnimator;
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index e1e1aaef6f2f..1534653bc1dd 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -48,7 +48,7 @@ import com.android.internal.annotations.VisibleForTesting;
 import com.android.settingslib.fuelgauge.Estimate;
 import com.android.settingslib.utils.ThreadUtils;
 import com.android.systemui.CoreStartable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
index 310d23407d5d..8e1b00d825aa 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
@@ -26,7 +26,7 @@ import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
 import android.widget.ImageView
 import android.widget.LinearLayout
 import com.android.settingslib.Utils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.view.LaunchableFrameLayout
 import com.android.systemui.statusbar.events.BackgroundAnimatableView
 
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipBuilder.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipBuilder.kt
index eec69f98b9be..4952d8dd8ad8 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipBuilder.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipBuilder.kt
@@ -15,7 +15,7 @@
 package com.android.systemui.privacy
 
 import android.content.Context
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 class PrivacyChipBuilder(private val context: Context, itemsList: List<PrivacyItem>) {
 
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt
index 35a7cf1bf402..ac9a5905782b 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt
@@ -29,7 +29,7 @@ import android.view.WindowInsets
 import android.widget.ImageView
 import android.widget.TextView
 import com.android.settingslib.Utils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.phone.SystemUIDialog
 import java.lang.ref.WeakReference
 import java.util.concurrent.atomic.AtomicBoolean
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogV2.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogV2.kt
index c202f14edc4d..b26ae6cdf0bd 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogV2.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogV2.kt
@@ -40,7 +40,7 @@ import androidx.annotation.WorkerThread
 import androidx.core.view.ViewCompat
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
 import com.android.settingslib.Utils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.ViewHierarchyAnimator
 import com.android.systemui.statusbar.phone.SystemUIDialog
 import com.android.systemui.util.maybeForceFullscreen
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt
index 8b41000d2543..d09fbb379190 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt
@@ -15,7 +15,7 @@
 package com.android.systemui.privacy
 
 import android.content.Context
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 typealias Privacy = PrivacyType
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/DataUsageGraph.java b/packages/SystemUI/src/com/android/systemui/qs/DataUsageGraph.java
index afce69e7f2d0..1b22f9889949 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/DataUsageGraph.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/DataUsageGraph.java
@@ -25,7 +25,7 @@ import android.util.AttributeSet;
 import android.view.View;
 
 import com.android.settingslib.Utils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 public class DataUsageGraph extends View {
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
index a3b901b675ed..6f35cfbfb4a5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
@@ -54,7 +54,7 @@ import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.TASK_MANAGER_
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.TASK_MANAGER_SHOW_USER_VISIBLE_JOBS
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.systemui.Dumpable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.DialogCuj
 import com.android.systemui.animation.DialogLaunchAnimator
 import com.android.systemui.animation.Expandable
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java b/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java
index e822dd58fb98..4770d5272508 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java
@@ -16,7 +16,7 @@ import android.widget.ImageView;
 import androidx.annotation.NonNull;
 
 import com.android.settingslib.Utils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.util.ArrayList;
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index ddd9463affd9..826f75f2f63b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -27,7 +27,7 @@ import androidx.viewpager.widget.ViewPager;
 
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.logging.UiEventLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.qs.QSPanel.QSTileLayout;
 import com.android.systemui.qs.QSPanelControllerBase.TileRecord;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PseudoGridView.java b/packages/SystemUI/src/com/android/systemui/qs/PseudoGridView.java
index 768598af6885..f0404357fab7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PseudoGridView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PseudoGridView.java
@@ -24,7 +24,7 @@ import android.view.View;
 import android.view.ViewGroup;
 import android.widget.BaseAdapter;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.lang.ref.WeakReference;
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index 37e750b86c21..b0f54ee78482 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -28,7 +28,7 @@ import android.view.View;
 import android.widget.FrameLayout;
 
 import com.android.systemui.Dumpable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.qs.customize.QSCustomizer;
 import com.android.systemui.shade.TouchLogger;
 import com.android.systemui.util.LargeScreenUtils;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDualTileLabel.java b/packages/SystemUI/src/com/android/systemui/qs/QSDualTileLabel.java
index 26399d8789aa..235fc0d1f657 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDualTileLabel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDualTileLabel.java
@@ -29,7 +29,7 @@ import android.widget.TextView;
 
 import androidx.annotation.Nullable;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.util.Objects;
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java
index 61905ae00be8..c908e6e2afbe 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java
@@ -35,7 +35,7 @@ import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
 import com.android.settingslib.development.DevelopmentSettingsEnabler;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * Footer of expanded Quick Settings, tiles page indicator, (optionally) build number and
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
index 85f557b10762..ffbd06f64908 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
@@ -23,7 +23,7 @@ import android.view.View;
 import android.widget.TextView;
 import android.widget.Toast;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.qs.dagger.QSScope;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 596d024958b0..fd81e9a5cd0a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -47,7 +47,7 @@ import androidx.lifecycle.LifecycleRegistry;
 import com.android.app.animation.Interpolators;
 import com.android.keyguard.BouncerPanelExpansionCalculator;
 import com.android.systemui.Dumpable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.animation.ShadeInterpolation;
 import com.android.systemui.compose.ComposeFacade;
 import com.android.systemui.dump.DumpManager;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSHost.java
index 4e914a592304..1ab64b76b0dc 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSHost.java
@@ -20,7 +20,7 @@ import android.content.res.Resources;
 import android.os.Build;
 import android.provider.Settings;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.util.leak.GarbageMonitor;
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index b936c41d9295..3227f75ed067 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -39,7 +39,7 @@ import androidx.annotation.VisibleForTesting;
 
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.widget.RemeasuringLinearLayout;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.qs.logging.QSLogger;
 import com.android.systemui.settings.brightness.BrightnessSliderController;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSScrollLayout.java b/packages/SystemUI/src/com/android/systemui/qs/QSScrollLayout.java
index 001cbbac5606..77a5ce34d3ea 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSScrollLayout.java
@@ -26,7 +26,7 @@ import android.widget.LinearLayout;
 
 import androidx.core.widget.NestedScrollView;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.qs.touch.OverScroll;
 import com.android.systemui.qs.touch.SwipeDetector;
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java
index b70b94b00923..5c96e98a4047 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java
@@ -73,7 +73,7 @@ import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
 import com.android.internal.jank.InteractionJankMonitor;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.animation.DialogCuj;
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.animation.Expandable;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
index 4c292e70c111..9a9626d7c7a0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
@@ -31,7 +31,7 @@ import androidx.annotation.Nullable;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.Dumpable;
 import com.android.systemui.ProtoDumpable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dump.nano.SystemUIProtoDump;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index 150137910f91..6c32ed384419 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -25,7 +25,7 @@ import android.widget.LinearLayout;
 
 import com.android.internal.logging.UiEventLogger;
 import com.android.systemui.FontSizeUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.plugins.qs.QSTile;
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java
index 585136ad0789..099d19d8619f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java
@@ -24,7 +24,7 @@ import androidx.annotation.VisibleForTesting;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.UiEventLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.media.controls.ui.MediaHierarchyManager;
 import com.android.systemui.media.controls.ui.MediaHost;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index 691a1a14444a..67c42086364c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -26,7 +26,7 @@ import android.view.View;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.util.LargeScreenUtils;
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/SideLabelTileLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/SideLabelTileLayout.kt
index 1ba11efc49a2..b52554d4e997 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/SideLabelTileLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/SideLabelTileLayout.kt
@@ -18,7 +18,7 @@ package com.android.systemui.qs
 
 import android.content.Context
 import android.util.AttributeSet
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 open class SideLabelTileLayout(
     context: Context,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
index 19bf0188c9d2..9dc6aeebc41c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
@@ -15,7 +15,7 @@ import androidx.annotation.Nullable;
 
 import com.android.internal.logging.UiEventLogger;
 import com.android.systemui.FontSizeUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.qs.QSPanel.QSTileLayout;
 import com.android.systemui.qs.QSPanelControllerBase.TileRecord;
 import com.android.systemui.qs.tileimpl.HeightOverrideable;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
index d511d8aea019..7888f4c7388d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -33,7 +33,7 @@ import androidx.annotation.Nullable;
 import androidx.recyclerview.widget.DefaultItemAnimator;
 import androidx.recyclerview.widget.RecyclerView;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.plugins.qs.QSContainerController;
 import com.android.systemui.qs.QSDetailClipper;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizerController.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizerController.java
index 4002ac3aa120..ce504b2c10a6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizerController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizerController.java
@@ -34,7 +34,7 @@ import androidx.recyclerview.widget.GridLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 
 import com.android.internal.logging.UiEventLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.plugins.qs.QSContainerController;
 import com.android.systemui.plugins.qs.QSTile;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index e8901701c3ac..c9a24d6a4608 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -44,7 +44,7 @@ import androidx.recyclerview.widget.RecyclerView.ViewHolder;
 
 import com.android.internal.logging.UiEventLogger;
 import com.android.systemui.FontSizeUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.qs.QSEditEvent;
 import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.TileLayout;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapterDelegate.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapterDelegate.java
index 1e426adac0b8..92f17f9db0f4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapterDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapterDelegate.java
@@ -23,7 +23,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
 import androidx.core.view.AccessibilityDelegateCompat;
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.util.List;
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
index d9f448493591..a6226b36b0fd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
@@ -33,7 +33,7 @@ import android.widget.Button;
 
 import androidx.annotation.Nullable;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.qs.QSTile;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java
index ce6b8d499ee0..bcd98035a8b9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java
@@ -23,7 +23,7 @@ import android.content.Context;
 import android.view.LayoutInflater;
 import android.view.View;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.RootView;
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.qs.QSContainerImpl;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileColorPicker.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileColorPicker.java
index 1caab5aa77ef..8b6d914d2ad8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileColorPicker.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileColorPicker.java
@@ -21,7 +21,7 @@ import android.service.quicksettings.Tile;
 
 import androidx.annotation.VisibleForTesting;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 public class TileColorPicker {
     @VisibleForTesting static final int[] DISABLE_STATE_SET = {-android.R.attr.state_enabled};
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialog.kt b/packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialog.kt
index d2c51e50c60d..1659c3e673ef 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialog.kt
@@ -22,7 +22,7 @@ import android.view.ContextThemeWrapper
 import android.view.LayoutInflater
 import android.view.ViewGroup
 import android.widget.TextView
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.plugins.qs.QSTile
 import com.android.systemui.plugins.qs.QSTileView
 import com.android.systemui.qs.tileimpl.QSTileImpl
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceRequestController.kt b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceRequestController.kt
index d9e5580fc14c..899d0e2a4e35 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceRequestController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceRequestController.kt
@@ -25,7 +25,7 @@ import android.os.RemoteException
 import android.util.Log
 import androidx.annotation.VisibleForTesting
 import com.android.internal.statusbar.IAddTileResultCallback
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.qs.QSHost
 import com.android.systemui.statusbar.CommandQueue
diff --git a/packages/SystemUI/src/com/android/systemui/qs/footer/data/repository/UserSwitcherRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/footer/data/repository/UserSwitcherRepository.kt
index e969d4c6e08a..5fa75ad68165 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/footer/data/repository/UserSwitcherRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/footer/data/repository/UserSwitcherRepository.kt
@@ -22,7 +22,7 @@ import android.os.Handler
 import android.os.UserManager
 import android.provider.Settings.Global.USER_SWITCHER_ENABLED
 import com.android.keyguard.KeyguardUpdateMonitor
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
 import com.android.systemui.dagger.SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/binder/FooterActionsViewBinder.kt b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/binder/FooterActionsViewBinder.kt
index 3c53d77c6beb..d09b21035cae 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/binder/FooterActionsViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/binder/FooterActionsViewBinder.kt
@@ -30,7 +30,7 @@ import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.LifecycleOwner
 import androidx.lifecycle.lifecycleScope
 import androidx.lifecycle.repeatOnLifecycle
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.ui.binder.IconViewBinder
 import com.android.systemui.dagger.SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt
index 32146b5b00e4..769cb1fe1370 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt
@@ -23,7 +23,7 @@ import androidx.lifecycle.DefaultLifecycleObserver
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.LifecycleOwner
 import com.android.settingslib.Utils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/data/repository/TileSpecRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/data/repository/TileSpecRepository.kt
index 18f59b1f2b28..47c99f25730b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/data/repository/TileSpecRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/data/repository/TileSpecRepository.kt
@@ -21,7 +21,7 @@ import android.content.res.Resources
 import android.database.ContentObserver
 import android.provider.Settings
 import android.util.SparseArray
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingList.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingList.kt
index b1c7433770de..83c8bc3b11fb 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingList.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingList.kt
@@ -18,7 +18,7 @@ package com.android.systemui.qs.pipeline.domain.autoaddable
 
 import android.content.res.Resources
 import android.util.Log
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.qs.pipeline.domain.model.AutoAddable
 import com.android.systemui.qs.pipeline.shared.TileSpec
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddable.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddable.kt
index 58a31bc22a57..88d7f06dfada 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddable.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddable.kt
@@ -20,7 +20,7 @@ import android.content.ComponentName
 import android.content.pm.PackageManager
 import android.content.res.Resources
 import android.text.TextUtils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
index 88c8e81bf1b5..d04e4f52ac4d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
@@ -34,7 +34,7 @@ import android.widget.ImageView;
 import android.widget.ImageView.ScaleType;
 
 import com.android.settingslib.Utils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.plugins.qs.QSIconView;
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.plugins.qs.QSTile.State;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
index 966d94161f91..5a9c0a1893f8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
@@ -44,7 +44,7 @@ import android.widget.TextView
 import androidx.annotation.VisibleForTesting
 import com.android.settingslib.Utils
 import com.android.systemui.FontSizeUtils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.LaunchableView
 import com.android.systemui.animation.LaunchableViewDelegate
 import com.android.systemui.plugins.qs.QSIconView
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt
index f672e518f0b3..168fa088cff2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt
@@ -15,7 +15,7 @@
  */
 package com.android.systemui.qs.tileimpl
 
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 /** Return the subtitle resource Id of the given tile. */
 object SubtitleArrayMapping {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
index 30765f7f974d..fb71cefe8e0a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
@@ -36,7 +36,7 @@ import androidx.annotation.Nullable;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt
index c709969ec6e2..d98141fcd6b9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt
@@ -13,7 +13,7 @@ import android.view.View
 import androidx.annotation.VisibleForTesting
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.internal.logging.MetricsLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.ActivityLaunchAnimator
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
index 9f10e6f1f2c6..18d472b9c755 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
@@ -29,7 +29,7 @@ import androidx.annotation.Nullable;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.ActivityStarter;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 83b09bebee69..1be514db44c4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -39,7 +39,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settingslib.Utils;
 import com.android.settingslib.bluetooth.BluetoothUtils;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.ActivityStarter;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CameraToggleTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CameraToggleTile.java
index 65ef6b9c31a5..b393f39719e7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CameraToggleTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CameraToggleTile.java
@@ -30,7 +30,7 @@ import androidx.annotation.DrawableRes;
 import androidx.annotation.NonNull;
 
 import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.ActivityStarter;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index e9a242847362..5c6e9028545a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -38,7 +38,7 @@ import com.android.internal.app.MediaRouteDialogPresenter;
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.animation.DialogCuj;
 import com.android.systemui.animation.DialogLaunchAnimator;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorCorrectionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorCorrectionTile.java
index cf9e3468c8f5..ee57b2b62d49 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorCorrectionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorCorrectionTile.java
@@ -28,8 +28,8 @@ import android.widget.Switch;
 import androidx.annotation.Nullable;
 
 import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.R;
-import com.android.systemui.R.drawable;
+import com.android.systemui.res.R;
+import com.android.systemui.res.R.drawable;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.ActivityStarter;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
index 4ecde6123dd5..993ada6b86aa 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -29,8 +29,8 @@ import androidx.annotation.Nullable;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.R;
-import com.android.systemui.R.drawable;
+import com.android.systemui.res.R;
+import com.android.systemui.res.R.drawable;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.ActivityStarter;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
index e769b5ef9989..ccf7afbe7016 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
@@ -28,7 +28,7 @@ import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.Prefs;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.animation.DialogCuj;
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.dagger.qualifiers.Background;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataUsageDetailView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataUsageDetailView.java
index 55785586464f..c15289fddb20 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataUsageDetailView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataUsageDetailView.java
@@ -28,7 +28,7 @@ import android.widget.TextView;
 import com.android.settingslib.Utils;
 import com.android.settingslib.net.DataUsageController;
 import com.android.systemui.FontSizeUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.qs.DataUsageGraph;
 
 import java.text.DecimalFormat;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
index ddaff3bb9a64..91b2d971c004 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
@@ -25,7 +25,7 @@ import android.view.View
 import androidx.annotation.VisibleForTesting
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.internal.logging.MetricsLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.ActivityLaunchAnimator
 import com.android.systemui.controls.ControlsServiceInfo
 import com.android.systemui.controls.dagger.ControlsComponent
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 9bb192b4c271..0617b30eb8fa 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -45,7 +45,7 @@ import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settingslib.notification.EnableZenModeDialog;
 import com.android.systemui.Prefs;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.animation.DialogCuj;
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.dagger.qualifiers.Background;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DreamTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DreamTile.java
index b5e6a0f5c60b..a08b3fca15aa 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DreamTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DreamTile.java
@@ -38,7 +38,7 @@ import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
 import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
index 2c986da8370a..9fab51fd931e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -29,7 +29,7 @@ import androidx.annotation.Nullable;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.ActivityStarter;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FontScalingTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/FontScalingTile.kt
index 1f9979a8b37c..64e3f16abec3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FontScalingTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FontScalingTile.kt
@@ -22,7 +22,7 @@ import android.provider.Settings
 import android.view.View
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.internal.logging.MetricsLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.accessibility.fontscaling.FontScalingDialog
 import com.android.systemui.animation.DialogCuj
 import com.android.systemui.animation.DialogLaunchAnimator
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index 7c76c1ae1bf5..9ee417e98d2d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -33,7 +33,7 @@ import androidx.annotation.Nullable;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settingslib.wifi.WifiEnterpriseRestrictionUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.ActivityStarter;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
index fb2f2ced1d3a..1b504a81a651 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
@@ -41,7 +41,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settingslib.graph.SignalDrawable;
 import com.android.settingslib.mobile.TelephonyIcons;
 import com.android.settingslib.net.DataUsageController;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.ActivityStarter;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTileNewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTileNewImpl.kt
index 956e7ab6d7ab..8103152dda37 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTileNewImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTileNewImpl.kt
@@ -22,7 +22,7 @@ import android.os.Looper
 import android.provider.Settings
 import android.view.View
 import com.android.internal.logging.MetricsLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.plugins.ActivityStarter
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index 8b69f614dedd..9ddcf2953491 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -29,7 +29,7 @@ import androidx.annotation.Nullable;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.ActivityStarter;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/MicrophoneToggleTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/MicrophoneToggleTile.java
index 86a6a8c6a2b6..7a7dbbc79558 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/MicrophoneToggleTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/MicrophoneToggleTile.java
@@ -30,7 +30,7 @@ import androidx.annotation.DrawableRes;
 import androidx.annotation.NonNull;
 
 import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.ActivityStarter;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
index 29ccb76de820..a239c28f4342 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
@@ -34,7 +34,7 @@ import androidx.annotation.Nullable;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
index 405e1394871c..7e0fa07d951f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
@@ -36,7 +36,7 @@ import androidx.annotation.StringRes;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.NightDisplayListenerModule;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/OneHandedModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/OneHandedModeTile.java
index 5b0237f87153..78af97668fc0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/OneHandedModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/OneHandedModeTile.java
@@ -28,7 +28,7 @@ import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.ActivityStarter;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QRCodeScannerTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/QRCodeScannerTile.java
index 1ba377bc9702..f70e27d72d69 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QRCodeScannerTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/QRCodeScannerTile.java
@@ -27,7 +27,7 @@ import androidx.annotation.Nullable;
 
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
index e382eca17369..3a247c5843d4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
@@ -42,7 +42,7 @@ import androidx.annotation.Nullable;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java
index 2e04afb0048a..b9d902afb891 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java
@@ -30,7 +30,7 @@ import androidx.annotation.Nullable;
 
 import com.android.internal.R;
 import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.R.drawable;
+import com.android.systemui.res.R.drawable;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.ActivityStarter;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
index 2d9f7dd038bc..ea162fa2921f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
@@ -36,7 +36,7 @@ import androidx.annotation.Nullable;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.ActivityStarter;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
index 2d4652db6b80..959afd86ee8d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
@@ -30,7 +30,7 @@ import androidx.annotation.Nullable;
 
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.animation.DialogCuj;
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.dagger.qualifiers.Background;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyToggleTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyToggleTile.java
index 7c4f097a1724..5832217f3e85 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyToggleTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyToggleTile.java
@@ -31,7 +31,7 @@ import androidx.annotation.DrawableRes;
 import androidx.annotation.Nullable;
 
 import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.ActivityStarter;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java
index 9ffcba62ad09..300cc564939d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java
@@ -31,7 +31,7 @@ import androidx.annotation.Nullable;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.ActivityStarter;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java
index 5840a3ddf44d..7426615a7f1a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java
@@ -32,7 +32,7 @@ import androidx.annotation.Nullable;
 
 import com.android.internal.util.ArrayUtils;
 import com.android.systemui.FontSizeUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.phone.UserAvatarView;
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
index b6b657ec82f6..32deb30d926b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
@@ -34,7 +34,7 @@ import com.android.internal.logging.UiEventLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.drawable.CircleFramedDrawable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.qs.PseudoGridView;
 import com.android.systemui.qs.QSUserSwitcherEvent;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
index c8c3c30a7302..7a9384a4bba4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
@@ -32,7 +32,7 @@ import androidx.annotation.Nullable;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.ActivityStarter;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetAdapter.java
index 176983e4b444..b866dda80134 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetAdapter.java
@@ -36,7 +36,7 @@ import androidx.recyclerview.widget.RecyclerView;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settingslib.Utils;
 import com.android.settingslib.wifi.WifiUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.wifitrackerlib.WifiEntry;
 
 import java.util.List;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
index c67078ff9093..2350b5dce8b8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
@@ -59,7 +59,7 @@ import com.android.internal.logging.UiEvent;
 import com.android.internal.logging.UiEventLogger;
 import com.android.settingslib.wifi.WifiEnterpriseRestrictionUtils;
 import com.android.systemui.Prefs;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.accessibility.floatingmenu.AnnotationLinkSpan;
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.dagger.SysUISingleton;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
index f026d20b23b1..f516f5521d25 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
@@ -75,7 +75,7 @@ import com.android.settingslib.mobile.TelephonyIcons;
 import com.android.settingslib.net.SignalStrengthUtil;
 import com.android.settingslib.wifi.WifiUtils;
 import com.android.settingslib.wifi.dpp.WifiDppIntentHelper;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.broadcast.BroadcastDispatcher;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt b/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt
index 4c9c99cc16f0..acd7510a6c2a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt
@@ -26,7 +26,7 @@ import android.view.LayoutInflater
 import androidx.annotation.VisibleForTesting
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.internal.logging.UiEventLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.DialogCuj
 import com.android.systemui.animation.DialogLaunchAnimator
 import com.android.systemui.animation.Expandable
diff --git a/packages/SystemUI/src/com/android/systemui/reardisplay/RearDisplayDialogController.java b/packages/SystemUI/src/com/android/systemui/reardisplay/RearDisplayDialogController.java
index 6912114140b0..4b21e447ebf5 100644
--- a/packages/SystemUI/src/com/android/systemui/reardisplay/RearDisplayDialogController.java
+++ b/packages/SystemUI/src/com/android/systemui/reardisplay/RearDisplayDialogController.java
@@ -29,7 +29,7 @@ import android.widget.LinearLayout;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.CoreStartable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.statusbar.CommandQueue;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsModule.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsModule.java
index f57bfad890ff..77a4b9f72cd8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsModule.java
@@ -18,7 +18,7 @@ package com.android.systemui.recents;
 
 import android.content.Context;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.ContextComponentHelper;
 
 import dagger.Binds;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
index 3577c00a7d0a..3e574e788494 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
@@ -54,7 +54,7 @@ import android.widget.TextView;
 import androidx.annotation.NonNull;
 
 import com.android.systemui.CoreStartable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.navigationbar.NavigationBarController;
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt
index 3e766073f720..3fb886d46890 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt
@@ -27,7 +27,7 @@ import androidx.core.view.isVisible
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.lifecycleScope
 import androidx.lifecycle.repeatOnLifecycle
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.compose.ComposeFacade
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.scene.shared.model.Scene
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootView.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootView.kt
index ef688a8e4337..7cff7ff1fd71 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootView.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootView.kt
@@ -25,7 +25,7 @@ import android.view.View
 import android.view.WindowInsets
 import android.widget.FrameLayout
 import androidx.core.view.updateMargins
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.compose.ComposeFacade
 
 /** A view that can serve as the root of the main SysUI window. */
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/BaseScreenSharePermissionDialog.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/BaseScreenSharePermissionDialog.kt
index 8dd25bc78746..64006fe4c265 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/BaseScreenSharePermissionDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/BaseScreenSharePermissionDialog.kt
@@ -32,7 +32,7 @@ import androidx.annotation.ColorRes
 import androidx.annotation.DrawableRes
 import androidx.annotation.LayoutRes
 import androidx.annotation.StringRes
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.phone.SystemUIDialog
 
 /** Base permission dialog for screen share and recording */
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/MediaProjectionPermissionDialog.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/MediaProjectionPermissionDialog.kt
index 8cbc4aab3bd3..47e28d86e01d 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/MediaProjectionPermissionDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/MediaProjectionPermissionDialog.kt
@@ -18,7 +18,7 @@ package com.android.systemui.screenrecord
 import android.content.Context
 import android.media.projection.MediaProjectionConfig
 import android.os.Bundle
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 /** Dialog to select screen recording options */
 class MediaProjectionPermissionDialog(
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
index 2c4555a2378a..7cdb6553c47e 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
@@ -41,7 +41,7 @@ import android.widget.Toast;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.UiEventLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.LongRunning;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.media.MediaProjectionCaptureTarget;
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java
index 91e3b60a2cf5..f0ce8a465d0d 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java
@@ -41,7 +41,7 @@ import android.widget.TextView;
 
 import androidx.annotation.Nullable;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.media.MediaProjectionCaptureTarget;
 import com.android.systemui.settings.UserContextProvider;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt
index 56d732eb230b..b5b7043e37a0 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt
@@ -32,7 +32,7 @@ import android.widget.ArrayAdapter
 import android.widget.Spinner
 import android.widget.Switch
 import androidx.annotation.LayoutRes
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.media.MediaProjectionAppSelectorActivity
 import com.android.systemui.media.MediaProjectionCaptureTarget
 import com.android.systemui.plugins.ActivityStarter
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordingAdapter.java b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordingAdapter.java
index 9962c914b476..eb58b2f1a112 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordingAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordingAdapter.java
@@ -25,7 +25,7 @@ import android.widget.ArrayAdapter;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.util.List;
 
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentCreator.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentCreator.kt
index ab2a8d9c6e95..8e9769ab7d0e 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentCreator.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentCreator.kt
@@ -23,7 +23,7 @@ import android.content.ContentProvider
 import android.content.Context
 import android.content.Intent
 import android.net.Uri
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 object ActionIntentCreator {
     /** @return a chooser intent to share the given URI. */
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java b/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
index 6f2256eb6b31..2f411ea3cb33 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
@@ -45,7 +45,7 @@ import androidx.customview.widget.ExploreByTouchHelper;
 import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
 
 import com.android.internal.graphics.ColorUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.util.List;
 
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/DraggableConstraintLayout.java b/packages/SystemUI/src/com/android/systemui/screenshot/DraggableConstraintLayout.java
index bdbc470a61f1..b55bba9f2279 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/DraggableConstraintLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/DraggableConstraintLayout.java
@@ -36,7 +36,7 @@ import android.view.ViewTreeObserver;
 
 import androidx.constraintlayout.widget.ConstraintLayout;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * ConstraintLayout that is draggable when touched in a specific region
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
index bf536a475fd4..9325e18abce7 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
@@ -44,7 +44,7 @@ import androidx.constraintlayout.widget.ConstraintLayout;
 import com.android.internal.app.ChooserActivity;
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.view.OneShotPreDrawListener;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.flags.FeatureFlags;
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/MagnifierView.java b/packages/SystemUI/src/com/android/systemui/screenshot/MagnifierView.java
index 78737329750a..0c543cd8909c 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/MagnifierView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/MagnifierView.java
@@ -34,7 +34,7 @@ import android.view.ViewPropertyAnimator;
 import androidx.annotation.Nullable;
 
 import com.android.internal.graphics.ColorUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * MagnifierView shows a full-res cropped circular display of a given ImageTileSet, contents and
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/MessageContainerController.kt b/packages/SystemUI/src/com/android/systemui/screenshot/MessageContainerController.kt
index b4ffabd78b8a..5cbea90580a1 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/MessageContainerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/MessageContainerController.kt
@@ -10,7 +10,7 @@ import android.view.ViewGroup.MarginLayoutParams
 import android.view.ViewTreeObserver
 import android.view.animation.AccelerateDecelerateInterpolator
 import androidx.constraintlayout.widget.Guideline
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/OverlayActionChip.java b/packages/SystemUI/src/com/android/systemui/screenshot/OverlayActionChip.java
index 9e8ea3aaec56..0588fe2bba82 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/OverlayActionChip.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/OverlayActionChip.java
@@ -29,7 +29,7 @@ import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
index cfd9a4930304..31086d85f747 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
@@ -47,7 +47,7 @@ import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.screenshot.ScreenshotController.SavedImageData.ActionTransition;
 
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index 87f6e4472d48..f08eb143efb4 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -92,7 +92,7 @@ import com.android.internal.app.ChooserActivity;
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.policy.PhoneWindow;
 import com.android.settingslib.applications.InterestingConfigChanges;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.broadcast.BroadcastSender;
 import com.android.systemui.clipboardoverlay.ClipboardOverlayController;
 import com.android.systemui.dagger.qualifiers.Main;
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotDetectionController.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotDetectionController.kt
index 253f07de7b3c..be39d2edf1ea 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotDetectionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotDetectionController.kt
@@ -24,7 +24,7 @@ import android.view.IWindowManager
 import android.view.ViewGroup
 import android.view.WindowManager
 import android.widget.TextView
-import com.android.systemui.R
+import com.android.systemui.res.R
 import javax.inject.Inject
 
 class ScreenshotDetectionController
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java
index 35f2a39e02ae..4344fd1a7567 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java
@@ -30,7 +30,7 @@ import android.util.DisplayMetrics;
 import android.view.WindowManager;
 
 import com.android.internal.messages.nano.SystemMessageProto;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SystemUIApplication;
 import com.android.systemui.util.NotificationChannels;
 
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotServiceErrorReceiver.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotServiceErrorReceiver.java
index 522f729a25d6..070fb1eef99a 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotServiceErrorReceiver.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotServiceErrorReceiver.java
@@ -21,7 +21,7 @@ import android.content.Context;
 import android.content.Intent;
 import android.view.WindowManager;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * Performs a number of miscellaneous, non-system-critical actions
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
index 03e1e15c5210..31c928406aac 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
@@ -86,7 +86,7 @@ import androidx.constraintlayout.widget.ConstraintLayout;
 
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.logging.UiEventLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
 import com.android.systemui.shared.system.InputChannelCompat;
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
index 32df5121b0b8..0be2265bf8fa 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
@@ -53,7 +53,7 @@ import android.widget.Toast;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.util.ScreenshotRequest;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.flags.FeatureFlags;
 
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/WorkProfileMessageController.kt b/packages/SystemUI/src/com/android/systemui/screenshot/WorkProfileMessageController.kt
index 798c4908e467..c801ca5aa8a1 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/WorkProfileMessageController.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/WorkProfileMessageController.kt
@@ -28,7 +28,7 @@ import android.view.View
 import android.view.ViewGroup
 import android.widget.ImageView
 import android.widget.TextView
-import com.android.systemui.R
+import com.android.systemui.res.R
 import javax.inject.Inject
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java
index 2f96f6c656c4..aa23d6bed5e1 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java
@@ -51,7 +51,7 @@ import androidx.lifecycle.ViewModelProvider;
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.logging.UiEventLogger.UiEventEnum;
 import com.android.settingslib.Utils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.screenshot.CropView;
 import com.android.systemui.settings.UserTracker;
 
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsService.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsService.java
index dce8c81c3462..06c0b8b6e769 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsService.java
@@ -37,7 +37,7 @@ import android.os.IBinder;
 import androidx.annotation.Nullable;
 
 import com.android.internal.statusbar.IAppClipsService;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Application;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.wm.shell.bubbles.Bubbles;
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java
index 6e5cef47400f..a31b30195fe9 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java
@@ -48,7 +48,7 @@ import com.android.internal.infra.AndroidFuture;
 import com.android.internal.infra.ServiceConnector;
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.statusbar.IAppClipsService;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.broadcast.BroadcastSender;
 import com.android.systemui.dagger.qualifiers.Application;
 import com.android.systemui.dagger.qualifiers.Background;
diff --git a/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseDialog.kt b/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseDialog.kt
index 71c5fad5322e..9d1278fd58e6 100644
--- a/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseDialog.kt
@@ -9,7 +9,7 @@ import android.view.View
 import android.view.WindowManager
 import android.widget.ImageView
 import com.android.internal.widget.DialogTitle
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.phone.SystemUIDialog
 
 class SensorUseDialog(
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java
index 38b1f14e45de..6783afa3eb9d 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java
@@ -35,7 +35,7 @@ import android.widget.FrameLayout;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
 import com.android.systemui.util.concurrency.DelayableExecutor;
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderController.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderController.java
index d0d37c4e685f..7415b7882c70 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderController.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderController.java
@@ -28,7 +28,7 @@ import androidx.annotation.Nullable;
 import com.android.internal.logging.UiEventLogger;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.systemui.Gefingerpoken;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.classifier.Classifier;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.statusbar.policy.BrightnessMirrorController;
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java
index 38cb441a4f8c..c88549224183 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java
@@ -33,7 +33,7 @@ import androidx.annotation.Nullable;
 
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.systemui.Gefingerpoken;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * {@code FrameLayout} used to show and manipulate a {@link ToggleSeekBar}.
diff --git a/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManagerImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManagerImpl.kt
index a9b3d0a1f3aa..b2e473685daa 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManagerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManagerImpl.kt
@@ -18,7 +18,7 @@ package com.android.systemui.shade
 
 import android.view.ViewGroup
 import androidx.constraintlayout.widget.ConstraintSet
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt
index 5850a846eed6..14659e7909ab 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt
@@ -18,7 +18,7 @@ package com.android.systemui.shade
 
 import android.content.Context
 import android.view.ViewGroup
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.statusbar.StatusBarState.SHADE
 import com.android.systemui.statusbar.StatusBarState.SHADE_LOCKED
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 92ccdb5abf84..d5934e614d4e 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -114,7 +114,7 @@ import com.android.keyguard.dagger.KeyguardUserSwitcherComponent;
 import com.android.systemui.DejankUtils;
 import com.android.systemui.Dumpable;
 import com.android.systemui.Gefingerpoken;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.animation.LaunchAnimator;
 import com.android.systemui.biometrics.AuthController;
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
index 2dbcbc9e0f22..c803e6f0c9f3 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
@@ -48,7 +48,7 @@ import android.view.WindowManagerGlobal;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.Dumpable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.dagger.SysUISingleton;
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
index 96fae14cec60..6cf4ff569662 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
@@ -36,7 +36,7 @@ import com.android.keyguard.KeyguardMessageAreaController;
 import com.android.keyguard.LockIconViewController;
 import com.android.keyguard.dagger.KeyguardBouncerComponent;
 import com.android.systemui.Dumpable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.back.domain.interactor.BackActionInteractor;
 import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor;
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt
index 3873ac47040d..cc46b23ec75f 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt
@@ -26,7 +26,7 @@ import androidx.constraintlayout.widget.ConstraintSet.END
 import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
 import androidx.constraintlayout.widget.ConstraintSet.START
 import androidx.constraintlayout.widget.ConstraintSet.TOP
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.flags.FeatureFlags
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQuickSettingsContainer.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQuickSettingsContainer.java
index 292cf8ec1d98..af44c4e36315 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQuickSettingsContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQuickSettingsContainer.java
@@ -32,7 +32,7 @@ import androidx.annotation.Nullable;
 import androidx.constraintlayout.widget.ConstraintLayout;
 import androidx.constraintlayout.widget.ConstraintSet;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.statusbar.notification.AboveShelfObserver;
diff --git a/packages/SystemUI/src/com/android/systemui/shade/QsBatteryModeController.kt b/packages/SystemUI/src/com/android/systemui/shade/QsBatteryModeController.kt
index 3eec7fa0e84a..1fcb70c6bc95 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/QsBatteryModeController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/QsBatteryModeController.kt
@@ -2,7 +2,7 @@ package com.android.systemui.shade
 
 import android.content.Context
 import android.view.DisplayCutout
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.battery.BatteryMeterView
 import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
index d653cb4fa9d7..e8be40eaf3fe 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
@@ -65,7 +65,7 @@ import com.android.keyguard.FaceAuthApiRequestReason;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.DejankUtils;
 import com.android.systemui.Dumpable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.classifier.Classifier;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dump.DumpManager;
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt
index 19a4ee8ef6a0..25bd8e7446bc 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt
@@ -38,7 +38,7 @@ import androidx.core.view.doOnLayout
 import com.android.app.animation.Interpolators
 import com.android.settingslib.Utils
 import com.android.systemui.Dumpable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.ShadeInterpolation
 import com.android.systemui.battery.BatteryMeterView
 import com.android.systemui.battery.BatteryMeterViewController
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt
index 3f7512a25732..38b358ff927e 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt
@@ -22,7 +22,7 @@ import android.os.Handler
 import android.view.LayoutInflater
 import android.view.ViewStub
 import androidx.constraintlayout.motion.widget.MotionLayout
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.battery.BatteryMeterView
 import com.android.systemui.battery.BatteryMeterViewController
 import com.android.systemui.biometrics.AuthRippleView
diff --git a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrier.java b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrier.java
index 8612cdf12c6e..6ca0ad47a0a7 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrier.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrier.java
@@ -33,7 +33,7 @@ import androidx.annotation.VisibleForTesting;
 import com.android.settingslib.Utils;
 import com.android.settingslib.graph.SignalDrawable;
 import com.android.systemui.FontSizeUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.pipeline.mobile.ui.view.ModernShadeCarrierGroupMobileView;
 import com.android.systemui.util.LargeScreenUtils;
 
diff --git a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroup.java b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroup.java
index 68561d1cfd0f..e84fb485829c 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroup.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroup.java
@@ -24,7 +24,7 @@ import android.widget.LinearLayout;
 import android.widget.TextView;
 
 import com.android.systemui.FontSizeUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * Displays Carrier name and network status in the shade header
diff --git a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java
index 98d8a53b83c8..3349345b1391 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java
@@ -39,7 +39,7 @@ import androidx.annotation.VisibleForTesting;
 import com.android.keyguard.CarrierTextManager;
 import com.android.settingslib.AccessibilityContentDescriptions;
 import com.android.settingslib.mobile.TelephonyIcons;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModel.kt
index c6c664dbdcf0..51276c6560a4 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModel.kt
@@ -22,7 +22,7 @@ import android.content.IntentFilter
 import android.icu.text.DateFormat
 import android.icu.text.DisplayContext
 import android.os.UserHandle
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java b/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java
index ba92c451f764..f54d0e70e3c7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java
@@ -25,7 +25,7 @@ import android.view.View;
 import android.widget.ImageView;
 import android.widget.RemoteViews.RemoteView;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 @RemoteView
 public class AnimatedImageView extends ImageView {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BatteryStatusChip.kt b/packages/SystemUI/src/com/android/systemui/statusbar/BatteryStatusChip.kt
index 520976746785..2281ea02aaf8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BatteryStatusChip.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BatteryStatusChip.kt
@@ -23,7 +23,7 @@ import android.view.View
 import android.widget.FrameLayout
 import android.widget.LinearLayout
 import com.android.settingslib.Utils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.battery.BatteryMeterView
 import com.android.systemui.statusbar.events.BackgroundAnimatableView
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt b/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
index a0cbdf3e3e01..6bbd4a504471 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
@@ -29,7 +29,7 @@ import android.view.SurfaceControl
 import android.view.ViewRootImpl
 import androidx.annotation.VisibleForTesting
 import com.android.systemui.Dumpable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.dump.DumpManager
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CastDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/CastDrawable.java
index 2f385d04c793..b1acc64d7fa8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CastDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CastDrawable.java
@@ -24,7 +24,7 @@ import android.graphics.drawable.Drawable;
 import android.graphics.drawable.DrawableWrapper;
 import android.util.AttributeSet;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ConnectedDisplayChip.kt b/packages/SystemUI/src/com/android/systemui/statusbar/ConnectedDisplayChip.kt
index 76636ab8e5f3..4c0f6f0cc672 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ConnectedDisplayChip.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ConnectedDisplayChip.kt
@@ -19,7 +19,7 @@ import android.content.Context
 import android.content.res.Configuration
 import android.util.AttributeSet
 import android.widget.FrameLayout
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.events.BackgroundAnimatableView
 
 /** Chip that appears in the status bar when an external display is connected. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java
index c1ebf1236def..d24f9d8f476c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java
@@ -19,7 +19,7 @@ package com.android.systemui.statusbar;
 import android.view.View;
 
 import com.android.app.animation.Interpolators;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java
index 24c66eb5d442..33c42e043901 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java
@@ -29,7 +29,7 @@ import android.widget.TextView;
 
 import androidx.annotation.NonNull;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.notification.row.StackScrollerDecorView;
 import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java
index 4d933d9ad21e..0715dfca8507 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java
@@ -26,7 +26,7 @@ import android.widget.TextView;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.keyguard.AlphaOptimizedLinearLayout;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry.OnSensitivityChangedListener;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ImmersiveModeConfirmation.java b/packages/SystemUI/src/com/android/systemui/statusbar/ImmersiveModeConfirmation.java
index a7ec02ff43c3..95768e55de34 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ImmersiveModeConfirmation.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ImmersiveModeConfirmation.java
@@ -74,7 +74,7 @@ import android.widget.FrameLayout;
 import android.widget.ImageView;
 
 import com.android.systemui.CoreStartable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.shared.system.TaskStackChangeListener;
 import com.android.systemui.shared.system.TaskStackChangeListeners;
 import com.android.systemui.util.settings.SecureSettings;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutAppItemLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutAppItemLayout.java
index 5377deef337e..3e854a40251b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutAppItemLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutAppItemLayout.java
@@ -23,7 +23,7 @@ import android.widget.ImageView;
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * Layout used for displaying keyboard shortcut items inside an alert dialog.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
index ec66e994b58a..68c48b9a261f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
@@ -70,7 +70,7 @@ import com.android.internal.app.AssistUtils;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settingslib.Utils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import com.google.android.material.bottomsheet.BottomSheetBehavior;
 import com.google.android.material.bottomsheet.BottomSheetDialog;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
index ae3d41e19b5f..61eaff9c2f8e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
@@ -67,7 +67,7 @@ import com.android.internal.app.AssistUtils;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settingslib.Utils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.util.ArrayList;
 import java.util.Collections;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
index 1a32d70a9745..1198d1baeaee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
@@ -39,7 +39,7 @@ import android.view.animation.Interpolator;
 import android.widget.ImageView;
 
 import com.android.app.animation.Interpolators;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.wm.shell.animation.FlingAnimationUtils;
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index feb02586a820..98e5124f7736 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -84,7 +84,7 @@ import com.android.keyguard.TrustGrantFlags;
 import com.android.keyguard.logging.KeyguardLogger;
 import com.android.settingslib.Utils;
 import com.android.settingslib.fuelgauge.BatteryStatus;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.biometrics.FaceHelpMessageDeferral;
 import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
@@ -309,7 +309,7 @@ public class KeyguardIndicationController {
         mFaceAcquiredMessageDeferral = faceHelpMessageDeferral;
         mCoExFaceAcquisitionMsgIdsToShow = new HashSet<>();
         int[] msgIds = context.getResources().getIntArray(
-                com.android.systemui.R.array.config_face_help_msgs_when_fingerprint_enrolled);
+                com.android.systemui.res.R.array.config_face_help_msgs_when_fingerprint_enrolled);
         for (int msgId : msgIds) {
             mCoExFaceAcquisitionMsgIdsToShow.add(msgId);
         }
@@ -704,7 +704,7 @@ public class KeyguardIndicationController {
                             .setTextColor(Utils.getColorAttr(
                                     mContext, com.android.internal.R.attr.textColorOnAccent))
                             .setBackground(mContext.getDrawable(
-                                    com.android.systemui.R.drawable.logout_button_background))
+                                    com.android.systemui.res.R.drawable.logout_button_background))
                             .setClickListener((view) -> {
                                 if (mFalsingManager.isFalseTap(LOW_PENALTY)) {
                                     return;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt
index 238317cfc99e..62c9980c336c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt
@@ -3,7 +3,7 @@ package com.android.systemui.statusbar
 import android.content.Context
 import android.util.IndentingPrintWriter
 import android.util.MathUtils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.media.controls.ui.MediaHierarchyManager
 import com.android.systemui.shade.ShadeViewController
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionController.kt
index 5f3d75786973..4d0552e7cb31 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionController.kt
@@ -21,7 +21,7 @@ import android.util.IndentingPrintWriter
 import android.util.MathUtils
 import androidx.annotation.FloatRange
 import androidx.annotation.Px
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.plugins.qs.QS
 import com.android.systemui.statusbar.policy.ConfigurationController
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeScrimTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeScrimTransitionController.kt
index af4a1aa98d9e..77a09608dbd3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeScrimTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeScrimTransitionController.kt
@@ -3,7 +3,7 @@ package com.android.systemui.statusbar
 import android.content.Context
 import android.util.IndentingPrintWriter
 import android.util.MathUtils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.statusbar.phone.ScrimController
 import com.android.systemui.statusbar.policy.ConfigurationController
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
index 29ca0f438aac..143e620abfa1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
@@ -16,7 +16,7 @@ import androidx.annotation.VisibleForTesting
 import com.android.systemui.Dumpable
 import com.android.systemui.ExpandHelper
 import com.android.systemui.Gefingerpoken
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.biometrics.UdfpsKeyguardViewControllerLegacy
 import com.android.systemui.classifier.Classifier
 import com.android.systemui.classifier.FalsingCollector
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index 8089fd94f7db..befc64d07426 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -48,7 +48,7 @@ import androidx.annotation.Nullable;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.statusbar.NotificationVisibility;
 import com.android.systemui.Dumpable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.power.domain.interactor.PowerInteractor;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index c760227aa124..09ad55e005d4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -37,7 +37,7 @@ import androidx.annotation.NonNull;
 import com.android.app.animation.Interpolators;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.policy.SystemBarUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.animation.ShadeInterpolation;
 import com.android.systemui.flags.Flags;
 import com.android.systemui.flags.ViewRefactorFlag;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
index 2c0741ecf986..3640ae067537 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
@@ -31,7 +31,7 @@ import androidx.annotation.VisibleForTesting
 import com.android.app.animation.Interpolators
 import com.android.systemui.Dumpable
 import com.android.systemui.Gefingerpoken
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.classifier.Classifier.NOTIFICATION_DRAG_DOWN
 import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.dagger.SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ScreenRecordDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/ScreenRecordDrawable.java
index 006b219d8e61..2b7e9c55ee4e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ScreenRecordDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ScreenRecordDrawable.java
@@ -26,7 +26,7 @@ import android.graphics.drawable.Drawable;
 import android.graphics.drawable.DrawableWrapper;
 import android.util.AttributeSet;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScroller.kt b/packages/SystemUI/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScroller.kt
index f1e51e21a9e5..603e863f9a10 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScroller.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScroller.kt
@@ -3,7 +3,7 @@ package com.android.systemui.statusbar
 import android.content.Context
 import android.content.res.Configuration
 import android.util.MathUtils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.app.animation.Interpolators
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
 import com.android.systemui.statusbar.policy.ConfigurationController
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScroller.kt b/packages/SystemUI/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScroller.kt
index 3d574caf3192..e47c914341a6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScroller.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScroller.kt
@@ -7,7 +7,7 @@ import android.content.res.Configuration
 import android.util.MathUtils
 import android.view.animation.PathInterpolator
 import com.android.internal.annotations.VisibleForTesting
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.app.animation.Interpolators
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.plugins.qs.QS
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index fbbee53468c5..8baab25e5c59 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -57,7 +57,7 @@ import com.android.app.animation.Interpolators;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.internal.util.ContrastColorUtil;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.notification.NotificationIconDozeHelper;
 import com.android.systemui.statusbar.notification.NotificationUtils;
 import com.android.systemui.util.drawable.DrawableSize;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
index 99297b21c9a0..e632214bcb2b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
@@ -43,7 +43,7 @@ import com.android.internal.logging.UiEventLogger;
 import com.android.keyguard.KeyguardClockSwitch;
 import com.android.systemui.DejankUtils;
 import com.android.systemui.Dumpable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ViewTransformationHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/ViewTransformationHelper.java
index 67ab0601cbf8..092e5b4c0e2c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ViewTransformationHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ViewTransformationHelper.java
@@ -26,7 +26,7 @@ import android.view.ViewGroup;
 import android.view.animation.Interpolator;
 
 import com.android.app.animation.Interpolators;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.notification.TransformState;
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/EthernetIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/EthernetIcons.java
index 196aad99dcb5..9734e262369d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/EthernetIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/EthernetIcons.java
@@ -16,7 +16,7 @@
 
 package com.android.systemui.statusbar.connectivity;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 class EthernetIcons {
     static final int[][] ETHERNET_ICONS = {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java
index c523d22456f6..d6df987ba5a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java
@@ -43,7 +43,7 @@ import com.android.settingslib.mobile.MobileStatusTracker.MobileStatus;
 import com.android.settingslib.mobile.MobileStatusTracker.SubscriptionDefaults;
 import com.android.settingslib.mobile.TelephonyIcons;
 import com.android.settingslib.net.SignalStrengthUtil;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy;
 import com.android.systemui.util.CarrierConfigTracker;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java
index f381b3792f68..9db61c6b3ba2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java
@@ -61,7 +61,7 @@ import com.android.settingslib.mobile.MobileStatusTracker.SubscriptionDefaults;
 import com.android.settingslib.mobile.TelephonyIcons;
 import com.android.settingslib.net.DataUsageController;
 import com.android.systemui.Dumpable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Background;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiSignalController.java
index f84b96c94a91..08defcce4b7c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiSignalController.java
@@ -34,7 +34,7 @@ import com.android.settingslib.SignalIcon.MobileIconGroup;
 import com.android.settingslib.graph.SignalDrawable;
 import com.android.settingslib.mobile.TelephonyIcons;
 import com.android.settingslib.wifi.WifiStatusTracker;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Background;
 
 import java.io.PrintWriter;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt
index 80274bde6ce2..4056e7b89c2c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt
@@ -16,7 +16,7 @@
 package com.android.systemui.statusbar.core
 
 import android.app.Fragment
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.fragments.FragmentHostManager
 import com.android.systemui.statusbar.phone.PhoneStatusBarTransitions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
index d1e0a7193948..5af7cfc212d5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
@@ -25,7 +25,7 @@ import android.view.Gravity
 import android.view.View
 import android.widget.FrameLayout
 import com.android.internal.annotations.GuardedBy
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.app.animation.Interpolators
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
index 1ad4620f9dfa..dccc23f61092 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
@@ -31,7 +31,7 @@ import androidx.core.animation.AnimatorListenerAdapter
 import androidx.core.animation.AnimatorSet
 import androidx.core.animation.ValueAnimator
 import com.android.internal.annotations.VisibleForTesting
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.statusbar.phone.StatusBarContentInsetsChangedListener
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt
index 2403920e69f9..7d866df73da9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt
@@ -20,7 +20,7 @@ import android.annotation.IntRange
 import android.content.Context
 import android.provider.DeviceConfig
 import android.provider.DeviceConfig.NAMESPACE_PRIVACY
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractor
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
index d667b91ea5ab..0190d5c9759b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
@@ -39,7 +39,7 @@ import android.view.ViewGroup
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.settingslib.Utils
 import com.android.systemui.Dumpable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/AnimatableProperty.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/AnimatableProperty.java
index fcff4376811e..8cefc56d135a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/AnimatableProperty.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/AnimatableProperty.java
@@ -20,7 +20,7 @@ import android.util.FloatProperty;
 import android.util.Property;
 import android.view.View;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.util.function.BiConsumer;
 import java.util.function.Function;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/AssistantFeedbackController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/AssistantFeedbackController.java
index 420dd3f0e464..24088d2dabfa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/AssistantFeedbackController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/AssistantFeedbackController.java
@@ -155,17 +155,17 @@ public class AssistantFeedbackController {
         int feedbackStatus = getFeedbackStatus(entry);
         switch (feedbackStatus) {
             case STATUS_ALERTED:
-                return com.android.systemui.R.string.notification_channel_summary_automatic_alerted;
+                return com.android.systemui.res.R.string.notification_channel_summary_automatic_alerted;
             case STATUS_SILENCED:
-                return com.android.systemui.R.string
+                return com.android.systemui.res.R.string
                         .notification_channel_summary_automatic_silenced;
             case STATUS_PROMOTED:
-                return com.android.systemui.R.string
+                return com.android.systemui.res.R.string
                         .notification_channel_summary_automatic_promoted;
             case STATUS_DEMOTED:
-                return com.android.systemui.R.string.notification_channel_summary_automatic_demoted;
+                return com.android.systemui.res.R.string.notification_channel_summary_automatic_demoted;
             default:
-                return com.android.systemui.R.string.notification_channel_summary_automatic;
+                return com.android.systemui.res.R.string.notification_channel_summary_automatic;
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/FakeShadowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/FakeShadowView.java
index 0c1891e1fde9..f3067c1042e0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/FakeShadowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/FakeShadowView.java
@@ -25,7 +25,7 @@ import android.view.ViewGroup;
 import android.view.ViewOutlineProvider;
 import android.widget.LinearLayout;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.AlphaOptimizedFrameLayout;
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java
index b09b9f42e6af..2ffbe4bd4521 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java
@@ -22,7 +22,7 @@ import android.view.View;
 import android.widget.ImageView;
 
 import com.android.app.animation.Interpolators;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.CrossFadeHelper;
 import com.android.systemui.statusbar.TransformableView;
 import com.android.systemui.statusbar.notification.row.HybridNotificationView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
index 11582d7e3cc8..ad9e312e3c39 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
@@ -49,7 +49,7 @@ import android.util.Pair;
 import com.android.internal.messages.nano.SystemMessageProto;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.systemui.CoreStartable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dagger.qualifiers.UiBackground;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingImageTransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingImageTransformState.java
index 2ee21539ca1d..1f4f04cf85e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingImageTransformState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingImageTransformState.java
@@ -20,7 +20,7 @@ import android.util.Pools;
 import android.view.View;
 
 import com.android.internal.widget.MessagingImageMessage;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.ViewTransformationHelper;
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
index a0456985e8d9..167efc784ff5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
@@ -25,7 +25,7 @@ import android.view.View;
 import android.widget.ImageView;
 
 import com.android.app.animation.Interpolators;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
 
 import java.util.function.Consumer;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationIconDozeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationIconDozeHelper.java
index 43e45b14cfbe..552bfb288d7a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationIconDozeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationIconDozeHelper.java
@@ -24,7 +24,7 @@ import android.graphics.PorterDuffColorFilter;
 import android.graphics.drawable.Drawable;
 import android.widget.ImageView;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 public class NotificationIconDozeHelper extends NotificationDozeHelper {
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java
index fb712108a787..eb1be6772b99 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java
@@ -23,7 +23,7 @@ import android.view.View;
 import android.widget.ImageView;
 
 import com.android.internal.util.ContrastColorUtil;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.notification.collection.ListEntry;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.util.Compile;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/Roundable.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/Roundable.kt
index 8029f48152f4..328a74100e48 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/Roundable.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/Roundable.kt
@@ -3,7 +3,7 @@ package com.android.systemui.statusbar.notification
 import android.util.FloatProperty
 import android.view.View
 import androidx.annotation.FloatRange
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.flags.ViewRefactorFlag
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
index 90eb630949fa..aa7a63e90854 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
@@ -27,7 +27,7 @@ import com.android.app.animation.Interpolators;
 import com.android.internal.widget.MessagingImageMessage;
 import com.android.internal.widget.MessagingPropertyAnimator;
 import com.android.internal.widget.ViewClippingUtil;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.CrossFadeHelper;
 import com.android.systemui.statusbar.TransformableView;
 import com.android.systemui.statusbar.ViewTransformationHelper;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ViewGroupFadeHelper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ViewGroupFadeHelper.kt
index 1b43922f652a..af4df321953f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ViewGroupFadeHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ViewGroupFadeHelper.kt
@@ -21,7 +21,7 @@ import android.animation.AnimatorListenerAdapter
 import android.animation.ValueAnimator
 import android.view.View
 import android.view.ViewGroup
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.app.animation.Interpolators
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt
index 93a34afc9fc9..94cc7e9d1a9f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt
@@ -17,7 +17,7 @@
 package com.android.systemui.statusbar.notification.collection.coordinator
 
 import android.content.Context
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.notification.AssistantFeedbackController
 import com.android.systemui.statusbar.notification.collection.ListEntry
 import com.android.systemui.statusbar.notification.collection.NotifPipeline
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionHeaderVisibilityProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionHeaderVisibilityProvider.kt
index 82c7aae08f6a..6b70a0807b86 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionHeaderVisibilityProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionHeaderVisibilityProvider.kt
@@ -17,7 +17,7 @@
 package com.android.systemui.statusbar.notification.collection.provider
 
 import android.content.Context
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import javax.inject.Inject
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/MediaContainerController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/MediaContainerController.kt
index 8de03819ec32..70fabc0587d4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/MediaContainerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/MediaContainerController.kt
@@ -19,7 +19,7 @@ package com.android.systemui.statusbar.notification.collection.render
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.statusbar.notification.stack.MediaContainerView
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/SectionHeaderController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/SectionHeaderController.kt
index 49990d9c559e..c2b6f3277ffb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/SectionHeaderController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/SectionHeaderController.kt
@@ -21,7 +21,7 @@ import android.content.Intent
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.statusbar.notification.dagger.HeaderClickAction
 import com.android.systemui.statusbar.notification.dagger.HeaderText
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt
index 75801a8db65d..ca43591e0776 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt
@@ -18,7 +18,7 @@ package com.android.systemui.statusbar.notification.dagger
 
 import android.annotation.StringRes
 import android.provider.Settings
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.statusbar.notification.collection.render.NodeController
 import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
index 5664a2af7c0e..8ee0de691557 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
@@ -20,7 +20,7 @@ import android.content.Context;
 
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.systemui.CoreStartable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.UiBackground;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt
index 98e167f84781..84678aa2ee23 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt
@@ -27,7 +27,7 @@ import android.util.Log
 import android.view.View
 import android.widget.ImageView
 import com.android.internal.statusbar.StatusBarIcon
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.statusbar.StatusBarIconView
 import com.android.systemui.statusbar.notification.InflationException
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt
index 26dfe3edf793..a54687c6c46b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt
@@ -30,7 +30,7 @@ import com.android.app.animation.Interpolators
 import com.android.internal.statusbar.StatusBarIcon
 import com.android.internal.util.ContrastColorUtil
 import com.android.settingslib.Utils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.demomode.DemoMode
 import com.android.systemui.demomode.DemoModeController
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index cb21291dae1b..c61258b5e0ec 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -36,7 +36,7 @@ import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.jank.InteractionJankMonitor.Configuration;
 import com.android.settingslib.Utils;
 import com.android.systemui.Gefingerpoken;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.NotificationShelf;
 import com.android.systemui.statusbar.notification.FakeShadowView;
 import com.android.systemui.statusbar.notification.NotificationUtils;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt
index 0de3246e01fa..4114eb2a7896 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt
@@ -38,7 +38,7 @@ import android.view.WindowInsets.Type.statusBars
 import android.view.WindowManager
 import android.widget.TextView
 import com.android.internal.annotations.VisibleForTesting
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import javax.inject.Inject
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorListView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorListView.kt
index 9c4aa072a83d..2cfd075a17a9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorListView.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorListView.kt
@@ -37,7 +37,7 @@ import android.widget.Switch
 import android.widget.TextView
 import com.android.settingslib.Utils
 
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.util.Assert
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index acece33f0b93..fb8024c88191 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -73,7 +73,7 @@ import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.util.ContrastColorUtil;
 import com.android.internal.widget.CachingIconView;
 import com.android.internal.widget.CallLayout;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
 import com.android.systemui.flags.ViewRefactorFlag;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragController.java
index b95018777fea..77f5717d0e91 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragController.java
@@ -48,7 +48,7 @@ import androidx.annotation.VisibleForTesting;
 import com.android.app.animation.Interpolators;
 import com.android.internal.logging.InstanceId;
 import com.android.internal.logging.InstanceIdSequence;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.shade.ShadeController;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.notification.logging.NotificationPanelLogger;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
index c8f13a6302cd..259923170477 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
@@ -28,7 +28,7 @@ import android.util.IndentingPrintWriter;
 import android.view.View;
 import android.view.ViewOutlineProvider;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.flags.Flags;
 import com.android.systemui.flags.ViewRefactorFlag;
 import com.android.systemui.statusbar.notification.RoundableState;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
index c4c116ba0613..5aae48899bc9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
@@ -34,7 +34,7 @@ import androidx.annotation.Nullable;
 
 import com.android.app.animation.Interpolators;
 import com.android.systemui.Dumpable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.StatusBarIconView;
 import com.android.systemui.statusbar.notification.Roundable;
 import com.android.systemui.statusbar.notification.RoundableState;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FeedbackInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FeedbackInfo.java
index 3f4fd5006408..42c80ed22717 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FeedbackInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FeedbackInfo.java
@@ -43,7 +43,7 @@ import android.widget.TextView;
 
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.systemui.Dependency;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.statusbar.notification.AssistantFeedbackController;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
index 0989df61a5e3..26db5f2bc095 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
@@ -34,7 +34,7 @@ import android.widget.TextView;
 import androidx.annotation.NonNull;
 
 import com.android.settingslib.Utils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
 import com.android.systemui.statusbar.notification.stack.ViewState;
 import com.android.systemui.util.DumpUtilsKt;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java
index 99a24cb3e9ca..43d99a0e03f2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java
@@ -27,7 +27,7 @@ import android.widget.ImageView;
 import android.widget.TextView;
 
 import com.android.internal.widget.ConversationLayout;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.notification.NotificationFadeAware;
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridGroupManager.java
index 3e10f2ad52e5..ddd9bddc7375 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridGroupManager.java
@@ -31,7 +31,7 @@ import android.view.ViewGroup;
 import android.widget.TextView;
 
 import com.android.internal.widget.ConversationLayout;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * A class managing hybrid groups that include {@link HybridNotificationView} and the notification
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java
index ce6dd893cb69..892a63505a71 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java
@@ -30,7 +30,7 @@ import androidx.annotation.ColorInt;
 
 import com.android.internal.util.ContrastColorUtil;
 import com.android.keyguard.AlphaOptimizedLinearLayout;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.CrossFadeHelper;
 import com.android.systemui.statusbar.TransformableView;
 import com.android.systemui.statusbar.ViewTransformationHelper;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
index 1fd4d12c06ca..b95e053ae508 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
@@ -33,7 +33,7 @@ import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
 import com.android.systemui.Dumpable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.io.PrintWriter;
 import java.util.Arrays;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
index f805183d52aa..f186e665f773 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
@@ -41,7 +41,7 @@ import android.widget.RemoteViews;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.widget.ImageMessageConsumer;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.media.controls.util.MediaFeatureFlag;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index 065828bee746..a27a305428c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -45,7 +45,7 @@ import androidx.annotation.MainThread;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.statusbar.IStatusBarService;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.statusbar.RemoteInputController;
 import com.android.systemui.statusbar.SmartReplyController;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
index 7134f15d4fec..62b268b90cf3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
@@ -65,7 +65,7 @@ import android.widget.TextView;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settingslib.notification.ConversationIconFactory;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java
index 047db2046529..b86d1d934269 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java
@@ -35,7 +35,7 @@ import androidx.annotation.Nullable;
 
 import com.android.app.animation.Interpolators;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index 44ead26de012..1dd3739d0e84 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -46,7 +46,7 @@ import com.android.internal.logging.UiEventLogger;
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settingslib.notification.ConversationIconFactory;
 import com.android.systemui.CoreStartable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
index 99a77550cc76..d8f31d4fb8a2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
@@ -60,7 +60,7 @@ import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.Dependency;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.notification.AssistantFeedbackController;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
index 5a129fccff06..a317f95c9e65 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
@@ -41,7 +41,7 @@ import android.widget.FrameLayout.LayoutParams;
 
 import com.android.app.animation.Interpolators;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.statusbar.AlphaOptimizedImageView;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java
index d5d7f75fbaa1..3443da19895e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java
@@ -49,7 +49,7 @@ import com.android.app.animation.Interpolators;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PartialConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PartialConversationInfo.java
index ac97e77f84a2..06c3b7951db3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PartialConversationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PartialConversationInfo.java
@@ -34,7 +34,7 @@ import android.widget.LinearLayout;
 import android.widget.TextView;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 
 import java.util.Set;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java
index 6feffe654630..8e974c24dd0c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java
@@ -23,7 +23,7 @@ import android.view.ViewGroup;
 
 import androidx.asynclayoutinflater.view.AsyncLayoutInflater;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.InflationTask;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCallTemplateViewWrapper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCallTemplateViewWrapper.kt
index bb43b95357db..2d946945597e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCallTemplateViewWrapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCallTemplateViewWrapper.kt
@@ -20,7 +20,7 @@ import android.content.Context
 import android.view.View
 import com.android.internal.widget.CachingIconView
 import com.android.internal.widget.CallLayout
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.notification.NotificationFadeAware
 import com.android.systemui.statusbar.notification.NotificationUtils
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
index 10753f215103..b4411f1a33a5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
@@ -25,7 +25,7 @@ import com.android.internal.widget.ConversationLayout
 import com.android.internal.widget.MessagingGroup
 import com.android.internal.widget.MessagingImageMessage
 import com.android.internal.widget.MessagingLinearLayout
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.notification.NotificationFadeAware
 import com.android.systemui.statusbar.notification.NotificationUtils
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapper.java
index fdff12d22354..45c35d8ff8d1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapper.java
@@ -21,7 +21,7 @@ import android.graphics.Color;
 import android.view.View;
 
 import com.android.internal.graphics.ColorUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.notification.NotificationFadeAware;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
index 87205e2df9c3..bd7f766c6860 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
@@ -37,7 +37,7 @@ import androidx.annotation.Nullable;
 import com.android.app.animation.Interpolators;
 import com.android.internal.widget.CachingIconView;
 import com.android.internal.widget.NotificationExpandButton;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.TransformableView;
 import com.android.systemui.statusbar.ViewTransformationHelper;
 import com.android.systemui.statusbar.notification.CustomInterpolatorTransformation;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMessagingTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMessagingTemplateViewWrapper.java
index 4592fde69a93..ba1deede65a6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMessagingTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMessagingTemplateViewWrapper.java
@@ -26,7 +26,7 @@ import com.android.internal.widget.MessagingGroup;
 import com.android.internal.widget.MessagingImageMessage;
 import com.android.internal.widget.MessagingLayout;
 import com.android.internal.widget.MessagingLinearLayout;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.TransformableView;
 import com.android.systemui.statusbar.ViewTransformationHelper;
 import com.android.systemui.statusbar.notification.NotificationUtils;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
index 199692bc3b79..875a409c07f0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
@@ -39,7 +39,7 @@ import androidx.annotation.Nullable;
 import com.android.internal.util.ContrastColorUtil;
 import com.android.internal.widget.NotificationActionListLayout;
 import com.android.systemui.Dependency;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.UiOffloadThread;
 import com.android.systemui.statusbar.CrossFadeHelper;
 import com.android.systemui.statusbar.TransformableView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
index 38a368e1fdc8..cb671447bbb4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
@@ -26,7 +26,7 @@ import android.util.MathUtils;
 import androidx.annotation.VisibleForTesting;
 
 import com.android.systemui.Dumpable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.shade.transition.LargeScreenShadeInterpolator;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java
index d73bbebe40b4..33473a6f6b0a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java
@@ -23,7 +23,7 @@ import android.animation.ValueAnimator;
 import android.view.View;
 
 import com.android.app.animation.Interpolators;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MediaContainerView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MediaContainerView.kt
index a8d8a8e03ed5..5d46f52dba87 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MediaContainerView.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MediaContainerView.kt
@@ -22,7 +22,7 @@ import android.graphics.Canvas
 import android.graphics.Path
 import android.graphics.RectF
 import android.util.AttributeSet
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.notification.row.ExpandableView
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index 626f851d9d11..a929e4f3ea7f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -42,7 +42,7 @@ import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.widget.NotificationExpandButton;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.CrossFadeHelper;
 import com.android.systemui.statusbar.NotificationGroupingUtil;
 import com.android.systemui.statusbar.notification.FeedbackIcon;
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 757ae6d9bd80..28f0a0c5fd78 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
@@ -86,7 +86,7 @@ import com.android.settingslib.Utils;
 import com.android.systemui.Dependency;
 import com.android.systemui.Dumpable;
 import com.android.systemui.ExpandHelper;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
 import com.android.systemui.flags.ViewRefactorFlag;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
index 24104d2f37e1..30708b708f25 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
@@ -20,7 +20,7 @@ import android.content.res.Resources
 import android.util.Log
 import android.view.View.GONE
 import androidx.annotation.VisibleForTesting
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.media.controls.pipeline.MediaDataManager
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java
index baf09c70f936..722c28c43e8a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java
@@ -28,7 +28,7 @@ import android.view.ViewGroup;
 import android.widget.ImageView;
 import android.widget.TextView;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.notification.row.StackScrollerDecorView;
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index 90e10a766cbc..f2d5394e0aee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -27,7 +27,7 @@ import android.view.ViewGroup;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.policy.SystemBarUtils;
 import com.android.keyguard.BouncerPanelExpansionCalculator;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.animation.ShadeInterpolation;
 import com.android.systemui.shade.transition.LargeScreenShadeInterpolator;
 import com.android.systemui.statusbar.EmptyShadeView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
index 2742a23d5fad..4e81d0c7cbdc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
@@ -24,7 +24,7 @@ import android.view.View;
 
 import com.android.app.animation.Interpolators;
 import com.android.keyguard.KeyguardSliceView;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.shared.clocks.AnimatableClockView;
 import com.android.systemui.statusbar.NotificationShelf;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java
index f4605be2b9c5..f097d068e903 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java
@@ -28,7 +28,7 @@ import android.view.animation.Interpolator;
 
 import com.android.app.animation.Interpolators;
 import com.android.systemui.Dumpable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.notification.AnimatableProperty;
 import com.android.systemui.statusbar.notification.NotificationFadeAware.FadeOptimizedNotification;
 import com.android.systemui.statusbar.notification.PropertyAnimator;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractor.kt
index 51b6c75f44b0..57cea5d3b31e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractor.kt
@@ -18,7 +18,7 @@
 package com.android.systemui.statusbar.notification.stack.domain.interactor
 
 import android.content.Context
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.common.ui.data.repository.ConfigurationRepository
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.statusbar.policy.SplitShadeStateController
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/SharedNotificationContainer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/SharedNotificationContainer.kt
index e52d604d7b02..b4f578fec910 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/SharedNotificationContainer.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/SharedNotificationContainer.kt
@@ -28,7 +28,7 @@ import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
 import androidx.constraintlayout.widget.ConstraintSet.START
 import androidx.constraintlayout.widget.ConstraintSet.TOP
 import androidx.constraintlayout.widget.ConstraintSet.VERTICAL
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 /**
  * Container for the stack scroller, so that the bounds can be externally specified, such as from
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt
index 45ae4e0afc3a..dee3973edb55 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt
@@ -17,7 +17,7 @@
 package com.android.systemui.statusbar.notification.stack.ui.viewbinder
 
 import android.view.LayoutInflater
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.statusbar.NotificationShelf
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
index baeae79f4d7d..07d3a1cf24c0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
@@ -30,7 +30,7 @@ import android.view.View
 import android.view.WindowManager
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.ActivityIntentHelper
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.ActivityLaunchAnimator
 import com.android.systemui.animation.ActivityLaunchAnimator.PendingIntentStarter
 import com.android.systemui.animation.DelegateLaunchAnimatorController
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
index 5eafa9e97088..697d2978db0c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
@@ -28,7 +28,7 @@ import android.os.UserHandle;
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.NightDisplayListenerModule;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.plugins.qs.QSTile;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
index 459071280a1e..f62a79f199e9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
@@ -35,7 +35,7 @@ import android.view.View;
 
 import com.android.app.animation.Interpolators;
 import com.android.settingslib.Utils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
index 3b9afa1a5eab..023efdd9a2e2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -47,7 +47,7 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.keyguard.KeyguardViewController;
 import com.android.keyguard.logging.BiometricUnlockLogger;
 import com.android.systemui.Dumpable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
index c9db153ff280..485ab3262725 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
@@ -47,7 +47,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.statusbar.LetterboxDetails;
 import com.android.internal.view.AppearanceRegion;
 import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.camera.CameraIntents;
 import com.android.systemui.dagger.SysUISingleton;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index 6b260ff77b3c..3a8850408f18 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -121,7 +121,7 @@ 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.res.R;
 import com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuController;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.assist.AssistManager;
@@ -2049,7 +2049,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
         }
 
         mPowerButtonReveal = new PowerButtonReveal(mContext.getResources().getDimensionPixelSize(
-                com.android.systemui.R.dimen.physical_power_button_center_screen_location_y));
+                com.android.systemui.res.R.dimen.physical_power_button_center_screen_location_y));
     }
 
     private void logStateToEventlog() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
index 374543dd0c58..de9854afdba1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
@@ -28,7 +28,7 @@ import android.view.ViewGroup;
 import android.widget.LinearLayout;
 
 import com.android.internal.statusbar.StatusBarIcon;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.demomode.DemoMode;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index ae715b3f20c8..7730f7d99f51 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -37,7 +37,7 @@ import androidx.annotation.VisibleForTesting;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.systemui.Dumpable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandableIndicator.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandableIndicator.java
index efc289185cfa..92b0f3f26258 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandableIndicator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandableIndicator.java
@@ -19,7 +19,7 @@ import android.graphics.drawable.AnimatedVectorDrawable;
 import android.util.AttributeSet;
 import android.widget.ImageView;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 public class ExpandableIndicator extends ImageView {
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
index a1f12b896d3b..270c40e801cd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
@@ -26,7 +26,7 @@ import androidx.annotation.NonNull;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.widget.ViewClippingUtil;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.shade.ShadeHeadsUpTracker;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
index 4f0cd80ab5ab..a5ea1426164b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
@@ -30,7 +30,7 @@ import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.policy.SystemBarUtils;
 import com.android.systemui.Dumpable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.kt
index 5de0d15ee7d6..25e634a03ef7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.kt
@@ -24,7 +24,7 @@ import android.view.WindowInsets
 import android.widget.FrameLayout
 import androidx.annotation.StringRes
 import com.android.keyguard.LockIconViewController
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.keyguard.ui.binder.KeyguardBottomAreaViewBinder
 import com.android.systemui.keyguard.ui.binder.KeyguardBottomAreaViewBinder.bind
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
index 924aac4e70be..430b0e9fab72 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
@@ -22,7 +22,7 @@ import android.content.pm.PackageManager
 import android.hardware.biometrics.BiometricSourceType
 import android.provider.Settings
 import com.android.systemui.Dumpable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.plugins.statusbar.StatusBarStateController
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
index fc3c85a0807b..fb5a530e3875 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -26,7 +26,7 @@ import android.util.MathUtils;
 import com.android.app.animation.Interpolators;
 import com.android.keyguard.BouncerPanelExpansionCalculator;
 import com.android.keyguard.KeyguardStatusView;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.shade.ShadeViewController;
 import com.android.systemui.statusbar.policy.KeyguardUserSwitcherListView;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java
index 29a249fcaa41..c6690c91c1f8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java
@@ -32,7 +32,7 @@ import androidx.annotation.StyleRes;
 
 import com.android.app.animation.Interpolators;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.keyguard.KeyguardIndication;
 
 /**
@@ -296,6 +296,6 @@ public class KeyguardIndicationTextView extends TextView {
 
     private int getYTranslationPixels() {
         return mContext.getResources().getDimensionPixelSize(
-                com.android.systemui.R.dimen.keyguard_indication_y_translation);
+                com.android.systemui.res.R.dimen.keyguard_indication_y_translation);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
index 914e0c0af358..7efa705b7929 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -43,7 +43,7 @@ import android.widget.TextView;
 import androidx.annotation.VisibleForTesting;
 
 import com.android.settingslib.Utils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.battery.BatteryMeterView;
 import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
 import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher.DarkChange;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
index 16413d2ef33a..fc9ecb3f14d6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
@@ -42,7 +42,7 @@ import com.android.keyguard.CarrierTextController;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.keyguard.logging.KeyguardLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.battery.BatteryMeterViewController;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.flags.FeatureFlags;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImpl.java
index d22ed3802eed..4bfce4cc173a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImpl.java
@@ -34,7 +34,7 @@ import com.android.app.animation.Interpolators;
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.internal.util.ContrastColorUtil;
 import com.android.settingslib.Utils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.demomode.DemoMode;
 import com.android.systemui.demomode.DemoModeController;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
index 46a2457670b0..572b7f12a8bf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -33,7 +33,7 @@ import android.view.ViewTreeObserver.OnPreDrawListener;
 
 import com.android.app.animation.Interpolators;
 import com.android.internal.graphics.ColorUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.KeyguardAffordanceView;
 
 import java.lang.annotation.Retention;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
index 365fbace1608..ec7767bca544 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
@@ -24,7 +24,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.Button;
 import android.widget.FrameLayout;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * Container for image of the multi user switcher (tappable).
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index 3770c1df77ff..7cbaf63bc6db 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -39,7 +39,7 @@ import androidx.collection.ArrayMap;
 import com.android.app.animation.Interpolators;
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.settingslib.Utils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.StatusBarIconView;
 import com.android.systemui.statusbar.notification.stack.AnimationFilter;
 import com.android.systemui.statusbar.notification.stack.AnimationProperties;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 79151fd987d1..54d81b83197e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -43,7 +43,7 @@ import android.view.View;
 
 import androidx.lifecycle.Observer;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.qualifiers.DisplayId;
 import com.android.systemui.dagger.qualifiers.Main;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
index cc38405701f5..ae3f92355510 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
@@ -22,7 +22,7 @@ import android.animation.ObjectAnimator;
 import android.content.res.Resources;
 import android.view.View;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 public final class PhoneStatusBarTransitions extends BarTransitions {
     private static final float ICON_ALPHA_WHEN_NOT_OPAQUE = 1;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index 1966033363d4..b53939e594fb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -36,7 +36,7 @@ import android.widget.LinearLayout;
 import com.android.internal.policy.SystemBarUtils;
 import com.android.systemui.Dependency;
 import com.android.systemui.Gefingerpoken;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
 import com.android.systemui.statusbar.phone.userswitcher.StatusBarUserSwitcherContainer;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
index fc5f91506c06..e1096e2d3482 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
@@ -24,7 +24,7 @@ import android.view.View
 import android.view.ViewGroup
 import android.view.ViewTreeObserver
 import com.android.systemui.Gefingerpoken
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.scene.shared.flag.SceneContainerFlags
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 40432eee95bb..5b552640f397 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -51,7 +51,7 @@ import com.android.settingslib.Utils;
 import com.android.systemui.CoreStartable;
 import com.android.systemui.DejankUtils;
 import com.android.systemui.Dumpable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.animation.ShadeInterpolation;
 import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants;
 import com.android.systemui.dagger.SysUISingleton;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt
index ad1817019284..6a24174ff3cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt
@@ -26,7 +26,7 @@ import android.view.DisplayCutout
 import androidx.annotation.VisibleForTesting
 import com.android.internal.policy.SystemBarUtils
 import com.android.systemui.Dumpable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.statusbar.policy.CallbackController
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index 4878d45cec84..ffeb1a8cb8b6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -31,7 +31,7 @@ import android.widget.LinearLayout.LayoutParams;
 import androidx.annotation.VisibleForTesting;
 
 import com.android.internal.statusbar.StatusBarIcon;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.demomode.DemoModeCommandReceiver;
 import com.android.systemui.plugins.DarkIconDispatcher;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
index 53662f4334e1..fb7f9d1ec19b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
@@ -31,7 +31,7 @@ import android.view.View;
 
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.systemui.InitController;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
index 344e56cf570f..30a445f7ce4a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
@@ -23,7 +23,7 @@ import android.util.ArraySet;
 import android.util.Log;
 
 import com.android.settingslib.mobile.TelephonyIcons;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.statusbar.connectivity.IconState;
 import com.android.systemui.statusbar.connectivity.NetworkController;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
index 5773612d55c7..40bd8d3446b5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
@@ -31,7 +31,7 @@ import android.view.WindowInsets;
 
 import com.android.internal.policy.SystemBarUtils;
 import com.android.systemui.Dumpable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.ScreenDecorations;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.scene.domain.interactor.SceneInteractor;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
index d83664f9156a..7910e6f7413c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
@@ -33,7 +33,7 @@ import android.util.Log;
 import android.view.View;
 
 import com.android.keyguard.AlphaOptimizedLinearLayout;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.StatusIconDisplayable;
 import com.android.systemui.statusbar.notification.stack.AnimationFilter;
 import com.android.systemui.statusbar.notification.stack.AnimationProperties;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListener.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListener.kt
index 881741ae5746..640ec281e162 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListener.kt
@@ -27,7 +27,7 @@ import androidx.annotation.ColorInt
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.lifecycleScope
 import androidx.lifecycle.repeatOnLifecycle
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.plugins.DarkIconDispatcher
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
index 69510cedaeb2..9d627af357cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
@@ -42,7 +42,7 @@ import android.view.WindowManager.LayoutParams;
 import androidx.annotation.Nullable;
 
 import com.android.systemui.Dependency;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.flags.FeatureFlags;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainView.java
index 52e0e8a7a0cb..a033e1d55333 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainView.java
@@ -28,7 +28,7 @@ import android.widget.TextView;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.wm.shell.animation.Interpolators;
 
 /**
@@ -83,7 +83,7 @@ public class TapAgainView extends TextView {
     public void animateOut() {
         long fadeOutDuration = 167L;  // From KeyguardIndicationTextView#getFadeOutDuration
         int yTranslation = mContext.getResources().getDimensionPixelSize(
-                com.android.systemui.R.dimen.keyguard_indication_y_translation);
+                com.android.systemui.res.R.dimen.keyguard_indication_y_translation);
 
         AnimatorSet animatorSet = new AnimatorSet();
         ObjectAnimator fadeOut = ObjectAnimator.ofFloat(this, View.ALPHA, 0f);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UserAvatarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UserAvatarView.java
index 1b93c16dd45c..c6d2eca4d533 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UserAvatarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UserAvatarView.java
@@ -25,7 +25,7 @@ import android.util.AttributeSet;
 import android.view.View;
 
 import com.android.settingslib.drawable.UserIconDrawable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * A view that displays a user image cropped to a circle with an optional frame.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
index 66f0f597ea6e..babd435c62ba 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
@@ -38,7 +38,7 @@ import com.android.app.animation.Interpolators;
 import com.android.app.animation.InterpolatorsAndroidX;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.Dumpable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.flags.FeatureFlags;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarIconBlocklist.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarIconBlocklist.kt
index b845bada29dc..48a9e0f51979 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarIconBlocklist.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarIconBlocklist.kt
@@ -37,7 +37,7 @@ fun getStatusBarIconBlocklist(
 ): List<String> {
     // Load the default blocklist from res
     val blocklist = res.getStringArray(
-            com.android.systemui.R.array.config_collapsed_statusbar_icon_blocklist).toList()
+            com.android.systemui.res.R.array.config_collapsed_statusbar_icon_blocklist).toList()
 
     val vibrateIconSlot: String = res.getString(R.string.status_bar_volume)
     val showVibrateIcon = settings.getIntForUser(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt
index 5903fa3d5bd1..e73063b809cf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt
@@ -21,7 +21,7 @@ import androidx.core.animation.AnimatorSet
 import androidx.core.animation.ValueAnimator
 import android.content.res.Resources
 import android.view.View
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.events.STATUS_BAR_X_MOVE_IN
 import com.android.systemui.statusbar.events.STATUS_BAR_X_MOVE_OUT
 import com.android.systemui.statusbar.events.SystemStatusAnimationCallback
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentModule.java
index cd6ccb5b9a8e..07c23d1f66a0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentModule.java
@@ -19,7 +19,7 @@ package com.android.systemui.statusbar.phone.fragment.dagger;
 import android.view.View;
 import android.view.ViewStub;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.battery.BatteryMeterView;
 import com.android.systemui.dagger.qualifiers.RootView;
 import com.android.systemui.statusbar.HeadsUpStatusBarView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
index 230bb58d0581..4b1e7a46836d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
@@ -29,7 +29,7 @@ import androidx.annotation.VisibleForTesting
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.systemui.CoreStartable
 import com.android.systemui.Dumpable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.ActivityLaunchAnimator
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherContainer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherContainer.kt
index 12594771a0df..387b970251fa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherContainer.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherContainer.kt
@@ -20,7 +20,7 @@ import android.content.Context
 import android.util.AttributeSet
 import android.widget.ImageView
 import android.widget.TextView
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.view.LaunchableLinearLayout
 
 class StatusBarUserSwitcherContainer(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractor.kt
index 3709e4c06009..b0b6b325bc83 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractor.kt
@@ -17,7 +17,7 @@
 package com.android.systemui.statusbar.pipeline.ethernet.domain
 
 import com.android.settingslib.AccessibilityContentDescriptions
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.dagger.SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
index 67b04db64463..74a849a8c01f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
@@ -30,7 +30,7 @@ import androidx.annotation.VisibleForTesting
 import com.android.internal.telephony.PhoneConstants
 import com.android.settingslib.SignalIcon.MobileIconGroup
 import com.android.settingslib.mobile.MobileMappings.Config
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
 import com.android.systemui.dagger.SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
index 7ec8e12e557e..f0470ca0a1ad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
@@ -28,7 +28,7 @@ import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.lifecycleScope
 import androidx.lifecycle.repeatOnLifecycle
 import com.android.settingslib.graph.SignalDrawable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.common.ui.binder.ContentDescriptionViewBinder
 import com.android.systemui.common.ui.binder.IconViewBinder
 import com.android.systemui.lifecycle.repeatWhenAttached
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernShadeCarrierGroupMobileView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernShadeCarrierGroupMobileView.kt
index f407127f3161..fbd074d5b003 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernShadeCarrierGroupMobileView.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernShadeCarrierGroupMobileView.kt
@@ -20,7 +20,7 @@ import android.content.Context
 import android.util.AttributeSet
 import android.view.LayoutInflater
 import android.widget.LinearLayout
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.StatusBarIconView.STATE_ICON
 import com.android.systemui.statusbar.pipeline.mobile.ui.MobileViewLogger
 import com.android.systemui.statusbar.pipeline.mobile.ui.binder.MobileIconBinder
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileView.kt
index 68d02de51dc9..900a92052153 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileView.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileView.kt
@@ -19,7 +19,7 @@ package com.android.systemui.statusbar.pipeline.mobile.ui.view
 import android.content.Context
 import android.util.AttributeSet
 import android.view.LayoutInflater
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.StatusBarIconView.getVisibleStateString
 import com.android.systemui.statusbar.pipeline.mobile.ui.MobileViewLogger
 import com.android.systemui.statusbar.pipeline.mobile.ui.binder.MobileIconBinder
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityConstants.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityConstants.kt
index 0fe53294fa7d..9ea167f4815c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityConstants.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityConstants.kt
@@ -19,7 +19,7 @@ package com.android.systemui.statusbar.pipeline.shared
 import android.content.Context
 import android.telephony.TelephonyManager
 import com.android.systemui.Dumpable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dump.DumpManager
 import java.io.PrintWriter
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepository.kt
index 7076f345df97..4227f9eb8f10 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepository.kt
@@ -31,7 +31,7 @@ import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
 import androidx.annotation.ArrayRes
 import androidx.annotation.VisibleForTesting
 import com.android.systemui.Dumpable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarView.kt
index a1b96dd327e9..fe69d818dedb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarView.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarView.kt
@@ -20,7 +20,7 @@ import android.content.Context
 import android.graphics.Rect
 import android.util.AttributeSet
 import android.view.Gravity
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.plugins.DarkIconDispatcher
 import com.android.systemui.statusbar.BaseStatusBarFrameLayout
 import com.android.systemui.statusbar.StatusBarIconView
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModel.kt
index 3f82c5bfc33c..a80ea905e6e7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModel.kt
@@ -17,7 +17,7 @@
 package com.android.systemui.statusbar.pipeline.shared.ui.viewmodel
 
 import android.content.Context
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Text
 import com.android.systemui.dagger.SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiConstants.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiConstants.kt
index 8bea7728170f..2da76d4f4051 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiConstants.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiConstants.kt
@@ -18,7 +18,7 @@ package com.android.systemui.statusbar.pipeline.wifi.shared
 
 import android.content.Context
 import com.android.systemui.Dumpable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dump.DumpManager
 import java.io.PrintWriter
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/binder/WifiViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/binder/WifiViewBinder.kt
index e593575bd791..a9ac51d7c472 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/binder/WifiViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/binder/WifiViewBinder.kt
@@ -23,7 +23,7 @@ import android.widget.ImageView
 import androidx.core.view.isVisible
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.common.ui.binder.IconViewBinder
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.statusbar.StatusBarIconView
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/model/WifiIcon.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/model/WifiIcon.kt
index 668c5b3c4b78..efa092bb3f40 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/model/WifiIcon.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/model/WifiIcon.kt
@@ -22,7 +22,7 @@ import androidx.annotation.StringRes
 import androidx.annotation.VisibleForTesting
 import com.android.settingslib.AccessibilityContentDescriptions.WIFI_CONNECTION_STRENGTH
 import com.android.settingslib.AccessibilityContentDescriptions.WIFI_NO_CONNECTION
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.log.table.Diffable
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt
index f23e10287164..4cd348412f63 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt
@@ -20,7 +20,7 @@ import android.annotation.SuppressLint
 import android.content.Context
 import android.util.AttributeSet
 import android.view.LayoutInflater
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.StatusBarIconView
 import com.android.systemui.statusbar.pipeline.shared.ui.view.ModernStatusBarView
 import com.android.systemui.statusbar.pipeline.wifi.ui.binder.WifiViewBinder
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryStateNotifier.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryStateNotifier.kt
index 27e40e06fcf0..a078dd5cf28c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryStateNotifier.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryStateNotifier.kt
@@ -23,7 +23,7 @@ import android.app.PendingIntent
 import android.content.Context
 import android.content.Intent
 import android.net.Uri
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.util.concurrency.DelayableExecutor
 import javax.inject.Inject
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
index 6186c43017b3..13f76feca9fd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
@@ -25,7 +25,7 @@ import android.view.View;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.settings.brightness.BrightnessSliderController;
 import com.android.systemui.settings.brightness.ToggleSlider;
 import com.android.systemui.shade.NotificationShadeWindowView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
index f7b601b9d284..b06ebe9b9358 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
@@ -35,7 +35,7 @@ import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
 
 import com.android.internal.annotations.GuardedBy;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.util.Utils;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index b7ae233c8e52..713283ebf947 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -47,7 +47,7 @@ import android.widget.TextView;
 import com.android.settingslib.Utils;
 import com.android.systemui.Dependency;
 import com.android.systemui.FontSizeUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.demomode.DemoModeCommandReceiver;
 import com.android.systemui.plugins.DarkIconDispatcher;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
index b5bd1d8f0102..74e02d7cfec1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
@@ -29,7 +29,7 @@ import android.util.AttributeSet;
 import android.widget.TextView;
 
 import com.android.systemui.Dependency;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 
 import java.util.Date;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt
index ffb743ff926c..1224275aaf93 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt
@@ -21,7 +21,7 @@ import android.content.Context
 import android.content.SharedPreferences
 import android.provider.Settings
 import android.util.Log
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.controls.ControlsServiceInfo
 import com.android.systemui.controls.dagger.ControlsComponent
 import com.android.systemui.controls.management.ControlsListingController
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index d472c3572433..e59ec044bece 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -34,7 +34,7 @@ import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.UiEvent;
 import com.android.internal.logging.UiEventLogger;
 import com.android.systemui.EventLogTags;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.statusbar.AlertingNotificationManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpUtil.java
index feef02913416..f4a1975fab52 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpUtil.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpUtil.java
@@ -21,7 +21,7 @@ import android.annotation.Nullable;
 import android.util.Log;
 import android.view.View;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.util.Compile;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
index a4821e0e9299..4b97197536cc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
@@ -32,7 +32,7 @@ import android.util.Log;
 import androidx.annotation.NonNull;
 
 import com.android.internal.util.ConcurrentUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java
index 880e0d2eef31..62e238164514 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java
@@ -35,7 +35,7 @@ import com.android.keyguard.KeyguardConstants;
 import com.android.keyguard.KeyguardVisibilityHelper;
 import com.android.keyguard.dagger.KeyguardUserSwitcherScope;
 import com.android.settingslib.drawable.CircleFramedDrawable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.animation.Expandable;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.FalsingManager;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
index 63dcad98f056..1c88289706f3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
@@ -37,7 +37,7 @@ import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.keyguard.logging.KeyguardUpdateMonitorLogger;
 import com.android.systemui.Dumpable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.flags.FeatureFlags;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserDetailItemView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserDetailItemView.java
index e1ec94fada81..012408e29b49 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserDetailItemView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserDetailItemView.java
@@ -26,7 +26,7 @@ import androidx.core.graphics.ColorUtils;
 
 import com.android.app.animation.Interpolators;
 import com.android.keyguard.KeyguardConstants;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.qs.tiles.UserDetailItemView;
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java
index 2d04ffa9e624..bb074ac33ddb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java
@@ -38,7 +38,7 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.keyguard.KeyguardVisibilityHelper;
 import com.android.keyguard.dagger.KeyguardUserSwitcherScope;
 import com.android.settingslib.drawable.CircleFramedDrawable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherScrim.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherScrim.java
index 1d9d33d2aab1..5ed207cc3447 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherScrim.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherScrim.java
@@ -28,7 +28,7 @@ import android.graphics.Shader;
 import android.graphics.drawable.Drawable;
 import android.view.View;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * Gradient background for the user switcher on Keyguard.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index e00365d8fbcb..53fed3d2438f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -81,7 +81,7 @@ import com.android.internal.logging.UiEvent;
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.util.ContrastColorUtil;
 import com.android.systemui.Dependency;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.RemoteInputController;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt
index 736b14574da0..a50fd6f86e09 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt
@@ -30,7 +30,7 @@ import android.util.ArraySet
 import android.util.Log
 import android.view.View
 import com.android.internal.logging.UiEventLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags.NOTIFICATION_INLINE_REPLY_ANIMATION
 import com.android.systemui.statusbar.NotificationRemoteInputManager
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ResourcesSplitShadeStateController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ResourcesSplitShadeStateController.kt
index e71c972266f2..c302d6aeadbc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ResourcesSplitShadeStateController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ResourcesSplitShadeStateController.kt
@@ -16,7 +16,7 @@
 package com.android.systemui.statusbar.policy
 
 import android.content.res.Resources
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 /**
  * Fake SplitShadeStateController
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
index 03656f000c07..4a4d4e1f27b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
@@ -50,7 +50,7 @@ import androidx.annotation.NonNull;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.net.LegacyVpnInfo;
 import com.android.internal.net.VpnConfig;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Background;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java
index 52a6bcaa6753..7ac3e9c2d94c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java
@@ -26,7 +26,7 @@ import android.util.KeyValueListParser;
 import android.util.Log;
 
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.util.DeviceConfigProxy;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt
index 1776e5b76e55..616992eb0865 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt
@@ -41,7 +41,7 @@ import android.view.ViewGroup
 import android.view.accessibility.AccessibilityNodeInfo
 import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction
 import android.widget.Button
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.shared.system.ActivityManagerWrapper
 import com.android.systemui.shared.system.DevicePolicyManagerWrapper
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
index fb6ba8542a3f..b46f52c2ac2d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
@@ -32,7 +32,7 @@ import androidx.annotation.NonNull;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ContrastColorUtil;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.notification.NotificationUtils;
 
 import java.text.BreakIterator;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitClockView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitClockView.java
index 9f6157492a38..0d36b48e9099 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitClockView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitClockView.java
@@ -27,7 +27,7 @@ import android.util.AttributeSet;
 import android.widget.LinearLayout;
 import android.widget.TextClock;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * Container for a clock which has two separate views for the clock itself and AM/PM indicator. This
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateControllerImpl.kt
index ab4a8afcc3c9..43905c593bdc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateControllerImpl.kt
@@ -16,7 +16,7 @@
 package com.android.systemui.statusbar.policy
 
 import android.content.res.Resources
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java
index a593d518c207..2ed9d1548007 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java
@@ -36,7 +36,7 @@ import androidx.annotation.NonNull;
 
 import com.android.internal.util.UserIcons;
 import com.android.settingslib.drawable.UserIconDrawable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.settings.UserTracker;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/VariableDateView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/VariableDateView.kt
index cd1dcd585ed9..2f171bbc0bfc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/VariableDateView.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/VariableDateView.kt
@@ -20,7 +20,7 @@ import android.content.Context
 import android.text.StaticLayout
 import android.util.AttributeSet
 import android.widget.TextView
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 /**
  * View for showing a date that can toggle between two different formats depending on size.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java
index f4cc0ed30781..e4e9554e1ab7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java
@@ -47,7 +47,7 @@ import android.view.WindowInsets;
 import android.view.WindowManager;
 
 import com.android.internal.policy.SystemBarUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.animation.DelegateLaunchAnimatorController;
 import com.android.systemui.dagger.SysUISingleton;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowModule.kt
index 874217a67613..1c7debcdf39d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowModule.kt
@@ -1,7 +1,7 @@
 package com.android.systemui.statusbar.window
 
 import android.view.LayoutInflater
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import dagger.Module
 import dagger.Provides
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
index c1ac800b8159..fa9256f82dbd 100644
--- a/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
+++ b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
@@ -36,7 +36,7 @@ import com.android.internal.annotations.VisibleForTesting
 import com.android.internal.logging.InstanceId
 import com.android.internal.logging.InstanceIdSequence
 import com.android.internal.logging.UiEventLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.log.DebugLogger.debugLog
diff --git a/packages/SystemUI/src/com/android/systemui/telephony/ui/activity/SwitchToManagedProfileForCallActivity.kt b/packages/SystemUI/src/com/android/systemui/telephony/ui/activity/SwitchToManagedProfileForCallActivity.kt
index b9c24871eac8..ccd8e48d164c 100644
--- a/packages/SystemUI/src/com/android/systemui/telephony/ui/activity/SwitchToManagedProfileForCallActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/telephony/ui/activity/SwitchToManagedProfileForCallActivity.kt
@@ -26,7 +26,7 @@ import android.telecom.TelecomManager
 import android.util.Log
 import android.view.WindowManager
 import com.android.internal.app.AlertActivity
-import com.android.systemui.R
+import com.android.systemui.res.R
 import javax.inject.Inject
 
 /** Dialog shown to the user to switch to managed profile for making a call using work SIM. */
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt
index f0aae0f83722..fc414b66b042 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt
@@ -39,7 +39,7 @@ import androidx.annotation.VisibleForTesting
 import com.android.app.animation.Interpolators
 import com.android.internal.widget.CachingIconView
 import com.android.systemui.Gefingerpoken
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.common.shared.model.ContentDescription.Companion.loadContentDescription
 import com.android.systemui.common.shared.model.Text.Companion.loadText
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt
index f24d5263ff89..4449f8d06f15 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt
@@ -21,7 +21,7 @@ import android.view.HapticFeedbackConstants
 import android.view.View
 import androidx.annotation.AttrRes
 import com.android.internal.logging.InstanceId
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.common.shared.model.Text
 import com.android.systemui.common.shared.model.TintedIcon
 import com.android.systemui.temporarydisplay.TemporaryViewInfo
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeModule.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeModule.java
index 7fa90df0e792..e78eba49a3da 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeModule.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeModule.java
@@ -18,7 +18,7 @@ package com.android.systemui.theme;
 
 import android.content.res.Resources;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.util.concurrency.SysUIConcurrencyModule;
 
diff --git a/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java b/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java
index 29f16c7b924a..d97cae2a99e3 100644
--- a/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java
+++ b/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java
@@ -170,9 +170,9 @@ public class SystemUIToast implements ToastPlugin.Toast {
         }
 
         final View toastView = mLayoutInflater.inflate(
-                    com.android.systemui.R.layout.text_toast, null);
-        final TextView textView = toastView.findViewById(com.android.systemui.R.id.text);
-        final ImageView iconView = toastView.findViewById(com.android.systemui.R.id.icon);
+                    com.android.systemui.res.R.layout.text_toast, null);
+        final TextView textView = toastView.findViewById(com.android.systemui.res.R.id.text);
+        final ImageView iconView = toastView.findViewById(com.android.systemui.res.R.id.icon);
         textView.setText(mText);
 
         ApplicationInfo appInfo = null;
@@ -189,7 +189,7 @@ public class SystemUIToast implements ToastPlugin.Toast {
             textView.setMaxLines(Integer.MAX_VALUE);
 
             // no app icon
-            toastView.findViewById(com.android.systemui.R.id.icon).setVisibility(View.GONE);
+            toastView.findViewById(com.android.systemui.res.R.id.icon).setVisibility(View.GONE);
         } else {
             Drawable icon = getBadgedIcon(mContext, mPackageName, mUserId);
             if (icon == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/toast/ToastDefaultAnimation.kt b/packages/SystemUI/src/com/android/systemui/toast/ToastDefaultAnimation.kt
index 8187956962b6..8b5fd0b33658 100644
--- a/packages/SystemUI/src/com/android/systemui/toast/ToastDefaultAnimation.kt
+++ b/packages/SystemUI/src/com/android/systemui/toast/ToastDefaultAnimation.kt
@@ -31,8 +31,8 @@ class ToastDefaultAnimation {
     companion object {
         // total duration shouldn't exceed NotificationManagerService's delay for "in" animation
         fun toastIn(view: View): AnimatorSet? {
-            val icon: View? = view.findViewById(com.android.systemui.R.id.icon)
-            val text: View? = view.findViewById(com.android.systemui.R.id.text)
+            val icon: View? = view.findViewById(com.android.systemui.res.R.id.icon)
+            val text: View? = view.findViewById(com.android.systemui.res.R.id.text)
             if (icon == null || text == null) {
                 return null
             }
@@ -69,8 +69,8 @@ class ToastDefaultAnimation {
 
         fun toastOut(view: View): AnimatorSet? {
             // total duration shouldn't exceed NotificationManagerService's delay for "out" anim
-            val icon: View? = view.findViewById(com.android.systemui.R.id.icon)
-            val text: View? = view.findViewById(com.android.systemui.R.id.text)
+            val icon: View? = view.findViewById(com.android.systemui.res.R.id.icon)
+            val text: View? = view.findViewById(com.android.systemui.res.R.id.text)
             if (icon == null || text == null) {
                 return null
             }
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/ClipboardView.java b/packages/SystemUI/src/com/android/systemui/tuner/ClipboardView.java
index 919f15050107..5ae4cdf1f56f 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/ClipboardView.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/ClipboardView.java
@@ -24,7 +24,7 @@ import android.view.MotionEvent;
 import android.view.View;
 import android.widget.ImageView;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 public class ClipboardView extends ImageView implements OnPrimaryClipChangedListener {
 
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
index 246488600eef..a43524a15b67 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
@@ -29,7 +29,7 @@ import androidx.preference.SwitchPreference;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.demomode.DemoMode;
 import com.android.systemui.demomode.DemoModeAvailabilityTracker;
 import com.android.systemui.demomode.DemoModeController;
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/LockscreenFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/LockscreenFragment.java
index 4dbceac9b3a7..771a8c8a0cfd 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/LockscreenFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/LockscreenFragment.java
@@ -41,7 +41,7 @@ import androidx.recyclerview.widget.RecyclerView;
 import androidx.recyclerview.widget.RecyclerView.ViewHolder;
 
 import com.android.systemui.Dependency;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.plugins.IntentButtonProvider.IntentButton;
 import com.android.systemui.statusbar.ScalingDrawableWrapper;
 import com.android.systemui.statusbar.phone.ExpandableIndicator;
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java b/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java
index 87d2063d18e9..ec6f86297bae 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java
@@ -46,7 +46,7 @@ import androidx.preference.Preference;
 import androidx.preference.Preference.OnPreferenceChangeListener;
 
 import com.android.systemui.Dependency;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.tuner.TunerService.Tunable;
 
 import java.util.ArrayList;
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/OtherPrefs.java b/packages/SystemUI/src/com/android/systemui/tuner/OtherPrefs.java
index 7239c8a22a31..32b1b2607323 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/OtherPrefs.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/OtherPrefs.java
@@ -18,7 +18,7 @@ import android.os.Bundle;
 
 import androidx.preference.PreferenceFragment;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 public class OtherPrefs extends PreferenceFragment {
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/PluginFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/PluginFragment.java
index 49995155f251..7635a84539ca 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/PluginFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/PluginFragment.java
@@ -36,7 +36,7 @@ import androidx.preference.SwitchPreference;
 
 import com.android.internal.util.ArrayUtils;
 import com.android.systemui.Dependency;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.plugins.PluginEnablerImpl;
 import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.shared.plugins.PluginActionManager;
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/PowerNotificationControlsFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/PowerNotificationControlsFragment.java
index 80f9de6b4ba5..ce1a2e9b329c 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/PowerNotificationControlsFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/PowerNotificationControlsFragment.java
@@ -27,7 +27,7 @@ import android.widget.TextView;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 public class PowerNotificationControlsFragment extends Fragment {
 
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/RadioListPreference.java b/packages/SystemUI/src/com/android/systemui/tuner/RadioListPreference.java
index 24758908cff2..20ce23077cdd 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/RadioListPreference.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/RadioListPreference.java
@@ -29,7 +29,7 @@ import androidx.preference.PreferenceScreen;
 
 import com.android.settingslib.Utils;
 import com.android.systemui.Dependency;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.fragments.FragmentService;
 
 import java.util.Objects;
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/SelectablePreference.java b/packages/SystemUI/src/com/android/systemui/tuner/SelectablePreference.java
index 0be793eefa18..386b7bb1e049 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/SelectablePreference.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/SelectablePreference.java
@@ -27,7 +27,7 @@ public class SelectablePreference extends CheckBoxPreference {
 
     public SelectablePreference(Context context) {
         super(context);
-        setWidgetLayoutResource(com.android.systemui.R.layout.preference_widget_radiobutton);
+        setWidgetLayoutResource(com.android.systemui.res.R.layout.preference_widget_radiobutton);
         setSelectable(true);
         mSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 32,
                 context.getResources().getDisplayMetrics());
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/ShortcutPicker.java b/packages/SystemUI/src/com/android/systemui/tuner/ShortcutPicker.java
index 11e1f278a271..5b340527dd3f 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/ShortcutPicker.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/ShortcutPicker.java
@@ -30,7 +30,7 @@ import androidx.preference.PreferenceScreen;
 import androidx.preference.PreferenceViewHolder;
 
 import com.android.systemui.Dependency;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.tuner.ShortcutParser.Shortcut;
 import com.android.systemui.tuner.TunerService.Tunable;
 
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
index ecaf7921a4df..14d7281e5b99 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
@@ -30,7 +30,7 @@ import androidx.preference.PreferenceFragment;
 import androidx.preference.PreferenceScreen;
 
 import com.android.systemui.Dependency;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.demomode.DemoModeController;
 import com.android.systemui.fragments.FragmentService;
 import com.android.systemui.util.settings.GlobalSettings;
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
index 989462a9fd34..9cc526a1c0f3 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
@@ -33,7 +33,7 @@ import androidx.preference.PreferenceFragment;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.shared.plugins.PluginPrefs;
 
 public class TunerFragment extends PreferenceFragment {
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
index ccc0a79d2cfe..8087a8755a6e 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
@@ -38,7 +38,7 @@ import androidx.annotation.WorkerThread;
 
 import com.android.internal.util.ArrayUtils;
 import com.android.systemui.DejankUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.demomode.DemoModeController;
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java
index 71355bbb23e1..1c441b39cc64 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java
@@ -9,7 +9,7 @@ import androidx.preference.SwitchPreference;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.Dependency;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.tuner.TunerService.Tunable;
 
 public class TunerSwitch extends SwitchPreference implements Tunable {
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java
index 3a7ac9c8a8bd..c1eb5b6a92df 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java
@@ -30,7 +30,7 @@ import android.view.WindowManager;
 
 import com.android.internal.app.AlertActivity;
 import com.android.internal.app.AlertController;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 
 import javax.inject.Inject;
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbAudioWarningDialogMessage.java b/packages/SystemUI/src/com/android/systemui/usb/UsbAudioWarningDialogMessage.java
index e06353b3aad3..7e9c5e9546cd 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbAudioWarningDialogMessage.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbAudioWarningDialogMessage.java
@@ -22,7 +22,7 @@ import android.annotation.IntDef;
 import android.content.res.Resources;
 import android.util.Log;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.lang.annotation.Retention;
 
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbContaminantActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbContaminantActivity.java
index 534049b65cb4..7ede21a025c2 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbContaminantActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbContaminantActivity.java
@@ -29,7 +29,7 @@ import android.view.WindowManager;
 import android.widget.TextView;
 import android.widget.Toast;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * Activity that alerts the user when contaminant is detected on USB port.
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
index 941cd7783ed0..e7e907a90d34 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
@@ -38,7 +38,7 @@ import android.widget.CheckBox;
 
 import com.android.internal.app.AlertActivity;
 import com.android.internal.app.AlertController;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 
 import javax.inject.Inject;
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingSecondaryUserActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingSecondaryUserActivity.java
index 2871263dbb1e..ea871be70936 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingSecondaryUserActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingSecondaryUserActivity.java
@@ -34,7 +34,7 @@ import android.view.WindowManager;
 
 import com.android.internal.app.AlertActivity;
 import com.android.internal.app.AlertController;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 
 import javax.inject.Inject;
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDialogActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDialogActivity.java
index 55dec5fbe344..44dee7234bd9 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbDialogActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDialogActivity.java
@@ -29,7 +29,7 @@ import android.widget.TextView;
 
 import com.android.internal.app.AlertActivity;
 import com.android.internal.app.AlertController;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 abstract class UsbDialogActivity extends AlertActivity
         implements DialogInterface.OnClickListener, CheckBox.OnCheckedChangeListener {
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java
index 02a763794a6c..080a9dc64ac8 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java
@@ -38,7 +38,7 @@ import android.widget.CheckBox;
 
 import com.android.internal.app.ResolverActivity;
 import com.android.internal.app.chooser.TargetInfo;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.util.ArrayList;
 import java.util.Iterator;
diff --git a/packages/SystemUI/src/com/android/systemui/user/CreateUserActivity.java b/packages/SystemUI/src/com/android/systemui/user/CreateUserActivity.java
index 08b0c647628c..562feb2e7b45 100644
--- a/packages/SystemUI/src/com/android/systemui/user/CreateUserActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/user/CreateUserActivity.java
@@ -33,7 +33,7 @@ import androidx.annotation.Nullable;
 
 import com.android.internal.logging.UiEventLogger;
 import com.android.settingslib.users.CreateUserDialogController;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.plugins.ActivityStarter;
 
 import javax.inject.Inject;
diff --git a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherFullscreenDialog.kt b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherFullscreenDialog.kt
index 5ad963035e36..6df02e86fb61 100644
--- a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherFullscreenDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherFullscreenDialog.kt
@@ -22,7 +22,7 @@ import android.view.LayoutInflater
 import android.view.ViewGroup.LayoutParams.MATCH_PARENT
 import android.view.WindowInsets
 import android.view.WindowInsetsController
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.statusbar.phone.SystemUIDialog
 import com.android.systemui.user.ui.binder.UserSwitcherViewBinder
diff --git a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherPopupMenu.kt b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherPopupMenu.kt
index ee84580ac4ec..1fa48723d0a6 100644
--- a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherPopupMenu.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherPopupMenu.kt
@@ -23,7 +23,7 @@ import android.view.View.MeasureSpec
 import android.widget.ListAdapter
 import android.widget.ListPopupWindow
 import android.widget.ListView
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 /**
  * Popup menu for displaying items on the fullscreen user switcher.
diff --git a/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt b/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt
index 8cfa55570723..f40454915ee3 100644
--- a/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt
@@ -23,7 +23,7 @@ import android.os.UserHandle
 import android.os.UserManager
 import android.provider.Settings
 import androidx.annotation.VisibleForTesting
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
 import com.android.systemui.dagger.SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt
index a3e648d4fb1b..e4894992b49f 100644
--- a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt
@@ -37,7 +37,7 @@ import com.android.internal.logging.UiEventLogger
 import com.android.internal.util.UserIcons
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.KeyguardUpdateMonitorCallback
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SystemUISecondaryUserService
 import com.android.systemui.animation.Expandable
 import com.android.systemui.broadcast.BroadcastDispatcher
diff --git a/packages/SystemUI/src/com/android/systemui/user/legacyhelper/data/LegacyUserDataHelper.kt b/packages/SystemUI/src/com/android/systemui/user/legacyhelper/data/LegacyUserDataHelper.kt
index 03a7470a3fe6..93573fa42c96 100644
--- a/packages/SystemUI/src/com/android/systemui/user/legacyhelper/data/LegacyUserDataHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/legacyhelper/data/LegacyUserDataHelper.kt
@@ -23,7 +23,7 @@ import android.graphics.Bitmap
 import android.os.UserManager
 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin
 import com.android.settingslib.RestrictedLockUtilsInternal
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.user.data.source.UserRecord
 import com.android.systemui.user.shared.model.UserActionModel
 
diff --git a/packages/SystemUI/src/com/android/systemui/user/legacyhelper/ui/LegacyUserUiHelper.kt b/packages/SystemUI/src/com/android/systemui/user/legacyhelper/ui/LegacyUserUiHelper.kt
index 1ac86ce6162b..8957fe1ee214 100644
--- a/packages/SystemUI/src/com/android/systemui/user/legacyhelper/ui/LegacyUserUiHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/legacyhelper/ui/LegacyUserUiHelper.kt
@@ -20,7 +20,7 @@ package com.android.systemui.user.legacyhelper.ui
 import android.content.Context
 import androidx.annotation.DrawableRes
 import androidx.annotation.StringRes
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.user.data.source.UserRecord
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/user/ui/binder/UserSwitcherViewBinder.kt b/packages/SystemUI/src/com/android/systemui/user/ui/binder/UserSwitcherViewBinder.kt
index 59f2cdb745ca..c57870291055 100644
--- a/packages/SystemUI/src/com/android/systemui/user/ui/binder/UserSwitcherViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/ui/binder/UserSwitcherViewBinder.kt
@@ -34,7 +34,7 @@ import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.lifecycleScope
 import androidx.lifecycle.repeatOnLifecycle
 import com.android.systemui.Gefingerpoken
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.user.UserSwitcherPopupMenu
diff --git a/packages/SystemUI/src/com/android/systemui/user/ui/binder/UserViewBinder.kt b/packages/SystemUI/src/com/android/systemui/user/ui/binder/UserViewBinder.kt
index e78807e675b3..8fc1b2515c6a 100644
--- a/packages/SystemUI/src/com/android/systemui/user/ui/binder/UserViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/ui/binder/UserViewBinder.kt
@@ -25,7 +25,7 @@ import android.view.View
 import android.widget.ImageView
 import androidx.core.content.res.ResourcesCompat
 import com.android.settingslib.Utils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.common.ui.binder.TextViewBinder
 import com.android.systemui.user.ui.viewmodel.UserViewModel
 
diff --git a/packages/SystemUI/src/com/android/systemui/user/ui/dialog/AddUserDialog.kt b/packages/SystemUI/src/com/android/systemui/user/ui/dialog/AddUserDialog.kt
index fdf13be13a9b..b88f9fb3cee2 100644
--- a/packages/SystemUI/src/com/android/systemui/user/ui/dialog/AddUserDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/ui/dialog/AddUserDialog.kt
@@ -82,7 +82,7 @@ class AddUserDialog(
             context.getString(R.string.user_add_user_message_short) +
                 if (showEphemeralMessage) {
                     context.getString(
-                        com.android.systemui.R.string.user_add_user_message_guest_remove
+                        com.android.systemui.res.R.string.user_add_user_message_guest_remove
                     )
                 } else {
                     ""
diff --git a/packages/SystemUI/src/com/android/systemui/user/ui/dialog/UserSwitchDialog.kt b/packages/SystemUI/src/com/android/systemui/user/ui/dialog/UserSwitchDialog.kt
index b8ae257aaac5..40582150a21d 100644
--- a/packages/SystemUI/src/com/android/systemui/user/ui/dialog/UserSwitchDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/ui/dialog/UserSwitchDialog.kt
@@ -5,7 +5,7 @@ import android.content.Intent
 import android.provider.Settings
 import android.view.LayoutInflater
 import com.android.internal.logging.UiEventLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.animation.DialogLaunchAnimator
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.plugins.FalsingManager
diff --git a/packages/SystemUI/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModel.kt b/packages/SystemUI/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModel.kt
index aeed5fc59281..61952baba7b1 100644
--- a/packages/SystemUI/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModel.kt
@@ -17,7 +17,7 @@
 
 package com.android.systemui.user.ui.viewmodel
 
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.common.shared.model.Text
 import com.android.systemui.common.ui.drawable.CircularDrawable
 import com.android.systemui.dagger.SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/util/AlphaTintDrawableWrapper.java b/packages/SystemUI/src/com/android/systemui/util/AlphaTintDrawableWrapper.java
index 516efc06386a..947746c94198 100644
--- a/packages/SystemUI/src/com/android/systemui/util/AlphaTintDrawableWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/util/AlphaTintDrawableWrapper.java
@@ -28,7 +28,7 @@ import android.util.AttributeSet;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
diff --git a/packages/SystemUI/src/com/android/systemui/util/DelayableMarqueeTextView.kt b/packages/SystemUI/src/com/android/systemui/util/DelayableMarqueeTextView.kt
index 8b90547f7bdb..ef9340a332dc 100644
--- a/packages/SystemUI/src/com/android/systemui/util/DelayableMarqueeTextView.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/DelayableMarqueeTextView.kt
@@ -18,7 +18,7 @@ package com.android.systemui.util
 
 import android.content.Context
 import android.util.AttributeSet
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 class DelayableMarqueeTextView @JvmOverloads constructor(
     context: Context,
diff --git a/packages/SystemUI/src/com/android/systemui/util/LargeScreenUtils.kt b/packages/SystemUI/src/com/android/systemui/util/LargeScreenUtils.kt
index 9b241a72b708..bbfdaa368a03 100644
--- a/packages/SystemUI/src/com/android/systemui/util/LargeScreenUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/LargeScreenUtils.kt
@@ -1,7 +1,7 @@
 package com.android.systemui.util
 
 import android.content.res.Resources
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 object LargeScreenUtils {
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java b/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
index 904a98b5e54d..8a6f79dc93b3 100644
--- a/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
+++ b/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
@@ -24,7 +24,7 @@ import android.provider.Settings;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.CoreStartable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.wm.shell.pip.tv.TvPipNotificationController;
 
 import java.util.Arrays;
diff --git a/packages/SystemUI/src/com/android/systemui/util/Utils.java b/packages/SystemUI/src/com/android/systemui/util/Utils.java
index e0daa0706b86..760fe6a96fda 100644
--- a/packages/SystemUI/src/com/android/systemui/util/Utils.java
+++ b/packages/SystemUI/src/com/android/systemui/util/Utils.java
@@ -23,7 +23,7 @@ import android.provider.Settings;
 import android.view.DisplayCutout;
 
 import com.android.internal.policy.SystemBarUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.settings.DisplayTracker;
 import com.android.systemui.shared.system.QuickStepContract;
 
diff --git a/packages/SystemUI/src/com/android/systemui/util/animation/UniqueObjectHostView.kt b/packages/SystemUI/src/com/android/systemui/util/animation/UniqueObjectHostView.kt
index 47a2d35e57f5..577d18eaea84 100644
--- a/packages/SystemUI/src/com/android/systemui/util/animation/UniqueObjectHostView.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/animation/UniqueObjectHostView.kt
@@ -21,7 +21,7 @@ import android.content.Context
 import android.view.View
 import android.view.ViewGroup
 import android.widget.FrameLayout
-import com.android.systemui.R
+import com.android.systemui.res.R
 
 /**
  * A special view that is designed to host a single "unique object". The unique object is
diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
index 58cffa761a66..de392d3f444f 100644
--- a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
@@ -48,7 +48,7 @@ import android.view.View;
 import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.CoreStartable;
 import com.android.systemui.Dumpable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/SensorModule.java b/packages/SystemUI/src/com/android/systemui/util/sensors/SensorModule.java
index 96980b85e410..7934ab1c197e 100644
--- a/packages/SystemUI/src/com/android/systemui/util/sensors/SensorModule.java
+++ b/packages/SystemUI/src/com/android/systemui/util/sensors/SensorModule.java
@@ -24,7 +24,7 @@ import android.util.Log;
 
 import androidx.annotation.NonNull;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.statusbar.policy.DevicePostureController;
 import com.android.systemui.util.concurrency.DelayableExecutor;
diff --git a/packages/SystemUI/src/com/android/systemui/util/service/dagger/ObservableServiceModule.java b/packages/SystemUI/src/com/android/systemui/util/service/dagger/ObservableServiceModule.java
index c62c95755ce8..bcf34f833d32 100644
--- a/packages/SystemUI/src/com/android/systemui/util/service/dagger/ObservableServiceModule.java
+++ b/packages/SystemUI/src/com/android/systemui/util/service/dagger/ObservableServiceModule.java
@@ -19,7 +19,7 @@ package com.android.systemui.util.service.dagger;
 
 import android.content.res.Resources;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Main;
 
 import javax.inject.Named;
diff --git a/packages/SystemUI/src/com/android/systemui/volume/CaptionsToggleImageButton.java b/packages/SystemUI/src/com/android/systemui/volume/CaptionsToggleImageButton.java
index ae23ca64e31e..ac41a509213d 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/CaptionsToggleImageButton.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/CaptionsToggleImageButton.java
@@ -26,7 +26,7 @@ import androidx.core.view.ViewCompat;
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat;
 
 import com.android.keyguard.AlphaOptimizedImageButton;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /** Toggle button in Volume Dialog for controlling system captions state */
 public class CaptionsToggleImageButton extends AlphaOptimizedImageButton {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/CsdWarningDialog.java b/packages/SystemUI/src/com/android/systemui/volume/CsdWarningDialog.java
index fb5a71c0b06f..eb0bf46159dd 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/CsdWarningDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/CsdWarningDialog.java
@@ -35,7 +35,7 @@ import android.view.WindowManager;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.messages.nano.SystemMessageProto;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
 import com.android.systemui.util.NotificationChannels;
diff --git a/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java b/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java
index 89bc75760b4b..d9593bd56f00 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java
@@ -25,7 +25,7 @@ import android.widget.Button;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.util.Objects;
 
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index 9cc3cdbf5c34..ea4d31bca035 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -64,7 +64,7 @@ import androidx.lifecycle.Observer;
 import com.android.internal.annotations.GuardedBy;
 import com.android.settingslib.volume.MediaSessions;
 import com.android.systemui.Dumpable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dump.DumpManager;
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index dcc0525bb436..727d649c8118 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -120,7 +120,7 @@ import com.android.internal.view.RotationPolicy;
 import com.android.settingslib.Utils;
 import com.android.systemui.Dumpable;
 import com.android.systemui.Prefs;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.media.dialog.MediaOutputDialogFactory;
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanelDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanelDialog.java
index 96936e3eb5f0..605038766651 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumePanelDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanelDialog.java
@@ -51,7 +51,7 @@ import com.android.settingslib.bluetooth.BluetoothUtils;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
 import com.android.settingslib.media.MediaOutputConstants;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
 
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanelSlicesAdapter.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanelSlicesAdapter.java
index 23714021a2cc..d7669d45cb64 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumePanelSlicesAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanelSlicesAdapter.java
@@ -33,7 +33,7 @@ import androidx.slice.Slice;
 import androidx.slice.SliceItem;
 import androidx.slice.widget.SliceView;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeToolTipView.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeToolTipView.java
index 1de55856f942..2143771ef696 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeToolTipView.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeToolTipView.java
@@ -28,7 +28,7 @@ import android.widget.LinearLayout;
 
 import androidx.core.content.ContextCompat;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.recents.TriangleShape;
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
index 0b3521b048c4..3451ae0a9be3 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
@@ -22,7 +22,7 @@ import android.os.Handler;
 import android.util.Log;
 
 import com.android.systemui.CoreStartable;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.qs.tiles.DndTile;
 
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java b/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java
index de9b5ee2e19a..0e6df6b11e7b 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java
@@ -30,7 +30,7 @@ import android.service.quickaccesswallet.QuickAccessWalletClient;
 import android.service.quickaccesswallet.QuickAccessWalletClientImpl;
 import android.util.Log;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Background;
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/DotIndicatorDecoration.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/DotIndicatorDecoration.java
index e5c55b0a5e7f..e90d9e281a9b 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/ui/DotIndicatorDecoration.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/DotIndicatorDecoration.java
@@ -27,7 +27,7 @@ import androidx.annotation.ColorInt;
 import androidx.core.graphics.ColorUtils;
 import androidx.recyclerview.widget.RecyclerView;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 final class DotIndicatorDecoration extends RecyclerView.ItemDecoration {
     private final int mUnselectedRadius;
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java
index 2491e2bdd623..750b6f95d52e 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java
@@ -40,7 +40,7 @@ import com.android.internal.logging.UiEventLogger;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.settingslib.Utils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.classifier.FalsingCollector;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardCarousel.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardCarousel.java
index b7c8b4900e87..02a764c97126 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardCarousel.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardCarousel.java
@@ -38,7 +38,7 @@ import androidx.recyclerview.widget.PagerSnapHelper;
 import androidx.recyclerview.widget.RecyclerView;
 import androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 import java.util.Collections;
 import java.util.List;
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardView.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardView.java
index fc1adc37d09b..7b50a6568da9 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardView.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardView.java
@@ -25,7 +25,7 @@ import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.cardview.widget.CardView;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /** Customized card view of the wallet card carousel. */
 public class WalletCardView extends CardView {
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardViewHolder.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardViewHolder.java
index 3197976456e3..c33a8053133e 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardViewHolder.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardViewHolder.java
@@ -22,7 +22,7 @@ import android.widget.ImageView;
 import androidx.cardview.widget.CardView;
 import androidx.recyclerview.widget.RecyclerView;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * View holder for the quick access wallet card.
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java
index 6fd0a4db5a14..d21ccc9502cf 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java
@@ -43,7 +43,7 @@ import androidx.annotation.NonNull;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.UiEventLogger;
 import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.settings.UserTracker;
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java
index cab47a3c4b4b..f498520f219b 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java
@@ -40,7 +40,7 @@ import android.widget.TextView;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settingslib.Utils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.classifier.FalsingCollector;
 
 import java.util.List;
diff --git a/packages/SystemUI/src/com/android/systemui/wifi/WifiDebuggingActivity.java b/packages/SystemUI/src/com/android/systemui/wifi/WifiDebuggingActivity.java
index 1c7a9b5e8681..f8ffab094e0f 100644
--- a/packages/SystemUI/src/com/android/systemui/wifi/WifiDebuggingActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/wifi/WifiDebuggingActivity.java
@@ -43,7 +43,7 @@ import android.widget.Toast;
 
 import com.android.internal.app.AlertActivity;
 import com.android.internal.app.AlertController;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * Alerts the user of an untrusted network when enabling wireless debugging.
diff --git a/packages/SystemUI/src/com/android/systemui/wifi/WifiDebuggingSecondaryUserActivity.java b/packages/SystemUI/src/com/android/systemui/wifi/WifiDebuggingSecondaryUserActivity.java
index f9f14e0bc362..972d3c01f75f 100644
--- a/packages/SystemUI/src/com/android/systemui/wifi/WifiDebuggingSecondaryUserActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/wifi/WifiDebuggingSecondaryUserActivity.java
@@ -30,7 +30,7 @@ import android.os.Bundle;
 
 import com.android.internal.app.AlertActivity;
 import com.android.internal.app.AlertController;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 
 /**
  * Alerts the user that wireless debugging cannot be enabled by a secondary user.
diff --git a/packages/SystemUI/tests/Android.bp b/packages/SystemUI/tests/Android.bp
index 3c418ed49adc..ec0414e94eba 100644
--- a/packages/SystemUI/tests/Android.bp
+++ b/packages/SystemUI/tests/Android.bp
@@ -20,6 +20,7 @@ package {
 
 android_test {
     name: "SystemUITests",
+    use_resource_processor: true,
 
     dxflags: ["--multi-dex"],
     platform_apis: true,
diff --git a/packages/SystemUI/tests/robolectric/src/com/android/systemui/robotests/SysuiResourceLoadingTest.java b/packages/SystemUI/tests/robolectric/src/com/android/systemui/robotests/SysuiResourceLoadingTest.java
index 188dff21efa4..205168ea0b7d 100644
--- a/packages/SystemUI/tests/robolectric/src/com/android/systemui/robotests/SysuiResourceLoadingTest.java
+++ b/packages/SystemUI/tests/robolectric/src/com/android/systemui/robotests/SysuiResourceLoadingTest.java
@@ -27,7 +27,7 @@ import org.junit.runner.RunWith;
 public class SysuiResourceLoadingTest extends SysuiRoboBase {
     @Test
     public void testResources() {
-        assertThat(getContext().getString(com.android.systemui.R.string.app_label))
+        assertThat(getContext().getString(com.android.systemui.res.R.string.app_label))
                 .isEqualTo("System UI");
         assertThat(getContext().getString(com.android.systemui.tests.R.string.test_content))
                 .isNotEmpty();
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java
index 9016220b40cf..9ce9bd6865a4 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java
@@ -55,7 +55,7 @@ import android.testing.AndroidTestingRunner;
 import android.text.TextUtils;
 
 import com.android.keyguard.logging.CarrierTextManagerLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.dump.LogBufferHelperKt;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/FaceWakeUpTriggersConfigTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/FaceWakeUpTriggersConfigTest.kt
index 6c5620d42abb..94c34a525547 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/FaceWakeUpTriggersConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/FaceWakeUpTriggersConfigTest.kt
@@ -67,7 +67,7 @@ class FaceWakeUpTriggersConfigTest : SysuiTestCase() {
 
     private fun createFaceWakeUpTriggersConfig(wakeUpTriggers: IntArray): FaceWakeUpTriggersConfig {
         overrideResource(
-            com.android.systemui.R.array.config_face_auth_wake_up_triggers,
+            com.android.systemui.res.R.array.config_face_auth_wake_up_triggers,
             wakeUpTriggers
         )
 
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java
index c894d914bfa3..42f65f6f53b4 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java
@@ -37,7 +37,7 @@ import com.android.internal.util.LatencyTracker;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardAbsKeyInputView.KeyDownListener;
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.classifier.FalsingCollector;
 import com.android.systemui.classifier.FalsingCollectorFake;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java
index 00f88bfa2abb..8401e6734d61 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java
@@ -27,7 +27,7 @@ import android.widget.TextView;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 
 import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java
index 3d8719656a1e..00a2efe7f838 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java
@@ -35,7 +35,7 @@ import android.widget.FrameLayout;
 import android.widget.LinearLayout;
 import android.widget.RelativeLayout;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.flags.FakeFeatureFlags;
@@ -148,7 +148,7 @@ public class KeyguardClockSwitchControllerBaseTest extends SysuiTestCase {
         when(mView.getResources()).thenReturn(mResources);
         when(mResources.getDimensionPixelSize(R.dimen.keyguard_clock_top_margin))
                 .thenReturn(100);
-        when(mResources.getDimensionPixelSize(R.dimen.keyguard_large_clock_top_margin))
+        when(mResources.getDimensionPixelSize(com.android.systemui.customization.R.dimen.keyguard_large_clock_top_margin))
                 .thenReturn(-200);
         when(mResources.getInteger(R.integer.keyguard_date_weather_view_invisibility))
                 .thenReturn(INVISIBLE);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
index 65c677ea7e5a..e54b1845ce6b 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
@@ -40,7 +40,7 @@ import android.view.ViewGroup;
 import android.widget.FrameLayout;
 import android.widget.TextView;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.ClockController;
 import com.android.systemui.plugins.ClockFaceController;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
index ee67348c9b93..f943acd9180e 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
@@ -24,7 +24,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.util.LatencyTracker
 import com.android.internal.widget.LockPatternUtils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingCollector
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
index 0ef9f4533015..e09009389f8b 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
@@ -24,7 +24,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.util.LatencyTracker
 import com.android.internal.widget.LockPatternUtils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingCollector
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java
index 2b90e7c66e8d..8322b37151de 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java
@@ -31,7 +31,7 @@ import androidx.test.filters.SmallTest;
 import com.android.internal.util.LatencyTracker;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.RoboPilotTest;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.classifier.FalsingCollector;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt
index a9f044ccd144..2f08804d8c05 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt
@@ -25,7 +25,7 @@ import androidx.test.filters.SmallTest
 import com.android.internal.util.LatencyTracker
 import com.android.internal.widget.LockPatternUtils
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingCollector
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPresentationTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPresentationTest.java
index 62906f3656c7..f3a1b68a87ae 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPresentationTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPresentationTest.java
@@ -32,7 +32,7 @@ import androidx.test.filters.SmallTest;
 
 import com.android.keyguard.KeyguardDisplayManager.KeyguardPresentation;
 import com.android.keyguard.dagger.KeyguardStatusViewComponent;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 
 import org.junit.After;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
index 929604bc81b6..f6649bdc9d3f 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
@@ -36,7 +36,7 @@ import com.android.internal.logging.UiEventLogger
 import com.android.internal.widget.LockPatternUtils
 import com.android.keyguard.KeyguardSecurityContainer.UserSwitcherViewMode.UserSwitcherCallback
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
index 3e330d65329e..aad11d90f5a4 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
@@ -56,7 +56,7 @@ import androidx.constraintlayout.widget.ConstraintSet;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.RoboPilotTest;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.classifier.FalsingA11yDelegate;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java
index 19bc8186eee5..b02b1f9df9fb 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java
@@ -35,7 +35,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.RoboPilotTest;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.flags.FeatureFlags;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt
index 4db5f35ca07d..d0bb5a999327 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt
@@ -24,7 +24,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.util.LatencyTracker
 import com.android.internal.widget.LockPatternUtils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingCollector
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt
index 47ff3b90e2e2..59cd26cc6b9b 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt
@@ -24,7 +24,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.util.LatencyTracker
 import com.android.internal.widget.LockPatternUtils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingCollector
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
index 77302ce30f09..6654a6ce816b 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
@@ -28,7 +28,7 @@ import androidx.slice.SliceSpecs;
 import androidx.slice.builders.ListBuilder;
 import androidx.slice.widget.RowContent;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.keyguard.KeyguardSliceProvider;
 
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt
index 210f3cb65ac0..86439e557f8b 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt
@@ -6,7 +6,7 @@ import android.testing.TestableLooper.RunWithLooper
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.children
 import com.google.common.truth.Truth.assertThat
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUnfoldTransitionTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUnfoldTransitionTest.kt
index bb03f288147e..3afca5933e5d 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUnfoldTransitionTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUnfoldTransitionTest.kt
@@ -20,7 +20,7 @@ import android.testing.AndroidTestingRunner
 import android.view.View
 import android.view.ViewGroup
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.statusbar.StatusBarState.KEYGUARD
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 1d7c32803248..47be236b1272 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -341,7 +341,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
         when(mUserTracker.getUserId()).thenReturn(mCurrentUserId);
 
         mContext.getOrCreateTestableResources().addOverride(
-                com.android.systemui.R.integer.config_face_auth_supported_posture,
+                com.android.systemui.res.R.integer.config_face_auth_supported_posture,
                 DEVICE_POSTURE_UNKNOWN);
         mFaceWakeUpTriggersConfig = new FaceWakeUpTriggersConfig(
                 mContext.getResources(),
@@ -349,7 +349,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
                 mDumpManager
         );
 
-        mContext.getOrCreateTestableResources().addOverride(com.android.systemui
+        mContext.getOrCreateTestableResources().addOverride(com.android.systemui.res
                         .R.array.config_fingerprint_listen_on_occluding_activity_packages,
                 new String[]{ PKG_ALLOWING_FP_LISTEN_ON_OCCLUDING_ACTIVITY });
 
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUserSwitcherAnchorTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUserSwitcherAnchorTest.kt
index 08185af1238e..c6740535d903 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUserSwitcherAnchorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUserSwitcherAnchorTest.kt
@@ -18,7 +18,7 @@ package com.android.keyguard
 import android.testing.AndroidTestingRunner
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
index 0e4b3c9b6a23..21a28222ccf4 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
@@ -39,7 +39,7 @@ import android.view.View;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityManager;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.biometrics.AuthRippleController;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/PinShapeHintingViewTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/PinShapeHintingViewTest.kt
index 42e12df431c5..835c9ff51381 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/PinShapeHintingViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/PinShapeHintingViewTest.kt
@@ -20,7 +20,7 @@ import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.view.LayoutInflater
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth
 import org.junit.Before
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/PinShapeNonHintingViewTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/PinShapeNonHintingViewTest.kt
index c04fd39168de..d431731b710e 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/PinShapeNonHintingViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/PinShapeNonHintingViewTest.kt
@@ -20,7 +20,7 @@ import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.view.LayoutInflater
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth
 import org.junit.Before
diff --git a/packages/SystemUI/tests/src/com/android/systemui/BatteryMeterDrawableTest.java b/packages/SystemUI/tests/src/com/android/systemui/BatteryMeterDrawableTest.java
index d1573c3cac76..532c59aab18b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/BatteryMeterDrawableTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/BatteryMeterDrawableTest.java
@@ -32,6 +32,7 @@ import android.test.suitebuilder.annotation.SmallTest;
 
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.settingslib.R;
 import com.android.settingslib.graph.BatteryMeterDrawableBase;
 
 import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
index f81ef10e6b14..af88df79be87 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
@@ -78,6 +78,7 @@ import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.test.filters.SmallTest;
 
+import com.android.systemui.res.R;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.decor.CornerDecorProvider;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
index 79dc057e4f28..8fd2bd6ad762 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
@@ -71,7 +71,7 @@ import android.widget.ImageView;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 
 import org.junit.After;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
index 09d0eebd510d..22ebd995b472 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
@@ -46,7 +46,7 @@ import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.LargeTest;
 
 import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.model.SysUiState;
 import com.android.systemui.util.settings.SecureSettings;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
index 39fe6fbe78fb..187f0986353e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
@@ -88,7 +88,7 @@ import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.LargeTest;
 
 import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.model.SysUiState;
 import com.android.systemui.settings.FakeDisplayTracker;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java
index 91c47480ae45..95e21cf6138a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java
@@ -59,7 +59,7 @@ import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView;
 import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView.OnSeekBarWithIconButtonsChangeListener;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapterTest.java
index afd5f77f7a4c..403385f21db0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapterTest.java
@@ -28,7 +28,7 @@ import android.view.View;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.accessibility.dialog.AccessibilityTarget;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.accessibility.floatingmenu.AccessibilityTargetAdapter.ViewHolder;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AnnotationLinkSpanTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AnnotationLinkSpanTest.java
index 46c930f9a5eb..43ebeee3f597 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AnnotationLinkSpanTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AnnotationLinkSpanTest.java
@@ -26,7 +26,7 @@ import android.view.View;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 
 import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuEduTooltipViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuEduTooltipViewTest.java
index 42b610a18bc0..9b819479ec70 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuEduTooltipViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuEduTooltipViewTest.java
@@ -26,7 +26,7 @@ import android.widget.TextView;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 
 import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegateTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegateTest.java
index 1b0a10e68062..5764839d160d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegateTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegateTest.java
@@ -37,7 +37,7 @@ import androidx.recyclerview.widget.RecyclerView;
 import androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate;
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.util.settings.SecureSettings;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogTest.kt
index 7b99314692b4..83bee932fc59 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogTest.kt
@@ -24,7 +24,7 @@ import android.view.ViewGroup
 import android.widget.Button
 import android.widget.SeekBar
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView
 import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView.OnSeekBarWithIconButtonsChangeListener
diff --git a/packages/SystemUI/tests/src/com/android/systemui/assist/ui/DisplayUtilsTest.java b/packages/SystemUI/tests/src/com/android/systemui/assist/ui/DisplayUtilsTest.java
index dd9683f83c37..957443a23f93 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/assist/ui/DisplayUtilsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/assist/ui/DisplayUtilsTest.java
@@ -25,7 +25,7 @@ import android.testing.AndroidTestingRunner;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 
 import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewControllerTest.java
index ec8be8ef3047..323f15a2cb46 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewControllerTest.java
@@ -33,7 +33,7 @@ import android.provider.Settings;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.flags.FakeFeatureFlags;
 import com.android.systemui.settings.UserTracker;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewTest.kt
index f0f4ca7f3e66..4ab7ab450fae 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewTest.kt
@@ -19,7 +19,7 @@ import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
 import android.widget.ImageView
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.battery.BatteryMeterView.BatteryEstimateFetcher
 import com.android.systemui.statusbar.policy.BatteryController.EstimateFetchCompletion
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconControllerTest.kt
index 52bf350bfcc8..215d63508306 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconControllerTest.kt
@@ -25,7 +25,7 @@ import android.view.ViewGroup.LayoutParams
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.airbnb.lottie.LottieAnimationView
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.biometrics.ui.binder.Spaghetti.BiometricState
 import com.google.common.truth.Truth.assertThat
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
index 969a01164734..f899e2fb968a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
@@ -37,7 +37,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.internal.widget.LockPatternUtils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository
 import com.android.systemui.biometrics.data.repository.FakePromptRepository
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index d0b3833a24a1..2bc0171939b4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -906,14 +906,14 @@ public class AuthControllerTest extends SysuiTestCase {
         when(mContextSpy.getResources()).thenReturn(mResources);
 
         doReturn(500).when(mResources)
-                .getDimensionPixelSize(eq(com.android.systemui.R.dimen
+                .getDimensionPixelSize(eq(com.android.systemui.res.R.dimen
                         .physical_fingerprint_sensor_center_screen_location_y));
         mAuthController.onConfigurationChanged(null /* newConfig */);
 
         final Point firstFpLocation = mAuthController.getFingerprintSensorLocation();
 
         doReturn(1000).when(mResources)
-                .getDimensionPixelSize(eq(com.android.systemui.R.dimen
+                .getDimensionPixelSize(eq(com.android.systemui.res.R.dimen
                         .physical_fingerprint_sensor_center_screen_location_y));
         mAuthController.onConfigurationChanged(null /* newConfig */);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
index 17928a3da140..57cf834bfa38 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
@@ -52,7 +52,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.airbnb.lottie.LottieAnimationView
 import com.android.keyguard.KeyguardUpdateMonitor
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.SysuiTestableContext
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
index c73541972a3c..21e614f3db3a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
@@ -37,7 +37,7 @@ import android.view.accessibility.AccessibilityManager
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardUpdateMonitor
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.ActivityLaunchAnimator
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 08e69374a177..ee3bd0d79ad8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -74,7 +74,7 @@ import androidx.test.filters.SmallTest;
 import com.android.internal.logging.InstanceIdSequence;
 import com.android.internal.util.LatencyTracker;
 import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.RoboPilotTest;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.animation.ActivityLaunchAnimator;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
index 6d4588da7751..ebadfc78a079 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
@@ -25,7 +25,7 @@ import android.view.LayoutInflater
 import android.view.Surface
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams
@@ -67,7 +67,7 @@ class UdfpsViewTest : SysuiTestCase() {
 
     @Before
     fun setup() {
-        context.setTheme(R.style.Theme_AppCompat)
+        context.setTheme(androidx.appcompat.R.style.Theme_AppCompat)
         view = LayoutInflater.from(context).inflate(R.layout.udfps_view, null) as UdfpsView
         view.animationViewController = animationViewController
         val sensorBounds = SensorLocationInternal("", SENSOR_X, SENSOR_Y, SENSOR_RADIUS).rect
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/BroadcastDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/BroadcastDialogTest.java
index 6fa19162b150..eee0ed45345d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/BroadcastDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/BroadcastDialogTest.java
@@ -36,7 +36,7 @@ import com.android.internal.logging.UiEventLogger;
 import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.broadcast.BroadcastSender;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.media.dialog.MediaOutputDialogFactory;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/data/repo/BouncerMessageRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/data/repo/BouncerMessageRepositoryTest.kt
index 562a8ef512d4..f158b433d5dc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/data/repo/BouncerMessageRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/data/repo/BouncerMessageRepositoryTest.kt
@@ -35,15 +35,15 @@ import com.android.keyguard.KeyguardSecurityModel
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode.PIN
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.KeyguardUpdateMonitorCallback
-import com.android.systemui.R
-import com.android.systemui.R.string.keyguard_enter_pin
-import com.android.systemui.R.string.kg_prompt_after_dpm_lock
-import com.android.systemui.R.string.kg_prompt_after_user_lockdown_pin
-import com.android.systemui.R.string.kg_prompt_auth_timeout
-import com.android.systemui.R.string.kg_prompt_pin_auth_timeout
-import com.android.systemui.R.string.kg_prompt_reason_restart_pin
-import com.android.systemui.R.string.kg_prompt_unattended_update
-import com.android.systemui.R.string.kg_trust_agent_disabled
+import com.android.systemui.res.R
+import com.android.systemui.res.R.string.keyguard_enter_pin
+import com.android.systemui.res.R.string.kg_prompt_after_dpm_lock
+import com.android.systemui.res.R.string.kg_prompt_after_user_lockdown_pin
+import com.android.systemui.res.R.string.kg_prompt_auth_timeout
+import com.android.systemui.res.R.string.kg_prompt_pin_auth_timeout
+import com.android.systemui.res.R.string.kg_prompt_reason_restart_pin
+import com.android.systemui.res.R.string.kg_prompt_unattended_update
+import com.android.systemui.res.R.string.kg_trust_agent_disabled
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.bouncer.data.factory.BouncerMessageFactory
 import com.android.systemui.bouncer.data.repository.BouncerMessageRepository
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
index 86e0c751085b..6205c277bbd9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
@@ -17,7 +17,7 @@
 package com.android.systemui.bouncer.domain.interactor
 
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.authentication.data.model.AuthenticationMethodModel
 import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerMessageInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerMessageInteractorTest.kt
index 4089abef399b..c1286a166421 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerMessageInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerMessageInteractorTest.kt
@@ -22,8 +22,8 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardSecurityModel
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode.PIN
-import com.android.systemui.R.string.kg_too_many_failed_attempts_countdown
-import com.android.systemui.R.string.kg_unlock_with_pin_or_fp
+import com.android.systemui.res.R.string.kg_too_many_failed_attempts_countdown
+import com.android.systemui.res.R.string.kg_unlock_with_pin_or_fp
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.bouncer.data.factory.BouncerMessageFactory
 import com.android.systemui.bouncer.data.repository.FakeBouncerMessageRepository
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorTest.kt
index a68e0192e951..9a5b4585e0ae 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorTest.kt
@@ -25,7 +25,7 @@ import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardSecurityModel
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.DejankUtils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepository
 import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.EXPANSION_HIDDEN
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
index 12090e5264df..8df29e4d4e58 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
@@ -17,7 +17,7 @@
 package com.android.systemui.bouncer.ui.viewmodel
 
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.authentication.data.model.AuthenticationMethodModel
 import com.android.systemui.coroutines.collectLastValue
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
index 8ce738ca89f6..102cfe21838e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
@@ -17,7 +17,7 @@
 package com.android.systemui.bouncer.ui.viewmodel
 
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.authentication.data.model.AuthenticationMethodModel
 import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
index a684221e1a78..35238ce00057 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
@@ -17,7 +17,7 @@
 package com.android.systemui.bouncer.ui.viewmodel
 
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.authentication.data.model.AuthenticationMethodModel
 import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
diff --git a/packages/SystemUI/tests/src/com/android/systemui/charging/WiredChargingRippleControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/charging/WiredChargingRippleControllerTest.kt
index 5a5c058793b2..11756d5b8ea2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/charging/WiredChargingRippleControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/charging/WiredChargingRippleControllerTest.kt
@@ -24,7 +24,7 @@ import android.view.WindowManager
 import android.view.WindowMetrics
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.UiEventLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
diff --git a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtilsTest.java b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtilsTest.java
index 673b5eb5dc3c..db85522f6cd8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtilsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtilsTest.java
@@ -39,7 +39,7 @@ import android.view.textclassifier.TextLinks;
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 
 import com.google.android.collect.Lists;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/IntentCreatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/IntentCreatorTest.java
index 662c89c268e6..fb07e6e4fa10 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/IntentCreatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/IntentCreatorTest.java
@@ -28,7 +28,7 @@ import android.text.SpannableString;
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 
 import org.junit.Test;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsViewTest.java
index f0006e5e0ba7..98f7f590216f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsViewTest.java
@@ -33,7 +33,7 @@ import android.widget.SeekBar;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView.OnSeekBarWithIconButtonsChangeListener;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationLayoutEngineTest.java b/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationLayoutEngineTest.java
index 69d8d0b6f091..a78f0b7295b8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationLayoutEngineTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationLayoutEngineTest.java
@@ -28,7 +28,7 @@ import android.view.View;
 import androidx.constraintlayout.widget.ConstraintLayout;
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.complication.ComplicationLayoutEngine.Margins;
 import com.android.systemui.touch.TouchInsetManager;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsTileResourceConfigurationImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsTileResourceConfigurationImplTest.kt
index bd4e8da6b326..581e88b52c0f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsTileResourceConfigurationImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsTileResourceConfigurationImplTest.kt
@@ -18,7 +18,7 @@ package com.android.systemui.controls.controller
 
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
 import org.junit.Assert.assertEquals
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsEditingActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsEditingActivityTest.kt
index bd3d09dfbb20..2a4524b971a4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsEditingActivityTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsEditingActivityTest.kt
@@ -11,7 +11,7 @@ import android.window.OnBackInvokedCallback
 import android.window.OnBackInvokedDispatcher
 import androidx.test.filters.SmallTest
 import androidx.test.rule.ActivityTestRule
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.activity.SingleActivityFactory
 import com.android.systemui.controls.CustomIconCache
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsFavoritingActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsFavoritingActivityTest.kt
index 70d93a10b445..88d36af71958 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsFavoritingActivityTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsFavoritingActivityTest.kt
@@ -13,7 +13,7 @@ import android.window.OnBackInvokedDispatcher
 import androidx.test.filters.FlakyTest
 import androidx.test.filters.SmallTest
 import androidx.test.rule.ActivityTestRule
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.activity.SingleActivityFactory
 import com.android.systemui.controls.ControlStatus
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsListingControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsListingControllerImplTest.kt
index 74d0d210b9b0..6361e94bd0ef 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsListingControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsListingControllerImplTest.kt
@@ -31,7 +31,7 @@ import android.service.controls.ControlsProviderService
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
 import com.android.settingslib.applications.ServiceListing
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.controls.ControlsServiceInfo
 import com.android.systemui.dump.DumpManager
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/PanelConfirmationDialogFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/PanelConfirmationDialogFactoryTest.kt
index 756f267671e1..4e8f86615522 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/PanelConfirmationDialogFactoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/PanelConfirmationDialogFactoryTest.kt
@@ -20,7 +20,7 @@ package com.android.systemui.controls.management
 import android.content.DialogInterface
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.statusbar.phone.SystemUIDialog
 import com.android.systemui.util.mockito.argumentCaptor
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImplTest.kt
index 7ac1953ee495..4828ba37ecb5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImplTest.kt
@@ -20,7 +20,7 @@ package com.android.systemui.controls.panels
 import android.content.SharedPreferences
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.settings.UserFileManager
 import com.android.systemui.settings.UserTracker
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlViewHolderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlViewHolderTest.kt
index 2ae342a5cfa5..101b8ed4f6f0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlViewHolderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlViewHolderTest.kt
@@ -30,7 +30,7 @@ import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.controls.ControlsMetricsLogger
 import com.android.systemui.controls.controller.ControlInfo
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsDialogsFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsDialogsFactoryTest.kt
index 1e8cd4117688..8eebceebe874 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsDialogsFactoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsDialogsFactoryTest.kt
@@ -19,7 +19,7 @@ package com.android.systemui.controls.ui
 
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.FakeSystemUIDialogController
 import com.google.common.truth.Truth.assertThat
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsPopupMenuTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsPopupMenuTest.kt
index df6fa11ff72c..48e3962717c1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsPopupMenuTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsPopupMenuTest.kt
@@ -26,7 +26,7 @@ import android.view.ViewGroup
 import android.widget.PopupWindow.OnDismissListener
 import androidx.test.ext.junit.rules.ActivityScenarioRule
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.activity.EmptyTestActivity
 import com.android.systemui.util.mockito.whenever
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt
index a400ff963026..5a4ad011bf49 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt
@@ -33,7 +33,7 @@ import android.view.View
 import android.view.ViewGroup
 import android.widget.FrameLayout
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.controls.ControlsMetricsLogger
 import com.android.systemui.controls.ControlsServiceInfo
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/TemperatureControlBehaviorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/TemperatureControlBehaviorTest.kt
index 588e34d3111d..ac1f90cc6dda 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/TemperatureControlBehaviorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/TemperatureControlBehaviorTest.kt
@@ -11,7 +11,7 @@ import android.service.controls.templates.ThumbnailTemplate
 import android.view.LayoutInflater
 import android.view.ViewGroup
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.controls.ControlsMetricsLogger
 import com.android.systemui.controls.controller.ControlInfo
diff --git a/packages/SystemUI/tests/src/com/android/systemui/decor/OverlayWindowTest.kt b/packages/SystemUI/tests/src/com/android/systemui/decor/OverlayWindowTest.kt
index 8bf17d7c62f9..a1cffc1419d5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/decor/OverlayWindowTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/decor/OverlayWindowTest.kt
@@ -23,7 +23,7 @@ import android.view.DisplayCutout
 import android.view.Surface
 import android.view.View
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import org.junit.Assert
 import org.junit.Before
diff --git a/packages/SystemUI/tests/src/com/android/systemui/decor/PrivacyDotDecorProviderFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/decor/PrivacyDotDecorProviderFactoryTest.kt
index 171b76748d26..e4ddc37c4f3c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/decor/PrivacyDotDecorProviderFactoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/decor/PrivacyDotDecorProviderFactoryTest.kt
@@ -20,7 +20,7 @@ import android.content.res.Resources
 import android.testing.AndroidTestingRunner
 import android.view.DisplayCutout
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import org.junit.Assert
 import org.junit.Before
diff --git a/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerDecorProviderFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerDecorProviderFactoryTest.kt
index 8f0b19307000..d1d48803c486 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerDecorProviderFactoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerDecorProviderFactoryTest.kt
@@ -20,7 +20,7 @@ import android.testing.AndroidTestingRunner
 import android.util.Size
 import android.view.DisplayCutout
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import org.junit.Assert
 import org.junit.Before
diff --git a/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerResDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerResDelegateTest.kt
index 4feba7bfd359..2bff7d22785a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerResDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerResDelegateTest.kt
@@ -23,7 +23,7 @@ import android.util.Size
 import androidx.annotation.DrawableRes
 import androidx.test.filters.SmallTest
 import com.android.internal.R as InternalR
-import com.android.systemui.R as SystemUIR
+import com.android.systemui.res.R as SystemUIR
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.tests.R
 import org.junit.Assert.assertEquals
diff --git a/packages/SystemUI/tests/src/com/android/systemui/display/ui/view/MirroringConfirmationDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/display/ui/view/MirroringConfirmationDialogTest.kt
index 46f758216aae..dcc15ae0e2c3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/display/ui/view/MirroringConfirmationDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/display/ui/view/MirroringConfirmationDialogTest.kt
@@ -20,7 +20,7 @@ import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.view.View
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/AlwaysOnDisplayPolicyTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/AlwaysOnDisplayPolicyTest.java
index ec9acdf26c8a..ea7467f9dc4d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/AlwaysOnDisplayPolicyTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/AlwaysOnDisplayPolicyTest.java
@@ -24,7 +24,7 @@ import android.text.format.DateUtils;
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 
 import org.junit.After;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
index af2dab599a66..9566e81ed08d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
@@ -46,7 +46,7 @@ import android.view.View;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.RoboPilotTest;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.log.LogBuffer;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsColumnLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsColumnLayoutTest.java
index 16d665cbafcd..f89a0b698c69 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsColumnLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsColumnLayoutTest.java
@@ -30,7 +30,7 @@ import android.view.View;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.util.leak.RotationUtils;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsGridLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsGridLayoutTest.java
index ea478597ef77..5a97b7489f39 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsGridLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsGridLayoutTest.java
@@ -28,7 +28,7 @@ import android.view.ViewGroup;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.util.leak.RotationUtils;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/ListGridLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/ListGridLayoutTest.java
index 74e8cc280979..a003e077e7aa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/ListGridLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/ListGridLayoutTest.java
@@ -25,7 +25,7 @@ import android.view.ViewGroup;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 
 import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/graphics/ImageLoaderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/graphics/ImageLoaderTest.kt
index 8f6634478617..76c3349c25ba 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/graphics/ImageLoaderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/graphics/ImageLoaderTest.kt
@@ -12,7 +12,7 @@ import android.net.Uri
 import android.util.Size
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
 import java.io.ByteArrayInputStream
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
index f3c9432cb4bf..6c990e457209 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
@@ -30,7 +30,7 @@ import android.testing.TestableLooper
 import android.view.SurfaceControlViewHost
 import androidx.test.filters.SmallTest
 import com.android.internal.widget.LockPatternUtils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SystemUIAppComponentFactoryBase
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.DialogLaunchAnimator
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt
index d84a4f741637..49168d087958 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt
@@ -25,7 +25,7 @@ import android.provider.Settings.Secure.ZEN_DURATION_PROMPT
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.settingslib.notification.EnableZenModeDialog
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.Expandable
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt
index b6dffff4c797..c3e28ae84805 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt
@@ -20,7 +20,7 @@ package com.android.systemui.keyguard.data.quickaffordance
 import android.content.Context
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.RoboPilotTest
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.keyguard.shared.quickaffordance.ActivationState
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt
index 1815ea9530e2..12fa4c85c34d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt
@@ -19,7 +19,7 @@ package com.android.systemui.keyguard.data.quickaffordance
 
 import android.app.Activity
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.controls.ControlsServiceInfo
 import com.android.systemui.controls.controller.ControlsController
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt
index 2fd4947b968c..ef56a9892060 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt
@@ -19,7 +19,7 @@ package com.android.systemui.keyguard.data.quickaffordance
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.Expandable
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfigTest.kt
index 7941a23fe30d..bd4525b28f71 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfigTest.kt
@@ -19,7 +19,7 @@ package com.android.systemui.keyguard.data.quickaffordance
 import android.content.Intent
 import android.net.Uri
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt
index de3bb6f3d031..4f071bd9904f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt
@@ -22,7 +22,7 @@ import android.content.res.Resources
 import android.provider.Settings
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.settings.FakeUserTracker
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
index edaff44cf543..bd0b71df3e5c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
@@ -22,7 +22,7 @@ import android.content.SharedPreferences
 import android.content.pm.UserInfo
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.backup.BackupHelper
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt
index b9c0b7fe35d7..613c4ce4ccef 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt
@@ -23,7 +23,7 @@ import android.service.quickaccesswallet.QuickAccessWalletClient
 import android.service.quickaccesswallet.WalletCard
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.ActivityLaunchAnimator
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt
index a6930d595326..360fa5652e20 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt
@@ -32,7 +32,7 @@ import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUT
 import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT
 import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT
 import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.biometrics.AuthController
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
index 3f87ee2b272a..5a95ebec1fb3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
@@ -42,7 +42,7 @@ import com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_ALTERNATE_BIOMET
 import com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_NOTIFICATION_PANEL_CLICKED
 import com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER
 import com.android.keyguard.KeyguardUpdateMonitor
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.biometrics.data.repository.FakeDisplayStateRepository
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
index 6b5be58b6d03..126b841610b4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
@@ -21,7 +21,7 @@ import android.content.pm.UserInfo
 import android.os.UserHandle
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt
index 0bbeeff8eee3..13025a016eff 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt
@@ -21,7 +21,7 @@ import android.content.Intent
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.UiEventLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
index e8542aad9cd2..8c13bb465103 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
@@ -22,7 +22,7 @@ import android.os.UserHandle
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.widget.LockPatternUtils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.DialogLaunchAnimator
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSectionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSectionTest.kt
index 4e31af22f771..8b8c59b78e46 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSectionTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSectionTest.kt
@@ -21,7 +21,7 @@ import android.view.ViewGroup
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.constraintlayout.widget.ConstraintSet
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSectionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSectionTest.kt
index 1c3b5e616ddf..74956377d345 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSectionTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSectionTest.kt
@@ -24,7 +24,7 @@ import androidx.constraintlayout.widget.ConstraintSet
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.LockIconViewController
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.biometrics.AuthController
 import com.android.systemui.flags.FeatureFlags
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
index 06bf7f06a12d..32d28a3d7bb2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
@@ -22,7 +22,7 @@ import android.os.UserHandle
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.testing.UiEventLoggerFake
 import com.android.internal.widget.LockPatternUtils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.DialogLaunchAnimator
 import com.android.systemui.animation.Expandable
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt
index b935e1d3c65a..1c6cc873c547 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt
@@ -22,7 +22,7 @@ import android.content.Intent
 import android.os.UserHandle
 import androidx.test.filters.SmallTest
 import com.android.internal.widget.LockPatternUtils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.DialogLaunchAnimator
 import com.android.systemui.animation.Expandable
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsAodViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsAodViewModelTest.kt
index bd17de3ee939..9ab9b3d160d1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsAodViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsAodViewModelTest.kt
@@ -66,7 +66,7 @@ class UdfpsAodViewModelTest : SysuiTestCase() {
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
-        overrideResource(com.android.systemui.R.dimen.lock_icon_padding, defaultPadding)
+        overrideResource(com.android.systemui.res.R.dimen.lock_icon_padding, defaultPadding)
         testScope = TestScope()
         shadeRepository = FakeShadeRepository()
         featureFlags =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsFingerprintViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsFingerprintViewModelTest.kt
index 0ad14d029e40..4f970d708425 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsFingerprintViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsFingerprintViewModelTest.kt
@@ -69,7 +69,7 @@ class UdfpsFingerprintViewModelTest : SysuiTestCase() {
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
-        overrideResource(com.android.systemui.R.dimen.lock_icon_padding, defaultPadding)
+        overrideResource(com.android.systemui.res.R.dimen.lock_icon_padding, defaultPadding)
         testScope = TestScope()
         configRepository = FakeConfigurationRepository()
         keyguardRepository = FakeKeyguardRepository()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/logcat/LogAccessDialogActivityTest.java b/packages/SystemUI/tests/src/com/android/systemui/logcat/LogAccessDialogActivityTest.java
index 1d7d5df80f45..eed7ecd9d7b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/logcat/LogAccessDialogActivityTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/logcat/LogAccessDialogActivityTest.java
@@ -31,7 +31,7 @@ import androidx.test.filters.LargeTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 
 import com.android.internal.app.ILogAccessDialogCallback;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 
 import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/models/player/SeekBarObserverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/models/player/SeekBarObserverTest.kt
index d6ceea11b801..043dae608aa7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/models/player/SeekBarObserverTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/models/player/SeekBarObserverTest.kt
@@ -24,7 +24,7 @@ import android.view.View
 import android.widget.SeekBar
 import android.widget.TextView
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.media.controls.ui.SquigglyProgress
 import com.google.common.truth.Truth.assertThat
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/models/recommendation/SmartspaceMediaDataTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/models/recommendation/SmartspaceMediaDataTest.kt
index 670f11787ce4..f7c20ac35957 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/models/recommendation/SmartspaceMediaDataTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/models/recommendation/SmartspaceMediaDataTest.kt
@@ -20,7 +20,7 @@ import android.app.smartspace.SmartspaceAction
 import android.graphics.drawable.Icon
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.InstanceId
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt
index 5939bb50bb25..fb0a4be25aa0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt
@@ -48,7 +48,7 @@ import com.android.dx.mockito.inline.extended.ExtendedMockito
 import com.android.internal.logging.InstanceId
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.InstanceIdSequenceFake
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.dump.DumpManager
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDeviceManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDeviceManagerTest.kt
index 0c57e7b82586..85d3fbad5a6e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDeviceManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDeviceManagerTest.kt
@@ -34,7 +34,7 @@ import com.android.settingslib.bluetooth.LocalBluetoothManager
 import com.android.settingslib.bluetooth.LocalBluetoothProfileManager
 import com.android.settingslib.media.LocalMediaManager
 import com.android.settingslib.media.MediaDevice
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.media.controls.MediaTestUtils
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt
index 3961a945414d..a4c2a0850ce4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt
@@ -31,7 +31,7 @@ import com.android.internal.logging.InstanceId
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.KeyguardUpdateMonitorCallback
 import com.android.keyguard.TestScopeProvider
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.dump.DumpManager
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
index 9a90a5ceb259..d6e2e973b29d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
@@ -61,7 +61,7 @@ import androidx.test.filters.SmallTest
 import com.android.internal.logging.InstanceId
 import com.android.internal.widget.CachingIconView
 import com.android.systemui.ActivityIntentHelper
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.bluetooth.BroadcastDialogController
 import com.android.systemui.broadcast.BroadcastSender
@@ -1884,7 +1884,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
     @Test
     fun bindRecommendation_listHasTooFewRecs_notDisplayed() {
         player.attachRecommendation(recommendationViewHolder)
-        val icon = Icon.createWithResource(context, R.drawable.ic_1x_mobiledata)
+        val icon = Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata)
         val data =
             smartspaceData.copy(
                 recommendations =
@@ -1911,7 +1911,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
     @Test
     fun bindRecommendation_listHasTooFewRecsWithIcons_notDisplayed() {
         player.attachRecommendation(recommendationViewHolder)
-        val icon = Icon.createWithResource(context, R.drawable.ic_1x_mobiledata)
+        val icon = Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata)
         val data =
             smartspaceData.copy(
                 recommendations =
@@ -1955,7 +1955,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
         val subtitle1 = "Subtitle1"
         val subtitle2 = "Subtitle2"
         val subtitle3 = "Subtitle3"
-        val icon = Icon.createWithResource(context, R.drawable.ic_1x_mobiledata)
+        val icon = Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata)
 
         val data =
             smartspaceData.copy(
@@ -1998,7 +1998,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
                     listOf(
                         SmartspaceAction.Builder("id1", "")
                             .setSubtitle("fake subtitle")
-                            .setIcon(Icon.createWithResource(context, R.drawable.ic_1x_mobiledata))
+                            .setIcon(Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata))
                             .setExtras(Bundle.EMPTY)
                             .build()
                     )
@@ -2013,7 +2013,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
         useRealConstraintSets()
         player.attachRecommendation(recommendationViewHolder)
 
-        val icon = Icon.createWithResource(context, R.drawable.ic_1x_mobiledata)
+        val icon = Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata)
         val data =
             smartspaceData.copy(
                 recommendations =
@@ -2047,7 +2047,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
         useRealConstraintSets()
         player.attachRecommendation(recommendationViewHolder)
 
-        val icon = Icon.createWithResource(context, R.drawable.ic_1x_mobiledata)
+        val icon = Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata)
         val data =
             smartspaceData.copy(
                 recommendations =
@@ -2086,7 +2086,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
                     listOf(
                         SmartspaceAction.Builder("id1", "title1")
                             .setSubtitle("")
-                            .setIcon(Icon.createWithResource(context, R.drawable.ic_1x_mobiledata))
+                            .setIcon(Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata))
                             .setExtras(Bundle.EMPTY)
                             .build(),
                         SmartspaceAction.Builder("id2", "title2")
@@ -2096,7 +2096,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
                             .build(),
                         SmartspaceAction.Builder("id3", "title3")
                             .setSubtitle("")
-                            .setIcon(Icon.createWithResource(context, R.drawable.ic_3g_mobiledata))
+                            .setIcon(Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_3g_mobiledata))
                             .setExtras(Bundle.EMPTY)
                             .build()
                     )
@@ -2119,7 +2119,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
                     listOf(
                         SmartspaceAction.Builder("id1", "")
                             .setSubtitle("subtitle1")
-                            .setIcon(Icon.createWithResource(context, R.drawable.ic_1x_mobiledata))
+                            .setIcon(Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata))
                             .setExtras(Bundle.EMPTY)
                             .build(),
                         SmartspaceAction.Builder("id2", "")
@@ -2129,7 +2129,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
                             .build(),
                         SmartspaceAction.Builder("id3", "")
                             .setSubtitle("subtitle3")
-                            .setIcon(Icon.createWithResource(context, R.drawable.ic_3g_mobiledata))
+                            .setIcon(Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_3g_mobiledata))
                             .setExtras(Bundle.EMPTY)
                             .build()
                     )
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaHierarchyManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaHierarchyManagerTest.kt
index 33ed01f115b5..25faeef85e50 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaHierarchyManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaHierarchyManagerTest.kt
@@ -24,7 +24,7 @@ import android.view.ViewGroup
 import android.widget.FrameLayout
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardViewController
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.controls.controller.ControlsControllerImplTest.Companion.eq
 import com.android.systemui.dreams.DreamOverlayStateController
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaViewControllerTest.kt
index ba97df910e43..1f99303f10ed 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaViewControllerTest.kt
@@ -22,7 +22,7 @@ import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.view.View
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.media.controls.models.player.MediaViewHolder
 import com.android.systemui.media.controls.models.recommendation.RecommendationViewHolder
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
index e4f89a226a34..2f057a2e14e4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
@@ -46,7 +46,7 @@ import androidx.test.filters.SmallTest;
 
 import com.android.settingslib.media.LocalMediaManager;
 import com.android.settingslib.media.MediaDevice;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 
 import com.google.common.collect.ImmutableList;
@@ -467,7 +467,7 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
     @Test
     public void subStatusSupported_onBindViewHolder_bindDeviceRequirePremium_verifyView() {
         String deviceStatus = (String) mContext.getText(
-                R.string.media_output_status_require_premium);
+                com.android.settingslib.R.string.media_output_status_require_premium);
         when(mMediaDevice2.hasSubtext()).thenReturn(true);
         when(mMediaDevice2.getSubtext()).thenReturn(SUBTEXT_SUBSCRIPTION_REQUIRED);
         when(mMediaDevice2.getSubtextString()).thenReturn(deviceStatus);
@@ -491,7 +491,7 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
     @Test
     public void subStatusSupported_onBindViewHolder_bindDeviceWithAdPlaying_verifyView() {
         String deviceStatus = (String) mContext.getText(
-                R.string.media_output_status_try_after_ad);
+                com.android.settingslib.R.string.media_output_status_try_after_ad);
         when(mMediaDevice2.hasSubtext()).thenReturn(true);
         when(mMediaDevice2.getSubtext()).thenReturn(SUBTEXT_AD_ROUTING_DISALLOWED);
         when(mMediaDevice2.getSubtextString()).thenReturn(deviceStatus);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
index db00e0927886..9dfb5a5dcb3d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
@@ -47,7 +47,7 @@ import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
 import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.broadcast.BroadcastSender;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogTest.java
index f25454c19ac9..e7400e7ba454 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogTest.java
@@ -50,7 +50,7 @@ import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
 import com.android.settingslib.media.BluetoothMediaDevice;
 import com.android.settingslib.media.LocalMediaManager;
 import com.android.settingslib.media.MediaDevice;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.broadcast.BroadcastSender;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
index 19315803c740..ce999cb41e60 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
@@ -71,7 +71,7 @@ import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.media.LocalMediaManager;
 import com.android.settingslib.media.MediaDevice;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.animation.DialogLaunchAnimator;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
index bfc8c83c1c2a..379136b0586f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
@@ -49,7 +49,7 @@ import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
 import com.android.settingslib.media.LocalMediaManager;
 import com.android.settingslib.media.MediaDevice;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.broadcast.BroadcastSender;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerTest.kt
index b09fc558d050..53e9dc814161 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerTest.kt
@@ -27,7 +27,7 @@ import android.media.AudioManager.MuteAwaitConnectionCallback.EVENT_CONNECTION
 import androidx.test.filters.SmallTest
 import com.android.settingslib.media.DeviceIconUtil
 import com.android.settingslib.media.LocalMediaManager
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.any
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt
index 6c3d6f533ace..5c6d9131e1f0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt
@@ -20,7 +20,7 @@ import android.content.pm.ApplicationInfo
 import android.content.pm.PackageManager
 import android.graphics.drawable.Drawable
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.ContentDescription.Companion.loadContentDescription
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
index 2b66e7b3cd80..e2be4cbab14d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
@@ -33,7 +33,7 @@ import android.widget.ImageView
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.InstanceId
 import com.android.internal.logging.testing.UiEventLoggerFake
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.media.taptotransfer.MediaTttFlags
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt
index c7a74da0a87d..83145bd8bee8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt
@@ -35,7 +35,7 @@ import android.widget.TextView
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.testing.UiEventLoggerFake
 import com.android.internal.statusbar.IUndoMediaTransferCallback
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.common.shared.model.Text.Companion.loadText
diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinatorTest.kt
index b396cafb28d5..d0c6d7cddc46 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinatorTest.kt
@@ -21,7 +21,7 @@ import android.app.NotificationManager
 import android.os.Handler
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.mediaprojection.taskswitcher.data.repository.ActivityTaskManagerTasksRepository
 import com.android.systemui.mediaprojection.taskswitcher.data.repository.FakeActivityTaskManager
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskBubblesServiceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskBubblesServiceTest.kt
index baac9e020280..06127a7d83e7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskBubblesServiceTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskBubblesServiceTest.kt
@@ -21,7 +21,7 @@ import android.graphics.drawable.Icon
 import android.os.UserHandle
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.notetask.NoteTaskBubblesController.NoteTaskBubblesService
 import com.android.wm.shell.bubbles.Bubbles
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
index b50032fb073b..cf43b2e12283 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
@@ -45,7 +45,7 @@ import android.provider.Settings
 import androidx.test.ext.truth.content.IntentSubject.assertThat
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.notetask.NoteTaskController.Companion.EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE
 import com.android.systemui.notetask.NoteTaskController.Companion.SHORTCUT_ID
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt
index 58c762e3cc99..119ffd28bebe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt
@@ -28,7 +28,7 @@ import android.os.UserManager
 import android.test.suitebuilder.annotation.SmallTest
 import android.testing.AndroidTestingRunner
 import com.android.dx.mockito.inline.extended.ExtendedMockito
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java
index bd913bab6f65..30d66dc8b040 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java
@@ -58,7 +58,7 @@ import android.util.DisplayMetrics;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.appwidget.IAppWidgetService;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
 import com.android.systemui.people.widget.PeopleTileKey;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java
index e6b960d75215..d0e8cce8559c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java
@@ -60,7 +60,7 @@ import android.widget.TextView;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.people.widget.PeopleTileKey;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
index e669d0697004..a63b2211f71a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
@@ -101,7 +101,7 @@ import android.text.TextUtils;
 import androidx.preference.PreferenceManager;
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.people.PeopleBackupFollowUpJob;
 import com.android.systemui.people.PeopleSpaceUtils;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
index b9ee19b9eaf2..2bdad2bc49a9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
@@ -45,7 +45,7 @@ import android.testing.TestableLooper.RunWithLooper;
 import android.testing.TestableResources;
 
 import com.android.settingslib.fuelgauge.Estimate;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt
index 1d687b141d1e..b7541456a76c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt
@@ -22,7 +22,7 @@ import android.view.View
 import android.view.ViewGroup
 import android.widget.TextView
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
 import org.junit.After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogV2Test.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogV2Test.kt
index f4644a578d24..6c01ba5b145b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogV2Test.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogV2Test.kt
@@ -24,7 +24,7 @@ import android.view.ViewGroup
 import android.view.ViewGroup.LayoutParams.MATCH_PARENT
 import android.widget.TextView
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
 import org.junit.After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSContainerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSContainerImplTest.kt
index bf237abba8fa..8c5d99a84411 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSContainerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSContainerImplTest.kt
@@ -5,7 +5,7 @@ import android.testing.TestableLooper
 import android.view.View
 import android.widget.FrameLayout
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.qs.customize.QSCustomizer
 import com.android.systemui.util.mockito.eq
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterViewControllerTest.java
index d9db60d77077..98e803f15561 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterViewControllerTest.java
@@ -34,7 +34,7 @@ import android.widget.TextView;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.retail.data.repository.FakeRetailModeRepository;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index 8afe095cbaf0..c4c233ca5eef 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -48,7 +48,7 @@ import androidx.lifecycle.Lifecycle;
 import androidx.test.filters.SmallTest;
 
 import com.android.keyguard.BouncerPanelExpansionCalculator;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiBaseFragmentTest;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.flags.FeatureFlags;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
index 24cd3e7de5b5..e2ac7bc4fc6e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
@@ -42,7 +42,7 @@ import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.logging.testing.UiEventLoggerFake;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.media.controls.ui.MediaHost;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
index 4cb194443112..5e4c954a0b26 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
@@ -7,7 +7,7 @@ import android.testing.TestableResources
 import android.view.ContextThemeWrapper
 import com.android.internal.logging.MetricsLogger
 import com.android.internal.logging.UiEventLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.media.controls.ui.MediaHost
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt
index 1df504a668f4..cc48640b15bc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt
@@ -26,7 +26,7 @@ import android.view.accessibility.AccessibilityNodeInfo
 import android.widget.FrameLayout
 import android.widget.LinearLayout
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.plugins.qs.QSTile
 import com.android.systemui.plugins.qs.QSTileView
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
index 2dc78a323f55..fbf3724c1d38 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
@@ -53,7 +53,7 @@ import android.widget.TextView;
 
 import androidx.annotation.Nullable;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.animation.Expandable;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
index 64d3b822f13c..b595e8de3bad 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
@@ -48,7 +48,7 @@ import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.util.CollectionUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.dump.nano.SystemUIProtoDump;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt
index 9bd3b7979946..2db79c2dc527 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt
@@ -22,7 +22,7 @@ import android.view.ContextThemeWrapper
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
 import com.android.internal.logging.testing.UiEventLoggerFake
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.media.controls.ui.MediaHost
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java
index 4a15d746eb32..f809259eedc1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java
@@ -39,7 +39,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
 
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.qs.tileimpl.QSTileViewImpl;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterDelegateTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterDelegateTest.java
index a5dead0f3258..6cad985c7b57 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterDelegateTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterDelegateTest.java
@@ -31,7 +31,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 
 import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java
index 2eed38fcb767..bde30382ba05 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java
@@ -50,7 +50,7 @@ import androidx.annotation.Nullable;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.InstanceId;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.qs.QSHost;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt
index 244f627c46b8..126dd633108e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt
@@ -34,7 +34,7 @@ import android.testing.TestableLooper
 import android.view.IWindowManager
 import android.view.View
 import com.android.internal.logging.MetricsLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.ActivityLaunchAnimator
 import com.android.systemui.animation.view.LaunchableFrameLayout
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileColorPickerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileColorPickerTest.java
index ec8552b7f394..b8e6403696a5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileColorPickerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileColorPickerTest.java
@@ -23,7 +23,7 @@ import android.test.suitebuilder.annotation.SmallTest;
 
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 
 import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileRequestDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileRequestDialogTest.kt
index fb17fc0a0595..365e8a5187d4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileRequestDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileRequestDialogTest.kt
@@ -23,7 +23,7 @@ import android.view.ViewGroup
 import android.widget.ImageView
 import android.widget.TextView
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.plugins.qs.QSTileView
 import com.google.common.truth.Truth.assertThat
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModelTest.kt
index d647d6add512..4ada44c40f49 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModelTest.kt
@@ -25,7 +25,7 @@ import android.view.ContextThemeWrapper
 import androidx.test.filters.SmallTest
 import com.android.settingslib.Utils
 import com.android.settingslib.drawable.UserIconDrawable
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.common.shared.model.ContentDescription
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt
index aef5fafe05ba..1c28e4c022a6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt
@@ -19,7 +19,7 @@ package com.android.systemui.qs.pipeline.data.repository
 import android.provider.Settings
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingListTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingListTest.kt
index 6e579d46fc34..15e401d24b02 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingListTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingListTest.kt
@@ -19,7 +19,7 @@ package com.android.systemui.qs.pipeline.domain.autoaddable
 import android.content.ComponentName
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.qs.pipeline.shared.TileSpec
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt
index 8036cb44e45d..5ce15fa57b1f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt
@@ -20,7 +20,7 @@ import android.content.ComponentName
 import android.content.pm.PackageManager
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt
index 780c56cf7c52..e0fff9c10873 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt
@@ -27,7 +27,7 @@ import android.view.View
 import android.view.accessibility.AccessibilityNodeInfo
 import android.widget.TextView
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.plugins.qs.QSTile
 import com.google.common.truth.Truth.assertThat
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/TilesStatesTextTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/TilesStatesTextTest.kt
index b8d018f5f850..f2400ec85feb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/TilesStatesTextTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/TilesStatesTextTest.kt
@@ -18,7 +18,7 @@ package com.android.systemui.qs.tileimpl
 
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.MediumTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
 import org.junit.Assert.assertEquals
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt
index c60cecb29d75..e2a3fac60ee8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt
@@ -22,7 +22,7 @@ import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.classifier.FalsingManagerFake
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt
index ff6814c06001..605dc1402fc3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt
@@ -24,7 +24,7 @@ import android.testing.TestableLooper.RunWithLooper
 import android.view.View
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingManagerFake
 import com.android.systemui.plugins.ActivityStarter
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt
index e5c55d8b6c56..623a8e0f7437 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt
@@ -11,7 +11,7 @@ import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
 import com.android.settingslib.Utils
 import com.android.settingslib.bluetooth.CachedBluetoothDevice
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingManagerFake
 import com.android.systemui.plugins.ActivityStarter
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt
index 70d82fdb6e5a..c4cf3425ed76 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt
@@ -21,7 +21,7 @@ import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingManagerFake
 import com.android.systemui.plugins.ActivityStarter
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ColorInversionTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ColorInversionTileTest.java
index 2e02bbe2ebf2..c93ff4b61f45 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ColorInversionTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ColorInversionTileTest.java
@@ -32,7 +32,7 @@ import android.testing.TestableLooper;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.plugins.ActivityStarter;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DataSaverTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DataSaverTileTest.kt
index 176b33fa9fc8..51e95be3611b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DataSaverTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DataSaverTileTest.kt
@@ -21,7 +21,7 @@ import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.DialogLaunchAnimator
 import com.android.systemui.classifier.FalsingManagerFake
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
index 1346069d3c25..bce4c06d320f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
@@ -27,7 +27,7 @@ import android.testing.TestableLooper
 import androidx.lifecycle.LifecycleOwner
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.ActivityLaunchAnimator
 import com.android.systemui.classifier.FalsingManagerFake
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt
index 77a443666442..5dd297ca1bdc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt
@@ -29,7 +29,7 @@ import android.view.ContextThemeWrapper
 import android.view.View
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.DialogLaunchAnimator
 import com.android.systemui.classifier.FalsingManagerFake
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java
index f231c6e56096..a0c107340dcd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java
@@ -41,7 +41,7 @@ import android.testing.TestableLooper;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.classifier.FalsingManagerFake;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/FlashlightTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/FlashlightTileTest.kt
index 73aa6991c18a..c1a09288d8a2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/FlashlightTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/FlashlightTileTest.kt
@@ -6,7 +6,7 @@ import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingManagerFake
 import com.android.systemui.plugins.ActivityStarter
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/HotspotTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/HotspotTileTest.java
index 73f61d0690e2..14dfdea6fbc9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/HotspotTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/HotspotTileTest.java
@@ -31,7 +31,7 @@ import androidx.test.filters.SmallTest;
 import com.android.dx.mockito.inline.extended.ExtendedMockito;
 import com.android.internal.logging.MetricsLogger;
 import com.android.settingslib.wifi.WifiEnterpriseRestrictionUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.plugins.ActivityStarter;
@@ -116,7 +116,7 @@ public class HotspotTileTest extends SysuiTestCase {
 
         assertThat(mState.state).isNotEqualTo(Tile.STATE_UNAVAILABLE);
         assertThat(String.valueOf(mState.secondaryLabel))
-                .isNotEqualTo(mContext.getString(R.string.wifitrackerlib_admin_restricted_network));
+                .isNotEqualTo(mContext.getString(com.android.wifitrackerlib.R.string.wifitrackerlib_admin_restricted_network));
         mockitoSession.finishMocking();
     }
 
@@ -131,7 +131,7 @@ public class HotspotTileTest extends SysuiTestCase {
 
         assertThat(mState.state).isEqualTo(Tile.STATE_UNAVAILABLE);
         assertThat(String.valueOf(mState.secondaryLabel))
-                .isEqualTo(mContext.getString(R.string.wifitrackerlib_admin_restricted_network));
+                .isEqualTo(mContext.getString(com.android.wifitrackerlib.R.string.wifitrackerlib_admin_restricted_network));
         mockitoSession.finishMocking();
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt
index b6cf459f579c..83f8f180ae9d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt
@@ -22,7 +22,7 @@ import android.testing.TestableLooper
 import android.testing.TestableLooper.RunWithLooper
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingManagerFake
 import com.android.systemui.plugins.ActivityStarter
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileTest.java
index 7957c6a7cfb6..c1f19645e4a7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileTest.java
@@ -29,7 +29,7 @@ import android.testing.TestableLooper;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.plugins.ActivityStarter;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/LocationTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/LocationTileTest.kt
index 0bf0b38f7471..62a50e369b7d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/LocationTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/LocationTileTest.kt
@@ -22,7 +22,7 @@ import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingManagerFake
 import com.android.systemui.plugins.ActivityStarter
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt
index ceff546106f4..3511bb31c443 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt
@@ -21,7 +21,7 @@ import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingManagerFake
 import com.android.systemui.plugins.ActivityStarter
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/NfcTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/NfcTileTest.java
index 763a7e5e4e06..118ad2c258a2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/NfcTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/NfcTileTest.java
@@ -30,7 +30,7 @@ import android.testing.TestableLooper;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.classifier.FalsingManagerFake;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/NightDisplayTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/NightDisplayTileTest.kt
index 6c8f76b48f03..a1d9e4149b95 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/NightDisplayTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/NightDisplayTileTest.kt
@@ -23,7 +23,7 @@ import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingManagerFake
 import com.android.systemui.dagger.NightDisplayListenerModule
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QRCodeScannerTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QRCodeScannerTileTest.java
index 71aa7a8d0015..7b3171dbedd0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QRCodeScannerTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QRCodeScannerTileTest.java
@@ -30,7 +30,7 @@ import android.testing.TestableLooper;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.plugins.ActivityStarter;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
index dd55baddc2d9..2d18f9293ec8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
@@ -58,7 +58,7 @@ import android.testing.TestableLooper;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.plugins.ActivityStarter;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java
index d2445944c182..c5721ffb912d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java
@@ -32,7 +32,7 @@ import androidx.test.filters.SmallTest;
 
 import com.android.internal.R;
 import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.R.drawable;
+import com.android.systemui.res.R.drawable;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.plugins.ActivityStarter;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/RotationLockTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/RotationLockTileTest.java
index 41545fc2abfd..df6993d11447 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/RotationLockTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/RotationLockTileTest.java
@@ -33,7 +33,7 @@ import android.testing.TestableLooper;
 import android.testing.TestableResources;
 
 import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.plugins.ActivityStarter;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
index fff2b8f5f8cd..5b3d45bb6625 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
@@ -35,7 +35,7 @@ import android.testing.TestableLooper;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.classifier.FalsingManagerFake;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UiModeNightTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UiModeNightTileTest.kt
index 79147e7e66b4..47fc3ec51078 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UiModeNightTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UiModeNightTileTest.kt
@@ -25,7 +25,7 @@ import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingManagerFake
 import com.android.systemui.plugins.ActivityStarter
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt
index 18e40f633955..f9d69c2cce64 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt
@@ -26,7 +26,7 @@ import android.view.ViewGroup
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.testing.UiEventLoggerFake
 import com.android.internal.util.UserIcons
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingManagerFake
 import com.android.systemui.qs.QSUserSwitcherEvent
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetAdapterTest.java
index df037c0661f3..8004c6de1602 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetAdapterTest.java
@@ -20,7 +20,7 @@ import android.widget.LinearLayout;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.wifitrackerlib.WifiEntry;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java
index 25684ce23330..6dc7a064af15 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java
@@ -63,7 +63,7 @@ import com.android.internal.logging.UiEventLogger;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.settingslib.wifi.WifiUtils;
 import com.android.settingslib.wifi.dpp.WifiDppIntentHelper;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -983,7 +983,7 @@ public class InternetDialogControllerTest extends SysuiTestCase {
         spyController.mCarrierNetworkChangeMode = true;
         String dds = spyController.getMobileNetworkSummary(SUB_ID);
 
-        assertThat(dds).contains(mContext.getString(R.string.carrier_network_change_mode));
+        assertThat(dds).contains(mContext.getString(com.android.settingslib.R.string.carrier_network_change_mode));
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java
index 2c74d4fa9748..039e58a64eb5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java
@@ -33,7 +33,7 @@ import androidx.test.filters.SmallTest;
 import com.android.dx.mockito.inline.extended.ExtendedMockito;
 import com.android.internal.logging.UiEventLogger;
 import com.android.settingslib.wifi.WifiEnterpriseRestrictionUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/reardisplay/RearDisplayDialogControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/reardisplay/RearDisplayDialogControllerTest.java
index 55813f60aecd..c108a80d0c72 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/reardisplay/RearDisplayDialogControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/reardisplay/RearDisplayDialogControllerTest.java
@@ -28,7 +28,7 @@ import android.widget.TextView;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.util.concurrency.FakeExecutor;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogTest.kt
index a6c25be1e6a5..d470d24489af 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogTest.kt
@@ -22,7 +22,7 @@ import android.testing.TestableLooper
 import android.view.View
 import android.widget.Spinner
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionIntentCreatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionIntentCreatorTest.kt
index ca4486b533ff..36639d4b7ca4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionIntentCreatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionIntentCreatorTest.kt
@@ -22,7 +22,7 @@ import android.content.Intent
 import android.net.Uri
 import androidx.test.ext.truth.content.IntentSubject.assertThat as assertThatIntent
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/MessageContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/MessageContainerControllerTest.kt
index d6720568cef5..d4e8d37b3b44 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/MessageContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/MessageContainerControllerTest.kt
@@ -61,19 +61,19 @@ class MessageContainerControllerTest : SysuiTestCase() {
         workProfileData = WorkProfileMessageController.WorkProfileFirstRunData(appName, icon)
 
         val guideline = Guideline(mContext)
-        guideline.id = com.android.systemui.R.id.guideline
+        guideline.id = com.android.systemui.res.R.id.guideline
         screenshotView.addView(guideline)
 
         container = FrameLayout(mContext)
-        container.id = com.android.systemui.R.id.screenshot_message_container
+        container.id = com.android.systemui.res.R.id.screenshot_message_container
         screenshotView.addView(container)
 
         workProfileFirstRunView = FrameLayout(mContext)
-        workProfileFirstRunView.id = com.android.systemui.R.id.work_profile_first_run
+        workProfileFirstRunView.id = com.android.systemui.res.R.id.work_profile_first_run
         container.addView(workProfileFirstRunView)
 
         detectionNoticeView = FrameLayout(mContext)
-        detectionNoticeView.id = com.android.systemui.R.id.screenshot_detection_notice
+        detectionNoticeView.id = com.android.systemui.res.R.id.screenshot_detection_notice
         container.addView(detectionNoticeView)
 
         messageContainer.setView(screenshotView)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java
index 31f7771bb939..10bd6af7ddf0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java
@@ -38,7 +38,7 @@ import android.widget.TextView;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.util.FakeSharedPreferences;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsActivityTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsActivityTest.java
index ab91d9fc0f8d..0f33aaf20195 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsActivityTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsActivityTest.java
@@ -47,7 +47,7 @@ import androidx.test.rule.ActivityTestRule;
 import androidx.test.runner.intercepting.SingleActivityFactory;
 
 import com.android.internal.logging.UiEventLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.screenshot.ImageExporter;
 import com.android.systemui.settings.UserTracker;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivityTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivityTest.java
index 674ce9cab0d2..3d5552719aca 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivityTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivityTest.java
@@ -57,7 +57,7 @@ import androidx.test.runner.intercepting.SingleActivityFactory;
 import com.android.internal.infra.ServiceConnector;
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.statusbar.IAppClipsService;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.broadcast.BroadcastSender;
 import com.android.systemui.dagger.qualifiers.Background;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt
index ed1397ff7013..152be6529464 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt
@@ -25,7 +25,7 @@ import android.view.ViewGroup
 import android.view.WindowManagerPolicyConstants.EXTRA_FROM_BRIGHTNESS_KEY
 import androidx.test.filters.SmallTest
 import androidx.test.rule.ActivityTestRule
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.activity.SingleActivityFactory
 import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
index 0a1eca69f1ce..2b3588aa6e3c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
@@ -22,7 +22,7 @@ import androidx.constraintlayout.widget.ConstraintSet
 import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
 import androidx.constraintlayout.widget.ConstraintSet.START
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Expect
 import com.google.common.truth.Truth.assertThat
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationControllerTest.kt
index 38a666eeb410..bff408a7ddba 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationControllerTest.kt
@@ -20,7 +20,7 @@ import android.testing.AndroidTestingRunner
 import android.view.View
 import android.view.ViewGroup
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.statusbar.StatusBarState.KEYGUARD
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index 9130bc266d11..31c8a3d77d6b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -79,7 +79,7 @@ import com.android.keyguard.dagger.KeyguardStatusBarViewComponent;
 import com.android.keyguard.dagger.KeyguardStatusViewComponent;
 import com.android.keyguard.dagger.KeyguardUserSwitcherComponent;
 import com.android.keyguard.logging.KeyguardLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
index 911cab4f9dd7..37ec7622a836 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
@@ -57,7 +57,7 @@ import androidx.test.filters.SmallTest;
 
 import com.android.keyguard.FaceAuthApiRequestReason;
 import com.android.systemui.DejankUtils;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.flags.Flags;
 import com.android.systemui.keyguard.shared.model.WakeSleepReason;
 import com.android.systemui.keyguard.shared.model.WakefulnessModel;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt
index b0125f8289ec..aead53e7ce9f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt
@@ -25,7 +25,7 @@ import android.view.ViewStub
 import androidx.test.filters.SmallTest
 import com.android.internal.util.CollectionUtils
 import com.android.keyguard.KeyguardClockSwitch.LARGE
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.flags.Flags.ONE_WAY_HAPTICS_API_MIGRATION
 import com.android.systemui.statusbar.StatusBarState.KEYGUARD
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
index dfd782b73a22..2d00e8c24f33 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
@@ -46,7 +46,7 @@ import android.view.WindowManager;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.colorextraction.ColorExtractor;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
index 3da5f6a4b7c0..223b1c431b2d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
@@ -26,7 +26,7 @@ import com.android.keyguard.KeyguardMessageAreaController
 import com.android.keyguard.KeyguardSecurityContainerController
 import com.android.keyguard.LockIconViewController
 import com.android.keyguard.dagger.KeyguardBouncerComponent
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.back.domain.interactor.BackActionInteractor
 import com.android.systemui.bouncer.data.factory.BouncerMessageFactory
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
index 04c4b45251f2..e8170163d616 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
@@ -25,7 +25,7 @@ import com.android.keyguard.KeyguardMessageAreaController
 import com.android.keyguard.KeyguardSecurityContainerController
 import com.android.keyguard.LockIconViewController
 import com.android.keyguard.dagger.KeyguardBouncerComponent
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.back.domain.interactor.BackActionInteractor
 import com.android.systemui.bouncer.data.factory.BouncerMessageFactory
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerLegacyTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerLegacyTest.kt
index e9e6d31ff214..e70dbc7f4fda 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerLegacyTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerLegacyTest.kt
@@ -27,7 +27,7 @@ import androidx.annotation.IdRes
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.constraintlayout.widget.ConstraintSet
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.flags.FakeFeatureFlags
 import com.android.systemui.flags.Flags
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt
index 6801f2fb7394..ac8c924fe689 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt
@@ -27,7 +27,7 @@ import androidx.annotation.IdRes
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.constraintlayout.widget.ConstraintSet
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.flags.FakeFeatureFlags
 import com.android.systemui.flags.Flags
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQuickSettingsContainerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQuickSettingsContainerTest.kt
index 8bb8f6247e25..f7d2497d0bbf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQuickSettingsContainerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQuickSettingsContainerTest.kt
@@ -22,7 +22,7 @@ import android.view.ViewGroup
 import android.widget.FrameLayout
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.qs.QSFragment
 import com.android.systemui.util.mockito.whenever
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt
index d421acac2daa..2cd740d35c14 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt
@@ -6,7 +6,7 @@ import android.graphics.Rect
 import android.testing.AndroidTestingRunner
 import android.view.DisplayCutout
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.battery.BatteryMeterView
 import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java
index 849127ed10e6..fb0d4db4840a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java
@@ -34,7 +34,7 @@ import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.UiEventLogger;
 import com.android.keyguard.KeyguardStatusView;
 import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository;
 import com.android.systemui.dump.DumpManager;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java
index 6d288e1db1cb..5ca45f3df472 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java
@@ -41,7 +41,7 @@ import android.view.MotionEvent;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.plugins.qs.QS;
 
 import org.junit.Test;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeHeaderControllerTest.kt
index 7d5f68e783d5..56061f64c315 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeHeaderControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeHeaderControllerTest.kt
@@ -35,7 +35,7 @@ import androidx.constraintlayout.motion.widget.MotionLayout
 import androidx.constraintlayout.widget.ConstraintSet
 import androidx.test.filters.SmallTest
 import com.android.app.animation.Interpolators
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.ShadeInterpolation
 import com.android.systemui.battery.BatteryMeterView
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierTest.java
index dae9c975b997..a657edfada27 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierTest.java
@@ -31,7 +31,7 @@ import android.widget.TextView;
 import androidx.test.filters.SmallTest;
 
 import com.android.settingslib.mobile.TelephonyIcons;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 
 import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt
index 342b1c5b1ad2..d018cbbfbc24 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt
@@ -25,7 +25,7 @@ import android.os.UserManager
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.UiEventLogger
 import com.android.keyguard.KeyguardUpdateMonitor
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
 import com.android.systemui.coroutines.collectLastValue
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/transition/LargeScreenShadeInterpolatorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/LargeScreenShadeInterpolatorImplTest.kt
index 36f82c2a0e1c..a844bffc3ea3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/transition/LargeScreenShadeInterpolatorImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/LargeScreenShadeInterpolatorImplTest.kt
@@ -2,7 +2,7 @@ package com.android.systemui.shade.transition
 
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.statusbar.policy.FakeConfigurationController
 import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shadow/DoubleShadowTextClockTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shadow/DoubleShadowTextClockTest.kt
index f5a24ff0c731..eb418fd05b5f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shadow/DoubleShadowTextClockTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shadow/DoubleShadowTextClockTest.kt
@@ -22,7 +22,7 @@ import android.content.res.TypedArray
 import android.testing.AndroidTestingRunner
 import android.util.AttributeSet
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.shared.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.shared.shadow.DoubleShadowTextClock
 import com.android.systemui.util.mockito.whenever
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/AnimatableClockViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/AnimatableClockViewTest.kt
index e92368df8663..7b0cd19ca7f2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/AnimatableClockViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/AnimatableClockViewTest.kt
@@ -20,7 +20,7 @@ import android.testing.AndroidTestingRunner
 import android.view.LayoutInflater
 import androidx.test.filters.SmallTest
 import com.android.app.animation.Interpolators
-import com.android.systemui.R
+import com.android.systemui.customization.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.TextAnimator
 import com.android.systemui.util.mockito.any
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt
index 3f3faf7f2327..bd3dae4f5fae 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt
@@ -24,7 +24,7 @@ import android.util.TypedValue
 import android.view.LayoutInflater
 import android.widget.FrameLayout
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.customization.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.plugins.ClockSettings
 import com.android.systemui.shared.clocks.DefaultClockController.Companion.DOZE_COLOR
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java
index 280897d8bd75..b98dc0016066 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java
@@ -39,7 +39,7 @@ import android.testing.TestableLooper;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerBaseTest.java
index d44846ec45b0..63e46d1895bd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerBaseTest.java
@@ -56,7 +56,7 @@ import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.keyguard.logging.KeyguardLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.biometrics.FaceHelpMessageDeferral;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index 1240f26c8af8..2bcad1d27b62 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -73,7 +73,7 @@ import androidx.test.filters.SmallTest;
 
 import com.android.keyguard.TrustGrantFlags;
 import com.android.settingslib.fuelgauge.BatteryStatus;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.keyguard.KeyguardIndication;
 import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt
index 673d63f3a07d..0b4de345e2d7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt
@@ -18,7 +18,7 @@ package com.android.systemui.statusbar
 
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.plugins.qs.QS
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
index 2c9dfcc25324..6e990a7aae23 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
@@ -6,7 +6,7 @@ import android.testing.TestableLooper
 import android.testing.TestableLooper.RunWithLooper
 import androidx.test.filters.SmallTest
 import com.android.systemui.ExpandHelper
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.classifier.FalsingCollectorFake
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
index a258f67932bd..68bc72b09f94 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
@@ -23,7 +23,7 @@ import android.view.Choreographer
 import android.view.View
 import android.view.ViewRootImpl
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.ShadeInterpolation
 import com.android.systemui.dump.DumpManager
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
index c75aa81e4c43..544860e935f5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
@@ -36,7 +36,7 @@ import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.statusbar.IStatusBarService;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
index 8d016e30c0c1..1592c3007ec8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
@@ -52,7 +52,7 @@ import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.internal.util.ContrastColorUtil;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 
 import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/CallbackHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/CallbackHandlerTest.java
index 2d29c80a15ac..44e3bb43c4ce 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/CallbackHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/CallbackHandlerTest.java
@@ -29,7 +29,7 @@ import androidx.test.runner.AndroidJUnit4;
 import com.android.settingslib.mobile.TelephonyIcons;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.connectivity.NetworkController.EmergencyListener;
-import com.android.systemui.tests.R;
+import com.android.systemui.res.R;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -179,7 +179,7 @@ public class CallbackHandlerTest extends SysuiTestCase {
     @Test
     public void testSignalCallback_setIsAirplaneMode() {
         IconState state =
-                new IconState(true, R.drawable.stat_sys_airplane_mode, "Test Description");
+                new IconState(true, com.android.settingslib.R.drawable.stat_sys_airplane_mode, "Test Description");
         mHandler.setIsAirplaneMode(state);
         waitForCallbacks();
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerSignalTest.java
index 35b9814cd81d..375ca0639926 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerSignalTest.java
@@ -41,7 +41,7 @@ import android.testing.TestableLooper.RunWithLooper;
 import com.android.settingslib.graph.SignalDrawable;
 import com.android.settingslib.mobile.TelephonyIcons;
 import com.android.settingslib.net.DataUsageController;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.log.LogBuffer;
 import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt
index 88ddc2d9ef03..31e1fef76383 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt
@@ -22,7 +22,7 @@ import android.app.StatusBarManager.DISABLE_NONE
 import android.app.StatusBarManager.DISABLE_NOTIFICATION_ALERTS
 import android.content.res.Configuration
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.log.LogBufferFactory
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java
index 524ead22ee94..a59ba071d7e8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java
@@ -32,7 +32,7 @@ import android.util.ArrayMap;
 import android.view.LayoutInflater;
 import android.view.View;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.media.dialog.MediaOutputDialogFactory;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt
index 470d34037e45..d86f8bbbeb15 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt
@@ -16,7 +16,7 @@ import com.android.systemui.statusbar.notification.row.NotificationTestHelper
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer
 import com.android.systemui.statusbar.phone.HeadsUpManagerPhone
 import com.android.systemui.statusbar.policy.HeadsUpUtil
-import com.android.systemui.tests.R
+import com.android.systemui.res.R
 import junit.framework.Assert.assertFalse
 import junit.framework.Assert.assertTrue
 import kotlinx.coroutines.test.TestScope
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/PropertyAnimatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/PropertyAnimatorTest.java
index f0abf2f4a24f..c664c39f4432 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/PropertyAnimatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/PropertyAnimatorTest.java
@@ -33,7 +33,7 @@ import android.view.View;
 import android.view.animation.Interpolator;
 
 import com.android.app.animation.Interpolators;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.notification.stack.AnimationFilter;
 import com.android.systemui.statusbar.notification.stack.AnimationProperties;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
index 90f6201e29d7..ccc9dc0d9618 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
@@ -50,7 +50,7 @@ import android.testing.AndroidTestingRunner;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.RankingBuilder;
 import com.android.systemui.statusbar.SbnBuilder;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
index daa45db6b90c..f05436f66d82 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
@@ -61,7 +61,7 @@ import android.testing.AndroidTestingRunner;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.testing.UiEventLoggerFake;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.settings.UserTracker;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt
index 3f61af0425de..ccef1d56c6a0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt
@@ -22,7 +22,7 @@ import android.testing.TestableLooper.RunWithLooper
 import android.view.View
 import androidx.test.filters.SmallTest
 import com.android.settingslib.Utils
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.statusbar.notification.FakeShadowView
 import com.android.systemui.statusbar.notification.NotificationUtils
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt
index c650e01263bc..5590b8ba2d08 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt
@@ -23,7 +23,7 @@ import android.net.Uri
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
 import com.android.internal.widget.NotificationDrawableConsumer
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.graphics.ImageLoader
 import com.android.systemui.util.mockito.argumentCaptor
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java
index cf1d2ca2859d..c9b77c5372df 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java
@@ -54,7 +54,7 @@ import android.widget.ImageView;
 import android.widget.TextView;
 
 import com.android.internal.statusbar.IStatusBarService;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.statusbar.notification.AssistantFeedbackController;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FooterViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FooterViewTest.java
index 90cb7341377d..b120c4747cb9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FooterViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FooterViewTest.java
@@ -31,7 +31,7 @@ import android.widget.TextView;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 
 import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
index e52cb572f289..b0996ad48d0a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
@@ -115,7 +115,7 @@ public class NotificationContentInflaterTest extends SysuiTestCase {
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
         mBuilder = new Notification.Builder(mContext).setSmallIcon(
-                R.drawable.ic_person)
+                com.android.systemui.res.R.drawable.ic_person)
                 .setContentTitle("Title")
                 .setContentText("Text")
                 .setStyle(new Notification.BigTextStyle().bigText("big text"));
@@ -191,7 +191,7 @@ public class NotificationContentInflaterTest extends SysuiTestCase {
     public void testInflationThrowsErrorDoesntCallUpdated() throws Exception {
         mRow.getPrivateLayout().removeAllViews();
         mRow.getEntry().getSbn().getNotification().contentView
-                = new RemoteViews(mContext.getPackageName(), R.layout.status_bar);
+                = new RemoteViews(mContext.getPackageName(), com.android.systemui.res.R.layout.status_bar);
         inflateAndWait(true /* expectingException */, mNotificationInflater, FLAG_CONTENT_VIEW_ALL,
                 mRow);
         assertTrue(mRow.getPrivateLayout().getChildCount() == 0);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
index 596e9a2613d7..1763d9b02358 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
@@ -74,7 +74,7 @@ import android.widget.TextView;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.settingslib.notification.ConversationIconFactory;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
 import com.android.systemui.shade.ShadeController;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsTest.kt
index fdfb4f4612fd..7f9471e5271f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsTest.kt
@@ -22,7 +22,7 @@ import android.testing.ViewUtils
 import android.view.LayoutInflater
 import android.view.View
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import org.junit.After
 import org.junit.Before
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
index 8dd0488c924e..f0b4dd46654a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
@@ -66,7 +66,7 @@ import android.widget.TextView;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.testing.UiEventLoggerFake;
 import com.android.systemui.Dependency;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.notification.AssistantFeedbackController;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationSnoozeTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationSnoozeTest.java
index f8f7af071e4c..0a15f0de0bf4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationSnoozeTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationSnoozeTest.java
@@ -23,7 +23,7 @@ import android.testing.TestableResources;
 import android.testing.UiThreadTest;
 import android.util.KeyValueListParser;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
index 638694038a6a..ac680e6c902e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
@@ -88,7 +88,7 @@ import com.android.systemui.statusbar.policy.InflatedSmartReplyViewHolder;
 import com.android.systemui.statusbar.policy.SmartReplyConstants;
 import com.android.systemui.statusbar.policy.SmartReplyStateInflater;
 import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent;
-import com.android.systemui.tests.R;
+import com.android.systemui.res.R;
 import com.android.systemui.wmshell.BubblesManager;
 import com.android.systemui.wmshell.BubblesTestActivity;
 
@@ -495,7 +495,7 @@ public class NotificationTestHelper {
         Notification publicVersion = new Notification.Builder(mContext).setSmallIcon(
                 R.drawable.ic_person)
                 .setCustomContentView(new RemoteViews(mContext.getPackageName(),
-                        R.layout.custom_view_dark))
+                        com.android.systemui.tests.R.layout.custom_view_dark))
                 .build();
         Notification.Builder notificationBuilder = new Notification.Builder(mContext, "channelId")
                 .setSmallIcon(R.drawable.ic_person)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java
index 12c8fd5db751..e42ce2789e0b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java
@@ -52,7 +52,7 @@ import android.widget.TextView;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.Dependency;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt
index 0909ff2e5993..f4e236e5bbf9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt
@@ -5,7 +5,7 @@ import android.testing.TestableLooper
 import android.view.LayoutInflater
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.R
+import com.android.systemui.res.R
 import junit.framework.Assert.assertTrue
 import org.junit.Before
 import org.junit.Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt
index 1dc0ab07349b..957cb885aa06 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt
@@ -6,7 +6,7 @@ import android.view.LayoutInflater
 import android.widget.FrameLayout
 import androidx.test.filters.SmallTest
 import com.android.keyguard.BouncerPanelExpansionCalculator.aboutToShowBouncerProgress
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.ShadeInterpolation
 import com.android.systemui.flags.FakeFeatureFlags
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 036a27c3831a..3a820e8087a8 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
@@ -65,7 +65,7 @@ import androidx.test.filters.SmallTest;
 
 import com.android.keyguard.BouncerPanelExpansionCalculator;
 import com.android.systemui.ExpandHelper;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.flags.FakeFeatureFlags;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt
index bc12bb0fca4e..2b3f9d0f3c39 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt
@@ -21,7 +21,7 @@ import android.service.notification.StatusBarNotification
 import android.testing.AndroidTestingRunner
 import android.view.View.VISIBLE
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.media.controls.pipeline.MediaDataManager
 import com.android.systemui.statusbar.LockscreenShadeTransitionController
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
index d9c3c3cecf9c..a52466d2fa41 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
@@ -5,7 +5,7 @@ import android.content.pm.PackageManager
 import android.widget.FrameLayout
 import androidx.test.filters.SmallTest
 import com.android.keyguard.BouncerPanelExpansionCalculator.aboutToShowBouncerProgress
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.ShadeInterpolation.getContentAlpha
 import com.android.systemui.dump.DumpManager
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorTest.kt
index 7fc399b44795..198f278bf43a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorTest.kt
@@ -19,7 +19,7 @@ package com.android.systemui.statusbar.notification.stack.domain.interactor
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
 import com.android.systemui.coroutines.collectLastValue
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
index bfc09103ba41..e254dd085b2e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
@@ -19,7 +19,7 @@ package com.android.systemui.statusbar.notification.stack.ui.viewmodel
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.SharedNotificationContainerPosition
 import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
index e4a2236211b1..416694b29f69 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
@@ -50,7 +50,7 @@ import android.testing.TestableLooper.RunWithLooper;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.dagger.NightDisplayListenerModule;
 import com.android.systemui.plugins.qs.QSTile;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index 26c0fd695b95..5c3dde59596e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -85,7 +85,7 @@ import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.TestScopeProvider;
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.InitController;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuController;
 import com.android.systemui.animation.ActivityLaunchAnimator;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
index bb20d1806bce..1bc522d72213 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
@@ -32,7 +32,7 @@ import android.testing.TestableLooper;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.UiEventLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.shade.ShadeExpansionStateManager;
 import com.android.systemui.statusbar.AlertingNotificationManager;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt
index 4aac8419af3b..ab441e39e862 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt
@@ -20,7 +20,7 @@ import android.content.pm.PackageManager
 import android.test.suitebuilder.annotation.SmallTest
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.plugins.statusbar.StatusBarStateController
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
index 5d2b59b6e00e..03f5f005ee47 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
@@ -30,7 +30,7 @@ import android.testing.AndroidTestingRunner;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.doze.util.BurnInHelperKt;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
index 79f8dbd687ee..2b1ce0e16bbf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
@@ -50,7 +50,7 @@ import com.android.keyguard.CarrierTextController;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.keyguard.logging.KeyguardLogger;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.battery.BatteryMeterViewController;
 import com.android.systemui.flags.FakeFeatureFlagsClassic;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewTest.java
index fe1205161e8d..e88fd95a5849 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewTest.java
@@ -25,7 +25,7 @@ import android.view.View;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 
 import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java
index 47f15a1720a9..c5abd026b369 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java
@@ -27,7 +27,7 @@ import android.content.Context;
 import android.os.UserHandle;
 import android.service.notification.StatusBarNotification;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.SbnBuilder;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationTapHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationTapHelperTest.java
index b70c6dd1242d..d25a06b6c8b3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationTapHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationTapHelperTest.java
@@ -29,7 +29,7 @@ import android.view.ViewConfiguration;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.util.concurrency.FakeExecutor;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitionsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitionsTest.kt
index 4af1b24ba96c..c4568a9ecfe6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitionsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitionsTest.kt
@@ -19,7 +19,7 @@ package com.android.systemui.statusbar.phone
 import android.testing.TestableLooper
 import android.view.View
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT
 import com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
index 3a629e642d3d..b7560ad79026 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
@@ -27,7 +27,7 @@ import android.view.ViewTreeObserver.OnPreDrawListener
 import android.widget.FrameLayout
 import androidx.test.filters.SmallTest
 import androidx.test.platform.app.InstrumentationRegistry
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt
index 63508e193bb8..1455693fc54b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt
@@ -31,7 +31,7 @@ import android.view.ViewGroupOverlay
 import android.widget.LinearLayout
 import androidx.annotation.ColorInt
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher.DarkChange
 import com.android.systemui.statusbar.policy.FakeConfigurationController
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
index b8f2cab3019e..bcb34d6d9342 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
@@ -48,7 +48,7 @@ import android.widget.FrameLayout;
 import androidx.test.filters.SmallTest;
 
 import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiBaseFragmentTest;
 import com.android.systemui.animation.AnimatorTestRule;
 import com.android.systemui.dump.DumpManager;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallBackgroundContainerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallBackgroundContainerTest.kt
index ec074d76da10..f0a457e2c19f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallBackgroundContainerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallBackgroundContainerTest.kt
@@ -21,7 +21,7 @@ import android.testing.TestableLooper
 import android.view.LayoutInflater
 import android.view.View
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallChronometerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallChronometerTest.kt
index c3326b2bb7a2..7e25aa373097 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallChronometerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallChronometerTest.kt
@@ -21,7 +21,7 @@ import android.testing.TestableLooper
 import android.view.LayoutInflater
 import android.view.View
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
index dc5d55ec274a..32320b45a36d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
@@ -30,7 +30,7 @@ import android.view.View
 import android.widget.LinearLayout
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.testing.UiEventLoggerFake
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.plugins.ActivityStarter
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractorTest.kt
index 5784be34ce25..6028712c29fc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractorTest.kt
@@ -18,7 +18,7 @@ package com.android.systemui.statusbar.pipeline.ethernet.domain
 
 import androidx.test.filters.SmallTest
 import com.android.settingslib.AccessibilityContentDescriptions
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt
index 59fc0aceec97..218fd33ac0fc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt
@@ -24,7 +24,7 @@ import android.testing.ViewUtils
 import android.view.View
 import android.widget.ImageView
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.log.table.TableLogBuffer
 import com.android.systemui.statusbar.StatusBarIconView
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt
index 87163d24bae2..15b9d61fc96b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt
@@ -17,7 +17,7 @@
 package com.android.systemui.statusbar.pipeline.shared.ui.viewmodel
 
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.ContentDescription.Companion.loadContentDescription
 import com.android.systemui.common.shared.model.Text
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt
index bbf048d6697f..a27f8990dec1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt
@@ -25,7 +25,7 @@ import android.view.View
 import android.view.ViewGroup
 import android.widget.ImageView
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.log.table.TableLogBuffer
 import com.android.systemui.statusbar.StatusBarIconView.STATE_DOT
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt
index 655775465e1f..fb4ccb52929a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt
@@ -24,7 +24,7 @@ import android.testing.AndroidTestingRunner
 
 import androidx.test.filters.SmallTest
 
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.controls.ControlsServiceInfo
 import com.android.systemui.controls.dagger.ControlsComponent
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java
index e5bbead520f2..64ebcd9e3abf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java
@@ -49,7 +49,7 @@ import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.logging.testing.UiEventLoggerFake;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.AlertingNotificationManager;
 import com.android.systemui.statusbar.AlertingNotificationManagerTest;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java
index dc08aba7d5e5..3fae3f6b4054 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java
@@ -38,7 +38,7 @@ import android.testing.TestableLooper;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.settings.UserTracker;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/InflatedSmartRepliesTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/InflatedSmartRepliesTest.java
index e4318659bef9..bf280c9a2d54 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/InflatedSmartRepliesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/InflatedSmartRepliesTest.java
@@ -37,7 +37,7 @@ import androidx.test.annotation.UiThreadTest;
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.DevicePolicyManagerWrapper;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt
index b86ca6fc5375..1250228e2d37 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt
@@ -24,7 +24,7 @@ import android.view.View
 import android.widget.FrameLayout
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.UiEventLogger
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.qs.user.UserSwitchDialogController
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt
index 1ab62d00d307..0bd6a685708b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt
@@ -25,7 +25,7 @@ import android.view.View
 import android.view.ViewGroup
 import androidx.test.filters.SmallTest
 import com.android.internal.util.UserIcons
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.qs.tiles.UserDetailItemView
 import com.android.systemui.user.data.source.UserRecord
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt
index cfb48a8f6995..635d63ed5eb2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt
@@ -19,7 +19,7 @@ import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
 import androidx.test.filters.SmallTest
 
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.statusbar.CommandQueue
 import com.google.common.truth.Truth.assertThat
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
index 79feb417a062..658e6b01d7b4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
@@ -67,7 +67,7 @@ import androidx.test.filters.SmallTest;
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.logging.testing.UiEventLoggerFake;
 import com.android.systemui.Dependency;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.animation.AnimatorTestRule;
 import com.android.systemui.flags.FakeFeatureFlags;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java
index e4e0dc9ec39c..3555a7415435 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java
@@ -29,7 +29,7 @@ import android.testing.TestableLooper;
 import android.testing.TestableResources;
 
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.util.DeviceConfigProxyFake;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
index ae38958ecb44..4b6c68aeccc7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
@@ -47,7 +47,7 @@ import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt
index d212c026d66e..5b9db4bf8869 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt
@@ -31,7 +31,7 @@ import androidx.test.filters.SmallTest
 import com.android.internal.logging.InstanceId
 import com.android.internal.logging.UiEventLogger
 import com.android.systemui.InstanceIdSequenceFake
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.argumentCaptor
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt
index 98bbb26eb703..ae4dfbd6ab31 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt
@@ -26,7 +26,7 @@ import android.view.accessibility.AccessibilityManager
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.InstanceId
 import com.android.internal.logging.testing.UiEventLoggerFake
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.dump.DumpManager
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt
index 8c21fac82dfe..1e7e1842fa33 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt
@@ -33,7 +33,7 @@ import androidx.core.animation.doOnCancel
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.InstanceId
 import com.android.internal.logging.testing.UiEventLoggerFake
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.common.shared.model.ContentDescription
diff --git a/packages/SystemUI/tests/src/com/android/systemui/toast/ToastUITest.java b/packages/SystemUI/tests/src/com/android/systemui/toast/ToastUITest.java
index 7593e8429e60..85359ca3aebe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/toast/ToastUITest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/toast/ToastUITest.java
@@ -62,7 +62,7 @@ import android.widget.Toast;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.util.IntPair;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.plugins.PluginManager;
@@ -364,7 +364,7 @@ public class ToastUITest extends SysuiTestCase {
 
         // THEN the view can have unlimited lines
         assertThat(((TextView) mToastUI.mToast.getView()
-                .findViewById(com.android.systemui.R.id.text))
+                .findViewById(com.android.systemui.res.R.id.text))
                 .getMaxLines()).isEqualTo(Integer.MAX_VALUE);
     }
 
@@ -383,7 +383,7 @@ public class ToastUITest extends SysuiTestCase {
 
         // THEN the view is limited to 2 lines
         assertThat(((TextView) mToastUI.mToast.getView()
-                .findViewById(com.android.systemui.R.id.text))
+                .findViewById(com.android.systemui.res.R.id.text))
                 .getMaxLines()).isEqualTo(2);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt
index 5a54aff72af4..bbc49c859821 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt
@@ -34,7 +34,7 @@ import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.KeyguardUpdateMonitorCallback
 import com.android.systemui.GuestResetOrExitSessionReceiver
 import com.android.systemui.GuestResumeSessionReceiver
-import com.android.systemui.R
+import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.shared.model.Text
@@ -120,7 +120,7 @@ class UserInteractorTest : SysuiTestCase() {
         whenever(manager.getUserIcon(anyInt())).thenReturn(ICON)
         whenever(manager.canAddMoreUsers(any())).thenReturn(true)
 
-        overrideResource(R.drawable.ic_account_circle, GUEST_ICON)
+        overrideResource(com.android.settingslib.R.drawable.ic_account_circle, GUEST_ICON)
         overrideResource(R.dimen.max_avatar_size, 10)
         overrideResource(
             com.android.internal.R.string.config_supervisedUserCreationPackage,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
index aa9d62da4b2a..8e57dc1f8b2c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
@@ -57,7 +57,7 @@ import androidx.test.filters.SmallTest;
 
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.systemui.Prefs;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.animation.AnimatorTestRule;
 import com.android.systemui.dump.DumpManager;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java
index 53e5e7d859ac..82631744d12d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java
@@ -37,7 +37,7 @@ import android.testing.TestableLooper;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.plugins.ActivityStarter;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index 7595a54a18fd..d8511e8f38e2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -87,7 +87,7 @@ import com.android.internal.colorextraction.ColorExtractor;
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.launcher3.icons.BubbleIconFactory;
-import com.android.systemui.R;
+import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
@@ -1273,9 +1273,9 @@ public class BubblesTest extends SysuiTestCase {
                 mBubbleController,
                 mBubbleController.getStackView(),
                 new BubbleIconFactory(mContext,
-                        mContext.getResources().getDimensionPixelSize(R.dimen.bubble_size),
-                        mContext.getResources().getDimensionPixelSize(R.dimen.bubble_badge_size),
-                        mContext.getResources().getColor(R.color.important_conversation),
+                        mContext.getResources().getDimensionPixelSize(com.android.wm.shell.R.dimen.bubble_size),
+                        mContext.getResources().getDimensionPixelSize(com.android.wm.shell.R.dimen.bubble_badge_size),
+                        mContext.getResources().getColor(com.android.launcher3.icons.R.color.important_conversation),
                         mContext.getResources().getDimensionPixelSize(
                                 com.android.internal.R.dimen.importance_ring_stroke_width)),
                 bubble,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java
index 5ff57aad9f5d..2d76027ba744 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java
@@ -28,6 +28,7 @@ import android.util.Log;
 import android.view.Display;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.systemui.res.R;
 
 import java.util.Set;
 
diff --git a/packages/SystemUI/unfold/Android.bp b/packages/SystemUI/unfold/Android.bp
index 1f0181f2e5bd..81fd8ce12f05 100644
--- a/packages/SystemUI/unfold/Android.bp
+++ b/packages/SystemUI/unfold/Android.bp
@@ -23,6 +23,7 @@ package {
 
 android_library {
     name: "SystemUIUnfoldLib",
+    use_resource_processor: true,
     srcs: [
         "src/**/*.java",
         "src/**/*.kt",
-- 
GitLab


From 852dd9d8d6eb4ce11a514fe3fdc94fecbf3c6a9e Mon Sep 17 00:00:00 2001
From: Diego Vela <diegovela@google.com>
Date: Fri, 15 Sep 2023 21:27:06 +0000
Subject: [PATCH 95/95] Add raw configuration change listener updates.

Add raw configuration change listener updates. Letterboxed Activities do
not receive a configuration update when they are repositioned. Listening
to all configuration changes will correctly update folding features.
Change exceptions from hard exceptions to Log.wtf so that we do not
crash on production apps.

Bug: 295785410
Test: Open Samples and open the slim (letterbox) Activities.
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:1a7c2f292e7cc1fddfc9b0c64d1e5e4264f60144)
Merged-In: Ia079d06a403a59bb0f1eafdaad6ce238749a2af2
Change-Id: Ia079d06a403a59bb0f1eafdaad6ce238749a2af2
---
 core/java/android/app/ActivityThread.java     |  23 ++++
 ...onfigurationChangedListenerController.java | 116 ++++++++++++++++++
 .../layout/WindowLayoutComponentImpl.java     |  39 +++++-
 3 files changed, 174 insertions(+), 4 deletions(-)
 create mode 100644 core/java/android/app/ConfigurationChangedListenerController.java

diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 34662c89cb8a..bee5011da657 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -255,6 +255,7 @@ import java.util.Objects;
 import java.util.TimeZone;
 import java.util.concurrent.Executor;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
 
 /**
  * This manages the execution of the main thread in an
@@ -369,6 +370,11 @@ public final class ActivityThread extends ClientTransactionHandler
     @GuardedBy("mAppThread")
     private int mLastProcessState = PROCESS_STATE_UNKNOWN;
     final ArrayList<WeakReference<AssistStructure>> mLastAssistStructures = new ArrayList<>();
+
+    @NonNull
+    private final ConfigurationChangedListenerController mConfigurationChangedListenerController =
+            new ConfigurationChangedListenerController();
+
     private int mLastSessionId;
     // Holds the value of the last reported device ID value from the server for the top activity.
     int mLastReportedDeviceId;
@@ -3536,6 +3542,21 @@ public final class ActivityThread extends ClientTransactionHandler
         return mConfigurationController.getConfiguration();
     }
 
+    /**
+     * @hide
+     */
+    public void addConfigurationChangedListener(Executor executor,
+            Consumer<IBinder> consumer) {
+        mConfigurationChangedListenerController.addListener(executor, consumer);
+    }
+
+    /**
+     * @hide
+     */
+    public void removeConfigurationChangedListener(Consumer<IBinder> consumer) {
+        mConfigurationChangedListenerController.removeListener(consumer);
+    }
+
     @Override
     public void updatePendingConfiguration(Configuration config) {
         final Configuration updatedConfig =
@@ -6094,6 +6115,8 @@ public final class ActivityThread extends ClientTransactionHandler
                                 " did not call through to super.onConfigurationChanged()");
             }
         }
+        mConfigurationChangedListenerController
+                .dispatchOnConfigurationChanged(activity.getActivityToken());
 
         return configToReport;
     }
diff --git a/core/java/android/app/ConfigurationChangedListenerController.java b/core/java/android/app/ConfigurationChangedListenerController.java
new file mode 100644
index 000000000000..c644d57fb9a7
--- /dev/null
+++ b/core/java/android/app/ConfigurationChangedListenerController.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2023 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 android.annotation.NonNull;
+import android.os.IBinder;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+
+/**
+ * Manages listeners for unfiltered configuration changes.
+ * @hide
+ */
+class ConfigurationChangedListenerController {
+
+    private final Object mLock = new Object();
+
+    @GuardedBy("mLock")
+    private final List<ListenerContainer> mListenerContainers = new ArrayList<>();
+
+    /**
+     * Adds a listener to receive updates when they are dispatched. This only dispatches updates and
+     * does not relay the last emitted value. If called with the same listener then this method does
+     * not have any effect.
+     * @param executor an executor that is used to dispatch the updates.
+     * @param consumer a listener interested in receiving updates.
+     */
+    void addListener(@NonNull Executor executor,
+            @NonNull Consumer<IBinder> consumer) {
+        synchronized (mLock) {
+            if (indexOf(consumer) > -1) {
+                return;
+            }
+            mListenerContainers.add(new ListenerContainer(executor, consumer));
+        }
+    }
+
+    /**
+     * Removes the listener that was previously registered. If the listener was not registered this
+     * method does not have any effect.
+     */
+    void removeListener(@NonNull Consumer<IBinder> consumer) {
+        synchronized (mLock) {
+            final int index = indexOf(consumer);
+            if (index > -1) {
+                mListenerContainers.remove(index);
+            }
+        }
+    }
+
+    /**
+     * Dispatches the update to all registered listeners
+     * @param activityToken a token for the {@link Activity} that received a configuration update.
+     */
+    void dispatchOnConfigurationChanged(@NonNull IBinder activityToken) {
+        final List<ListenerContainer> consumers;
+        synchronized (mLock) {
+            consumers = new ArrayList<>(mListenerContainers);
+        }
+        for (int i = 0; i < consumers.size(); i++) {
+            consumers.get(i).accept(activityToken);
+        }
+    }
+
+    @GuardedBy("mLock")
+    private int indexOf(Consumer<IBinder> consumer) {
+        for (int i = 0; i < mListenerContainers.size(); i++) {
+            if (mListenerContainers.get(i).isMatch(consumer)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    private static final class ListenerContainer {
+
+        @NonNull
+        private final Executor mExecutor;
+        @NonNull
+        private final Consumer<IBinder> mConsumer;
+
+        ListenerContainer(@NonNull Executor executor,
+                @NonNull Consumer<IBinder> consumer) {
+            mExecutor = executor;
+            mConsumer = consumer;
+        }
+
+        public boolean isMatch(@NonNull Consumer<IBinder> consumer) {
+            return mConsumer.equals(consumer);
+        }
+
+        public void accept(@NonNull IBinder activityToken) {
+            mExecutor.execute(() -> mConsumer.accept(activityToken));
+        }
+
+    }
+}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
index 69c1d294eab0..a1fe7f75a826 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
@@ -24,6 +24,7 @@ import static androidx.window.util.ExtensionHelper.rotateRectToDisplayRotation;
 import static androidx.window.util.ExtensionHelper.transformToWindowSpaceRect;
 
 import android.app.Activity;
+import android.app.ActivityThread;
 import android.app.Application;
 import android.app.WindowConfiguration;
 import android.content.ComponentCallbacks;
@@ -33,6 +34,7 @@ import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.util.ArrayMap;
+import android.util.Log;
 
 import androidx.annotation.GuardedBy;
 import androidx.annotation.NonNull;
@@ -59,7 +61,7 @@ import java.util.Set;
  * Please refer to {@link androidx.window.sidecar.SampleSidecarImpl} instead.
  */
 public class WindowLayoutComponentImpl implements WindowLayoutComponent {
-    private static final String TAG = "SampleExtension";
+    private static final String TAG = WindowLayoutComponentImpl.class.getSimpleName();
 
     private final Object mLock = new Object();
 
@@ -81,6 +83,9 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
     private final Map<java.util.function.Consumer<WindowLayoutInfo>, Consumer<WindowLayoutInfo>>
             mJavaToExtConsumers = new ArrayMap<>();
 
+    private final RawConfigurationChangedListener mRawConfigurationChangedListener =
+            new RawConfigurationChangedListener();
+
     public WindowLayoutComponentImpl(@NonNull Context context,
             @NonNull DeviceStateManagerFoldingFeatureProducer foldingFeatureProducer) {
         ((Application) context.getApplicationContext())
@@ -109,6 +114,7 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
         final Consumer<WindowLayoutInfo> extConsumer = consumer::accept;
         synchronized (mLock) {
             mJavaToExtConsumers.put(consumer, extConsumer);
+            updateListenerRegistrations();
         }
         addWindowLayoutInfoListener(activity, extConsumer);
     }
@@ -162,6 +168,7 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
         final Consumer<WindowLayoutInfo> extConsumer;
         synchronized (mLock) {
             extConsumer = mJavaToExtConsumers.remove(consumer);
+            updateListenerRegistrations();
         }
         if (extConsumer != null) {
             removeWindowLayoutInfoListener(extConsumer);
@@ -191,6 +198,17 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
         }
     }
 
+    @GuardedBy("mLock")
+    private void updateListenerRegistrations() {
+        ActivityThread currentThread = ActivityThread.currentActivityThread();
+        if (mJavaToExtConsumers.isEmpty()) {
+            currentThread.removeConfigurationChangedListener(mRawConfigurationChangedListener);
+        } else {
+            currentThread.addConfigurationChangedListener(Runnable::run,
+                    mRawConfigurationChangedListener);
+        }
+    }
+
     @GuardedBy("mLock")
     @NonNull
     private Set<Context> getContextsListeningForLayoutChanges() {
@@ -336,25 +354,28 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
                 continue;
             }
             if (featureRect.left != 0 && featureRect.top != 0) {
-                throw new IllegalArgumentException("Bounding rectangle must start at the top or "
+                Log.wtf(TAG, "Bounding rectangle must start at the top or "
                         + "left of the window. BaseFeatureRect: " + baseFeature.getRect()
                         + ", FeatureRect: " + featureRect
                         + ", WindowConfiguration: " + windowConfiguration);
+                continue;
 
             }
             if (featureRect.left == 0
                     && featureRect.width() != windowConfiguration.getBounds().width()) {
-                throw new IllegalArgumentException("Horizontal FoldingFeature must have full width."
+                Log.wtf(TAG, "Horizontal FoldingFeature must have full width."
                         + " BaseFeatureRect: " + baseFeature.getRect()
                         + ", FeatureRect: " + featureRect
                         + ", WindowConfiguration: " + windowConfiguration);
+                continue;
             }
             if (featureRect.top == 0
                     && featureRect.height() != windowConfiguration.getBounds().height()) {
-                throw new IllegalArgumentException("Vertical FoldingFeature must have full height."
+                Log.wtf(TAG, "Vertical FoldingFeature must have full height."
                         + " BaseFeatureRect: " + baseFeature.getRect()
                         + ", FeatureRect: " + featureRect
                         + ", WindowConfiguration: " + windowConfiguration);
+                continue;
             }
             features.add(new FoldingFeature(featureRect, baseFeature.getType(), state));
         }
@@ -407,6 +428,16 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
         }
     }
 
+    private final class RawConfigurationChangedListener implements
+            java.util.function.Consumer<IBinder> {
+        @Override
+        public void accept(IBinder activityToken) {
+            synchronized (mLock) {
+                onDisplayFeaturesChangedIfListening(activityToken);
+            }
+        }
+    }
+
     private final class ConfigurationChangeListener implements ComponentCallbacks {
         final IBinder mToken;
 
-- 
GitLab