Merge "Hide immersive mode confirmation dialog during SurfaceFlingerPerfTests" into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 3abaa69..7913ad1 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -15,12 +15,14 @@
 aconfig_srcjars = [
     ":android.app.usage.flags-aconfig-java{.generated_srcjars}",
     ":android.content.pm.flags-aconfig-java{.generated_srcjars}",
+    ":android.nfc.flags-aconfig-java{.generated_srcjars}",
     ":android.os.flags-aconfig-java{.generated_srcjars}",
     ":android.os.vibrator.flags-aconfig-java{.generated_srcjars}",
     ":android.security.flags-aconfig-java{.generated_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}",
@@ -32,6 +34,7 @@
     ":sdk_sandbox_flags_lib{.generated_srcjars}",
     ":android.permission.flags-aconfig-java{.generated_srcjars}",
     ":hwui_flags_java_lib{.generated_srcjars}",
+    ":display_flags_lib{.generated_srcjars}",
 ]
 
 filegroup {
@@ -121,6 +124,19 @@
     aconfig_declarations: "com.android.text.flags-aconfig",
 }
 
+// NFC
+aconfig_declarations {
+    name: "android.nfc.flags-aconfig",
+    package: "android.nfc",
+    srcs: ["core/java/android/nfc/*.aconfig"],
+}
+
+java_aconfig_library {
+    name: "android.nfc.flags-aconfig-java",
+    aconfig_declarations: "android.nfc.flags-aconfig",
+    defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
+
 // Security
 aconfig_declarations {
     name: "android.security.flags-aconfig",
@@ -271,9 +287,29 @@
     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",
     aconfig_declarations: "hwui_flags",
     defaults: ["framework-minus-apex-aconfig-java-defaults"],
 }
+
+// Display
+java_aconfig_library {
+    name: "display_flags_lib",
+    aconfig_declarations: "display_flags",
+    defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
diff --git a/apct-tests/perftests/core/src/android/accessibility/AccessibilityPerfTest.java b/apct-tests/perftests/core/src/android/accessibility/AccessibilityPerfTest.java
index 7927aa9..885000f 100644
--- a/apct-tests/perftests/core/src/android/accessibility/AccessibilityPerfTest.java
+++ b/apct-tests/perftests/core/src/android/accessibility/AccessibilityPerfTest.java
@@ -22,7 +22,6 @@
 import android.app.Instrumentation;
 import android.app.UiAutomation;
 import android.perftests.utils.PerfTestActivity;
-import android.platform.test.annotations.LargeTest;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
@@ -32,6 +31,7 @@
 
 import androidx.benchmark.BenchmarkState;
 import androidx.benchmark.junit4.BenchmarkRule;
+import androidx.test.filters.LargeTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 import androidx.test.rule.ActivityTestRule;
 
diff --git a/apct-tests/perftests/core/src/android/text/TextViewCursorAnchorInfoPerfTest.java b/apct-tests/perftests/core/src/android/text/TextViewCursorAnchorInfoPerfTest.java
index 898111f..436ee16 100644
--- a/apct-tests/perftests/core/src/android/text/TextViewCursorAnchorInfoPerfTest.java
+++ b/apct-tests/perftests/core/src/android/text/TextViewCursorAnchorInfoPerfTest.java
@@ -22,13 +22,13 @@
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
 import android.perftests.utils.PerfTestActivity;
-import android.platform.test.annotations.LargeTest;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.inputmethod.CursorAnchorInfo;
 import android.widget.TextView;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.rule.ActivityTestRule;
 
 import org.junit.Before;
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index e7ea7c2..a143d6f 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -1762,8 +1762,16 @@
                 sEnqueuedJwiHighWaterMarkLogger.logSampleWithUid(uId, jobStatus.getWorkCount());
             }
 
-            FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED,
-                    uId, null, jobStatus.getBatteryName(),
+            final int sourceUid = uId;
+            FrameworkStatsLog.write(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED,
+                    jobStatus.isProxyJob()
+                            ? new int[]{sourceUid, jobStatus.getUid()} : new int[]{sourceUid},
+                    // Given that the source tag is set by the calling app, it should be connected
+                    // to the calling app in the attribution for a proxied job.
+                    jobStatus.isProxyJob()
+                            ? new String[]{null, jobStatus.getSourceTag()}
+                            : new String[]{jobStatus.getSourceTag()},
+                    jobStatus.getBatteryName(),
                     FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__SCHEDULED,
                     JobProtoEnums.INTERNAL_STOP_REASON_UNKNOWN, jobStatus.getStandbyBucket(),
                     jobStatus.getLoggingJobId(),
@@ -2191,8 +2199,16 @@
                 cancelled, reason, internalReasonCode, debugReason);
         // If the job was running, the JobServiceContext should log with state FINISHED.
         if (!wasRunning) {
-            FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED,
-                    cancelled.getSourceUid(), null, cancelled.getBatteryName(),
+            final int sourceUid = cancelled.getSourceUid();
+            FrameworkStatsLog.write(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED,
+                    cancelled.isProxyJob()
+                            ? new int[]{sourceUid, cancelled.getUid()} : new int[]{sourceUid},
+                    // Given that the source tag is set by the calling app, it should be connected
+                    // to the calling app in the attribution for a proxied job.
+                    cancelled.isProxyJob()
+                            ? new String[]{null, cancelled.getSourceTag()}
+                            : new String[]{cancelled.getSourceTag()},
+                    cancelled.getBatteryName(),
                     FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__CANCELLED,
                     internalReasonCode, cancelled.getStandbyBucket(),
                     cancelled.getLoggingJobId(),
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
index b737041..43d2ae9 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
@@ -470,8 +470,15 @@
                 return false;
             }
             mJobPackageTracker.noteActive(job);
-            FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED,
-                    job.getSourceUid(), null, job.getBatteryName(),
+            final int sourceUid = job.getSourceUid();
+            FrameworkStatsLog.write(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED,
+                    job.isProxyJob() ? new int[]{sourceUid, job.getUid()} : new int[]{sourceUid},
+                    // Given that the source tag is set by the calling app, it should be connected
+                    // to the calling app in the attribution for a proxied job.
+                    job.isProxyJob()
+                            ? new String[]{null, job.getSourceTag()}
+                            : new String[]{job.getSourceTag()},
+                    job.getBatteryName(),
                     FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__STARTED,
                     JobProtoEnums.INTERNAL_STOP_REASON_UNKNOWN,
                     job.getStandbyBucket(),
@@ -1531,8 +1538,16 @@
         }
         mJobPackageTracker.noteInactive(completedJob,
                 loggingInternalStopReason, loggingDebugReason);
-        FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED,
-                completedJob.getSourceUid(), null, completedJob.getBatteryName(),
+        final int sourceUid = completedJob.getSourceUid();
+        FrameworkStatsLog.write(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED,
+                completedJob.isProxyJob()
+                        ? new int[]{sourceUid, completedJob.getUid()} : new int[]{sourceUid},
+                // Given that the source tag is set by the calling app, it should be connected
+                // to the calling app in the attribution for a proxied job.
+                completedJob.isProxyJob()
+                        ? new String[]{null, completedJob.getSourceTag()}
+                        : new String[]{completedJob.getSourceTag()},
+                completedJob.getBatteryName(),
                 FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__FINISHED,
                 loggingInternalStopReason, completedJob.getStandbyBucket(),
                 completedJob.getLoggingJobId(),
diff --git a/apex/jobscheduler/service/java/com/android/server/job/TEST_MAPPING b/apex/jobscheduler/service/java/com/android/server/job/TEST_MAPPING
index d9c4632..8504b1f 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/TEST_MAPPING
+++ b/apex/jobscheduler/service/java/com/android/server/job/TEST_MAPPING
@@ -4,7 +4,7 @@
             "name": "CtsJobSchedulerTestCases",
             "options": [
                 {"exclude-annotation": "android.platform.test.annotations.FlakyTest"},
-                {"exclude-annotation": "android.platform.test.annotations.LargeTest"},
+                {"exclude-annotation": "androidx.test.filters.LargeTest"},
                 {"exclude-annotation": "androidx.test.filters.FlakyTest"},
                 {"exclude-annotation": "androidx.test.filters.LargeTest"}
             ]
@@ -14,7 +14,7 @@
             "options": [
                 {"include-filter": "com.android.server.job"},
                 {"exclude-annotation": "android.platform.test.annotations.FlakyTest"},
-                {"exclude-annotation": "android.platform.test.annotations.LargeTest"},
+                {"exclude-annotation": "androidx.test.filters.LargeTest"},
                 {"exclude-annotation": "androidx.test.filters.FlakyTest"}
             ]
         },
@@ -23,7 +23,7 @@
             "options": [
                 {"include-filter": "com.android.server.job"},
                 {"exclude-annotation": "android.platform.test.annotations.FlakyTest"},
-                {"exclude-annotation": "android.platform.test.annotations.LargeTest"},
+                {"exclude-annotation": "androidx.test.filters.LargeTest"},
                 {"exclude-annotation": "androidx.test.filters.FlakyTest"}
             ]
         }
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
index e0c766f..458ff35 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
@@ -255,6 +255,9 @@
 
     final String tag;
 
+    /** Whether this job was scheduled by one app on behalf of another. */
+    final boolean mIsProxyJob;
+
     private GrantedUriPermissions uriPerms;
     private boolean prepared;
 
@@ -626,6 +629,9 @@
                 : bnNamespace + job.getService().flattenToShortString();
         this.tag = "*job*/" + this.batteryName + "#" + job.getId();
 
+        final String componentPackage = job.getService().getPackageName();
+        mIsProxyJob = !this.sourcePackageName.equals(componentPackage);
+
         this.earliestRunTimeElapsedMillis = earliestRunTimeElapsedMillis;
         this.latestRunTimeElapsedMillis = latestRunTimeElapsedMillis;
         this.mOriginalLatestRunTimeElapsedMillis = latestRunTimeElapsedMillis;
@@ -1048,6 +1054,11 @@
         return mLoggingJobId;
     }
 
+    /** Returns whether this job was scheduled by one app on behalf of another. */
+    public boolean isProxyJob() {
+        return mIsProxyJob;
+    }
+
     public void printUniqueId(PrintWriter pw) {
         if (mNamespace != null) {
             pw.print(mNamespace);
@@ -1292,6 +1303,12 @@
         return mNamespaceHash;
     }
 
+    /**
+     * Returns the tag passed by the calling app to describe the source app work. This is primarily
+     * only valid if {@link #isProxyJob()} returns true, but may be non-null if an app uses
+     * {@link JobScheduler#scheduleAsPackage(JobInfo, String, int, String)} for itself.
+     */
+    @Nullable
     public String getSourceTag() {
         return sourceTag;
     }
@@ -1871,9 +1888,13 @@
         mReadyDynamicSatisfied = mDynamicConstraints != 0
                 && mDynamicConstraints == (satisfiedConstraints & mDynamicConstraints);
         if (STATS_LOG_ENABLED && (STATSD_CONSTRAINTS_TO_LOG & constraint) != 0) {
-            FrameworkStatsLog.write_non_chained(
+            FrameworkStatsLog.write(
                     FrameworkStatsLog.SCHEDULED_JOB_CONSTRAINT_CHANGED,
-                    sourceUid, null, getBatteryName(), getProtoConstraint(constraint),
+                    isProxyJob() ? new int[]{sourceUid, getUid()} : new int[]{sourceUid},
+                    // Given that the source tag is set by the calling app, it should be connected
+                    // to the calling app in the attribution for a proxied job.
+                    isProxyJob() ? new String[]{null, sourceTag} : new String[]{sourceTag},
+                    getBatteryName(), getProtoConstraint(constraint),
                     state ? FrameworkStatsLog.SCHEDULED_JOB_CONSTRAINT_CHANGED__STATE__SATISFIED
                             : FrameworkStatsLog
                                     .SCHEDULED_JOB_CONSTRAINT_CHANGED__STATE__UNSATISFIED);
diff --git a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
index 9dedf70..0d3dc49 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 @@
                 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/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 3de7748..9b8d2b4 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -554,6 +554,30 @@
 
 }
 
+package android.se.omapi {
+
+  @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public class SeFrameworkInitializer {
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @Nullable public static android.se.omapi.SeServiceManager getSeServiceManager();
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public static void setSeServiceManager(@NonNull android.se.omapi.SeServiceManager);
+  }
+
+  @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public class SeServiceManager {
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public android.se.omapi.SeServiceManager.ServiceRegisterer getSeManagerServiceRegisterer();
+  }
+
+  @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public static class SeServiceManager.ServiceNotFoundException extends java.lang.Exception {
+    ctor @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public SeServiceManager.ServiceNotFoundException(@NonNull String);
+  }
+
+  @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public static final class SeServiceManager.ServiceRegisterer {
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @Nullable public android.os.IBinder get();
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public android.os.IBinder getOrThrow() throws android.se.omapi.SeServiceManager.ServiceNotFoundException;
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void register(@NonNull android.os.IBinder);
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @Nullable public android.os.IBinder tryGet();
+  }
+
+}
+
 package android.telecom {
 
   public abstract class ConnectionService extends android.app.Service {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 7c78f09..ad65806 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -3232,6 +3232,7 @@
     method public int getDefaultActivityPolicy();
     method public int getDefaultNavigationPolicy();
     method public int getDevicePolicy(int);
+    method @FlaggedApi(Flags.FLAG_VDM_CUSTOM_HOME) @Nullable public android.content.ComponentName getHomeComponent();
     method public int getLockState();
     method @Nullable public String getName();
     method @NonNull public java.util.Set<android.os.UserHandle> getUsersWithMatchingAccounts();
@@ -3263,6 +3264,7 @@
     method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setBlockedActivities(@NonNull java.util.Set<android.content.ComponentName>);
     method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setBlockedCrossTaskNavigations(@NonNull java.util.Set<android.content.ComponentName>);
     method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setDevicePolicy(int, int);
+    method @FlaggedApi(Flags.FLAG_VDM_CUSTOM_HOME) @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setHomeComponent(@Nullable android.content.ComponentName);
     method @NonNull @RequiresPermission(value=android.Manifest.permission.ADD_ALWAYS_UNLOCKED_DISPLAY, conditional=true) public android.companion.virtual.VirtualDeviceParams.Builder setLockState(int);
     method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setName(@NonNull String);
     method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setUsersWithMatchingAccounts(@NonNull java.util.Set<android.os.UserHandle>);
@@ -9627,6 +9629,73 @@
 
 }
 
+package android.nfc.cardemulation {
+
+  @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public final class AidGroup implements android.os.Parcelable {
+    ctor @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public AidGroup(@NonNull java.util.List<java.lang.String>, @Nullable String);
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @Nullable public static android.nfc.cardemulation.AidGroup createFromXml(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public int describeContents();
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void dump(@NonNull android.util.proto.ProtoOutputStream);
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public java.util.List<java.lang.String> getAids();
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public String getCategory();
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void writeAsXml(@NonNull org.xmlpull.v1.XmlSerializer) throws java.io.IOException;
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public static final android.os.Parcelable.Creator<android.nfc.cardemulation.AidGroup> CREATOR;
+  }
+
+  @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public final class ApduServiceInfo implements android.os.Parcelable {
+    ctor @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public ApduServiceInfo(@NonNull android.content.pm.PackageManager, @NonNull android.content.pm.ResolveInfo, boolean) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public int describeContents();
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void dump(@NonNull android.os.ParcelFileDescriptor, @NonNull java.io.PrintWriter, @NonNull String[]);
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void dumpDebug(@NonNull android.util.proto.ProtoOutputStream);
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public java.util.List<android.nfc.cardemulation.AidGroup> getAidGroups();
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public java.util.List<java.lang.String> getAids();
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public String getCategoryForAid(@NonNull String);
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public android.content.ComponentName getComponent();
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public String getDescription();
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public android.nfc.cardemulation.AidGroup getDynamicAidGroupForCategory(@NonNull String);
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @Nullable public String getOffHostSecureElement();
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public java.util.List<java.lang.String> getPrefixAids();
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public String getSettingsActivityName();
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public java.util.List<java.lang.String> getSubsetAids();
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public int getUid();
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public boolean hasCategory(@NonNull String);
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public boolean isOnHost();
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public CharSequence loadAppLabel(@NonNull android.content.pm.PackageManager);
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public android.graphics.drawable.Drawable loadBanner(@NonNull android.content.pm.PackageManager);
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public android.graphics.drawable.Drawable loadIcon(@NonNull android.content.pm.PackageManager);
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public CharSequence loadLabel(@NonNull android.content.pm.PackageManager);
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public boolean removeDynamicAidGroupForCategory(@NonNull String);
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public boolean requiresScreenOn();
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public boolean requiresUnlock();
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void resetOffHostSecureElement();
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void setDynamicAidGroup(@NonNull android.nfc.cardemulation.AidGroup);
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void setOffHostSecureElement(@NonNull String);
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public static final android.os.Parcelable.Creator<android.nfc.cardemulation.ApduServiceInfo> CREATOR;
+  }
+
+  @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public final class NfcFServiceInfo implements android.os.Parcelable {
+    ctor @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public NfcFServiceInfo(@NonNull android.content.pm.PackageManager, @NonNull android.content.pm.ResolveInfo) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public int describeContents();
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void dump(@NonNull android.os.ParcelFileDescriptor, @NonNull java.io.PrintWriter, @NonNull String[]);
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void dumpDebug(@NonNull android.util.proto.ProtoOutputStream);
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public android.content.ComponentName getComponent();
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public String getDescription();
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public String getNfcid2();
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public String getSystemCode();
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public String getT3tPmm();
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public int getUid();
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public android.graphics.drawable.Drawable loadIcon(@NonNull android.content.pm.PackageManager);
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public CharSequence loadLabel(@NonNull android.content.pm.PackageManager);
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void setDynamicNfcid2(@NonNull String);
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void setDynamicSystemCode(@NonNull String);
+    method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public static final android.os.Parcelable.Creator<android.nfc.cardemulation.NfcFServiceInfo> CREATOR;
+  }
+
+}
+
 package android.os {
 
   public class BatteryManager {
@@ -10635,12 +10704,14 @@
     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/api/system-lint-baseline.txt b/core/api/system-lint-baseline.txt
index ee031db..b11a686 100644
--- a/core/api/system-lint-baseline.txt
+++ b/core/api/system-lint-baseline.txt
@@ -251,6 +251,18 @@
     New API must be flagged with @FlaggedApi: method android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.isBatteryCharging()
 UnflaggedApi: android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.Builder#setBatteryCharging(boolean):
     New API must be flagged with @FlaggedApi: method android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.Builder.setBatteryCharging(boolean)
+UnflaggedApi: android.nfc.cardemulation.AidGroup#CONTENTS_FILE_DESCRIPTOR:
+    New API must be flagged with @FlaggedApi: field android.nfc.cardemulation.AidGroup.CONTENTS_FILE_DESCRIPTOR
+UnflaggedApi: android.nfc.cardemulation.AidGroup#PARCELABLE_WRITE_RETURN_VALUE:
+    New API must be flagged with @FlaggedApi: field android.nfc.cardemulation.AidGroup.PARCELABLE_WRITE_RETURN_VALUE
+UnflaggedApi: android.nfc.cardemulation.ApduServiceInfo#CONTENTS_FILE_DESCRIPTOR:
+    New API must be flagged with @FlaggedApi: field android.nfc.cardemulation.ApduServiceInfo.CONTENTS_FILE_DESCRIPTOR
+UnflaggedApi: android.nfc.cardemulation.ApduServiceInfo#PARCELABLE_WRITE_RETURN_VALUE:
+    New API must be flagged with @FlaggedApi: field android.nfc.cardemulation.ApduServiceInfo.PARCELABLE_WRITE_RETURN_VALUE
+UnflaggedApi: android.nfc.cardemulation.NfcFServiceInfo#CONTENTS_FILE_DESCRIPTOR:
+    New API must be flagged with @FlaggedApi: field android.nfc.cardemulation.NfcFServiceInfo.CONTENTS_FILE_DESCRIPTOR
+UnflaggedApi: android.nfc.cardemulation.NfcFServiceInfo#PARCELABLE_WRITE_RETURN_VALUE:
+    New API must be flagged with @FlaggedApi: field android.nfc.cardemulation.NfcFServiceInfo.PARCELABLE_WRITE_RETURN_VALUE
 UnflaggedApi: android.os.BugreportParams#BUGREPORT_MODE_ONBOARDING:
     New API must be flagged with @FlaggedApi: field android.os.BugreportParams.BUGREPORT_MODE_ONBOARDING
 UnflaggedApi: android.provider.Settings#ACTION_APP_PERMISSIONS_SETTINGS:
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index b4f6d6f..4f45691 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -5192,11 +5192,21 @@
      * @hide
      */
     public static void broadcastStickyIntent(Intent intent, int appOp, Bundle options, int userId) {
+        broadcastStickyIntent(intent, null, appOp, options, userId);
+    }
+
+    /**
+     * Convenience for sending a sticky broadcast.  For internal use only.
+     *
+     * @hide
+     */
+    public static void broadcastStickyIntent(Intent intent, String[] excludedPackages,
+            int appOp, Bundle options, int userId) {
         try {
             getService().broadcastIntentWithFeature(
                     null, null, intent, null, null, Activity.RESULT_OK, null, null,
                     null /*requiredPermissions*/, null /*excludedPermissions*/,
-                    null /*excludedPackages*/, appOp, options, false, true, userId);
+                    excludedPackages, appOp, options, false, true, userId);
         } catch (RemoteException ex) {
         }
     }
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index c54a7d9..25c48e6 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -167,6 +167,8 @@
 import android.provider.FontsContract;
 import android.provider.Settings;
 import android.renderscript.RenderScriptCacheDir;
+import android.se.omapi.SeFrameworkInitializer;
+import android.se.omapi.SeServiceManager;
 import android.security.NetworkSecurityPolicy;
 import android.security.net.config.NetworkSecurityConfigProvider;
 import android.system.ErrnoException;
@@ -266,6 +268,7 @@
 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
@@ -383,6 +386,11 @@
     @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;
@@ -3609,6 +3617,21 @@
         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 +6275,8 @@
                                 " did not call through to super.onConfigurationChanged()");
             }
         }
+        mConfigurationChangedListenerController
+                .dispatchOnConfigurationChanged(activity.getActivityToken());
 
         return configToReport;
     }
@@ -8379,8 +8404,8 @@
             BinderCallsStats.startForBluetooth(context);
         });
         NfcFrameworkInitializer.setNfcServiceManager(new NfcServiceManager());
-
         DeviceConfigInitializer.setDeviceConfigServiceManager(new DeviceConfigServiceManager());
+        SeFrameworkInitializer.setSeServiceManager(new SeServiceManager());
     }
 
     private void purgePendingResources() {
diff --git a/core/java/android/app/ConfigurationChangedListenerController.java b/core/java/android/app/ConfigurationChangedListenerController.java
new file mode 100644
index 0000000..c644d57
--- /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/core/java/android/app/TEST_MAPPING b/core/java/android/app/TEST_MAPPING
index 93107ce..315a055 100644
--- a/core/java/android/app/TEST_MAPPING
+++ b/core/java/android/app/TEST_MAPPING
@@ -138,7 +138,7 @@
                     "include-annotation": "android.platform.test.annotations.Presubmit"
                 },
                 {
-                    "exclude-annotation": "android.platform.test.annotations.LargeTest"
+                    "exclude-annotation": "androidx.test.filters.LargeTest"
                 },
                 {
                     "exclude-annotation": "androidx.test.filters.FlakyTest"
diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java
index 634089b..5f8b765 100644
--- a/core/java/android/app/TaskInfo.java
+++ b/core/java/android/app/TaskInfo.java
@@ -255,6 +255,12 @@
     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 @@
                 && Objects.equals(mTopActivityLocusId, that.mTopActivityLocusId)
                 && parentTaskId == that.parentTaskId
                 && Objects.equals(topActivity, that.topActivity)
-                && isUserFullscreenOverrideEnabled == that.isUserFullscreenOverrideEnabled;
+                && isUserFullscreenOverrideEnabled == that.isUserFullscreenOverrideEnabled
+                && isTopActivityTransparent == that.isTopActivityTransparent;
     }
 
     /**
@@ -583,7 +590,9 @@
                     == that.configuration.getLayoutDirection())
                 && (!hasCompatUI() || configuration.uiMode == that.configuration.uiMode)
                 && (!hasCompatUI() || isVisible == that.isVisible)
-                && isUserFullscreenOverrideEnabled == that.isUserFullscreenOverrideEnabled;
+                && isFocused == that.isFocused
+                && isUserFullscreenOverrideEnabled == that.isUserFullscreenOverrideEnabled
+                && isTopActivityTransparent == that.isTopActivityTransparent;
     }
 
     /**
@@ -640,6 +649,7 @@
         topActivityLetterboxWidth = source.readInt();
         topActivityLetterboxHeight = source.readInt();
         isUserFullscreenOverrideEnabled = source.readBoolean();
+        isTopActivityTransparent = source.readBoolean();
     }
 
     /**
@@ -697,6 +707,7 @@
         dest.writeInt(topActivityLetterboxWidth);
         dest.writeInt(topActivityLetterboxHeight);
         dest.writeBoolean(isUserFullscreenOverrideEnabled);
+        dest.writeBoolean(isTopActivityTransparent);
     }
 
     @Override
@@ -744,6 +755,7 @@
                 + " topActivityLetterboxWidth=" + topActivityLetterboxWidth
                 + " topActivityLetterboxHeight=" + topActivityLetterboxHeight
                 + " isUserFullscreenOverrideEnabled=" + isUserFullscreenOverrideEnabled
+                + " isTopActivityTransparent=" + isTopActivityTransparent
                 + " locusId=" + mTopActivityLocusId
                 + " displayAreaFeatureId=" + displayAreaFeatureId
                 + " cameraCompatControlState="
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index c31aa01..fce5e4f 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -2429,11 +2429,8 @@
     }
 
     /**
-     * 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 @@
 
     /**
      * 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 @@
      */
     @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 @@
      * 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 @@
      */
     @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());
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 213e5cb..7704486 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -10335,11 +10335,14 @@
      * @return the current credential manager policy if null then this policy has not been
      * configured.
      */
+    @UserHandleAware(
+            enabledSinceTargetSdkVersion = UPSIDE_DOWN_CAKE,
+            requiresPermissionIfNotCaller = INTERACT_ACROSS_USERS)
     public @Nullable PackagePolicy getCredentialManagerPolicy() {
         throwIfParentInstance("getCredentialManagerPolicy");
         if (mService != null) {
             try {
-                return mService.getCredentialManagerPolicy();
+                return mService.getCredentialManagerPolicy(myUserId());
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index c49b820..58f9d57 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -346,7 +346,7 @@
     boolean hasManagedProfileCallerIdAccess(int userId, String packageName);
 
     void setCredentialManagerPolicy(in PackagePolicy policy);
-    PackagePolicy getCredentialManagerPolicy();
+    PackagePolicy getCredentialManagerPolicy(int userId);
 
     void setManagedProfileContactsAccessPolicy(in PackagePolicy policy);
     PackagePolicy getManagedProfileContactsAccessPolicy();
diff --git a/core/java/android/app/backup/BackupManagerMonitor.java b/core/java/android/app/backup/BackupManagerMonitor.java
index f73366b..812bf8e 100644
--- a/core/java/android/app/backup/BackupManagerMonitor.java
+++ b/core/java/android/app/backup/BackupManagerMonitor.java
@@ -18,6 +18,7 @@
 
 import android.annotation.SystemApi;
 import android.app.backup.BackupAnnotations.OperationType;
+import android.content.pm.PackageInfo;
 import android.os.Bundle;
 
 /**
@@ -190,6 +191,56 @@
   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/core/java/android/companion/virtual/VirtualDeviceParams.java b/core/java/android/companion/virtual/VirtualDeviceParams.java
index b4c740ec..0fa78c8 100644
--- a/core/java/android/companion/virtual/VirtualDeviceParams.java
+++ b/core/java/android/companion/virtual/VirtualDeviceParams.java
@@ -229,6 +229,7 @@
     @Nullable private final String mName;
     // Mapping of @PolicyType to @DevicePolicy
     @NonNull private final SparseIntArray mDevicePolicies;
+    @Nullable private final ComponentName mHomeComponent;
     @NonNull private final List<VirtualSensorConfig> mVirtualSensorConfigs;
     @Nullable private final IVirtualSensorCallback mVirtualSensorCallback;
     private final int mAudioPlaybackSessionId;
@@ -243,6 +244,7 @@
             @NonNull Set<ComponentName> activityPolicyExemptions,
             @Nullable String name,
             @NonNull SparseIntArray devicePolicies,
+            @Nullable ComponentName homeComponent,
             @NonNull List<VirtualSensorConfig> virtualSensorConfigs,
             @Nullable IVirtualSensorCallback virtualSensorCallback,
             int audioPlaybackSessionId,
@@ -258,6 +260,7 @@
                 new ArraySet<>(Objects.requireNonNull(activityPolicyExemptions));
         mName = name;
         mDevicePolicies = Objects.requireNonNull(devicePolicies);
+        mHomeComponent = homeComponent;
         mVirtualSensorConfigs = Objects.requireNonNull(virtualSensorConfigs);
         mVirtualSensorCallback = virtualSensorCallback;
         mAudioPlaybackSessionId = audioPlaybackSessionId;
@@ -280,6 +283,7 @@
                 IVirtualSensorCallback.Stub.asInterface(parcel.readStrongBinder());
         mAudioPlaybackSessionId = parcel.readInt();
         mAudioRecordingSessionId = parcel.readInt();
+        mHomeComponent = parcel.readTypedObject(ComponentName.CREATOR);
     }
 
     /**
@@ -291,6 +295,19 @@
     }
 
     /**
+     * Returns the custom component used as home on all displays owned by this virtual device that
+     * support home activities.
+     *
+     * @see Builder#setHomeComponent
+     */
+    // TODO(b/297168328): Link to the relevant API for creating displays with home support.
+    @FlaggedApi(Flags.FLAG_VDM_CUSTOM_HOME)
+    @Nullable
+    public ComponentName getHomeComponent() {
+        return mHomeComponent;
+    }
+
+    /**
      * Returns the user handles with matching managed accounts on the remote device to which
      * this virtual device is streaming.
      *
@@ -468,6 +485,7 @@
                 mVirtualSensorCallback != null ? mVirtualSensorCallback.asBinder() : null);
         dest.writeInt(mAudioPlaybackSessionId);
         dest.writeInt(mAudioRecordingSessionId);
+        dest.writeTypedObject(mHomeComponent, flags);
     }
 
     @Override
@@ -508,7 +526,7 @@
         int hashCode = Objects.hash(
                 mLockState, mUsersWithMatchingAccounts, mCrossTaskNavigationExemptions,
                 mDefaultNavigationPolicy, mActivityPolicyExemptions, mDefaultActivityPolicy, mName,
-                mDevicePolicies, mAudioPlaybackSessionId, mAudioRecordingSessionId);
+                mDevicePolicies, mHomeComponent, mAudioPlaybackSessionId, mAudioRecordingSessionId);
         for (int i = 0; i < mDevicePolicies.size(); i++) {
             hashCode = 31 * hashCode + mDevicePolicies.keyAt(i);
             hashCode = 31 * hashCode + mDevicePolicies.valueAt(i);
@@ -528,6 +546,7 @@
                 + " mActivityPolicyExemptions=" + mActivityPolicyExemptions
                 + " mName=" + mName
                 + " mDevicePolicies=" + mDevicePolicies
+                + " mHomeComponent=" + mHomeComponent
                 + " mAudioPlaybackSessionId=" + mAudioPlaybackSessionId
                 + " mAudioRecordingSessionId=" + mAudioRecordingSessionId
                 + ")";
@@ -588,6 +607,7 @@
         @Nullable private VirtualSensorCallback mVirtualSensorCallback;
         @Nullable private Executor mVirtualSensorDirectChannelCallbackExecutor;
         @Nullable private VirtualSensorDirectChannelCallback mVirtualSensorDirectChannelCallback;
+        @Nullable private ComponentName mHomeComponent;
 
         private static class VirtualSensorCallbackDelegate extends IVirtualSensorCallback.Stub {
             @NonNull
@@ -665,6 +685,23 @@
         }
 
         /**
+         * Specifies a component to be used as home on all displays owned by this virtual device
+         * that support home activities.
+         * *
+         * <p>Note: Only relevant for virtual displays that support home activities.</p>
+         *
+         * @param homeComponent The component name to be used as home. If unset, then the system-
+         *   default secondary home activity will be used.
+         */
+        // TODO(b/297168328): Link to the relevant API for creating displays with home support.
+        @FlaggedApi(Flags.FLAG_VDM_CUSTOM_HOME)
+        @NonNull
+        public Builder setHomeComponent(@Nullable ComponentName homeComponent) {
+            mHomeComponent = homeComponent;
+            return this;
+        }
+
+        /**
          * Sets the user handles with matching managed accounts on the remote device to which
          * this virtual device is streaming. The caller is responsible for verifying the presence
          * and legitimacy of a matching managed account on the remote device.
@@ -1031,6 +1068,7 @@
                     mActivityPolicyExemptions,
                     mName,
                     mDevicePolicies,
+                    mHomeComponent,
                     mVirtualSensorConfigs,
                     virtualSensorCallbackDelegate,
                     mAudioPlaybackSessionId,
diff --git a/core/java/android/companion/virtual/flags.aconfig b/core/java/android/companion/virtual/flags.aconfig
index ee36f18..3e96c96 100644
--- a/core/java/android/companion/virtual/flags.aconfig
+++ b/core/java/android/companion/virtual/flags.aconfig
@@ -15,6 +15,13 @@
 }
 
 flag {
+  name: "vdm_custom_home"
+  namespace: "virtual_devices"
+  description: "Enable custom home API"
+  bug: "297168328"
+}
+
+flag {
   name: "vdm_public_apis"
   namespace: "virtual_devices"
   description: "Enable public VDM API for device capabilities"
diff --git a/core/java/android/content/TEST_MAPPING b/core/java/android/content/TEST_MAPPING
index 01a9373..addede4 100644
--- a/core/java/android/content/TEST_MAPPING
+++ b/core/java/android/content/TEST_MAPPING
@@ -7,7 +7,7 @@
           "include-annotation": "android.platform.test.annotations.Presubmit"
         },
         {
-          "exclude-annotation": "android.platform.test.annotations.LargeTest"
+          "exclude-annotation": "androidx.test.filters.LargeTest"
         },
         {
           "exclude-annotation": "androidx.test.filters.FlakyTest"
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 3165e29..dbaa4c9 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.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 @@
         }
         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;
         }
     }
diff --git a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
index 257ad71..5b24fb6 100644
--- a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
@@ -218,7 +218,8 @@
             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 {}
 
@@ -310,6 +311,12 @@
     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
      */
     int FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000;
diff --git a/core/java/android/hardware/biometrics/flags.aconfig b/core/java/android/hardware/biometrics/flags.aconfig
new file mode 100644
index 0000000..66429e5
--- /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"
+}
+
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index b1aa7de..4700720 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -32,6 +32,7 @@
 import android.view.SurfaceControl.RefreshRateRange;
 import android.view.SurfaceControl.Transaction;
 import android.window.DisplayWindowPolicyController;
+import android.window.ScreenCapture;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -111,6 +112,25 @@
     public abstract void unregisterDisplayGroupListener(DisplayGroupListener listener);
 
     /**
+     * Screenshot for internal system-only use such as rotation, etc.  This method includes
+     * secure layers and the result should never be exposed to non-system applications.
+     * This method does not apply any rotation and provides the output in natural orientation.
+     *
+     * @param displayId The display id to take the screenshot of.
+     * @return The buffer or null if we have failed.
+     */
+    public abstract ScreenCapture.ScreenshotHardwareBuffer systemScreenshot(int displayId);
+
+    /**
+     * General screenshot functionality that excludes secure layers and applies appropriate
+     * rotation that the device is currently in.
+     *
+     * @param displayId The display id to take the screenshot of.
+     * @return The buffer or null if we have failed.
+     */
+    public abstract ScreenCapture.ScreenshotHardwareBuffer userScreenshot(int displayId);
+
+    /**
      * Returns information about the specified logical display.
      *
      * @param displayId The logical display id.
diff --git a/core/java/android/nfc/cardemulation/AidGroup.java b/core/java/android/nfc/cardemulation/AidGroup.java
index 2436e57..958669e 100644
--- a/core/java/android/nfc/cardemulation/AidGroup.java
+++ b/core/java/android/nfc/cardemulation/AidGroup.java
@@ -16,7 +16,11 @@
 
 package android.nfc.cardemulation;
 
-import android.compat.annotation.UnsupportedAppUsage;
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.nfc.Flags;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.Log;
@@ -29,6 +33,11 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Locale;
+
+/**********************************************************************
+ * This file is not a part of the NFC mainline module                 *
+ * *******************************************************************/
 
 /**
  * The AidGroup class represents a group of Application Identifiers (AIDs).
@@ -39,28 +48,30 @@
  *
  * @hide
  */
+@SystemApi
+@FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
 public final class AidGroup implements Parcelable {
     /**
      * The maximum number of AIDs that can be present in any one group.
      */
-    public static final int MAX_NUM_AIDS = 256;
+    private static final int MAX_NUM_AIDS = 256;
 
-    static final String TAG = "AidGroup";
+    private static final String TAG = "AidGroup";
 
-    @UnsupportedAppUsage
-    final List<String> aids;
-    @UnsupportedAppUsage
-    final String category;
-    @UnsupportedAppUsage
-    final String description;
+
+    private final List<String> mAids;
+    private final String mCategory;
+    @SuppressWarnings("unused") // Unused as of now, but part of the XML input.
+    private final String mDescription;
 
     /**
      * Creates a new AidGroup object.
      *
-     * @param aids The list of AIDs present in the group
-     * @param category The category of this group, e.g. {@link CardEmulation#CATEGORY_PAYMENT}
+     * @param aids list of AIDs present in the group
+     * @param category category of this group, e.g. {@link CardEmulation#CATEGORY_PAYMENT}
      */
-    public AidGroup(List<String> aids, String category) {
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    public AidGroup(@NonNull List<String> aids, @Nullable String category) {
         if (aids == null || aids.size() == 0) {
             throw new IllegalArgumentException("No AIDS in AID group.");
         }
@@ -73,45 +84,55 @@
             }
         }
         if (isValidCategory(category)) {
-            this.category = category;
+            this.mCategory = category;
         } else {
-            this.category = CardEmulation.CATEGORY_OTHER;
+            this.mCategory = CardEmulation.CATEGORY_OTHER;
         }
-        this.aids = new ArrayList<String>(aids.size());
+        this.mAids = new ArrayList<String>(aids.size());
         for (String aid : aids) {
-            this.aids.add(aid.toUpperCase());
+            this.mAids.add(aid.toUpperCase(Locale.US));
         }
-        this.description = null;
-    }
-
-    @UnsupportedAppUsage
-    AidGroup(String category, String description) {
-        this.aids = new ArrayList<String>();
-        this.category = category;
-        this.description = description;
+        this.mDescription = null;
     }
 
     /**
+     * Creates a new AidGroup object.
+     *
+     * @param category category of this group, e.g. {@link CardEmulation#CATEGORY_PAYMENT}
+     * @param description description of this group
+     */
+    AidGroup(@NonNull String category, @NonNull String description) {
+        this.mAids = new ArrayList<String>();
+        this.mCategory = category;
+        this.mDescription = description;
+    }
+
+    /**
+     * Returns the category of this group.
      * @return the category of this AID group
      */
-    @UnsupportedAppUsage
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    @NonNull
     public String getCategory() {
-        return category;
+        return mCategory;
     }
 
     /**
+     * Returns the list of AIDs in this group.
+     *
      * @return the list of AIDs in this group
      */
-    @UnsupportedAppUsage
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    @NonNull
     public List<String> getAids() {
-        return aids;
+        return mAids;
     }
 
     @Override
     public String toString() {
-        StringBuilder out = new StringBuilder("Category: " + category +
-                  ", AIDs:");
-        for (String aid : aids) {
+        StringBuilder out = new StringBuilder("Category: " + mCategory
+                + ", AIDs:");
+        for (String aid : mAids) {
             out.append(aid);
             out.append(", ");
         }
@@ -119,41 +140,44 @@
     }
 
     /**
-     * Dump debugging info as AidGroupProto
+     * Dump debugging info as AidGroupProto.
      *
      * If the output belongs to a sub message, the caller is responsible for wrapping this function
      * between {@link ProtoOutputStream#start(long)} and {@link ProtoOutputStream#end(long)}.
      *
      * @param proto the ProtoOutputStream to write to
      */
-    public void dump(ProtoOutputStream proto) {
-        proto.write(AidGroupProto.CATEGORY, category);
-        for (String aid : aids) {
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    public void dump(@NonNull ProtoOutputStream proto) {
+        proto.write(AidGroupProto.CATEGORY, mCategory);
+        for (String aid : mAids) {
             proto.write(AidGroupProto.AIDS, aid);
         }
     }
 
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
     @Override
     public int describeContents() {
         return 0;
     }
 
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
     @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(category);
-        dest.writeInt(aids.size());
-        if (aids.size() > 0) {
-            dest.writeStringList(aids);
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString8(mCategory);
+        dest.writeInt(mAids.size());
+        if (mAids.size() > 0) {
+            dest.writeStringList(mAids);
         }
     }
 
-    @UnsupportedAppUsage
-    public static final @android.annotation.NonNull Parcelable.Creator<AidGroup> CREATOR =
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    public static final @NonNull Parcelable.Creator<AidGroup> CREATOR =
             new Parcelable.Creator<AidGroup>() {
 
         @Override
         public AidGroup createFromParcel(Parcel source) {
-            String category = source.readString();
+            String category = source.readString8();
             int listSize = source.readInt();
             ArrayList<String> aidList = new ArrayList<String>();
             if (listSize > 0) {
@@ -168,8 +192,17 @@
         }
     };
 
-    @UnsupportedAppUsage
-    static public AidGroup createFromXml(XmlPullParser parser) throws XmlPullParserException, IOException {
+    /**
+     * Create an instance of AID group from XML file.
+     *
+     * @param parser input xml parser stream
+     * @throws XmlPullParserException If an error occurs parsing the element.
+     * @throws IOException If an error occurs reading the element.
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    @Nullable
+    public static AidGroup createFromXml(@NonNull XmlPullParser parser)
+            throws XmlPullParserException, IOException {
         String category = null;
         ArrayList<String> aids = new ArrayList<String>();
         AidGroup group = null;
@@ -210,11 +243,16 @@
         return group;
     }
 
-    @UnsupportedAppUsage
-    public void writeAsXml(XmlSerializer out) throws IOException {
+    /**
+     * Serialize instance of AID group to XML file.
+     * @param out XML serializer stream
+     * @throws IOException If an error occurs reading the element.
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    public void writeAsXml(@NonNull XmlSerializer out) throws IOException {
         out.startTag(null, "aid-group");
-        out.attribute(null, "category", category);
-        for (String aid : aids) {
+        out.attribute(null, "category", mCategory);
+        for (String aid : mAids) {
             out.startTag(null, "aid");
             out.attribute(null, "value", aid);
             out.endTag(null, "aid");
@@ -222,7 +260,7 @@
         out.endTag(null, "aid-group");
     }
 
-    static boolean isValidCategory(String category) {
+    private static boolean isValidCategory(String category) {
         return CardEmulation.CATEGORY_PAYMENT.equals(category) ||
                 CardEmulation.CATEGORY_OTHER.equals(category);
     }
diff --git a/core/java/android/nfc/cardemulation/ApduServiceInfo.java b/core/java/android/nfc/cardemulation/ApduServiceInfo.java
index 793a70e..18ec914 100644
--- a/core/java/android/nfc/cardemulation/ApduServiceInfo.java
+++ b/core/java/android/nfc/cardemulation/ApduServiceInfo.java
@@ -14,10 +14,16 @@
  * limitations under the License.
  */
 
+/**********************************************************************
+ * This file is not a part of the NFC mainline module                 *
+ * *******************************************************************/
+
 package android.nfc.cardemulation;
 
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.compat.annotation.UnsupportedAppUsage;
+import android.annotation.SystemApi;
 import android.content.ComponentName;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -28,7 +34,9 @@
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
 import android.graphics.drawable.Drawable;
+import android.nfc.Flags;
 import android.os.Parcel;
+import android.os.ParcelFileDescriptor;
 import android.os.Parcelable;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -38,7 +46,6 @@
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
-import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -47,82 +54,82 @@
 import java.util.Map;
 
 /**
+ * Class holding APDU service info.
+ *
  * @hide
  */
+@SystemApi
+@FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
 public final class ApduServiceInfo implements Parcelable {
-    static final String TAG = "ApduServiceInfo";
+    private static final String TAG = "ApduServiceInfo";
 
     /**
      * The service that implements this
      */
-    @UnsupportedAppUsage
-    final ResolveInfo mService;
+    private final ResolveInfo mService;
 
     /**
      * Description of the service
      */
-    final String mDescription;
+    private final String mDescription;
 
     /**
      * Whether this service represents AIDs running on the host CPU
      */
-    final boolean mOnHost;
+    private final boolean mOnHost;
 
     /**
      * Offhost reader name.
      * eg: SIM, eSE etc
      */
-    String mOffHostName;
+    private String mOffHostName;
 
     /**
      * Offhost reader name from manifest file.
-     * Used for unsetOffHostSecureElement()
+     * Used for resetOffHostSecureElement()
      */
-    final String mStaticOffHostName;
+    private final String mStaticOffHostName;
 
     /**
      * Mapping from category to static AID group
      */
-    @UnsupportedAppUsage
-    final HashMap<String, AidGroup> mStaticAidGroups;
+    private final HashMap<String, AidGroup> mStaticAidGroups;
 
     /**
      * Mapping from category to dynamic AID group
      */
-    @UnsupportedAppUsage
-    final HashMap<String, AidGroup> mDynamicAidGroups;
+    private final HashMap<String, AidGroup> mDynamicAidGroups;
 
     /**
      * Whether this service should only be started when the device is unlocked.
      */
-    final boolean mRequiresDeviceUnlock;
+    private final boolean mRequiresDeviceUnlock;
 
     /**
      * Whether this service should only be started when the device is screen on.
      */
-    final boolean mRequiresDeviceScreenOn;
+    private final boolean mRequiresDeviceScreenOn;
 
     /**
      * The id of the service banner specified in XML.
      */
-    final int mBannerResourceId;
+    private final int mBannerResourceId;
 
     /**
      * The uid of the package the service belongs to
      */
-    final int mUid;
+    private final int mUid;
 
     /**
      * Settings Activity for this service
      */
-    final String mSettingsActivityName;
+    private final String mSettingsActivityName;
 
     /**
      * @hide
      */
-    @UnsupportedAppUsage
     public ApduServiceInfo(ResolveInfo info, boolean onHost, String description,
-            ArrayList<AidGroup> staticAidGroups, ArrayList<AidGroup> dynamicAidGroups,
+            List<AidGroup> staticAidGroups, List<AidGroup> dynamicAidGroups,
             boolean requiresUnlock, int bannerResource, int uid,
             String settingsActivityName, String offHost, String staticOffHost) {
         this(info, onHost, description, staticAidGroups, dynamicAidGroups,
@@ -134,7 +141,7 @@
      * @hide
      */
     public ApduServiceInfo(ResolveInfo info, boolean onHost, String description,
-            ArrayList<AidGroup> staticAidGroups, ArrayList<AidGroup> dynamicAidGroups,
+            List<AidGroup> staticAidGroups, List<AidGroup> dynamicAidGroups,
             boolean requiresUnlock, boolean requiresScreenOn, int bannerResource, int uid,
             String settingsActivityName, String offHost, String staticOffHost) {
         this.mService = info;
@@ -147,19 +154,28 @@
         this.mRequiresDeviceUnlock = requiresUnlock;
         this.mRequiresDeviceScreenOn = requiresScreenOn;
         for (AidGroup aidGroup : staticAidGroups) {
-            this.mStaticAidGroups.put(aidGroup.category, aidGroup);
+            this.mStaticAidGroups.put(aidGroup.getCategory(), aidGroup);
         }
         for (AidGroup aidGroup : dynamicAidGroups) {
-            this.mDynamicAidGroups.put(aidGroup.category, aidGroup);
+            this.mDynamicAidGroups.put(aidGroup.getCategory(), aidGroup);
         }
         this.mBannerResourceId = bannerResource;
         this.mUid = uid;
         this.mSettingsActivityName = settingsActivityName;
     }
 
-    @UnsupportedAppUsage
-    public ApduServiceInfo(PackageManager pm, ResolveInfo info, boolean onHost) throws
-            XmlPullParserException, IOException {
+    /**
+     * Creates a new ApduServiceInfo object.
+     *
+     * @param pm packageManager instance
+     * @param info app component info
+     * @param onHost whether service is on host or not (secure element)
+     * @throws XmlPullParserException If an error occurs parsing the element.
+     * @throws IOException If an error occurs reading the element.
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    public ApduServiceInfo(@NonNull PackageManager pm, @NonNull ResolveInfo info, boolean onHost)
+            throws XmlPullParserException, IOException {
         ServiceInfo si = info.serviceInfo;
         XmlResourceParser parser = null;
         try {
@@ -277,9 +293,9 @@
                     groupAttrs.recycle();
                 } else if (eventType == XmlPullParser.END_TAG && "aid-group".equals(tagName) &&
                         currentGroup != null) {
-                    if (currentGroup.aids.size() > 0) {
-                        if (!mStaticAidGroups.containsKey(currentGroup.category)) {
-                            mStaticAidGroups.put(currentGroup.category, currentGroup);
+                    if (currentGroup.getAids().size() > 0) {
+                        if (!mStaticAidGroups.containsKey(currentGroup.getCategory())) {
+                            mStaticAidGroups.put(currentGroup.getCategory(), currentGroup);
                         }
                     } else {
                         Log.e(TAG, "Not adding <aid-group> with empty or invalid AIDs");
@@ -291,8 +307,8 @@
                             com.android.internal.R.styleable.AidFilter);
                     String aid = a.getString(com.android.internal.R.styleable.AidFilter_name).
                             toUpperCase();
-                    if (CardEmulation.isValidAid(aid) && !currentGroup.aids.contains(aid)) {
-                        currentGroup.aids.add(aid);
+                    if (CardEmulation.isValidAid(aid) && !currentGroup.getAids().contains(aid)) {
+                        currentGroup.getAids().add(aid);
                     } else {
                         Log.e(TAG, "Ignoring invalid or duplicate aid: " + aid);
                     }
@@ -305,8 +321,8 @@
                             toUpperCase();
                     // Add wildcard char to indicate prefix
                     aid = aid.concat("*");
-                    if (CardEmulation.isValidAid(aid) && !currentGroup.aids.contains(aid)) {
-                        currentGroup.aids.add(aid);
+                    if (CardEmulation.isValidAid(aid) && !currentGroup.getAids().contains(aid)) {
+                        currentGroup.getAids().add(aid);
                     } else {
                         Log.e(TAG, "Ignoring invalid or duplicate aid: " + aid);
                     }
@@ -319,8 +335,8 @@
                             toUpperCase();
                     // Add wildcard char to indicate suffix
                     aid = aid.concat("#");
-                    if (CardEmulation.isValidAid(aid) && !currentGroup.aids.contains(aid)) {
-                        currentGroup.aids.add(aid);
+                    if (CardEmulation.isValidAid(aid) && !currentGroup.getAids().contains(aid)) {
+                        currentGroup.getAids().add(aid);
                     } else {
                         Log.e(TAG, "Ignoring invalid or duplicate aid: " + aid);
                     }
@@ -336,11 +352,25 @@
         mUid = si.applicationInfo.uid;
     }
 
+    /**
+     * Returns the app component corresponding to this APDU service.
+     *
+     * @return app component for this service
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    @NonNull
     public ComponentName getComponent() {
         return new ComponentName(mService.serviceInfo.packageName,
                 mService.serviceInfo.name);
     }
 
+    /**
+     * Returns the offhost secure element name (if the service is offhost).
+     *
+     * @return offhost secure element name for offhost services
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    @Nullable
     public String getOffHostSecureElement() {
         return mOffHostName;
     }
@@ -353,18 +383,30 @@
      * for that category.
      * @return List of AIDs registered by the service
      */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    @NonNull
     public List<String> getAids() {
         final ArrayList<String> aids = new ArrayList<String>();
         for (AidGroup group : getAidGroups()) {
-            aids.addAll(group.aids);
+            aids.addAll(group.getAids());
         }
         return aids;
     }
 
+    /**
+     * Returns a consolidated list of AIDs with prefixes from the AID groups
+     * registered by this service. Note that if a service has both
+     * a static (manifest-based) AID group for a category and a dynamic
+     * AID group, only the dynamically registered AIDs will be returned
+     * for that category.
+     * @return List of prefix AIDs registered by the service
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    @NonNull
     public List<String> getPrefixAids() {
         final ArrayList<String> prefixAids = new ArrayList<String>();
         for (AidGroup group : getAidGroups()) {
-            for (String aid : group.aids) {
+            for (String aid : group.getAids()) {
                 if (aid.endsWith("*")) {
                     prefixAids.add(aid);
                 }
@@ -373,10 +415,20 @@
         return prefixAids;
     }
 
+    /**
+     * Returns a consolidated list of AIDs with subsets from the AID groups
+     * registered by this service. Note that if a service has both
+     * a static (manifest-based) AID group for a category and a dynamic
+     * AID group, only the dynamically registered AIDs will be returned
+     * for that category.
+     * @return List of prefix AIDs registered by the service
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    @NonNull
     public List<String> getSubsetAids() {
         final ArrayList<String> subsetAids = new ArrayList<String>();
         for (AidGroup group : getAidGroups()) {
-            for (String aid : group.aids) {
+            for (String aid : group.getAids()) {
                 if (aid.endsWith("#")) {
                     subsetAids.add(aid);
                 }
@@ -384,14 +436,28 @@
         }
         return subsetAids;
     }
+
     /**
      * Returns the registered AID group for this category.
+     *
+     * @param category category name
+     * @return {@link AidGroup} instance for the provided category
      */
-    public AidGroup getDynamicAidGroupForCategory(String category) {
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    @NonNull
+    public AidGroup getDynamicAidGroupForCategory(@NonNull String category) {
         return mDynamicAidGroups.get(category);
     }
 
-    public boolean removeDynamicAidGroupForCategory(String category) {
+    /**
+     * Removes the registered AID group for this category.
+     *
+     * @param category category name
+     * @return {@code true} if an AID group existed
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    @NonNull
+    public boolean removeDynamicAidGroupForCategory(@NonNull String category) {
         return (mDynamicAidGroups.remove(category) != null);
     }
 
@@ -403,7 +469,9 @@
      * for that category.
      * @return List of AIDs registered by the service
      */
-    public ArrayList<AidGroup> getAidGroups() {
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    @NonNull
+    public List<AidGroup> getAidGroups() {
         final ArrayList<AidGroup> groups = new ArrayList<AidGroup>();
         for (Map.Entry<String, AidGroup> entry : mDynamicAidGroups.entrySet()) {
             groups.add(entry.getValue());
@@ -421,49 +489,83 @@
     /**
      * Returns the category to which this service has attributed the AID that is passed in,
      * or null if we don't know this AID.
+     * @param aid AID to lookup for
+     * @return category name corresponding to this AID
      */
-    public String getCategoryForAid(String aid) {
-        ArrayList<AidGroup> groups = getAidGroups();
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    @NonNull
+    public String getCategoryForAid(@NonNull String aid) {
+        List<AidGroup> groups = getAidGroups();
         for (AidGroup group : groups) {
-            if (group.aids.contains(aid.toUpperCase())) {
-                return group.category;
+            if (group.getAids().contains(aid.toUpperCase())) {
+                return group.getCategory();
             }
         }
         return null;
     }
 
-    public boolean hasCategory(String category) {
+    /**
+     * Returns whether there is any AID group for this category.
+     * @param category category name
+     * @return {@code true} if an AID group exists
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    public boolean hasCategory(@NonNull String category) {
         return (mStaticAidGroups.containsKey(category) || mDynamicAidGroups.containsKey(category));
     }
 
-    @UnsupportedAppUsage
+    /**
+     * Returns whether the service is on host or not.
+     * @return true if the service is on host (not secure element)
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
     public boolean isOnHost() {
         return mOnHost;
     }
 
-    @UnsupportedAppUsage
+    /**
+     * Returns whether the service requires device unlock.
+     * @return whether the service requires device unlock
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
     public boolean requiresUnlock() {
         return mRequiresDeviceUnlock;
     }
 
     /**
      * Returns whether this service should only be started when the device is screen on.
+     * @return whether the service requires screen on
      */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
     public boolean requiresScreenOn() {
         return mRequiresDeviceScreenOn;
     }
 
-    @UnsupportedAppUsage
+    /**
+     * Returns description of service.
+     * @return user readable description of service
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    @NonNull
     public String getDescription() {
         return mDescription;
     }
 
-    @UnsupportedAppUsage
+    /**
+     * Returns uid of service.
+     * @return uid of the service
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
     public int getUid() {
         return mUid;
     }
 
-    public void setOrReplaceDynamicAidGroup(AidGroup aidGroup) {
+    /**
+     * Add or replace an AID group to this service.
+     * @param aidGroup instance of aid group to set or replace
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    public void setDynamicAidGroup(@NonNull AidGroup aidGroup) {
         mDynamicAidGroups.put(aidGroup.getCategory(), aidGroup);
     }
 
@@ -476,7 +578,8 @@
      *                  TS26_NFC_REQ_070: For embedded SE, Secure Element Name SHALL be eSE[number]
      *                                    (e.g. eSE/eSE1, eSE2, etc.).
      */
-    public void setOffHostSecureElement(String offHost) {
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    public void setOffHostSecureElement(@NonNull String offHost) {
         mOffHostName = offHost;
     }
 
@@ -484,15 +587,30 @@
      * Resets the off host Secure Element to statically defined
      * by the service in the manifest file.
      */
-    public void unsetOffHostSecureElement() {
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    public void resetOffHostSecureElement() {
         mOffHostName = mStaticOffHostName;
     }
 
-    public CharSequence loadLabel(PackageManager pm) {
+    /**
+     * Load label for this service.
+     * @param pm packagemanager instance
+     * @return label name corresponding to service
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    @NonNull
+    public CharSequence loadLabel(@NonNull PackageManager pm) {
         return mService.loadLabel(pm);
     }
 
-    public CharSequence loadAppLabel(PackageManager pm) {
+    /**
+     * Load application label for this service.
+     * @param pm packagemanager instance
+     * @return app label name corresponding to service
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    @NonNull
+    public CharSequence loadAppLabel(@NonNull PackageManager pm) {
         try {
             return pm.getApplicationLabel(pm.getApplicationInfo(
                     mService.resolvePackageName, PackageManager.GET_META_DATA));
@@ -501,12 +619,25 @@
         }
     }
 
-    public Drawable loadIcon(PackageManager pm) {
+    /**
+     * Load application icon for this service.
+     * @param pm packagemanager instance
+     * @return app icon corresponding to service
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    @NonNull
+    public Drawable loadIcon(@NonNull PackageManager pm) {
         return mService.loadIcon(pm);
     }
 
-    @UnsupportedAppUsage
-    public Drawable loadBanner(PackageManager pm) {
+    /**
+     * Load application banner for this service.
+     * @param pm packagemanager instance
+     * @return app banner corresponding to service
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    @NonNull
+    public Drawable loadBanner(@NonNull PackageManager pm) {
         Resources res;
         try {
             res = pm.getResourcesForApplication(mService.serviceInfo.packageName);
@@ -521,7 +652,12 @@
         }
     }
 
-    @UnsupportedAppUsage
+    /**
+     * Load activity name for this service.
+     * @return activity name for this service
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    @NonNull
     public String getSettingsActivityName() { return mSettingsActivityName; }
 
     @Override
@@ -556,14 +692,15 @@
         return getComponent().hashCode();
     }
 
-
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
     @Override
     public int describeContents() {
         return 0;
     }
 
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
     @Override
-    public void writeToParcel(Parcel dest, int flags) {
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
         mService.writeToParcel(dest, flags);
         dest.writeString(mDescription);
         dest.writeInt(mOnHost ? 1 : 0);
@@ -584,8 +721,8 @@
         dest.writeString(mSettingsActivityName);
     };
 
-    @UnsupportedAppUsage
-    public static final @android.annotation.NonNull Parcelable.Creator<ApduServiceInfo> CREATOR =
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    public static final @NonNull Parcelable.Creator<ApduServiceInfo> CREATOR =
             new Parcelable.Creator<ApduServiceInfo>() {
         @Override
         public ApduServiceInfo createFromParcel(Parcel source) {
@@ -620,7 +757,15 @@
         }
     };
 
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+    /**
+     * Dump contents for debugging.
+     * @param fd parcelfiledescriptor instance
+     * @param pw printwriter instance
+     * @param args args for dumping
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    public void dump(@NonNull ParcelFileDescriptor fd, @NonNull PrintWriter pw,
+                     @NonNull String[] args) {
         pw.println("    " + getComponent()
                 + " (Description: " + getDescription() + ")"
                 + " (UID: " + getUid() + ")");
@@ -633,15 +778,15 @@
         }
         pw.println("    Static AID groups:");
         for (AidGroup group : mStaticAidGroups.values()) {
-            pw.println("        Category: " + group.category);
-            for (String aid : group.aids) {
+            pw.println("        Category: " + group.getCategory());
+            for (String aid : group.getAids()) {
                 pw.println("            AID: " + aid);
             }
         }
         pw.println("    Dynamic AID groups:");
         for (AidGroup group : mDynamicAidGroups.values()) {
-            pw.println("        Category: " + group.category);
-            for (String aid : group.aids) {
+            pw.println("        Category: " + group.getCategory());
+            for (String aid : group.getAids()) {
                 pw.println("            AID: " + aid);
             }
         }
@@ -651,7 +796,7 @@
     }
 
     /**
-     * Dump debugging info as ApduServiceInfoProto
+     * Dump debugging info as ApduServiceInfoProto.
      *
      * If the output belongs to a sub message, the caller is responsible for wrapping this function
      * between {@link ProtoOutputStream#start(long)} and {@link ProtoOutputStream#end(long)}.
@@ -659,7 +804,8 @@
      *
      * @param proto the ProtoOutputStream to write to
      */
-    public void dumpDebug(ProtoOutputStream proto) {
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    public void dumpDebug(@NonNull ProtoOutputStream proto) {
         Utils.dumpDebugComponentName(getComponent(), proto, ApduServiceInfoProto.COMPONENT_NAME);
         proto.write(ApduServiceInfoProto.DESCRIPTION, getDescription());
         proto.write(ApduServiceInfoProto.ON_HOST, mOnHost);
diff --git a/core/java/android/nfc/cardemulation/NfcFServiceInfo.java b/core/java/android/nfc/cardemulation/NfcFServiceInfo.java
index 7a36b26..ec919e4 100644
--- a/core/java/android/nfc/cardemulation/NfcFServiceInfo.java
+++ b/core/java/android/nfc/cardemulation/NfcFServiceInfo.java
@@ -14,9 +14,16 @@
  * limitations under the License.
  */
 
+/**********************************************************************
+ * This file is not a part of the NFC mainline module                 *
+ * *******************************************************************/
+
 package android.nfc.cardemulation;
 
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.content.ComponentName;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -26,7 +33,9 @@
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
 import android.graphics.drawable.Drawable;
+import android.nfc.Flags;
 import android.os.Parcel;
+import android.os.ParcelFileDescriptor;
 import android.os.Parcelable;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -36,13 +45,16 @@
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
-import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.PrintWriter;
 
 /**
+ * Class to hold NfcF service info.
+ *
  * @hide
  */
+@SystemApi
+@FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
 public final class NfcFServiceInfo implements Parcelable {
     static final String TAG = "NfcFServiceInfo";
 
@@ -51,42 +63,42 @@
     /**
      * The service that implements this
      */
-    final ResolveInfo mService;
+    private final ResolveInfo mService;
 
     /**
      * Description of the service
      */
-    final String mDescription;
+    private final String mDescription;
 
     /**
      * System Code of the service
      */
-    final String mSystemCode;
+    private final String mSystemCode;
 
     /**
      * System Code of the service registered by API
      */
-    String mDynamicSystemCode;
+    private String mDynamicSystemCode;
 
     /**
      * NFCID2 of the service
      */
-    final String mNfcid2;
+    private final String mNfcid2;
 
     /**
      * NFCID2 of the service registered by API
      */
-    String mDynamicNfcid2;
+    private String mDynamicNfcid2;
 
     /**
      * The uid of the package the service belongs to
      */
-    final int mUid;
+    private final int mUid;
 
     /**
      * LF_T3T_PMM of the service
      */
-    final String mT3tPmm;
+    private final String mT3tPmm;
 
     /**
      * @hide
@@ -104,7 +116,16 @@
         this.mT3tPmm = t3tPmm;
     }
 
-    public NfcFServiceInfo(PackageManager pm, ResolveInfo info)
+    /**
+     * Creates a new NfcFServiceInfo object.
+     *
+     * @param pm packageManager instance
+     * @param info app component info
+     * @throws XmlPullParserException If an error occurs parsing the element.
+     * @throws IOException If an error occurs reading the element.
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    public NfcFServiceInfo(@NonNull PackageManager pm, @NonNull ResolveInfo info)
             throws XmlPullParserException, IOException {
         ServiceInfo si = info.serviceInfo;
         XmlResourceParser parser = null;
@@ -192,44 +213,107 @@
         mUid = si.applicationInfo.uid;
     }
 
+    /**
+     * Returns the app component corresponding to this NFCF service.
+     *
+     * @return app component for this service
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    @NonNull
     public ComponentName getComponent() {
         return new ComponentName(mService.serviceInfo.packageName,
                 mService.serviceInfo.name);
     }
 
+    /**
+     * Returns the system code corresponding to this service.
+     *
+     * @return system code for this service
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    @NonNull
     public String getSystemCode() {
         return (mDynamicSystemCode == null ? mSystemCode : mDynamicSystemCode);
     }
 
-    public void setOrReplaceDynamicSystemCode(String systemCode) {
+    /**
+     * Add or replace a system code to this service.
+     * @param systemCode system code to set or replace
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    public void setDynamicSystemCode(@NonNull String systemCode) {
         mDynamicSystemCode = systemCode;
     }
 
+    /**
+     * Returns NFC ID2.
+     *
+     * @return nfc id2 to return
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    @NonNull
     public String getNfcid2() {
         return (mDynamicNfcid2 == null ? mNfcid2 : mDynamicNfcid2);
     }
 
-    public void setOrReplaceDynamicNfcid2(String nfcid2) {
+    /**
+     * Set or replace NFC ID2
+     *
+     * @param nfcid2 NFC ID2 string
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    public void setDynamicNfcid2(@NonNull String nfcid2) {
         mDynamicNfcid2 = nfcid2;
     }
 
+    /**
+     * Returns description of service.
+     * @return user readable description of service
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    @NonNull
     public String getDescription() {
         return mDescription;
     }
 
+    /**
+     * Returns uid of service.
+     * @return uid of the service
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
     public int getUid() {
         return mUid;
     }
 
+    /**
+     * Returns LF_T3T_PMM of the service
+     * @return returns LF_T3T_PMM of the service
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    @NonNull
     public String getT3tPmm() {
         return mT3tPmm;
     }
 
-    public CharSequence loadLabel(PackageManager pm) {
+    /**
+     * Load application label for this service.
+     * @param pm packagemanager instance
+     * @return label name corresponding to service
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    @NonNull
+    public CharSequence loadLabel(@NonNull PackageManager pm) {
         return mService.loadLabel(pm);
     }
 
-    public Drawable loadIcon(PackageManager pm) {
+    /**
+     * Load application icon for this service.
+     * @param pm packagemanager instance
+     * @return app icon corresponding to service
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    @NonNull
+    public Drawable loadIcon(@NonNull PackageManager pm) {
         return mService.loadIcon(pm);
     }
 
@@ -270,13 +354,15 @@
         return getComponent().hashCode();
     }
 
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
     @Override
     public int describeContents() {
         return 0;
     }
 
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
     @Override
-    public void writeToParcel(Parcel dest, int flags) {
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
         mService.writeToParcel(dest, flags);
         dest.writeString(mDescription);
         dest.writeString(mSystemCode);
@@ -293,7 +379,8 @@
         dest.writeString(mT3tPmm);
     };
 
-    public static final @android.annotation.NonNull Parcelable.Creator<NfcFServiceInfo> CREATOR =
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    public static final @NonNull Parcelable.Creator<NfcFServiceInfo> CREATOR =
             new Parcelable.Creator<NfcFServiceInfo>() {
         @Override
         public NfcFServiceInfo createFromParcel(Parcel source) {
@@ -322,7 +409,15 @@
         }
     };
 
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+    /**
+     * Dump contents of the service for debugging.
+     * @param fd parcelfiledescriptor instance
+     * @param pw printwriter instance
+     * @param args args for dumping
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    public void dump(@NonNull ParcelFileDescriptor fd, @NonNull PrintWriter pw,
+                     @NonNull String[] args) {
         pw.println("    " + getComponent()
                 + " (Description: " + getDescription() + ")"
                 + " (UID: " + getUid() + ")");
@@ -332,14 +427,15 @@
     }
 
     /**
-     * Dump debugging info as NfcFServiceInfoProto
+     * Dump debugging info as NfcFServiceInfoProto.
      *
      * If the output belongs to a sub message, the caller is responsible for wrapping this function
      * between {@link ProtoOutputStream#start(long)} and {@link ProtoOutputStream#end(long)}.
      *
      * @param proto the ProtoOutputStream to write to
      */
-    public void dumpDebug(ProtoOutputStream proto) {
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    public void dumpDebug(@NonNull ProtoOutputStream proto) {
         Utils.dumpDebugComponentName(getComponent(), proto, NfcFServiceInfoProto.COMPONENT_NAME);
         proto.write(NfcFServiceInfoProto.DESCRIPTION, getDescription());
         proto.write(NfcFServiceInfoProto.SYSTEM_CODE, getSystemCode());
@@ -347,4 +443,3 @@
         proto.write(NfcFServiceInfoProto.T3T_PMM, getT3tPmm());
     }
 }
-
diff --git a/core/java/android/nfc/flags.aconfig b/core/java/android/nfc/flags.aconfig
new file mode 100644
index 0000000..e3faf39
--- /dev/null
+++ b/core/java/android/nfc/flags.aconfig
@@ -0,0 +1,8 @@
+package: "android.nfc"
+
+flag {
+    name: "enable_nfc_mainline"
+    namespace: "nfc"
+    description: "Flag for NFC mainline changes"
+    bug: "292140387"
+}
diff --git a/core/java/android/os/TEST_MAPPING b/core/java/android/os/TEST_MAPPING
index 60622f18..ad3abd9 100644
--- a/core/java/android/os/TEST_MAPPING
+++ b/core/java/android/os/TEST_MAPPING
@@ -7,7 +7,7 @@
       ],
       "name": "FrameworksVibratorCoreTests",
       "options": [
-        {"exclude-annotation": "android.platform.test.annotations.LargeTest"},
+        {"exclude-annotation": "androidx.test.filters.LargeTest"},
         {"exclude-annotation": "android.platform.test.annotations.FlakyTest"},
         {"exclude-annotation": "androidx.test.filters.FlakyTest"},
         {"exclude-annotation": "org.junit.Ignore"}
@@ -20,7 +20,7 @@
       ],
       "name": "FrameworksVibratorServicesTests",
       "options": [
-        {"exclude-annotation": "android.platform.test.annotations.LargeTest"},
+        {"exclude-annotation": "androidx.test.filters.LargeTest"},
         {"exclude-annotation": "android.platform.test.annotations.FlakyTest"},
         {"exclude-annotation": "androidx.test.filters.FlakyTest"},
         {"exclude-annotation": "org.junit.Ignore"}
@@ -33,7 +33,7 @@
       ],
       "name": "CtsVibratorTestCases",
       "options": [
-        {"exclude-annotation": "android.platform.test.annotations.LargeTest"},
+        {"exclude-annotation": "androidx.test.filters.LargeTest"},
         {"exclude-annotation": "android.platform.test.annotations.FlakyTest"},
         {"exclude-annotation": "androidx.test.filters.FlakyTest"},
         {"exclude-annotation": "org.junit.Ignore"}
diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig
index febe6f7..a95e66d 100644
--- a/core/java/android/os/flags.aconfig
+++ b/core/java/android/os/flags.aconfig
@@ -16,7 +16,7 @@
 
 flag {
     name: "allow_private_profile"
-    namespace: "private_profile"
+    namespace: "profile_experiences"
     description: "Guards a new Private Profile type in UserManager - everything from its setup to config to deletion."
     bug: "299069460"
 }
diff --git a/core/java/android/permission/IPermissionController.aidl b/core/java/android/permission/IPermissionController.aidl
index e3f02e7..1cb7930 100644
--- a/core/java/android/permission/IPermissionController.aidl
+++ b/core/java/android/permission/IPermissionController.aidl
@@ -43,7 +43,7 @@
     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 @@
                 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 18ede44d..7cecfdc 100644
--- a/core/java/android/permission/IPermissionManager.aidl
+++ b/core/java/android/permission/IPermissionManager.aidl
@@ -78,7 +78,7 @@
     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 84a197a..ba75918 100644
--- a/core/java/android/permission/PermissionControllerManager.java
+++ b/core/java/android/permission/PermissionControllerManager.java
@@ -764,13 +764,14 @@
      * 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 @@
             @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 11005a6..9fe2599 100644
--- a/core/java/android/permission/PermissionControllerService.java
+++ b/core/java/android/permission/PermissionControllerService.java
@@ -30,6 +30,7 @@
 
 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.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.ParcelFileDescriptor;
 import android.os.UserHandle;
 import android.permission.PermissionControllerManager.CountPermissionAppsFlag;
+import android.permission.flags.Flags;
 import android.util.ArrayMap;
 import android.util.Log;
 
@@ -296,13 +299,32 @@
      * 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
      *
      * @param permissionGroupName The permission group whose permissions are desired
@@ -341,13 +363,42 @@
      * @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 @@
             }
 
             @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 @@
 
             @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 @@
                         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 7d39210..e10ea10 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -214,6 +214,12 @@
     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>
      * Type: {@code List<PermissionGroupUsage>}
@@ -1392,8 +1398,8 @@
             @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/core/java/android/printservice/PrintService.java b/core/java/android/printservice/PrintService.java
index ecf1770..dc02470 100644
--- a/core/java/android/printservice/PrintService.java
+++ b/core/java/android/printservice/PrintService.java
@@ -178,7 +178,7 @@
      * <pre> &lt;print-service
      *     android:vendor="SomeVendor"
      *     android:settingsActivity="foo.bar.MySettingsActivity"
-     *     andorid:addPrintersActivity="foo.bar.MyAddPrintersActivity."
+     *     android:addPrintersActivity="foo.bar.MyAddPrintersActivity."
      *     . . .
      * /&gt;</pre>
      * <p>
diff --git a/core/java/android/security/FileIntegrityManager.java b/core/java/android/security/FileIntegrityManager.java
index d6f3bf3..2dbb5da 100644
--- a/core/java/android/security/FileIntegrityManager.java
+++ b/core/java/android/security/FileIntegrityManager.java
@@ -49,9 +49,18 @@
     }
 
     /**
-     * Returns true if APK Verity is supported on the device. When supported, an APK can be
-     * installed with a fs-verity signature (if verified with trusted App Source Certificate) for
-     * continuous on-access verification.
+     * Returns whether fs-verity is supported on the device. fs-verity provides on-access
+     * verification, although the app APIs are only made available to apps in a later SDK version.
+     * Only when this method returns true, the other fs-verity APIs in the same class can succeed.
+     *
+     * <p>The app may not need this method and just call the other APIs (i.e. {@link
+     * #setupFsVerity(File)} and {@link #getFsVerityDigest(File)}) normally and handle any failure.
+     * If some app feature really depends on fs-verity (e.g. protecting integrity of a large file
+     * download), an early check of support status may avoid any cost if it is to fail late.
+     *
+     * <p>Note: for historical reasons this is named {@code isApkVeritySupported()} instead of
+     * {@code isFsVeritySupported()}. It has also been available since API level 30, predating the
+     * other fs-verity APIs.
      */
     public boolean isApkVeritySupported() {
         try {
diff --git a/core/java/android/service/notification/TEST_MAPPING b/core/java/android/service/notification/TEST_MAPPING
index 59b2bc1..7b8d52f 100644
--- a/core/java/android/service/notification/TEST_MAPPING
+++ b/core/java/android/service/notification/TEST_MAPPING
@@ -13,9 +13,6 @@
           "exclude-annotation": "org.junit.Ignore"
         },
         {
-          "exclude-annotation": "android.platform.test.annotations.LargeTest"
-        },
-        {
           "exclude-annotation": "androidx.test.filters.LargeTest"
         }
       ]
@@ -33,9 +30,6 @@
           "exclude-annotation": "org.junit.Ignore"
         },
         {
-          "exclude-annotation": "android.platform.test.annotations.LargeTest"
-        },
-        {
           "exclude-annotation": "androidx.test.filters.LargeTest"
         }
       ]
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index bb4cc8f..b17d2d1 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -1990,8 +1990,23 @@
     }
 
     /**
-     * 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/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 052c2832..be6fb31 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -263,6 +263,8 @@
             long nativeObject, int compatibility);
     private static native void nativeSetFrameRateCategory(
             long transactionObj, long nativeObject, int category);
+    private static native void nativeSetFrameRateSelectionStrategy(
+            long transactionObj, long nativeObject, int strategy);
     private static native long nativeGetHandle(long nativeObject);
 
     private static native void nativeSetFixedTransformHint(long transactionObj, long nativeObject,
@@ -850,6 +852,35 @@
      */
     public static final int METADATA_GAME_MODE = 8;
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"FRAME_RATE_SELECTION_STRATEGY_"},
+            value = {FRAME_RATE_SELECTION_STRATEGY_SELF,
+                    FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN})
+    public @interface FrameRateSelectionStrategy {}
+
+    // From window.h. Keep these in sync.
+    /**
+     * Default value. The layer uses its own frame rate specifications, assuming it has any
+     * specifications, instead of its parent's.
+     * However, {@link #FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN} on an ancestor layer
+     * supersedes this behavior, meaning that this layer will inherit the frame rate specifications
+     * of that ancestor layer.
+     * @hide
+     */
+    public static final int FRAME_RATE_SELECTION_STRATEGY_SELF = 0;
+
+    /**
+     * The layer's frame rate specifications will propagate to and override those of its descendant
+     * layers.
+     * The layer with this strategy has the {@link #FRAME_RATE_SELECTION_STRATEGY_SELF} behavior
+     * for itself. This does mean that any parent or ancestor layer that also has the strategy
+     * {@link FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN} will override this layer's
+     * frame rate specifications.
+     * @hide
+     */
+    public static final int FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN = 1;
+
     /**
      * Builder class for {@link SurfaceControl} objects.
      *
@@ -3669,6 +3700,31 @@
         }
 
         /**
+         * Sets the frame rate selection strategy for the {@link SurfaceControl}.
+         *
+         * This instructs the system on how to choose a display refresh rate, following the
+         * strategy for the layer's frame rate specifications relative to other layers'.
+         *
+         * @param sc The SurfaceControl to specify the frame rate category of.
+         * @param strategy The frame rate selection strategy.
+         *
+         * @return This transaction object.
+         *
+         * @see #setFrameRate(SurfaceControl, float, int, int)
+         * @see #setFrameRateCategory(SurfaceControl, int)
+         * @see #setDefaultFrameRateCompatibility(SurfaceControl, int)
+         *
+         * @hide
+         */
+        @NonNull
+        public Transaction setFrameRateSelectionStrategy(
+                @NonNull SurfaceControl sc, @FrameRateSelectionStrategy int strategy) {
+            checkPreconditions(sc);
+            nativeSetFrameRateSelectionStrategy(mNativeObject, sc.mNativeObject, strategy);
+            return this;
+        }
+
+        /**
          * Sets focus on the window identified by the input {@code token} if the window is focusable
          * otherwise the request is dropped.
          *
diff --git a/core/java/android/view/TEST_MAPPING b/core/java/android/view/TEST_MAPPING
index 1e39716..db35908 100644
--- a/core/java/android/view/TEST_MAPPING
+++ b/core/java/android/view/TEST_MAPPING
@@ -10,7 +10,7 @@
           "include-annotation": "android.platform.test.annotations.Presubmit"
         },
         {
-          "exclude-annotation": "android.platform.test.annotations.LargeTest"
+          "exclude-annotation": "androidx.test.filters.LargeTest"
         },
         {
           "exclude-annotation": "androidx.test.filters.FlakyTest"
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index ff6165b..0ba5d06 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1151,14 +1151,10 @@
     }
 
     private boolean isInTouchMode() {
-        IWindowManager windowManager = WindowManagerGlobal.getWindowManagerService();
-        if (windowManager != null) {
-            try {
-                return windowManager.isInTouchMode(getDisplayId());
-            } catch (RemoteException e) {
-            }
+        if (mAttachInfo == null) {
+            return mContext.getResources().getBoolean(R.bool.config_defaultInTouchMode);
         }
-        return false;
+        return mAttachInfo.mInTouchMode;
     }
 
     /**
diff --git a/core/java/android/view/inputmethod/RemoteInputConnectionImpl.java b/core/java/android/view/inputmethod/RemoteInputConnectionImpl.java
index 61470f2..3557f16 100644
--- a/core/java/android/view/inputmethod/RemoteInputConnectionImpl.java
+++ b/core/java/android/view/inputmethod/RemoteInputConnectionImpl.java
@@ -417,7 +417,9 @@
         if (mBeamer == null) {
             return;
         }
-        mBeamer.forget(token);
+        dispatch(() -> {
+            mBeamer.forget(token);
+        });
     }
 
     @Override
diff --git a/core/java/android/window/DisplayWindowPolicyController.java b/core/java/android/window/DisplayWindowPolicyController.java
index 2747233a..8d71a8e 100644
--- a/core/java/android/window/DisplayWindowPolicyController.java
+++ b/core/java/android/window/DisplayWindowPolicyController.java
@@ -109,6 +109,12 @@
     }
 
     /**
+     * @return the custom home component specified for the relevant display, if any.
+     */
+    @Nullable
+    public abstract ComponentName getCustomHomeComponent();
+
+    /**
      * Returns {@code true} if all of the given activities can be launched on this virtual display
      * in the configuration defined by the rest of the arguments.
      *
diff --git a/core/java/android/window/ScreenCapture.java b/core/java/android/window/ScreenCapture.java
index e42193d..95e9e86 100644
--- a/core/java/android/window/ScreenCapture.java
+++ b/core/java/android/window/ScreenCapture.java
@@ -24,6 +24,7 @@
 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 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 @@
     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(
@@ -52,6 +56,37 @@
     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.
      *
      * @param layer      The root layer to capture.
@@ -484,6 +519,92 @@
     }
 
     /**
+     * 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.
      *
      * @hide
@@ -561,6 +682,7 @@
 
     /**
      * 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 @@
 
     /**
      * 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/java/android/window/flags/windowing_sdk.aconfig b/core/java/android/window/flags/windowing_sdk.aconfig
index b8d251f..ec5d4ff 100644
--- a/core/java/android/window/flags/windowing_sdk.aconfig
+++ b/core/java/android/window/flags/windowing_sdk.aconfig
@@ -15,3 +15,10 @@
     description: "Whether the overlay presentation feature is enabled"
     bug: "243518738"
 }
+
+flag {
+    namespace: "windowing_sdk"
+    name: "task_fragment_system_organizer_flag"
+    description: "Whether the TaskFragment system organizer feature is enabled"
+    bug: "284050041"
+}
diff --git a/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java b/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java
index 4a848f6..cb2d934 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 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/core/java/com/android/internal/infra/AbstractRemoteService.java b/core/java/com/android/internal/infra/AbstractRemoteService.java
index 18414cf..556c246 100644
--- a/core/java/com/android/internal/infra/AbstractRemoteService.java
+++ b/core/java/com/android/internal/infra/AbstractRemoteService.java
@@ -355,9 +355,10 @@
                 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 @@
         } else {
             if (mVerbose) Slog.v(mTag, "handlePendingRequest(): " + pendingRequest);
 
-            mUnfinishedRequests.add(pendingRequest);
+            synchronized (mUnfinishedRequests) {
+                mUnfinishedRequests.add(pendingRequest);
+            }
             cancelScheduledUnbind();
 
             pendingRequest.run();
diff --git a/core/java/com/android/internal/policy/AttributeCache.java b/core/java/com/android/internal/policy/AttributeCache.java
index 1bdad25..970f511 100644
--- a/core/java/com/android/internal/policy/AttributeCache.java
+++ b/core/java/com/android/internal/policy/AttributeCache.java
@@ -16,12 +16,18 @@
 
 package com.android.internal.policy;
 
+import android.annotation.RequiresPermission;
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
+import android.net.Uri;
+import android.os.Handler;
 import android.os.UserHandle;
 import android.util.ArrayMap;
 import android.util.LruCache;
@@ -46,6 +52,8 @@
     @GuardedBy("this")
     private final Configuration mConfiguration = new Configuration();
 
+    private PackageMonitor mPackageMonitor;
+
     public final static class Package {
         public final Context context;
         private final SparseArray<ArrayMap<int[], Entry>> mMap = new SparseArray<>();
@@ -77,6 +85,34 @@
         }
     }
 
+    /**
+     * Start monitor package change, so the resources can be loaded correctly.
+     */
+    void monitorPackageRemove(Handler handler) {
+        if (mPackageMonitor == null) {
+            mPackageMonitor = new PackageMonitor(mContext, handler);
+        }
+    }
+
+    static class PackageMonitor extends BroadcastReceiver {
+        @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
+        PackageMonitor(Context context, Handler handler) {
+            final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED);
+            filter.addDataScheme(IntentFilter.SCHEME_PACKAGE);
+            context.registerReceiverAsUser(this, UserHandle.ALL, filter,
+                    null /* broadcastPermission */, handler);
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final Uri packageUri = intent.getData();
+            if (packageUri != null) {
+                final String packageName = packageUri.getEncodedSchemeSpecificPart();
+                AttributeCache.instance().removePackage(packageName);
+            }
+        }
+    }
+
     public static AttributeCache instance() {
         return sInstance;
     }
diff --git a/core/java/com/android/internal/policy/TransitionAnimation.java b/core/java/com/android/internal/policy/TransitionAnimation.java
index 8f4df80..40a437f 100644
--- a/core/java/com/android/internal/policy/TransitionAnimation.java
+++ b/core/java/com/android/internal/policy/TransitionAnimation.java
@@ -48,6 +48,7 @@
 import android.hardware.HardwareBuffer;
 import android.media.Image;
 import android.media.ImageReader;
+import android.os.Handler;
 import android.os.SystemProperties;
 import android.util.Slog;
 import android.view.InflateException;
@@ -1399,4 +1400,14 @@
         // Approximation of WCAG 2.0 relative luminance.
         return ((r * 8) + (g * 22) + (b * 2)) >> 5;
     }
+
+    /**
+     * For non-system server process, it must call this method to initialize the AttributeCache and
+     * start monitor package change, so the resources can be loaded correctly.
+     */
+    public static void initAttributeCache(Context context, Handler handler) {
+        AttributeCache.init(context);
+        AttributeCache.instance().monitorPackageRemove(handler);
+    }
+
 }
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 74f64b7..9384f41 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -967,6 +967,13 @@
     transaction->setFrameRateCategory(ctrl, static_cast<int8_t>(category));
 }
 
+static void nativeSetFrameRateSelectionStrategy(JNIEnv* env, jclass clazz, jlong transactionObj,
+                                                jlong nativeObject, jint strategy) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+    const auto ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
+    transaction->setFrameRateSelectionStrategy(ctrl, static_cast<int8_t>(strategy));
+}
+
 static void nativeSetFixedTransformHint(JNIEnv* env, jclass clazz, jlong transactionObj,
                                         jlong nativeObject, jint transformHint) {
     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
@@ -2173,6 +2180,8 @@
             (void*)nativeSetDefaultFrameRateCompatibility},
     {"nativeSetFrameRateCategory", "(JJI)V",
             (void*)nativeSetFrameRateCategory},
+    {"nativeSetFrameRateSelectionStrategy", "(JJI)V",
+            (void*)nativeSetFrameRateSelectionStrategy},
     {"nativeSetDisplaySurface", "(JLandroid/os/IBinder;J)V",
             (void*)nativeSetDisplaySurface },
     {"nativeSetDisplayLayerStack", "(JLandroid/os/IBinder;I)V",
diff --git a/core/jni/android_window_ScreenCapture.cpp b/core/jni/android_window_ScreenCapture.cpp
index beb8c9b..bdf7eaa 100644
--- a/core/jni/android_window_ScreenCapture.cpp
+++ b/core/jni/android_window_ScreenCapture.cpp
@@ -50,6 +50,13 @@
 } gCaptureArgsClassInfo;
 
 static struct {
+    jfieldID displayToken;
+    jfieldID width;
+    jfieldID height;
+    jfieldID useIdentityTransform;
+} gDisplayCaptureArgsClassInfo;
+
+static struct {
     jfieldID layer;
     jfieldID childrenOnly;
 } gLayerCaptureArgsClassInfo;
@@ -174,6 +181,39 @@
                                  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 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 @@
     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 =
diff --git a/core/res/res/layout/autofill_fill_dialog.xml b/core/res/res/layout/autofill_fill_dialog.xml
index 37d2fa0..196af6d 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 bed19a8..8b6c901 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>
+                >
+                <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"/>
 
-            <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"/>
+                <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>
+            </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/layout/simple_list_item_multiple_choice.xml b/core/res/res/layout/simple_list_item_multiple_choice.xml
index 440b6fd..fd9bf76 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 02cb7f7..a66308e 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"
diff --git a/core/res/res/values-sw640dp/dimens.xml b/core/res/res/values-sw640dp/dimens.xml
new file mode 100644
index 0000000..c632176
--- /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 0000000..64b20f7
--- /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 0000000..1f0c0b8
--- /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-watch/config.xml b/core/res/res/values-watch/config.xml
index 4027f5c..af30532 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>
diff --git a/core/res/res/values/bools.xml b/core/res/res/values/bools.xml
index fe296c7..b097a61 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 0f2c264a..49295fd 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -874,7 +874,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>
@@ -885,6 +885,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 e0f128d..83fb098 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3653,6 +3653,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"/>
@@ -3709,6 +3710,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/core/tests/GameManagerTests/src/android/app/GameManagerTests.java b/core/tests/GameManagerTests/src/android/app/GameManagerTests.java
index fac3a0e..d34c91e 100644
--- a/core/tests/GameManagerTests/src/android/app/GameManagerTests.java
+++ b/core/tests/GameManagerTests/src/android/app/GameManagerTests.java
@@ -86,16 +86,6 @@
         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/core/tests/coretests/src/android/colormodel/CamTest.java b/core/tests/coretests/src/android/colormodel/CamTest.java
index 5bcc593..05fc0e0 100644
--- a/core/tests/coretests/src/android/colormodel/CamTest.java
+++ b/core/tests/coretests/src/android/colormodel/CamTest.java
@@ -18,7 +18,7 @@
 
 import static org.junit.Assert.assertEquals;
 
-import android.platform.test.annotations.LargeTest;
+import androidx.test.filters.LargeTest;
 
 import org.junit.Assert;
 import org.junit.Test;
diff --git a/core/tests/coretests/src/android/provider/NameValueCacheTest.java b/core/tests/coretests/src/android/provider/NameValueCacheTest.java
index 87e4a42..989c992 100644
--- a/core/tests/coretests/src/android/provider/NameValueCacheTest.java
+++ b/core/tests/coretests/src/android/provider/NameValueCacheTest.java
@@ -55,7 +55,6 @@
  * Due to how the classes are structured, we have to test it in a somewhat roundabout way. We're
  * mocking out the contentProvider and are handcrafting very specific Bundles to answer the queries.
  */
-@Ignore("b/297724333")
 @Presubmit
 @RunWith(AndroidJUnit4.class)
 @SmallTest
@@ -229,6 +228,8 @@
 
     @After
     public void cleanUp() throws IOException {
+        Settings.Config.clearProviderForTest();
+        Settings.Secure.clearProviderForTest();
         mConfigsStorage.clear();
         mSettingsStorage.clear();
         mSettingsCacheGenerationStore.close();
diff --git a/core/tests/fuzzers/ParcelFuzzer/ReadUtils.java b/core/tests/fuzzers/ParcelFuzzer/ReadUtils.java
index b5e5b25..cb98855 100644
--- a/core/tests/fuzzers/ParcelFuzzer/ReadUtils.java
+++ b/core/tests/fuzzers/ParcelFuzzer/ReadUtils.java
@@ -364,6 +364,12 @@
                         TestClassLoader loader = new TestClassLoader();
                         parcel.readParcelableArray(loader);
                     },
+                    (parcel, provider) -> {
+                        parcel.readParcelable(null);
+                    },
+                    (parcel, provider) -> {
+                        parcel.readParcelableArray(null);
+                    },
 
                     // read lists
                     (parcel, provider) -> {
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.bp b/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.bp
index d0645b0..23a2a7fb 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.bp
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.bp
@@ -28,7 +28,7 @@
 
     srcs: ["src/**/*.java"],
 
-    sdk_version: "16",
+    sdk_version: "19",
 
     javacflags: ["-nowarn"],
 
@@ -43,5 +43,5 @@
         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 c0c8aba..4ddaeef 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.bp
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.bp
@@ -40,7 +40,7 @@
         enabled: false,
     },
 
-    min_sdk_version: "16",
+    min_sdk_version: "19",
 }
 
 android_test_helper_app {
@@ -66,5 +66,5 @@
         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 fe29416..afb111d 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyTestAppTests/Android.bp
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestAppTests/Android.bp
@@ -28,7 +28,7 @@
 
     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 c558153..8c57df6 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyTestAppTests2/Android.bp
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestAppTests2/Android.bp
@@ -31,7 +31,7 @@
 
     javacflags: ["-nowarn"],
 
-    min_sdk_version: "16",
+    min_sdk_version: "19",
 
     instrumentation_for: "MultiDexLegacyTestApp",
 }
@@ -51,7 +51,7 @@
 
     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 9a4c3c5..840daab 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 75c753c..2244a83 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyTestServicesTests2/Android.bp
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestServicesTests2/Android.bp
@@ -24,5 +24,5 @@
     libs: ["android-support-multidex"],
     static_libs: ["androidx.test.rules"],
 
-    sdk_version: "16",
+    sdk_version: "19",
 }
diff --git a/core/tests/vibrator/TEST_MAPPING b/core/tests/vibrator/TEST_MAPPING
index f3333d8..2f3afa6 100644
--- a/core/tests/vibrator/TEST_MAPPING
+++ b/core/tests/vibrator/TEST_MAPPING
@@ -3,7 +3,7 @@
     {
       "name": "FrameworksVibratorCoreTests",
       "options": [
-        {"exclude-annotation": "android.platform.test.annotations.LargeTest"},
+        {"exclude-annotation": "androidx.test.filters.LargeTest"},
         {"exclude-annotation": "android.platform.test.annotations.FlakyTest"},
         {"exclude-annotation": "androidx.test.filters.FlakyTest"},
         {"exclude-annotation": "org.junit.Ignore"}
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index e46ba9a..ad0ead7 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/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java
index c3d8f9a..a663f9f 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.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 @@
                     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 ba57b76..9b84a48 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,7 @@
 import static androidx.window.util.ExtensionHelper.transformToWindowSpaceRect;
 
 import android.app.Activity;
-import android.app.ActivityClient;
+import android.app.ActivityThread;
 import android.app.Application;
 import android.app.WindowConfiguration;
 import android.content.ComponentCallbacks;
@@ -34,8 +35,7 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.util.ArrayMap;
-import android.view.WindowManager;
-import android.window.TaskFragmentOrganizer;
+import android.util.Log;
 
 import androidx.annotation.GuardedBy;
 import androidx.annotation.NonNull;
@@ -51,7 +51,6 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
 import java.util.Set;
 
 /**
@@ -63,7 +62,7 @@
  * 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();
 
@@ -85,16 +84,15 @@
     private final Map<java.util.function.Consumer<WindowLayoutInfo>, Consumer<WindowLayoutInfo>>
             mJavaToExtConsumers = new ArrayMap<>();
 
-    private final TaskFragmentOrganizer mTaskFragmentOrganizer;
+    private final RawConfigurationChangedListener mRawConfigurationChangedListener =
+            new RawConfigurationChangedListener();
 
     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;
     }
 
     /**
@@ -109,6 +107,7 @@
         final Consumer<WindowLayoutInfo> extConsumer = consumer::accept;
         synchronized (mLock) {
             mJavaToExtConsumers.put(consumer, extConsumer);
+            updateListenerRegistrations();
         }
         addWindowLayoutInfoListener(activity, extConsumer);
     }
@@ -162,6 +161,7 @@
         final Consumer<WindowLayoutInfo> extConsumer;
         synchronized (mLock) {
             extConsumer = mJavaToExtConsumers.remove(consumer);
+            updateListenerRegistrations();
         }
         if (extConsumer != null) {
             removeWindowLayoutInfoListener(extConsumer);
@@ -192,6 +192,17 @@
     }
 
     @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() {
         return mWindowLayoutChangeListeners.keySet();
@@ -336,25 +347,28 @@
                 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));
         }
@@ -374,38 +388,11 @@
             // 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")
@@ -434,6 +421,16 @@
         }
     }
 
+    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;
 
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 3e0297a..e9df936 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 7e0c207..fa56516 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"
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 39e3180..bb30c5e 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 @@
         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/src/com/android/wm/shell/compatui/CompatUIController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
index 0e6b203..953efa7 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
@@ -176,6 +176,18 @@
     // 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,
@@ -230,6 +242,11 @@
         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);
@@ -322,6 +339,46 @@
         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.isTopActivityTransparent
+                && 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);
     }
@@ -572,7 +629,8 @@
         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 77aefc8..c2dec62 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.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 @@
 
     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 @@
             @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;
@@ -180,11 +192,18 @@
         }
     }
 
+    @VisibleForTesting
+    boolean isShowingButton() {
+        return (mUserAspectRatioButtonShownChecker.get()
+                && !isHideDelayReached(mNextButtonHideTimeMs));
+    }
+
     private void showUserAspectRatioButton() {
         if (mLayout == null) {
             return;
         }
         mLayout.setUserAspectRatioButtonVisibility(true);
+        mUserAspectRatioButtonStateConsumer.accept(true);
         // Only show by default for the first time.
         if (!mCompatUIHintsState.mHasShownUserAspectRatioSettingsButtonHint) {
             mLayout.setUserAspectRatioSettingsHintVisibility(/* show= */ true);
@@ -210,7 +229,8 @@
     private boolean getHasUserAspectRatioSettingsButton(@NonNull TaskInfo taskInfo) {
         return taskInfo.topActivityEligibleForUserAspectRatioButton
                 && (taskInfo.topActivityBoundsLetterboxed
-                    || taskInfo.isUserFullscreenOverrideEnabled);
+                    || taskInfo.isUserFullscreenOverrideEnabled)
+                && (!mUserAspectRatioButtonShownChecker.get() || isShowingButton());
     }
 
     private long getDisappearTimeMs() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
index 13c0ac4..b71c48e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
@@ -76,6 +76,10 @@
     private IRemoteTransition mOccludeByDreamTransition = null;
     private IRemoteTransition mUnoccludeTransition = null;
 
+    // While set true, Keyguard has created a remote animation runner to handle the open app
+    // transition.
+    private boolean mIsLaunchingActivityOverLockscreen;
+
     private final class StartedTransition {
         final TransitionInfo mInfo;
         final SurfaceControl.Transaction mFinishT;
@@ -120,7 +124,7 @@
             @NonNull SurfaceControl.Transaction startTransaction,
             @NonNull SurfaceControl.Transaction finishTransaction,
             @NonNull TransitionFinishCallback finishCallback) {
-        if (!handles(info)) {
+        if (!handles(info) || mIsLaunchingActivityOverLockscreen) {
             return false;
         }
 
@@ -313,5 +317,11 @@
                 mUnoccludeTransition = unoccludeTransition;
             });
         }
+
+        @Override
+        public void setLaunchingActivityOverLockscreen(boolean isLaunchingActivityOverLockscreen) {
+            mMainExecutor.execute(() ->
+                    mIsLaunchingActivityOverLockscreen = isLaunchingActivityOverLockscreen);
+        }
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitions.java
index b4b327f..33c299f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitions.java
@@ -38,4 +38,9 @@
             @NonNull IRemoteTransition occludeTransition,
             @NonNull IRemoteTransition occludeByDreamTransition,
             @NonNull IRemoteTransition unoccludeTransition) {}
+
+    /**
+     * Notify whether keyguard has created a remote animation runner for next app launch.
+     */
+    default void setLaunchingActivityOverLockscreen(boolean isLaunchingActivityOverLockscreen) {}
 }
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 003273f..3d825f0 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
@@ -1554,6 +1554,11 @@
             @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 {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
index 00f6a1c..83dc7fa 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
@@ -111,6 +111,14 @@
         WindowContainerTransaction mFinishWCT = null;
 
         /**
+         * Whether the transition has request for remote transition while mLeftoversHandler
+         * isn't remote transition handler.
+         * If true and the mLeftoversHandler can handle the transition, need to notify remote
+         * transition handler to consume the transition.
+         */
+        boolean mHasRequestToRemote;
+
+        /**
          * Mixed transitions are made up of multiple "parts". This keeps track of how many
          * parts are currently animating.
          */
@@ -200,6 +208,10 @@
                     MixedTransition.TYPE_OPTIONS_REMOTE_AND_PIP_CHANGE, transition);
             mixed.mLeftoversHandler = handler.first;
             mActiveTransitions.add(mixed);
+            if (mixed.mLeftoversHandler != mPlayer.getRemoteTransitionHandler()) {
+                mixed.mHasRequestToRemote = true;
+                mPlayer.getRemoteTransitionHandler().handleRequest(transition, request);
+            }
             return handler.second;
         } else if (mSplitHandler.isSplitScreenVisible()
                 && isOpeningType(request.getType())
@@ -316,12 +328,22 @@
         // the time of handleRequest, but we need more information than is available at that time.
         if (KeyguardTransitionHandler.handles(info)) {
             if (mixed != null && mixed.mType != MixedTransition.TYPE_KEYGUARD) {
-                ProtoLog.w(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
-                        "Converting mixed transition into a keyguard transition");
-                onTransitionConsumed(transition, false, null);
+                final MixedTransition keyguardMixed =
+                        new MixedTransition(MixedTransition.TYPE_KEYGUARD, transition);
+                mActiveTransitions.add(keyguardMixed);
+                final boolean hasAnimateKeyguard = animateKeyguard(keyguardMixed, info,
+                        startTransaction, finishTransaction, finishCallback);
+                if (hasAnimateKeyguard) {
+                    ProtoLog.w(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
+                            "Converting mixed transition into a keyguard transition");
+                    // Consume the original mixed transition
+                    onTransitionConsumed(transition, false, null);
+                    return true;
+                } else {
+                    // Keyguard handler cannot handle it, process through original mixed
+                    mActiveTransitions.remove(keyguardMixed);
+                }
             }
-            mixed = new MixedTransition(MixedTransition.TYPE_KEYGUARD, transition);
-            mActiveTransitions.add(mixed);
         }
 
         if (mixed == null) return false;
@@ -332,8 +354,17 @@
         } else if (mixed.mType == MixedTransition.TYPE_DISPLAY_AND_SPLIT_CHANGE) {
             return false;
         } else if (mixed.mType == MixedTransition.TYPE_OPTIONS_REMOTE_AND_PIP_CHANGE) {
-            return animateOpenIntentWithRemoteAndPip(mixed, info, startTransaction,
-                    finishTransaction, finishCallback);
+            final boolean handledToPip = animateOpenIntentWithRemoteAndPip(mixed, info,
+                    startTransaction, finishTransaction, finishCallback);
+            // Consume the transition on remote handler if the leftover handler already handle this
+            // transition. And if it cannot, the transition will be handled by remote handler, so
+            // don't consume here.
+            // Need to check leftOverHandler as it may change in #animateOpenIntentWithRemoteAndPip
+            if (handledToPip && mixed.mHasRequestToRemote
+                    && mixed.mLeftoversHandler != mPlayer.getRemoteTransitionHandler()) {
+                mPlayer.getRemoteTransitionHandler().onTransitionConsumed(transition, false, null);
+            }
+            return handledToPip;
         } else if (mixed.mType == MixedTransition.TYPE_RECENTS_DURING_SPLIT) {
             for (int i = info.getChanges().size() - 1; i >= 0; --i) {
                 final TransitionInfo.Change change = info.getChanges().get(i);
@@ -799,5 +830,8 @@
         } else if (mixed.mType == MixedTransition.TYPE_UNFOLD) {
             mUnfoldHandler.onTransitionConsumed(transition, aborted, finishT);
         }
+        if (mixed.mHasRequestToRemote) {
+            mPlayer.getRemoteTransitionHandler().onTransitionConsumed(transition, aborted, finishT);
+        }
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
index 7df658e..de03f58 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
@@ -99,7 +99,6 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.policy.AttributeCache;
 import com.android.internal.policy.ScreenDecorationsUtils;
 import com.android.internal.policy.TransitionAnimation;
 import com.android.internal.protolog.common.ProtoLog;
@@ -182,7 +181,7 @@
                 /* broadcastPermission = */ null,
                 mMainHandler);
 
-        AttributeCache.init(mContext);
+        TransitionAnimation.initAttributeCache(mContext, mMainHandler);
     }
 
     private void updateEnterpriseThumbnailDrawable() {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt
index 77f14f1..adf92d8 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt
@@ -50,7 +50,7 @@
         }
 
     @Before
-    fun before() {
+    fun setUp() {
         Assume.assumeTrue(tapl.isTablet && letterboxRule.isIgnoreOrientationRequest)
     }
 
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RotateImmersiveAppInFullscreenTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RotateImmersiveAppInFullscreenTest.kt
new file mode 100644
index 0000000..ba2b3e7
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RotateImmersiveAppInFullscreenTest.kt
@@ -0,0 +1,199 @@
+/*
+ * 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.flicker.appcompat
+
+import android.os.Build
+import android.tools.common.datatypes.Rect
+import android.platform.test.annotations.Postsubmit
+import android.system.helpers.CommandsHelper
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.common.flicker.assertions.FlickerTest
+import android.tools.common.traces.component.ComponentNameMatcher
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.device.flicker.legacy.FlickerBuilder
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
+import android.tools.device.helpers.FIND_TIMEOUT
+import android.tools.device.traces.parsers.toFlickerComponent
+import androidx.test.uiautomator.By
+import androidx.test.uiautomator.UiDevice
+import androidx.test.uiautomator.Until
+import com.android.server.wm.flicker.helpers.LetterboxAppHelper
+import com.android.server.wm.flicker.testapp.ActivityOptions
+import org.junit.Assume
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+/**
+ * Test rotating an immersive app in fullscreen.
+ *
+ * To run this test: `atest WMShellFlickerTestsOther:RotateImmersiveAppInFullscreenTest`
+ *
+ * Actions:
+ * ```
+ *     Rotate the device by 90 degrees to trigger a rotation through sensors
+ *     Verify that the button exists
+ * ```
+ *
+ * Notes:
+ * ```
+ *     Some default assertions that are inherited from
+ *     the `BaseTest` are ignored due to the nature of the immersive apps.
+ *
+ *     This test only works with Cuttlefish devices.
+ * ```
+ */
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+class RotateImmersiveAppInFullscreenTest(flicker: LegacyFlickerTest) : BaseAppCompat(flicker) {
+
+    private val immersiveApp = LetterboxAppHelper(instrumentation,
+            launcherName = ActivityOptions.PortraitImmersiveActivity.LABEL,
+            component =
+            ActivityOptions.PortraitImmersiveActivity.COMPONENT.toFlickerComponent())
+
+    private val cmdHelper: CommandsHelper = CommandsHelper.getInstance(instrumentation)
+    private val execAdb: (String) -> String = { cmd -> cmdHelper.executeShellCommand(cmd) }
+
+    protected val uiDevice: UiDevice = UiDevice.getInstance(instrumentation)
+
+    private val isCuttlefishDevice: Boolean = Build.MODEL.contains("Cuttlefish")
+
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit
+        get() = {
+            setup {
+                setStartRotation()
+                immersiveApp.launchViaIntent(wmHelper)
+                startDisplayBounds =
+                        wmHelper.currentState.layerState.physicalDisplayBounds
+                                ?: error("Display not found")
+            }
+            transitions {
+                if (isCuttlefishDevice) {
+                    // Simulates a device rotation through sensors because the rotation button
+                    // only appears in a rotation event through sensors
+                    execAdb("/vendor/bin/cuttlefish_sensor_injection rotate 0")
+                    // verify rotation button existence
+                    val rotationButtonSelector = By.res(LAUNCHER_PACKAGE, "rotate_suggestion")
+                    uiDevice.wait(Until.hasObject(rotationButtonSelector), FIND_TIMEOUT)
+                    uiDevice.findObject(rotationButtonSelector)
+                            ?: error("rotation button not found")
+                }
+            }
+            teardown {
+                immersiveApp.exit(wmHelper)
+            }
+        }
+
+    @Before
+    fun setUpForImmersiveAppTests() {
+        Assume.assumeTrue(isCuttlefishDevice)
+    }
+
+    /** {@inheritDoc} */
+    @Test
+    @Ignore("Not applicable to this CUJ. App is in immersive mode.")
+    override fun taskBarLayerIsVisibleAtStartAndEnd() {
+    }
+
+    /** {@inheritDoc} */
+    @Test
+    @Ignore("Not applicable to this CUJ. App is in immersive mode.")
+    override fun navBarLayerIsVisibleAtStartAndEnd() {
+    }
+
+    /** {@inheritDoc} */
+    @Test
+    @Ignore("Not applicable to this CUJ. App is in immersive mode.")
+    override fun statusBarLayerIsVisibleAtStartAndEnd() {
+    }
+
+    /** {@inheritDoc} */
+    @Test
+    @Ignore("Not applicable to this CUJ. App is in immersive mode.")
+    override fun taskBarWindowIsAlwaysVisible() {
+    }
+
+    /** {@inheritDoc} */
+    @Test
+    @Ignore("Not applicable to this CUJ. App is in immersive mode.")
+    override fun navBarWindowIsAlwaysVisible() {
+    }
+
+    /** {@inheritDoc} */
+    @Test
+    @Ignore("Not applicable to this CUJ. App is in immersive mode.")
+    override fun statusBarWindowIsAlwaysVisible() {
+    }
+
+    @Test
+    @Ignore("Not applicable to this CUJ. App is in immersive mode.")
+    override fun statusBarLayerPositionAtStartAndEnd() {
+    }
+
+    @Test
+    @Ignore("Not applicable to this CUJ. App is in immersive mode.")
+    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
+    }
+
+    /** Test that app is fullscreen by checking status bar and task bar visibility. */
+    @Postsubmit
+    @Test
+    fun appWindowFullScreen() {
+        flicker.assertWmEnd {
+            this.isAppWindowInvisible(ComponentNameMatcher.STATUS_BAR)
+                    .isAppWindowInvisible(ComponentNameMatcher.TASK_BAR)
+                    .visibleRegion(immersiveApp).coversExactly(startDisplayBounds)
+        }
+    }
+
+    /** Test that app is in the original rotation we have set up. */
+    @Postsubmit
+    @Test
+    fun appInOriginalRotation() {
+        flicker.assertWmEnd {
+            this.hasRotation(Rotation.ROTATION_90)
+        }
+    }
+
+    companion object {
+        private var startDisplayBounds = Rect.EMPTY
+        const val LAUNCHER_PACKAGE = "com.google.android.apps.nexuslauncher"
+
+        /**
+         * Creates the test configurations.
+         *
+         * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
+         * navigation modes.
+         */
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): Collection<FlickerTest> {
+            return LegacyFlickerTestFactory.nonRotationTests(
+                    supportedRotations = listOf(Rotation.ROTATION_90),
+                    // TODO(b/292403378): 3 button mode not added as rotation button is hidden in taskbar
+                    supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
+
+            )
+        }
+    }
+}
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 8cb25fe..69499b9 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 @@
 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 2539fd5..bd627f4 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 @@
 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()
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 0000000..f583321
--- /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
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 9b9600e..f85d707 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 dagger.Lazy;
 
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -523,13 +524,175 @@
                 .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());
+    }
+
+    @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,
+                /* 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;
         taskInfo.topActivityInSizeCompat = hasSizeCompat;
         taskInfo.cameraCompatControlState = cameraCompatControlState;
+        taskInfo.isVisible = isVisible;
+        taskInfo.isFocused = isFocused;
+        taskInfo.isTopActivityTransparent = isTopActivityTransparent;
         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 ce1290b..f460d1b 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 @@
         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 08cc2f7..5a4d6c8 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.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 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 @@
  *  atest WMShellUnitTests:UserAspectRatioSettingsWindowManagerTest
  */
 @RunWith(AndroidTestingRunner.class)
+@RunWithLooper
 @SmallTest
 public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase {
 
@@ -81,6 +84,8 @@
 
     @Mock private SyncTransactionQueue mSyncTransactionQueue;
     @Mock
+    private Supplier<Boolean> mUserAspectRatioButtonShownChecker;
+    @Mock
     private BiConsumer<TaskInfo, ShellTaskOrganizer.TaskListener>
             mOnUserAspectRatioSettingsButtonClicked;
     @Mock private ShellTaskOrganizer.TaskListener mTaskListener;
@@ -106,10 +111,12 @@
                 false, /* topActivityBoundsLetterboxed */ true);
         mWindowManager = new UserAspectRatioSettingsWindowManager(mContext, mTaskInfo,
                 mSyncTransactionQueue, mTaskListener, new DisplayLayout(), new CompatUIHintsState(),
-                mOnUserAspectRatioSettingsButtonClicked, mExecutor, flags -> 0);
+                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 +300,39 @@
     }
 
     @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();
         mWindowManager.attachToParentSurface(b);
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index fe611a2..b00fc69 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -918,10 +918,10 @@
 }
 
 void CanvasContext::prepareAndDraw(RenderNode* node) {
-    ATRACE_CALL();
+    int64_t vsyncId = mRenderThread.timeLord().lastVsyncId();
+    ATRACE_FORMAT("%s %" PRId64, __func__, vsyncId);
 
     nsecs_t vsync = mRenderThread.timeLord().computeFrameTimeNanos();
-    int64_t vsyncId = mRenderThread.timeLord().lastVsyncId();
     int64_t frameDeadline = mRenderThread.timeLord().lastFrameDeadline();
     int64_t frameInterval = mRenderThread.timeLord().frameIntervalNanos();
     int64_t frameInfo[UI_THREAD_FRAME_INFO_SIZE];
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 842542f..adc0e16 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -941,27 +941,15 @@
     }
 
     /**
-     * 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 a6e8fa0..aaaf25f 100644
--- a/media/java/android/media/RemoteController.java
+++ b/media/java/android/media/RemoteController.java
@@ -220,33 +220,21 @@
         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/media/java/android/media/RouteDiscoveryPreference.java b/media/java/android/media/RouteDiscoveryPreference.java
index 71d8261..161fd2f 100644
--- a/media/java/android/media/RouteDiscoveryPreference.java
+++ b/media/java/android/media/RouteDiscoveryPreference.java
@@ -194,6 +194,7 @@
 
         String indent = prefix + "  ";
 
+        pw.println(indent + "mShouldPerformActiveScan=" + mShouldPerformActiveScan);
         pw.println(indent + "mPreferredFeatures=" + mPreferredFeatures);
         pw.println(indent + "mPackageOrder=" + mPackageOrder);
         pw.println(indent + "mAllowedPackages=" + mAllowedPackages);
diff --git a/omapi/java/android/se/omapi/SeFrameworkInitializer.java b/omapi/java/android/se/omapi/SeFrameworkInitializer.java
new file mode 100644
index 0000000..d09a35d
--- /dev/null
+++ b/omapi/java/android/se/omapi/SeFrameworkInitializer.java
@@ -0,0 +1,70 @@
+/*
+ * 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.se.omapi;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.nfc.Flags;
+
+/**
+ * Class for performing registration for SE service.
+ *
+ * @hide
+ */
+@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+@FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+public class SeFrameworkInitializer {
+    private SeFrameworkInitializer() {}
+
+    private static volatile SeServiceManager sSeServiceManager;
+
+    /**
+     * Sets an instance of {@link SeServiceManager} that allows
+     * the se mainline module to register/obtain se binder services. This is called
+     * by the platform during the system initialization.
+     *
+     * @param seServiceManager instance of {@link SeServiceManager} that allows
+     * the se/nfc mainline module to register/obtain se binder services.
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    public static void setSeServiceManager(
+            @NonNull SeServiceManager seServiceManager) {
+        if (sSeServiceManager != null) {
+            throw new IllegalStateException("setSeServiceManager called twice!");
+        }
+
+        if (seServiceManager == null) {
+            throw new IllegalArgumentException("seServiceManager must not be null");
+        }
+
+        sSeServiceManager = seServiceManager;
+    }
+
+    /**
+     * Gets an instance of {@link SeServiceManager} that allows
+     * the se mainline module to register/obtain se binder services.
+     *
+     * @return instance of {@link SeServiceManager} that allows
+     * the se/nfc mainline module to register/obtain se binder services.
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    @Nullable
+    public static SeServiceManager getSeServiceManager() {
+        return sSeServiceManager;
+    }
+}
diff --git a/omapi/java/android/se/omapi/SeServiceManager.java b/omapi/java/android/se/omapi/SeServiceManager.java
new file mode 100644
index 0000000..79107370
--- /dev/null
+++ b/omapi/java/android/se/omapi/SeServiceManager.java
@@ -0,0 +1,140 @@
+/*
+ * 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.
+ */
+
+
+/**********************************************************************
+ * This file is not a part of the SE mainline module                 *
+ * *******************************************************************/
+
+package android.se.omapi;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.annotation.SystemApi.Client;
+import android.content.Context;
+import android.nfc.Flags;
+import android.os.IBinder;
+import android.os.ServiceManager;
+
+/**
+ * Provides a way to register and obtain the system service binder objects managed by the
+ * SecureElement service.
+ *
+ * @hide
+ */
+@SystemApi(client = Client.MODULE_LIBRARIES)
+@FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+public class SeServiceManager {
+
+    /**
+     * @hide
+     */
+    public SeServiceManager() {
+    }
+
+    /**
+     * A class that exposes the methods to register and obtain each system service.
+     * @hide
+     */
+    @SystemApi(client = Client.MODULE_LIBRARIES)
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    public static final class ServiceRegisterer {
+        private final String mServiceName;
+
+        /**
+         * @hide
+         */
+        public ServiceRegisterer(String serviceName) {
+            mServiceName = serviceName;
+        }
+
+        /**
+         * Register a system server binding object for a service.
+         */
+        @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+        public void register(@NonNull IBinder service) {
+            ServiceManager.addService(mServiceName, service);
+        }
+
+        /**
+         * Get the system server binding object for a service.
+         *
+         * <p>This blocks until the service instance is ready,
+         * or a timeout happens, in which case it returns null.
+         */
+        @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+        @Nullable
+        public IBinder get() {
+            return ServiceManager.getService(mServiceName);
+        }
+
+        /**
+         * Get the system server binding object for a service.
+         *
+         * <p>This blocks until the service instance is ready,
+         * or a timeout happens, in which case it throws {@link ServiceNotFoundException}.
+         */
+        @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+        @NonNull
+        public IBinder getOrThrow() throws ServiceNotFoundException {
+            try {
+                return ServiceManager.getServiceOrThrow(mServiceName);
+            } catch (ServiceManager.ServiceNotFoundException e) {
+                throw new ServiceNotFoundException(mServiceName);
+            }
+        }
+
+        /**
+         * Get the system server binding object for a service. If the specified service is
+         * not available, it returns null.
+         */
+        @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+        @Nullable
+        public IBinder tryGet() {
+            return ServiceManager.checkService(mServiceName);
+        }
+    }
+
+    /**
+     * See {@link ServiceRegisterer#getOrThrow}.
+     * @hide
+     */
+    @SystemApi(client = Client.MODULE_LIBRARIES)
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    public static class ServiceNotFoundException extends ServiceManager.ServiceNotFoundException {
+        /**
+         * Constructor.
+         *
+         * @param name the name of the binder service that cannot be found.
+         *
+         */
+        @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+        public ServiceNotFoundException(@NonNull String name) {
+            super(name);
+        }
+    }
+
+    /**
+     * Returns {@link ServiceRegisterer} for the "secure_element" service.
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
+    @NonNull
+    public ServiceRegisterer getSeManagerServiceRegisterer() {
+        return new ServiceRegisterer(Context.SECURE_ELEMENT_SERVICE);
+    }
+}
diff --git a/packages/CredentialManager/horologist/Android.bp b/packages/CredentialManager/horologist/Android.bp
index bb324bb..bb255bd 100644
--- a/packages/CredentialManager/horologist/Android.bp
+++ b/packages/CredentialManager/horologist/Android.bp
@@ -16,6 +16,7 @@
         "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 0000000..e6025fc
--- /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 0000000..57e0c10
--- /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 0000000..74e54c0
--- /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 0000000..39de2e1
--- /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 0000000..0bfceee
--- /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
new file mode 100644
index 0000000..38d98a9
--- /dev/null
+++ b/packages/CredentialManager/shared/Android.bp
@@ -0,0 +1,19 @@
+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",
+        "guava",
+    ],
+}
diff --git a/packages/CredentialManager/shared/AndroidManifest.xml b/packages/CredentialManager/shared/AndroidManifest.xml
new file mode 100644
index 0000000..a460887
--- /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/IntentParser.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/IntentParser.kt
new file mode 100644
index 0000000..defba8d
--- /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/LogConstants.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/LogConstants.kt
new file mode 100644
index 0000000..44d33ff
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/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
+
+const val TAG = "CredentialSelector"
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/factory/CredentialEntryFactory.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/factory/CredentialEntryFactory.kt
new file mode 100644
index 0000000..a2c1f03
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/factory/CredentialEntryFactory.kt
@@ -0,0 +1,25 @@
+package com.android.credentialmanager.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/ktx/IntentKtx.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/IntentKtx.kt
new file mode 100644
index 0000000..a4c20bf
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/IntentKtx.kt
@@ -0,0 +1,48 @@
+/*
+ * 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.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?
+    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
+    )
+
+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/ktx/PackageManagerKtx.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/PackageManagerKtx.kt
new file mode 100644
index 0000000..5f4f298
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/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.ktx
+
+import android.content.pm.PackageManager
+import android.text.TextUtils
+import android.util.Log
+import com.android.credentialmanager.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/mapper/RequestCancelMapper.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestCancelMapper.kt
new file mode 100644
index 0000000..86a6d23
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestCancelMapper.kt
@@ -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.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.mapper
+
+import android.content.Intent
+import com.android.credentialmanager.ktx.cancelUiRequest
+import com.android.credentialmanager.model.Request
+
+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 0000000..ed9d563
--- /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/model/Request.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/Request.kt
new file mode 100644
index 0000000..bc07310
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/Request.kt
@@ -0,0 +1,39 @@
+/*
+ * 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.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.
+ */
+sealed class Request {
+    data class Cancel(
+        val showCancellationUi: Boolean,
+        val appPackageName: String?
+    ) : 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 639e8d1..c0dff16 100644
--- a/packages/CredentialManager/wear/Android.bp
+++ b/packages/CredentialManager/wear/Android.bp
@@ -21,6 +21,7 @@
     },
 
     static_libs: [
+        "CredentialManagerShared",
         "Horologist",
         "PlatformComposeCore",
         "androidx.activity_activity-compose",
@@ -31,6 +32,7 @@
         "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 0000000..be366bf
--- /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 10ea918..109644f 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 77fffaa..53122ba 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,72 @@
 
 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)
+                        is CredentialSelectorUiState.Get -> {
+                            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 0000000..d22d5d1
--- /dev/null
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorViewModel.kt
@@ -0,0 +1,123 @@
+/*
+ * 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.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.model.Request
+import com.android.credentialmanager.ui.mapper.toGet
+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
+                    }
+
+                    is Request.Get -> {
+                        _uiState.value = request.toGet()
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * 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 {
+    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()
+    data object Finish : CredentialSelectorUiState()
+}
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 ee6ea5e..7d1a49b 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 @@
 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/WearApp.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/WearApp.kt
index 5ec0c8c..19ea9ed 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.composable
 
 @Composable
-fun WearApp(
-    navController: NavHostController
-) {
+fun WearApp() {
+    val navController = rememberSwipeDismissableNavController()
     val swipeToDismissBoxState = rememberSwipeToDismissBoxState()
     val navHostState =
         rememberSwipeDismissableNavHostState(swipeToDismissBoxState = swipeToDismissBoxState)
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 0000000..c20ee0c
--- /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 0000000..5cb3c15
--- /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 0000000..97900b7
--- /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 0000000..956c56b
--- /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 0000000..5ceec178
--- /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.factory.fromSlice
+import com.android.credentialmanager.ui.model.PasswordUiModel
+import com.android.credentialmanager.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 0000000..a368de2
--- /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 0000000..52bbfaa
--- /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 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 662d710..94a671e 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.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.")
     }
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 0000000..f344ad0
--- /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 0000000..c8f871e
--- /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 0000000..d863d3c
--- /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(),
+    )
+}
+
diff --git a/packages/SettingsLib/ActionBarShadow/Android.bp b/packages/SettingsLib/ActionBarShadow/Android.bp
index bf4c858..6f94458 100644
--- a/packages/SettingsLib/ActionBarShadow/Android.bp
+++ b/packages/SettingsLib/ActionBarShadow/Android.bp
@@ -9,6 +9,7 @@
 
 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 98c4cb4..4ec6870 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 b6e1677..1228555 100644
--- a/packages/SettingsLib/ActionButtonsPreference/Android.bp
+++ b/packages/SettingsLib/ActionButtonsPreference/Android.bp
@@ -9,6 +9,7 @@
 
 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 4b9f1ab..01ad598 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 4d3ca945..3e65d94 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.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 0cd9fe3..41de29a 100644
--- a/packages/SettingsLib/ActivityEmbedding/Android.bp
+++ b/packages/SettingsLib/ActivityEmbedding/Android.bp
@@ -9,6 +9,7 @@
 
 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 0949e1d..c67f51c 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 934aacf..df72a92 100644
--- a/packages/SettingsLib/AdaptiveIcon/Android.bp
+++ b/packages/SettingsLib/AdaptiveIcon/Android.bp
@@ -9,6 +9,7 @@
 
 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 256b8f3..7709ad3 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 723caf2..fc41c93 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 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 e829974..12c234e 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 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 0ba47a8..69b9d44 100644
--- a/packages/SettingsLib/AppPreference/Android.bp
+++ b/packages/SettingsLib/AppPreference/Android.bp
@@ -9,6 +9,7 @@
 
 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 4b9f1ab..9d01497 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 60d00da..b1d31108 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.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 cfe7013..f1d162e 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 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 781bfcd..87bfc81 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 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 0f7a451..da91344 100644
--- a/packages/SettingsLib/BannerMessagePreference/Android.bp
+++ b/packages/SettingsLib/BannerMessagePreference/Android.bp
@@ -9,6 +9,7 @@
 
 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 dd51ea3..a93a1fe 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 afeb24a..33775a6 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.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 5ca6fb6..ff4e79d 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 androidx.annotation.Nullable;
 
+import com.android.settingslib.widget.preference.banner.R;
+
 /**
  * The view providing {@link BannerMessagePreference}.
  *
@@ -75,7 +77,7 @@
 
         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 5c5da98..be1e0cf 100644
--- a/packages/SettingsLib/BarChartPreference/Android.bp
+++ b/packages/SettingsLib/BarChartPreference/Android.bp
@@ -9,6 +9,7 @@
 
 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 4b9f1ab..fda4e1d 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 eeaf273..a32a24d 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 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 20e0a3b..d63fc3c 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.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 93a34c0..7c74971 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 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 922337a..4b6ca4a 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.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 39f804f..35572fad 100644
--- a/packages/SettingsLib/ButtonPreference/Android.bp
+++ b/packages/SettingsLib/ButtonPreference/Android.bp
@@ -9,6 +9,7 @@
 
 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 2d35c331..f867707 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 5364783..16ba962 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.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 df43863..70f7554 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp
@@ -9,6 +9,7 @@
 
 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 51fc7ed..dabba68 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 3582897..8ebbac3 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.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 dcc6e5a..04c44e6 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.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 @@
         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 19b7e85..143101f 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.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 1c2288a..155cfbb 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.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 e4e34f8..f70add9 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.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 103309a..72df6cd 100644
--- a/packages/SettingsLib/DeviceStateRotationLock/Android.bp
+++ b/packages/SettingsLib/DeviceStateRotationLock/Android.bp
@@ -9,6 +9,7 @@
 
 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 136f883..eab35a1 100644
--- a/packages/SettingsLib/DisplayUtils/Android.bp
+++ b/packages/SettingsLib/DisplayUtils/Android.bp
@@ -9,6 +9,7 @@
 
 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 25b4905..986baf7 100644
--- a/packages/SettingsLib/EmergencyNumber/Android.bp
+++ b/packages/SettingsLib/EmergencyNumber/Android.bp
@@ -9,6 +9,7 @@
 
 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 bd83cdc..17b662c 100644
--- a/packages/SettingsLib/EntityHeaderWidgets/Android.bp
+++ b/packages/SettingsLib/EntityHeaderWidgets/Android.bp
@@ -9,6 +9,7 @@
 
 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 4b9f1ab..ad4d22d 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 6e95a0e..d802e5b 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.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 1e55f2e..0439ff5 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 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 8b976bb..b45cd65 100644
--- a/packages/SettingsLib/FooterPreference/Android.bp
+++ b/packages/SettingsLib/FooterPreference/Android.bp
@@ -9,6 +9,7 @@
 
 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 96d9e51..9046b10 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 bf24c86..5b2fa1d 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.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 @@
     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 868fead..16d4475 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.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 13fcf8c..041fce2 100644
--- a/packages/SettingsLib/HelpUtils/Android.bp
+++ b/packages/SettingsLib/HelpUtils/Android.bp
@@ -9,6 +9,7 @@
 
 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 ccad6e4..35c7515 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 70c8658..2c13695 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 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 24ccab2..4d4759b 100644
--- a/packages/SettingsLib/IllustrationPreference/Android.bp
+++ b/packages/SettingsLib/IllustrationPreference/Android.bp
@@ -9,6 +9,7 @@
 
 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 73163fc..a0d10c3 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 37ae2d4..f4d4dba 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 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 @@
         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 c29e1f7..53ded23 100644
--- a/packages/SettingsLib/LayoutPreference/Android.bp
+++ b/packages/SettingsLib/LayoutPreference/Android.bp
@@ -9,6 +9,7 @@
 
 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 4b9f1ab..a8427a1 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 2a635b0..49f045f 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 @@
     }
 
     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 @@
     }
 
     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 6e0d827..4b3acbf 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 d1703c3..56b3eac 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 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 53cc268..11a6804 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 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 1c610d9..03868f9 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 @@
 
 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 250cd75..155ed2e 100644
--- a/packages/SettingsLib/ProfileSelector/Android.bp
+++ b/packages/SettingsLib/ProfileSelector/Android.bp
@@ -9,6 +9,7 @@
 
 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 a57469e..80f6b76 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 ac426ed..be5753be 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 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 daf2564..f5ab647 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 @@
 
 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 fb3c4e6..d876573 100644
--- a/packages/SettingsLib/ProgressBar/Android.bp
+++ b/packages/SettingsLib/ProgressBar/Android.bp
@@ -9,6 +9,7 @@
 
 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 256b8f3..fbd6eb0 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 1387daa..505ba05 100644
--- a/packages/SettingsLib/RadioButtonPreference/Android.bp
+++ b/packages/SettingsLib/RadioButtonPreference/Android.bp
@@ -9,6 +9,7 @@
 
 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 fda7fde..8b5c3b1 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 02d3c06..fc4b714 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 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 6a8fef3..028489d 100644
--- a/packages/SettingsLib/RestrictedLockUtils/Android.bp
+++ b/packages/SettingsLib/RestrictedLockUtils/Android.bp
@@ -15,6 +15,7 @@
 
 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 0975640..50a55a7 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 c4373bb..2d93e4e 100644
--- a/packages/SettingsLib/SchedulesProvider/Android.bp
+++ b/packages/SettingsLib/SchedulesProvider/Android.bp
@@ -9,6 +9,7 @@
 
 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 f96011a..c07a802 100644
--- a/packages/SettingsLib/SearchProvider/Android.bp
+++ b/packages/SettingsLib/SearchProvider/Android.bp
@@ -9,6 +9,7 @@
 
 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 2c06673..7e2c47f 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 5aaee2a..ad9e167 100644
--- a/packages/SettingsLib/SearchWidget/Android.bp
+++ b/packages/SettingsLib/SearchWidget/Android.bp
@@ -9,6 +9,7 @@
 
 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 5798801..5982b02 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 b5a21bd..702387e 100644
--- a/packages/SettingsLib/SelectorWithWidgetPreference/Android.bp
+++ b/packages/SettingsLib/SelectorWithWidgetPreference/Android.bp
@@ -9,6 +9,7 @@
 
 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 51fc7ed..919d1a9 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 1d1316a..f2ce8a9 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 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 cbb570e..0eec505 100644
--- a/packages/SettingsLib/SettingsSpinner/Android.bp
+++ b/packages/SettingsLib/SettingsSpinner/Android.bp
@@ -9,6 +9,7 @@
 
 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 4b9f1ab..123175c 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 7288494..f33cacd 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.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 6952875..63fe1b5 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 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 e6fb720..996477c 100644
--- a/packages/SettingsLib/SettingsTheme/Android.bp
+++ b/packages/SettingsLib/SettingsTheme/Android.bp
@@ -9,6 +9,7 @@
 
 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 fda7fde..56d137a 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 48cc75d..06493c0 100644
--- a/packages/SettingsLib/SettingsTransition/Android.bp
+++ b/packages/SettingsLib/SettingsTransition/Android.bp
@@ -9,6 +9,7 @@
 
 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 244b367..3e64d56 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/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 37c8eef..d289646 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 @@
     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/screenshot/Android.bp b/packages/SettingsLib/Spa/screenshot/Android.bp
index 4e6b646..bd508cb 100644
--- a/packages/SettingsLib/Spa/screenshot/Android.bp
+++ b/packages/SettingsLib/Spa/screenshot/Android.bp
@@ -20,6 +20,7 @@
 
 android_test {
     name: "SpaScreenshotTests",
+    use_resource_processor: true,
     test_suites: ["device-tests"],
 
     asset_dirs: ["assets"],
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 a258185..5d248e1 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 @@
 fun SettingsExposedDropdownMenuCheckBox(
     label: String,
     options: List<String>,
-    selectedOptionsState: SnapshotStateList<String>,
+    selectedOptionsState: SnapshotStateList<Int>,
+    emptyVal: String = "",
     enabled: Boolean,
     onSelectedOptionStateChange: () -> Unit,
 ) {
@@ -70,7 +71,8 @@
             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 @@
                     .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 @@
                             verticalAlignment = Alignment.CenterVertically
                         ) {
                             Checkbox(
-                                checked = selectedOptionsState.contains(option),
+                                checked = selectedOptionsState.contains(index),
                                 onCheckedChange = null,
                             )
                             Text(text = option)
@@ -130,7 +132,7 @@
 @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 b0271ae1..2b78ed7 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 @@
     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
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 a370ebf..f54de15 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 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 ea83e1d..fc10a27 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 @@
     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 cc570cc..eb9e329 100644
--- a/packages/SettingsLib/Tile/Android.bp
+++ b/packages/SettingsLib/Tile/Android.bp
@@ -9,6 +9,7 @@
 
 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 5d09a1a..77b7ac1 100644
--- a/packages/SettingsLib/TopIntroPreference/Android.bp
+++ b/packages/SettingsLib/TopIntroPreference/Android.bp
@@ -9,6 +9,7 @@
 
 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 96d9e51..6cf643f 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 5a5a9b8..1bbd76d 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 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 a3e50a9..5aa906e 100644
--- a/packages/SettingsLib/TwoTargetPreference/Android.bp
+++ b/packages/SettingsLib/TwoTargetPreference/Android.bp
@@ -9,6 +9,7 @@
 
 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 120b085..15e9368 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 9130662..b125f71 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.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 ad6e7ab..4cc90cc 100644
--- a/packages/SettingsLib/UsageProgressBarPreference/Android.bp
+++ b/packages/SettingsLib/UsageProgressBarPreference/Android.bp
@@ -9,6 +9,7 @@
 
 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 51fc7ed..1e9df9c 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 4eedab2..712f6f0 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 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 dc2b52d..c7ad24c 100644
--- a/packages/SettingsLib/Utils/Android.bp
+++ b/packages/SettingsLib/Utils/Android.bp
@@ -9,6 +9,7 @@
 
 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 918d696..202e7fe 100644
--- a/packages/SettingsLib/search/Android.bp
+++ b/packages/SettingsLib/search/Android.bp
@@ -16,6 +16,7 @@
 
 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 b1d1ea5e..758f090 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
@@ -126,10 +126,10 @@
             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 f5257b0..8c0dc41 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 @@
         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 d53c3a7..2999c83 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 @@
         }
         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 2d6f058..98272cc 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 @@
         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 8970deb..b03c43c 100644
--- a/packages/SettingsLib/tests/integ/Android.bp
+++ b/packages/SettingsLib/tests/integ/Android.bp
@@ -23,6 +23,7 @@
 
 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 2a4dfdd..a95da303 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 b81d13d..c8b20c1 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.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 a9ad00d..a66d3fb 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.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 c037c40..dd9cb9c 100644
--- a/packages/SettingsLib/tests/robotests/Android.bp
+++ b/packages/SettingsLib/tests/robotests/Android.bp
@@ -27,6 +27,7 @@
 
 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 4811d950..e1577e0 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 @@
         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 @@
         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 32a16716..d9cf9f2 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 @@
         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 ff84dc9..2b1e808 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 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 @@
         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 @@
         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 9f31cef..6d9261d 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 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 @@
 
     @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 @@
 
     @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 @@
 
     @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 @@
 
     @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 @@
 
     @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 @@
 
     @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 @@
 
     @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 @@
 
     @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 @@
 
     @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 @@
 
     @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 @@
 
     @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 @@
 
     @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 @@
 
     @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 10862403..6195d75 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.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 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 @@
     @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 @@
         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 b2bc53d..943b994 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 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 c9b066a..172c178 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.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 @@
 
     @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 @@
 
     @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 @@
 
     @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 e2b242c..9112f6b 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 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 9e265a4..6c8fd50 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 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 @@
 
     @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 0d88913..721e69d 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 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 @@
     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 567d90f..ae6573e 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 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 @@
         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 @@
     @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 @@
     @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 @@
         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 @@
     @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 d78f8e7..f3fe517 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 @@
 
     @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 a26f200..ccbe4f0 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 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 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 21e119a..6590bbd 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 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.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 99261a3..58817fb 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 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 24037ca..942e915 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.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 e58c04a..c2e81bd 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 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 a5028ff..0f708cd 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 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 34efe82..60885f1 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 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 23b4c2a..3befdda 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 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 a4558f1..19ab1c6 100644
--- a/packages/SettingsLib/tests/unit/Android.bp
+++ b/packages/SettingsLib/tests/unit/Android.bp
@@ -20,6 +20,7 @@
 
 android_test {
     name: "SettingsLibUnitTests",
+    use_resource_processor: true,
     test_suites: ["device-tests"],
 
     srcs: [
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index 0a98032..e9533e5 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -137,6 +137,13 @@
     private static final String ATTR_VALUE_BASE64 = "valueBase64";
     private static final String ATTR_DEFAULT_VALUE_BASE64 = "defaultValueBase64";
 
+    /**
+     * In the config table, there are special flags of the form {@code staged/namespace*flagName}.
+     * On boot, when the XML file is initially parsed, these transform into
+     * {@code namespace/flagName}, and the special staged flags are deleted.
+     */
+    private static final String CONFIG_STAGED_PREFIX = "staged/";
+
     // This was used in version 120 and before.
     private static final String NULL_VALUE_OLD_STYLE = "null";
 
@@ -1191,6 +1198,42 @@
         }
     }
 
+    /**
+     * Transforms a staged flag name to its real flag name.
+     *
+     * Staged flags take the form {@code staged/namespace*flagName}. If
+     * {@code stagedFlagName} takes the proper form, returns
+     * {@code namespace/flagName}. Otherwise, returns {@code stagedFlagName}
+     * unmodified, and logs an error message.
+     *
+     */
+    @VisibleForTesting
+    public static String createRealFlagName(String stagedFlagName) {
+        int slashIndex = stagedFlagName.indexOf("/");
+        if (slashIndex == -1 || slashIndex == stagedFlagName.length() - 1
+                || slashIndex == 0) {
+            Slog.w(LOG_TAG, "invalid staged flag, not applying: " + stagedFlagName);
+            return stagedFlagName;
+        }
+
+        String namespaceAndFlag =
+                stagedFlagName.substring(slashIndex + 1);
+
+        int starIndex = namespaceAndFlag.indexOf("*");
+        if (starIndex == -1 || starIndex == namespaceAndFlag.length() - 1
+                || starIndex == 0) {
+            Slog.w(LOG_TAG, "invalid staged flag, not applying: " + stagedFlagName);
+            return stagedFlagName;
+        }
+
+        String namespace =
+                namespaceAndFlag.substring(0, starIndex);
+        String flagName =
+                namespaceAndFlag.substring(starIndex + 1);
+
+        return namespace + "/" + flagName;
+    }
+
     @GuardedBy("mLock")
     private void parseSettingsLocked(TypedXmlPullParser parser)
             throws IOException, XmlPullParserException {
@@ -1199,6 +1242,7 @@
 
         final int outerDepth = parser.getDepth();
         int type;
+        HashSet<String> flagsWithStagedValueApplied = new HashSet<String>();
         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
@@ -1221,6 +1265,18 @@
                     fromSystem = parser.getAttributeBoolean(null, ATTR_DEFAULT_SYS_SET, false);
                     tag = getValueAttribute(parser, ATTR_TAG, ATTR_TAG_BASE64);
                 }
+
+                if (isConfigSettingsKey(mKey)) {
+                    if (flagsWithStagedValueApplied.contains(name)) {
+                        continue;
+                    }
+
+                    if (name.startsWith(CONFIG_STAGED_PREFIX)) {
+                        name = createRealFlagName(name);
+                        flagsWithStagedValueApplied.add(name);
+                    }
+                }
+
                 mSettings.put(name, new Setting(name, value, defaultValue, packageName, tag,
                         fromSystem, id, isPreservedInRestore));
 
@@ -1229,6 +1285,16 @@
                 }
             }
         }
+
+        if (isConfigSettingsKey(mKey) && !flagsWithStagedValueApplied.isEmpty()) {
+            // On boot, the config table XML file includes special staged flags. On the initial
+            // boot XML -> HashMap parse, these staged flags get transformed into real flags.
+            // After this, the HashMap contains no special staged flags (only the transformed
+            // real flags), but the XML still does. We then have no need for the special staged
+            // flags in the XML, so we overwrite the XML with the latest contents of the
+            // HashMap.
+            writeStateAsyncLocked();
+        }
     }
 
     @GuardedBy("mLock")
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
index 26cac37..df4d2a1 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
@@ -51,6 +51,21 @@
     private static final String SYSTEM_PACKAGE = "android";
     private static final String SETTING_NAME = "test_setting";
 
+    private static final String FLAG_NAME_1 = "namespace123/flag456";
+    private static final String FLAG_NAME_1_STAGED = "staged/namespace123*flag456";
+    private static final String FLAG_NAME_2 = "not_staged/flag101";
+
+    private static final String INVALID_STAGED_FLAG_1 = "stagednamespace*flagName";
+    private static final String INVALID_STAGED_FLAG_2 = "staged/";
+    private static final String INVALID_STAGED_FLAG_3 = "staged/namespace*";
+    private static final String INVALID_STAGED_FLAG_4 = "staged/*flagName";
+
+    private static final String VALID_STAGED_FLAG_1 = "staged/namespace*flagName";
+    private static final String VALID_STAGED_FLAG_1_TRANSFORMED = "namespace/flagName";
+
+    private static final String VALUE1 = "5";
+    private static final String VALUE2 = "6";
+
     private final Object mLock = new Object();
 
     private File mSettingsFile;
@@ -454,4 +469,68 @@
             }
         }
     }
+
+    public void testApplyStagedConfigValues() {
+        int configKey = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_CONFIG, 0);
+        Object lock = new Object();
+        SettingsState settingsState = new SettingsState(
+                getContext(), lock, mSettingsFile, configKey,
+                SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, Looper.getMainLooper());
+
+        synchronized (lock) {
+            settingsState.insertSettingLocked(
+                    FLAG_NAME_1_STAGED, VALUE1, null, false, TEST_PACKAGE);
+            settingsState.insertSettingLocked(FLAG_NAME_2, VALUE2, null, false, TEST_PACKAGE);
+            settingsState.persistSyncLocked();
+
+            assertEquals(VALUE1, settingsState.getSettingLocked(FLAG_NAME_1_STAGED).getValue());
+            assertEquals(VALUE2, settingsState.getSettingLocked(FLAG_NAME_2).getValue());
+        }
+
+        settingsState = new SettingsState(getContext(), lock, mSettingsFile, configKey,
+                SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, Looper.getMainLooper());
+
+        synchronized (lock) {
+            assertEquals(VALUE1, settingsState.getSettingLocked(FLAG_NAME_1).getValue());
+            assertEquals(VALUE2, settingsState.getSettingLocked(FLAG_NAME_2).getValue());
+
+            assertEquals(null, settingsState.getSettingLocked(FLAG_NAME_1_STAGED).getValue());
+        }
+    }
+
+    public void testStagingTransformation() {
+        assertEquals(INVALID_STAGED_FLAG_1,
+                SettingsState.createRealFlagName(INVALID_STAGED_FLAG_1));
+        assertEquals(INVALID_STAGED_FLAG_2,
+                SettingsState.createRealFlagName(INVALID_STAGED_FLAG_2));
+        assertEquals(INVALID_STAGED_FLAG_3,
+                SettingsState.createRealFlagName(INVALID_STAGED_FLAG_3));
+        assertEquals(INVALID_STAGED_FLAG_4,
+                SettingsState.createRealFlagName(INVALID_STAGED_FLAG_4));
+
+        assertEquals(VALID_STAGED_FLAG_1_TRANSFORMED,
+                SettingsState.createRealFlagName(VALID_STAGED_FLAG_1));
+    }
+
+    public void testInvalidStagedFlagsUnaffectedByReboot() {
+        int configKey = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_CONFIG, 0);
+        Object lock = new Object();
+        SettingsState settingsState = new SettingsState(
+                getContext(), lock, mSettingsFile, configKey,
+                SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, Looper.getMainLooper());
+
+        synchronized (lock) {
+            settingsState.insertSettingLocked(INVALID_STAGED_FLAG_1,
+                    VALUE2, null, false, TEST_PACKAGE);
+            settingsState.persistSyncLocked();
+            assertEquals(VALUE2, settingsState.getSettingLocked(INVALID_STAGED_FLAG_1).getValue());
+        }
+
+        settingsState = new SettingsState(getContext(), lock, mSettingsFile, configKey,
+                SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, Looper.getMainLooper());
+
+        synchronized (lock) {
+            assertEquals(VALUE2, settingsState.getSettingLocked(INVALID_STAGED_FLAG_1).getValue());
+        }
+    }
 }
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 15620b7..11ae9c3 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/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 6080101..5e7e044 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -116,6 +116,7 @@
 //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 @@
             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 @@
 
 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 {
     name: "SystemUI-tests",
+    use_resource_processor: true,
     defaults: [
         "SystemUI_compose_defaults",
     ],
@@ -485,6 +482,7 @@
 
 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 ff723e3..8b12f3c 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/Android.bp
+++ b/packages/SystemUI/accessibility/accessibilitymenu/Android.bp
@@ -29,6 +29,7 @@
 
 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 1757dda..538ecb3 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp
+++ b/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp
@@ -20,6 +20,7 @@
 
 android_test {
     name: "AccessibilityMenuServiceTests",
+    use_resource_processor: true,
     certificate: "platform",
     libs: [
         "android.test.runner",
diff --git a/packages/SystemUI/aconfig/OWNERS b/packages/SystemUI/aconfig/OWNERS
new file mode 100644
index 0000000..e1a7a0f
--- /dev/null
+++ b/packages/SystemUI/aconfig/OWNERS
@@ -0,0 +1 @@
+per-file accessibility.aconfig = file:/core/java/android/view/accessibility/OWNERS
diff --git a/packages/SystemUI/animation/Android.bp b/packages/SystemUI/animation/Android.bp
index 6f53b42..8438051 100644
--- a/packages/SystemUI/animation/Android.bp
+++ b/packages/SystemUI/animation/Android.bp
@@ -24,6 +24,7 @@
 android_library {
 
     name: "SystemUIAnimationLib",
+    use_resource_processor: true,
 
     srcs: [
         "src/**/*.java",
@@ -52,6 +53,7 @@
 
 android_library {
     name: "SystemUIShaderLib",
+    use_resource_processor: true,
 
     srcs: [
         "src/com/android/systemui/surfaceeffects/**/*.java",
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 1b56d4a..0f2e4ba 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.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 @@
     /** 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 @@
                 Log.d(
                     TAG,
                     "Calling controller.onIntentStarted(willAnimate=$willAnimate) " +
-                            "[controller=$this]"
+                        "[controller=$this]"
                 )
             }
             this.onIntentStarted(willAnimate)
@@ -431,7 +439,8 @@
         internal val delegate: AnimationDelegate
 
         init {
-            delegate = AnimationDelegate(controller, callback, listener, launchAnimator)
+            delegate =
+                AnimationDelegate(controller, callback, listener, launchAnimator, disableWmTimeout)
         }
 
         @BinderThread
@@ -461,13 +470,26 @@
         /** 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()
@@ -487,11 +509,11 @@
 
         @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/common/Android.bp b/packages/SystemUI/common/Android.bp
index e36ada8..482776a 100644
--- a/packages/SystemUI/common/Android.bp
+++ b/packages/SystemUI/common/Android.bp
@@ -24,6 +24,7 @@
 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 ab3efb8..510fa1e 100644
--- a/packages/SystemUI/compose/core/Android.bp
+++ b/packages/SystemUI/compose/core/Android.bp
@@ -38,4 +38,5 @@
     ],
 
     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 5a8a374..52c6385 100644
--- a/packages/SystemUI/compose/core/tests/Android.bp
+++ b/packages/SystemUI/compose/core/tests/Android.bp
@@ -47,4 +47,5 @@
     ],
 
     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 c6438c9..e4426fe 100644
--- a/packages/SystemUI/compose/features/Android.bp
+++ b/packages/SystemUI/compose/features/Android.bp
@@ -23,6 +23,7 @@
 
 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 5505eaf..46a9d42 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.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/PasswordBouncer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PasswordBouncer.kt
index 8a8557a..df22a70 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PasswordBouncer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PasswordBouncer.kt
@@ -17,8 +17,11 @@
 package com.android.systemui.bouncer.ui.composable
 
 import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.ExperimentalLayoutApi
 import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.WindowInsets
 import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.imeAnimationTarget
 import androidx.compose.foundation.text.KeyboardActions
 import androidx.compose.foundation.text.KeyboardOptions
 import androidx.compose.material3.LocalTextStyle
@@ -29,6 +32,7 @@
 import androidx.compose.runtime.collectAsState
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberUpdatedState
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.drawBehind
@@ -44,6 +48,7 @@
 import com.android.systemui.bouncer.ui.viewmodel.PasswordBouncerViewModel
 
 /** UI for the input part of a password-requiring version of the bouncer. */
+@OptIn(ExperimentalLayoutApi::class)
 @Composable
 internal fun PasswordBouncer(
     viewModel: PasswordBouncerViewModel,
@@ -54,6 +59,10 @@
     val isInputEnabled: Boolean by viewModel.isInputEnabled.collectAsState()
     val animateFailure: Boolean by viewModel.animateFailure.collectAsState()
 
+    val density = LocalDensity.current
+    val isImeVisible by rememberUpdatedState(WindowInsets.imeAnimationTarget.getBottom(density) > 0)
+    LaunchedEffect(isImeVisible) { viewModel.onImeVisibilityChanged(isImeVisible) }
+
     LaunchedEffect(Unit) {
         // When the UI comes up, request focus on the TextField to bring up the software keyboard.
         focusRequester.requestFocus()
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 e5c6977..6491b70 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 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 77065cf..055ece3 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 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 77daebb..c3a3752 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.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 68f010e..e12b7ea 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.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 1e6f4a2..26cc9b9 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.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 4822200..689a0a2 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.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 272e507..8e34008 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.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 c7c9140..c85cd7b 100644
--- a/packages/SystemUI/compose/features/tests/Android.bp
+++ b/packages/SystemUI/compose/features/tests/Android.bp
@@ -24,6 +24,7 @@
 // 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 fc37b355..927fd8e 100644
--- a/packages/SystemUI/customization/Android.bp
+++ b/packages/SystemUI/customization/Android.bp
@@ -23,6 +23,7 @@
 
 android_library {
     name: "SystemUICustomizationLib",
+    use_resource_processor: true,
     srcs: [
         "src/**/*.java",
         "src/**/*.kt",
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 054f9ec..c41dc53 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 @@
             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 @@
     fun verifyLoadedProviders() {
         val shouldSchedule = isVerifying.compareAndSet(false, true)
         if (!shouldSchedule) {
+            logger.tryLog(
+                TAG,
+                LogLevel.VERBOSE,
+                {},
+                { "verifyLoadedProviders: shouldSchedule=false" }
+            )
             return
         }
 
@@ -670,6 +676,7 @@
                     { str1 = clockId },
                     { "Clock $str1 not loaded; using default" }
                 )
+                verifyLoadedProviders()
             } else {
                 logger.tryLog(
                     TAG,
diff --git a/packages/SystemUI/log/Android.bp b/packages/SystemUI/log/Android.bp
index 627ac4b..2be22a6 100644
--- a/packages/SystemUI/log/Android.bp
+++ b/packages/SystemUI/log/Android.bp
@@ -23,6 +23,7 @@
 
 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 bb47a2f..c428952 100644
--- a/packages/SystemUI/plugin/Android.bp
+++ b/packages/SystemUI/plugin/Android.bp
@@ -50,6 +50,7 @@
 
     // 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 3f0fded..66951b5 100644
--- a/packages/SystemUI/plugin/ExamplePlugin/Android.bp
+++ b/packages/SystemUI/plugin/ExamplePlugin/Android.bp
@@ -10,6 +10,7 @@
 android_app {
 
     name: "ExamplePlugin",
+    use_resource_processor: true,
 
     libs: ["SystemUIPluginLib"],
 
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index 8c81733..d1067a9 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -105,6 +105,13 @@
          screen. -->
     <item name="half_opened_bouncer_height_ratio" type="dimen" format="float">0.0</item>
 
+    <!-- Proportion of the screen height to use to set the maximum height of the bouncer to when
+     the device is in the DEVICE_POSTURE_HALF_OPENED posture.
+
+     This value is only used when motion layout bouncer is used - when flag
+     landscape.enable_lockscreen (b/293252410) is on -->
+    <item name="motion_layout_half_fold_bouncer_height_ratio" type="dimen" format="float">0.55</item>
+
     <!-- The actual amount of translation that is applied to the security when it animates from one
          side of the screen to the other in one-handed or user switcher mode. Note that it will
          always translate from the side of the screen to the other (it will "jump" closer to the
diff --git a/packages/SystemUI/res-keyguard/xml/keyguard_pattern_scene.xml b/packages/SystemUI/res-keyguard/xml/keyguard_pattern_scene.xml
index 6112411..751d6d8 100644
--- a/packages/SystemUI/res-keyguard/xml/keyguard_pattern_scene.xml
+++ b/packages/SystemUI/res-keyguard/xml/keyguard_pattern_scene.xml
@@ -10,9 +10,34 @@
         motion:duration="0"
         motion:autoTransition="none"/>
 
+    <Transition
+        motion:constraintSetStart="@id/single_constraints"
+        motion:constraintSetEnd="@+id/half_folded_single_constraints"
+        motion:duration="@integer/material_motion_duration_short_1"
+        motion:autoTransition="none"/>
+
     <!-- No changes to default layout -->
     <ConstraintSet android:id="@+id/single_constraints"/>
 
+    <ConstraintSet android:id="@+id/half_folded_single_constraints">
+
+        <Constraint
+            android:id="@+id/pattern_top_guideline"
+            androidprv:layout_constraintGuide_percent=
+                "@dimen/motion_layout_half_fold_bouncer_height_ratio"/>
+
+        <Constraint
+            android:id="@+id/keyguard_selector_fade_container"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="0dp"
+            android:layout_marginTop="@dimen/keyguard_eca_top_margin"
+            android:orientation="vertical"
+            androidprv:layout_constraintBottom_toBottomOf="parent"
+            androidprv:layout_constraintTop_toBottomOf="@+id/flow1"/>
+
+    </ConstraintSet>
+
     <ConstraintSet android:id="@+id/split_constraints">
 
         <Constraint
diff --git a/packages/SystemUI/res-keyguard/xml/keyguard_pin_scene.xml b/packages/SystemUI/res-keyguard/xml/keyguard_pin_scene.xml
index 2a1270c..cc498f4 100644
--- a/packages/SystemUI/res-keyguard/xml/keyguard_pin_scene.xml
+++ b/packages/SystemUI/res-keyguard/xml/keyguard_pin_scene.xml
@@ -26,11 +26,35 @@
         motion:constraintSetStart="@id/single_constraints"
         motion:constraintSetEnd="@+id/split_constraints"
         motion:duration="0"
-        motion:autoTransition="none"/>
+        motion:autoTransition="none" />
+
+    <Transition
+        motion:constraintSetStart="@id/single_constraints"
+        motion:constraintSetEnd="@+id/half_folded_single_constraints"
+        motion:duration="@integer/material_motion_duration_short_1" />
 
     <!-- No changes to default layout -->
     <ConstraintSet android:id="@+id/single_constraints"/>
 
+    <ConstraintSet android:id="@+id/half_folded_single_constraints">
+
+        <Constraint
+            android:id="@+id/pin_pad_top_guideline"
+            androidprv:layout_constraintGuide_percent=
+                "@dimen/motion_layout_half_fold_bouncer_height_ratio"/>
+
+        <Constraint
+            android:id="@+id/keyguard_selector_fade_container"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="0dp"
+            android:layout_marginTop="@dimen/keyguard_eca_top_margin"
+            android:orientation="vertical"
+            androidprv:layout_constraintBottom_toBottomOf="parent"
+            androidprv:layout_constraintTop_toBottomOf="@+id/flow1"/>
+
+    </ConstraintSet>
+
     <ConstraintSet android:id="@+id/split_constraints">
 
         <Constraint
@@ -68,4 +92,5 @@
             android:layout_marginTop="@dimen/keyguard_eca_top_margin" />
 
     </ConstraintSet>
+
 </MotionScene>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/bluetooth_device_item.xml b/packages/SystemUI/res/layout/bluetooth_device_item.xml
new file mode 100644
index 0000000..6dd44fb
--- /dev/null
+++ b/packages/SystemUI/res/layout/bluetooth_device_item.xml
@@ -0,0 +1,94 @@
+<?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.
+  -->
+
+<!-- TODO(b/298124674) remove this root -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/bluetooth_device_list_container"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:layout_marginBottom="4dp">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/bluetooth_device_row"
+        style="@style/BluetoothTileDialog.Device"
+        android:layout_height="@dimen/bluetooth_dialog_device_height"
+        android:paddingEnd="24dp"
+        android:paddingStart="20dp"
+        android:baselineAligned="false">
+
+        <ImageView
+            android:id="@+id/bluetooth_device_icon"
+            android:contentDescription="@string/accessibility_bluetooth_device_icon"
+            android:layout_width="24dp"
+            android:layout_height="24dp"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            android:layout_gravity="center_vertical" />
+
+        <View
+            android:id="@+id/bluetooth_device"
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            app:layout_constraintTop_toTopOf="@+id/bluetooth_device_name"
+            app:layout_constraintBottom_toBottomOf="@+id/bluetooth_device_summary"
+            app:layout_constraintStart_toStartOf="@+id/bluetooth_device_name"
+            app:layout_constraintEnd_toEndOf="@+id/bluetooth_device_name" />
+
+        <TextView
+            android:layout_width="0dp"
+            android:id="@+id/bluetooth_device_name"
+            style="@style/BluetoothTileDialog.DeviceName"
+            android:paddingStart="20dp"
+            android:paddingTop="10dp"
+            app:layout_constraintWidth_percent="0.7"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintStart_toEndOf="@+id/bluetooth_device_icon"
+            app:layout_constraintEnd_toStartOf="@+id/gear_icon"
+            app:layout_constraintBottom_toTopOf="@+id/bluetooth_device_summary"
+            android:gravity="center_vertical"
+            android:textSize="14sp" />
+
+        <TextView
+            android:layout_width="0dp"
+            android:id="@+id/bluetooth_device_summary"
+            style="@style/BluetoothTileDialog.DeviceSummary"
+            android:paddingStart="20dp"
+            android:paddingBottom="10dp"
+            app:layout_constraintWidth_percent="0.7"
+            app:layout_constraintTop_toBottomOf="@+id/bluetooth_device_name"
+            app:layout_constraintStart_toEndOf="@+id/bluetooth_device_icon"
+            app:layout_constraintEnd_toStartOf="@+id/gear_icon"
+            app:layout_constraintBottom_toBottomOf="parent"
+            android:gravity="center_vertical" />
+
+        <ImageView
+            android:id="@+id/gear_icon"
+            android:src="@drawable/ic_settings_24dp"
+            android:contentDescription="@string/accessibility_bluetooth_device_settings_gear"
+            android:layout_width="0dp"
+            android:layout_height="24dp"
+            app:layout_constraintStart_toEndOf="@+id/bluetooth_device_name"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintWidth_percent="0.3"
+            android:gravity="center_vertical"
+            android:paddingStart="10dp" />
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml b/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml
new file mode 100644
index 0000000..16aeb95
--- /dev/null
+++ b/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml
@@ -0,0 +1,188 @@
+<?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.
+  -->
+
+<androidx.constraintlayout.widget.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/root"
+    style="@style/Widget.SliceView.Panel"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content">
+
+    <TextView
+        android:id="@+id/bluetooth_tile_dialog_title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:paddingTop="24dp"
+        android:ellipsize="end"
+        android:gravity="center_vertical|center_horizontal"
+        android:text="@string/quick_settings_bluetooth_label"
+        android:textAppearance="@style/TextAppearance.Dialog.Title"
+        android:textSize="24sp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintBottom_toTopOf="@id/bluetooth_tile_dialog_subtitle"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <TextView
+        android:id="@+id/bluetooth_tile_dialog_subtitle"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="4dp"
+        android:layout_marginBottom="@dimen/bluetooth_dialog_layout_margin"
+        android:ellipsize="end"
+        android:gravity="center_vertical|center_horizontal"
+        android:maxLines="1"
+        android:text="@string/quick_settings_bluetooth_tile_subtitle"
+        android:textAppearance="@style/TextAppearance.Dialog.Body.Message"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintBottom_toTopOf="@id/bluetooth_toggle_title"
+        app:layout_constraintTop_toBottomOf="@id/bluetooth_tile_dialog_title" />
+
+    <TextView
+        android:id="@+id/bluetooth_toggle_title"
+        style="@style/BluetoothTileDialog.Device"
+        android:layout_width="0dp"
+        android:layout_height="64dp"
+        android:gravity="center_vertical"
+        android:layout_marginTop="4dp"
+        android:text="@string/turn_on_bluetooth"
+        android:textAppearance="@style/TextAppearance.Dialog.Body.Message"
+        android:textSize="16sp"
+        app:layout_constraintEnd_toStartOf="@+id/bluetooth_toggle"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/bluetooth_tile_dialog_subtitle" />
+
+    <Switch
+        android:id="@+id/bluetooth_toggle"
+        style="@style/BluetoothTileDialog.Device"
+        android:layout_width="0dp"
+        android:layout_height="48dp"
+        android:gravity="center|center_vertical"
+        android:paddingEnd="24dp"
+        android:layout_marginTop="10dp"
+        android:contentDescription="@string/turn_on_bluetooth"
+        android:switchMinWidth="@dimen/settingslib_switch_track_width"
+        android:theme="@style/MainSwitch.Settingslib"
+        android:thumb="@drawable/settingslib_thumb_selector"
+        android:track="@drawable/settingslib_track_selector"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toEndOf="@+id/bluetooth_toggle_title"
+        app:layout_constraintTop_toBottomOf="@id/bluetooth_tile_dialog_subtitle" />
+
+    <androidx.constraintlayout.widget.Group
+        android:id="@+id/pair_new_device_layout_group"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:visibility="gone"
+        app:constraint_referenced_ids="ic_add,pair_new_device_text" />
+
+    <ImageView
+        android:id="@+id/ic_add"
+        android:layout_width="24dp"
+        android:layout_height="24dp"
+        android:layout_marginStart="36dp"
+        android:gravity="center_vertical"
+        android:importantForAccessibility="no"
+        android:src="@drawable/ic_add"
+        app:layout_constraintBottom_toTopOf="@id/device_list"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toStartOf="@id/pair_new_device_text"
+        app:layout_constraintTop_toBottomOf="@id/bluetooth_toggle_title"
+        android:tint="?android:attr/textColorPrimary" />
+
+    <TextView
+        android:id="@+id/pair_new_device_text"
+        style="@style/BluetoothTileDialog.Device"
+        android:layout_width="0dp"
+        android:layout_height="@dimen/bluetooth_dialog_device_height"
+        android:gravity="center_vertical"
+        android:layout_marginStart="0dp"
+        android:paddingStart="20dp"
+        android:text="@string/pair_new_bluetooth_devices"
+        android:textSize="14sp"
+        android:textAppearance="@style/TextAppearance.Dialog.Title"
+        app:layout_constraintBottom_toTopOf="@id/device_list"
+        app:layout_constraintStart_toEndOf="@+id/ic_add"
+        app:layout_constraintTop_toBottomOf="@id/bluetooth_toggle_title"
+        app:layout_constraintEnd_toEndOf="parent" />
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/device_list"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:nestedScrollingEnabled="false"
+        android:overScrollMode="never"
+        android:scrollbars="vertical"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/pair_new_device_text"
+        app:layout_constraintBottom_toTopOf="@+id/see_all_text" />
+
+    <androidx.constraintlayout.widget.Group
+        android:id="@+id/see_all_layout_group"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:visibility="gone"
+        app:constraint_referenced_ids="ic_arrow,see_all_text" />
+
+    <ImageView
+        android:id="@+id/ic_arrow"
+        android:layout_marginStart="36dp"
+        android:layout_width="24dp"
+        android:layout_height="24dp"
+        android:importantForAccessibility="no"
+        android:gravity="center_vertical"
+        android:src="@drawable/ic_arrow_forward"
+        app:layout_constraintBottom_toTopOf="@+id/done_button"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toStartOf="@id/see_all_text"
+        app:layout_constraintTop_toBottomOf="@id/device_list" />
+
+    <TextView
+        android:id="@+id/see_all_text"
+        style="@style/BluetoothTileDialog.Device"
+        android:layout_width="0dp"
+        android:layout_height="@dimen/bluetooth_dialog_device_height"
+        android:gravity="center_vertical"
+        android:layout_marginStart="0dp"
+        android:paddingStart="20dp"
+        android:text="@string/see_all_bluetooth_devices"
+        android:textSize="14sp"
+        android:textAppearance="@style/TextAppearance.Dialog.Title"
+        app:layout_constraintBottom_toTopOf="@+id/done_button"
+        app:layout_constraintStart_toEndOf="@+id/ic_arrow"
+        app:layout_constraintTop_toBottomOf="@id/device_list"
+        app:layout_constraintEnd_toEndOf="parent" />
+
+    <Button
+        android:id="@+id/done_button"
+        style="@style/Widget.Dialog.Button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="@dimen/dialog_bottom_padding"
+        android:layout_marginEnd="@dimen/dialog_side_padding"
+        android:layout_marginStart="@dimen/dialog_side_padding"
+        android:clickable="true"
+        android:ellipsize="end"
+        android:focusable="true"
+        android:maxLines="1"
+        android:text="@string/inline_done_button"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/see_all_text" />
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values-land/bools.xml b/packages/SystemUI/res/values-land/bools.xml
index e24792d..c112edc 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 c4d77e8..36926a2 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 3956662..234c6df 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>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 7e9d3f5..88726af 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1643,6 +1643,11 @@
     <!-- Radius of switch track -->
     <dimen name="settingslib_switch_track_radius">35dp</dimen>
 
+    <!-- Bluetooth dialog related dimensions -->
+    <dimen name="bluetooth_dialog_layout_margin">16dp</dimen>
+    <!-- The height of the bluetooth device in bluetooth dialog. -->
+    <dimen name="bluetooth_dialog_device_height">72dp</dimen>
+
     <!-- Height percentage of the parent container occupied by the communal view -->
     <item name="communal_source_height_percentage" format="float" type="dimen">0.80</item>
 
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 29c9767..5860806 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -459,7 +459,12 @@
 
     <!-- Content description of the bluetooth icon when connected for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_bluetooth_connected">Bluetooth connected.</string>
-    <!-- Content description of the bluetooth icon when connecting for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+
+    <!-- Content description of the bluetooth device icon. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_bluetooth_device_icon">Bluetooth device icon</string>
+
+    <!-- Content description of the bluetooth device settings gear icon. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_bluetooth_device_settings_gear">Bluetooth device settings gear</string>
 
     <!-- Content description of the battery when battery state is unknown for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_battery_unknown">Battery percentage unknown.</string>
@@ -621,6 +626,19 @@
     <!-- QuickSettings: Bluetooth (Off) [CHAR LIMIT=NONE] -->
     <!-- QuickSettings: Bluetooth detail panel, text when there are no items [CHAR LIMIT=NONE] -->
     <string name="quick_settings_bluetooth_detail_empty_text">No paired devices available</string>
+    <!-- QuickSettings: Bluetooth dialog subtitle [CHAR LIMIT=NONE]-->
+    <string name="quick_settings_bluetooth_tile_subtitle">Tap a device to connect</string>
+    <!-- QuickSettings: Bluetooth dialog pair new devices [CHAR LIMIT=NONE]-->
+    <string name="pair_new_bluetooth_devices">Pair new device</string>
+    <!-- QuickSettings: Bluetooth dialog see all devices [CHAR LIMIT=NONE]-->
+    <string name="see_all_bluetooth_devices">See all</string>
+    <!-- QuickSettings: Bluetooth dialog turn on Bluetooth [CHAR LIMIT=NONE]-->
+    <string name="turn_on_bluetooth">Use Bluetooth</string>
+    <!-- QuickSettings: Bluetooth dialog device connected default summary [CHAR LIMIT=NONE]-->
+    <string name="quick_settings_bluetooth_device_connected">Connected</string>
+    <!-- QuickSettings: Bluetooth dialog device saved default summary [CHAR LIMIT=NONE]-->
+    <string name="quick_settings_bluetooth_device_saved">Saved</string>
+
     <!-- QuickSettings: Bluetooth secondary label for the battery level of a connected device [CHAR LIMIT=20]-->
     <string name="quick_settings_bluetooth_secondary_label_battery_level"><xliff:g id="battery_level_as_percentage">%s</xliff:g> battery</string>
     <!-- QuickSettings: Bluetooth secondary label for an audio device being connected [CHAR LIMIT=20]-->
@@ -3086,7 +3104,7 @@
     configured. This is shown as part of a dialog that explains to the user why they cannot select
     this shortcut for their lock screen right now. [CHAR LIMIT=NONE].
     -->
-    <string name="home_quick_affordance_unavailable_configure_the_app">&#8226; At least one device is available</string>
+    <string name="home_quick_affordance_unavailable_configure_the_app">&#8226; At least one device or device panel are available</string>
 
     <!---
     Explains that the notes app is not available. This is shown as part of a dialog that explains to
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 6991b96..084cb88 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -15,7 +15,7 @@
 -->
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
-           xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
 
     <style name="TextAppearance.StatusBar.Clock" parent="@*android:style/TextAppearance.StatusBar.Icon">
         <item name="android:textSize">@dimen/status_bar_clock_size</item>
@@ -54,10 +54,10 @@
     </style>
 
     <style name="TextAppearance.StatusBar.Expanded.EmergencyCallsOnly"
-           parent="TextAppearance.StatusBar.Expanded.AboveDateTime" />
+        parent="TextAppearance.StatusBar.Expanded.AboveDateTime" />
 
     <style name="TextAppearance.StatusBar.Expanded.ChargingInfo"
-            parent="TextAppearance.StatusBar.Expanded.AboveDateTime" />
+        parent="TextAppearance.StatusBar.Expanded.AboveDateTime" />
 
     <style name="TextAppearance.StatusBar.Expanded.UserSwitcher">
         <item name="android:textSize">@dimen/kg_user_switcher_text_size</item>
@@ -645,7 +645,7 @@
     </style>
 
     <style name="TextAppearance.HeadsUpStatusBarText"
-           parent="@*android:style/TextAppearance.DeviceDefault.Notification.Info">
+        parent="@*android:style/TextAppearance.DeviceDefault.Notification.Info">
     </style>
 
     <style name="TextAppearance.QSEdit" >
@@ -699,7 +699,7 @@
     </style>
 
     <style name="MediaPlayer.SessionAction"
-           parent="@android:style/Widget.Material.Button.Borderless.Small">
+        parent="@android:style/Widget.Material.Button.Borderless.Small">
         <item name="android:background">@drawable/qs_media_light_source</item>
         <item name="android:tint">?android:attr/textColorPrimary</item>
         <item name="android:paddingTop">12dp</item>
@@ -929,12 +929,13 @@
         <item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
     </style>
 
-     <style name="Theme.SystemUI.Dialog.Control.DetailPanel" parent="@android:style/Theme.DeviceDefault.Dialog.NoActionBar">
-      <item name="android:windowFullscreen">false</item>
-      <item name="android:windowIsFloating">false</item>
-      <item name="android:windowBackground">@color/controls_task_view_bg</item>
-      <item name="android:backgroundDimEnabled">false</item>
-      <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
+    <style name="Theme.SystemUI.Dialog.Control.DetailPanel"
+           parent="@android:style/Theme.DeviceDefault.Dialog.NoActionBar">
+        <item name="android:windowFullscreen">false</item>
+        <item name="android:windowIsFloating">false</item>
+        <item name="android:windowBackground">@color/controls_task_view_bg</item>
+        <item name="android:backgroundDimEnabled">false</item>
+        <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
     </style>
 
     <style name="Control" />
@@ -1034,17 +1035,17 @@
     <style name="Wallet" />
 
     <style name="Wallet.TextAppearance">
-      <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
-      <item name="android:textColor">?android:attr/textColorPrimary</item>
-      <item name="android:singleLine">true</item>
-      <item name="android:textSize">14sp</item>
+        <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
+        <item name="android:textColor">?android:attr/textColorPrimary</item>
+        <item name="android:singleLine">true</item>
+        <item name="android:textSize">14sp</item>
     </style>
 
     <style name="Wallet.Theme" parent="@android:style/Theme.DeviceDefault">
-      <item name="android:colorBackground">@color/material_dynamic_neutral10</item>
-      <item name="android:itemBackground">@color/material_dynamic_neutral20</item>
-      <!-- Setting a placeholder will avoid using the SystemUI icon on the splash screen.  -->
-      <item name="android:windowSplashScreenAnimatedIcon">@drawable/ic_blank</item>
+        <item name="android:colorBackground">@color/material_dynamic_neutral10</item>
+        <item name="android:itemBackground">@color/material_dynamic_neutral20</item>
+        <!-- Setting a placeholder will avoid using the SystemUI icon on the splash screen.  -->
+        <item name="android:windowSplashScreenAnimatedIcon">@drawable/ic_blank</item>
     </style>
 
     <style name="Animation.InternetDialog" parent="@android:style/Animation.InputMethod">
@@ -1169,7 +1170,7 @@
     </style>
 
     <style name="TrimmedHorizontalProgressBar"
-           parent="android:Widget.Material.ProgressBar.Horizontal">
+        parent="android:Widget.Material.ProgressBar.Horizontal">
         <item name="android:indeterminateDrawable">
             @drawable/progress_indeterminate_horizontal_material_trimmed
         </item>
@@ -1254,6 +1255,36 @@
         <item name="android:textColor">?android:attr/textColorSecondary</item>
     </style>
 
+    <style name="BluetoothTileDialog">
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_gravity">center_vertical|start</item>
+    </style>
+
+    <style name="BluetoothTileDialog.Device">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">88dp</item>
+        <item name="android:layout_gravity">center_vertical|start</item>
+        <item name="android:layout_marginStart">@dimen/bluetooth_dialog_layout_margin</item>
+        <item name="android:layout_marginEnd">@dimen/bluetooth_dialog_layout_margin</item>
+        <item name="android:paddingStart">22dp</item>
+        <item name="android:paddingEnd">22dp</item>
+        <item name="android:orientation">horizontal</item>
+        <item name="android:focusable">true</item>
+        <item name="android:clickable">true</item>
+    </style>
+
+    <style name="BluetoothTileDialog.DeviceName">
+        <item name="android:textSize">14sp</item>
+        <item name="android:textAppearance">@style/TextAppearance.Dialog.Title</item>
+    </style>
+
+    <style name="BluetoothTileDialog.DeviceSummary">
+        <item name="android:ellipsize">end</item>
+        <item name="android:maxLines">2</item>
+        <item name="android:textAppearance">@style/TextAppearance.Dialog.Body.Message</item>
+    </style>
+
     <style name="BroadcastDialog">
         <item name="android:layout_width">wrap_content</item>
         <item name="android:layout_height">wrap_content</item>
@@ -1397,7 +1428,7 @@
     </style>
 
     <style name="PermissionGrantButtonTop"
-           parent="@android:style/Widget.DeviceDefault.Button.Borderless.Colored">
+        parent="@android:style/Widget.DeviceDefault.Button.Borderless.Colored">
         <item name="android:layout_width">332dp</item>
         <item name="android:layout_height">56dp</item>
         <item name="android:layout_marginTop">2dp</item>
@@ -1406,7 +1437,7 @@
     </style>
 
     <style name="PermissionGrantButtonBottom"
-           parent="@android:style/Widget.DeviceDefault.Button.Borderless.Colored">
+        parent="@android:style/Widget.DeviceDefault.Button.Borderless.Colored">
         <item name="android:layout_width">332dp</item>
         <item name="android:layout_height">56dp</item>
         <item name="android:layout_marginTop">2dp</item>
@@ -1465,14 +1496,14 @@
     </style>
 
     <style name="TextAppearance.PrivacyDialog.Item.Title"
-           parent="@android:style/TextAppearance.DeviceDefault.Medium">
+        parent="@android:style/TextAppearance.DeviceDefault.Medium">
         <item name="android:textSize">14sp</item>
         <item name="android:lineHeight">20sp</item>
         <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
     </style>
 
     <style name="TextAppearance.PrivacyDialog.Item.Summary"
-           parent="@android:style/TextAppearance.DeviceDefault.Small">
+        parent="@android:style/TextAppearance.DeviceDefault.Small">
         <item name="android:textSize">14sp</item>
         <item name="android:lineHeight">20sp</item>
         <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
@@ -1481,4 +1512,4 @@
     <style name="Theme.PrivacyDialog" parent="@style/Theme.SystemUI.Dialog">
         <item name="android:colorBackground">?androidprv:attr/materialColorSurfaceContainer</item>
     </style>
-</resources>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/shared/Android.bp b/packages/SystemUI/shared/Android.bp
index 0415341..9c368eb 100644
--- a/packages/SystemUI/shared/Android.bp
+++ b/packages/SystemUI/shared/Android.bp
@@ -38,6 +38,7 @@
 
 android_library {
     name: "SystemUISharedLib",
+    use_resource_processor: true,
     srcs: [
         "src/**/*.java",
         "src/**/*.kt",
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 7719e95..f9f2c63 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 @@
         mComponentName = componentName;
         mPluginFactory = pluginFactory;
         mPlugin = plugin;
-        mTag = TAG + mComponentName.toShortString()
+        mTag = TAG + "[" + mComponentName.getShortClassName() + "]"
                 + '@' + Integer.toHexString(hashCode());
 
         if (mPlugin != null) {
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierText.java b/packages/SystemUI/src/com/android/keyguard/CarrierText.java
index 87a9b0f..ae282c7 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.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 b52ee01..873c3d9 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java
@@ -39,7 +39,7 @@
 
 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 006974c..d677a15 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.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 225bebe..b2ffccc 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.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 788a66d..6a170a5 100644
--- a/packages/SystemUI/src/com/android/keyguard/FaceWakeUpTriggersConfig.kt
+++ b/packages/SystemUI/src/com/android/keyguard/FaceWakeUpTriggersConfig.kt
@@ -20,10 +20,11 @@
 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
+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 @@
     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 @@
             } else {
                 defaultTriggerFaceAuthOnWakeUpFrom
             }
+        wakeSleepReasonsToTriggerFaceAuth =
+            triggerFaceAuthOnWakeUpFrom
+                .map {
+                    val enumVal = WakeSleepReason.fromPowerManagerWakeReason(it)
+                    assert(enumVal != WakeSleepReason.OTHER)
+                    enumVal
+                }
+                .toSet()
         dumpManager.registerDumpable(this)
     }
 
@@ -59,6 +69,9 @@
         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/keyguard/KeyguardAbsKeyInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
index c6d1471..dfeb1f3 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
@@ -25,7 +25,7 @@
 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 e3f9de1..167bd59 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.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 a78c293..f7db48a 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.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 610df11..ba8e427 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -22,7 +22,7 @@
 
 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 11f9589..29414ea 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.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 @@
         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 1c5a575..9c015fe 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
@@ -39,7 +39,7 @@
 
 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 ccbb0c5..fc4e122 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.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 98f082f..38c8495 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.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 abd1563..29ce18c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
@@ -29,7 +29,7 @@
 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 fc66527..7e44866 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java
@@ -27,7 +27,7 @@
 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 72b4ae5..622b67f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
@@ -17,6 +17,7 @@
 package com.android.keyguard;
 
 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
 
 import static com.android.internal.jank.InteractionJankMonitor.CUJ_LOCKSCREEN_PIN_APPEAR;
 import static com.android.internal.jank.InteractionJankMonitor.CUJ_LOCKSCREEN_PIN_DISAPPEAR;
@@ -40,7 +41,7 @@
 
 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;
 
 /**
@@ -52,6 +53,8 @@
     private final DisappearAnimationUtils mDisappearAnimationUtils;
     private final DisappearAnimationUtils mDisappearAnimationUtilsLocked;
     @Nullable private MotionLayout mContainerMotionLayout;
+    // TODO (b/293252410) - usage of mContainerConstraintLayout should be removed
+    //  when the flag is enabled/removed
     @Nullable private ConstraintLayout mContainerConstraintLayout;
     private int mDisappearYTranslation;
     private View[][] mViews;
@@ -59,7 +62,7 @@
     private int mYTransOffset;
     private View mBouncerMessageArea;
     private boolean mAlreadyUsingSplitBouncer = false;
-    private boolean mIsLockScreenLandscapeEnabled = false;
+    private boolean mIsSmallLockScreenLandscapeEnabled = false;
     @DevicePostureInt private int mLastDevicePosture = DEVICE_POSTURE_UNKNOWN;
     public static final long ANIMATION_DURATION = 650;
 
@@ -87,12 +90,12 @@
     /** Use motion layout (new bouncer implementation) if LOCKSCREEN_ENABLE_LANDSCAPE flag is
      *  enabled, instead of constraint layout (old bouncer implementation) */
     public void setIsLockScreenLandscapeEnabled(boolean isLockScreenLandscapeEnabled) {
-        mIsLockScreenLandscapeEnabled = isLockScreenLandscapeEnabled;
+        mIsSmallLockScreenLandscapeEnabled = isLockScreenLandscapeEnabled;
         findContainerLayout();
     }
 
     private void findContainerLayout() {
-        if (mIsLockScreenLandscapeEnabled) {
+        if (mIsSmallLockScreenLandscapeEnabled) {
             mContainerMotionLayout = findViewById(R.id.pin_container);
         } else {
             mContainerConstraintLayout = findViewById(R.id.pin_container);
@@ -109,7 +112,7 @@
         if (mLastDevicePosture == posture) return;
         mLastDevicePosture = posture;
 
-        if (mIsLockScreenLandscapeEnabled) {
+        if (mIsSmallLockScreenLandscapeEnabled) {
             boolean useSplitBouncerAfterFold =
                     mLastDevicePosture == DEVICE_POSTURE_CLOSED
                     && getResources().getConfiguration().orientation == ORIENTATION_LANDSCAPE
@@ -166,21 +169,45 @@
             }
         }
 
+        if (mIsSmallLockScreenLandscapeEnabled) {
+            updateHalfFoldedConstraints();
+        } else {
+            updateHalfFoldedGuideline();
+        }
+    }
+
+    private void updateHalfFoldedConstraints() {
+        // Update the constraints based on the device posture...
+        if (mAlreadyUsingSplitBouncer) return;
+
+        boolean shouldCollapsePin =
+                mLastDevicePosture == DEVICE_POSTURE_HALF_OPENED
+                        && mContext.getResources().getConfiguration().orientation
+                        == ORIENTATION_PORTRAIT;
+
+        int expectedMotionLayoutState = shouldCollapsePin
+                ? R.id.half_folded_single_constraints
+                : R.id.single_constraints;
+
+        transitionToMotionLayoutState(expectedMotionLayoutState);
+    }
+
+    // TODO (b/293252410) - this method can be removed when the flag is enabled/removed
+    private void updateHalfFoldedGuideline() {
         // Update the guideline based on the device posture...
         float halfOpenPercentage =
                 mContext.getResources().getFloat(R.dimen.half_opened_bouncer_height_ratio);
 
-        if (mIsLockScreenLandscapeEnabled) {
-            ConstraintSet cs = mContainerMotionLayout.getConstraintSet(R.id.single_constraints);
-            cs.setGuidelinePercent(R.id.pin_pad_top_guideline,
-                    mLastDevicePosture == DEVICE_POSTURE_HALF_OPENED ? halfOpenPercentage : 0.0f);
-            cs.applyTo(mContainerMotionLayout);
-        } else {
-            ConstraintSet cs = new ConstraintSet();
-            cs.clone(mContainerConstraintLayout);
-            cs.setGuidelinePercent(R.id.pin_pad_top_guideline,
-                    mLastDevicePosture == DEVICE_POSTURE_HALF_OPENED ? halfOpenPercentage : 0.0f);
-            cs.applyTo(mContainerConstraintLayout);
+        ConstraintSet cs = new ConstraintSet();
+        cs.clone(mContainerConstraintLayout);
+        cs.setGuidelinePercent(R.id.pin_pad_top_guideline,
+                mLastDevicePosture == DEVICE_POSTURE_HALF_OPENED ? halfOpenPercentage : 0.0f);
+        cs.applyTo(mContainerConstraintLayout);
+    }
+
+    private void transitionToMotionLayoutState(int state) {
+        if (mContainerMotionLayout.getCurrentState() != state) {
+            mContainerMotionLayout.transitionToState(state);
         }
     }
 
@@ -189,12 +216,24 @@
      *  Only called when flag LANDSCAPE_ENABLE_LOCKSCREEN is enabled. */
     @Override
     protected void updateConstraints(boolean useSplitBouncer) {
+        if (!mIsSmallLockScreenLandscapeEnabled) return;
+
         mAlreadyUsingSplitBouncer = useSplitBouncer;
+
         if (useSplitBouncer) {
             mContainerMotionLayout.jumpToState(R.id.split_constraints);
             mContainerMotionLayout.setMaxWidth(Integer.MAX_VALUE);
         } else {
-            mContainerMotionLayout.jumpToState(R.id.single_constraints);
+            boolean useHalfFoldedConstraints =
+                    mLastDevicePosture == DEVICE_POSTURE_HALF_OPENED
+                            && mContext.getResources().getConfiguration().orientation
+                            == ORIENTATION_PORTRAIT;
+
+            if (useHalfFoldedConstraints) {
+                mContainerMotionLayout.jumpToState(R.id.half_folded_single_constraints);
+            } else {
+                mContainerMotionLayout.jumpToState(R.id.single_constraints);
+            }
             mContainerMotionLayout.setMaxWidth(getResources()
                     .getDimensionPixelSize(R.dimen.keyguard_security_width));
         }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
index 8d5fc04..51c0676 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.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 ab8cd53..959cf6f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
@@ -39,7 +39,7 @@
 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 56706b5..5c206e9 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
@@ -16,6 +16,7 @@
 package com.android.keyguard;
 
 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
 
 import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_CLOSED;
 import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_HALF_OPENED;
@@ -42,7 +43,7 @@
 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
@@ -81,9 +82,11 @@
     BouncerKeyguardMessageArea mSecurityMessageDisplay;
     private View mEcaView;
     @Nullable private MotionLayout mContainerMotionLayout;
+    // TODO (b/293252410) - usage of mContainerConstraintLayout should be removed
+    //  when the flag is enabled/removed
     @Nullable private ConstraintLayout mContainerConstraintLayout;
     private boolean mAlreadyUsingSplitBouncer = false;
-    private boolean mIsLockScreenLandscapeEnabled = false;
+    private boolean mIsSmallLockScreenLandscapeEnabled = false;
     @DevicePostureInt private int mLastDevicePosture = DEVICE_POSTURE_UNKNOWN;
 
     public KeyguardPatternView(Context context) {
@@ -111,12 +114,12 @@
      * enabled, instead of constraint layout (old bouncer implementation)
      */
     public void setIsLockScreenLandscapeEnabled(boolean isLockScreenLandscapeEnabled) {
-        mIsLockScreenLandscapeEnabled = isLockScreenLandscapeEnabled;
+        mIsSmallLockScreenLandscapeEnabled = isLockScreenLandscapeEnabled;
         findContainerLayout();
     }
 
     private void findContainerLayout() {
-        if (mIsLockScreenLandscapeEnabled) {
+        if (mIsSmallLockScreenLandscapeEnabled) {
             mContainerMotionLayout = findViewById(R.id.pattern_container);
         } else {
             mContainerConstraintLayout = findViewById(R.id.pattern_container);
@@ -132,7 +135,7 @@
         if (mLastDevicePosture == posture) return;
         mLastDevicePosture = posture;
 
-        if (mIsLockScreenLandscapeEnabled) {
+        if (mIsSmallLockScreenLandscapeEnabled) {
             boolean useSplitBouncerAfterFold =
                     mLastDevicePosture == DEVICE_POSTURE_CLOSED
                     && getResources().getConfiguration().orientation == ORIENTATION_LANDSCAPE
@@ -147,21 +150,45 @@
     }
 
     private void updateMargins() {
+        if (mIsSmallLockScreenLandscapeEnabled) {
+            updateHalfFoldedConstraints();
+        } else {
+            updateHalfFoldedGuideline();
+        }
+    }
+
+    private void updateHalfFoldedConstraints() {
+        // Update the constraints based on the device posture...
+        if (mAlreadyUsingSplitBouncer) return;
+
+        boolean shouldCollapsePattern =
+                mLastDevicePosture == DEVICE_POSTURE_HALF_OPENED
+                        && mContext.getResources().getConfiguration().orientation
+                        == ORIENTATION_PORTRAIT;
+
+        int expectedMotionLayoutState = shouldCollapsePattern
+                ? R.id.half_folded_single_constraints
+                : R.id.single_constraints;
+
+        transitionToMotionLayoutState(expectedMotionLayoutState);
+    }
+
+    // TODO (b/293252410) - this method can be removed when the flag is enabled/removed
+    private void updateHalfFoldedGuideline() {
         // Update the guideline based on the device posture...
         float halfOpenPercentage =
                 mContext.getResources().getFloat(R.dimen.half_opened_bouncer_height_ratio);
 
-        if (mIsLockScreenLandscapeEnabled) {
-            ConstraintSet cs = mContainerMotionLayout.getConstraintSet(R.id.single_constraints);
-            cs.setGuidelinePercent(R.id.pattern_top_guideline,
-                    mLastDevicePosture == DEVICE_POSTURE_HALF_OPENED ? halfOpenPercentage : 0.0f);
-            cs.applyTo(mContainerMotionLayout);
-        } else {
-            ConstraintSet cs = new ConstraintSet();
-            cs.clone(mContainerConstraintLayout);
-            cs.setGuidelinePercent(R.id.pattern_top_guideline,
-                    mLastDevicePosture == DEVICE_POSTURE_HALF_OPENED ? halfOpenPercentage : 0.0f);
-            cs.applyTo(mContainerConstraintLayout);
+        ConstraintSet cs = new ConstraintSet();
+        cs.clone(mContainerConstraintLayout);
+        cs.setGuidelinePercent(R.id.pattern_top_guideline,
+                mLastDevicePosture == DEVICE_POSTURE_HALF_OPENED ? halfOpenPercentage : 0.0f);
+        cs.applyTo(mContainerConstraintLayout);
+    }
+
+    private void transitionToMotionLayoutState(int state) {
+        if (mContainerMotionLayout.getCurrentState() != state) {
+            mContainerMotionLayout.transitionToState(state);
         }
     }
 
@@ -172,12 +199,24 @@
      */
     @Override
     protected void updateConstraints(boolean useSplitBouncer) {
+        if (!mIsSmallLockScreenLandscapeEnabled) return;
+
         mAlreadyUsingSplitBouncer = useSplitBouncer;
+
         if (useSplitBouncer) {
             mContainerMotionLayout.jumpToState(R.id.split_constraints);
             mContainerMotionLayout.setMaxWidth(Integer.MAX_VALUE);
         } else {
-            mContainerMotionLayout.jumpToState(R.id.single_constraints);
+            boolean useHalfFoldedConstraints =
+                    mLastDevicePosture == DEVICE_POSTURE_HALF_OPENED
+                            && mContext.getResources().getConfiguration().orientation
+                            == ORIENTATION_PORTRAIT;
+
+            if (useHalfFoldedConstraints) {
+                mContainerMotionLayout.jumpToState(R.id.half_folded_single_constraints);
+            } else {
+                mContainerMotionLayout.jumpToState(R.id.single_constraints);
+            }
             mContainerMotionLayout.setMaxWidth(getResources()
                     .getDimensionPixelSize(R.dimen.biometric_auth_pattern_view_max_size));
         }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
index 98312b1..714ba81 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.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 38e5dc5..9d6d033 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
@@ -39,7 +39,7 @@
 
 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 31cbdde..aacf866 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
@@ -25,7 +25,7 @@
 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 0af803f..9a78868 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
@@ -23,7 +23,7 @@
 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 3f3efe9..f7a4d47 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.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 e9dd08c..625c1de 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.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/KeyguardSecurityView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityView.java
index 21960e2..83b1a2c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityView.java
@@ -67,42 +67,6 @@
     int PROMPT_REASON_TRUSTAGENT_EXPIRED = 8;
 
     /**
-     * Prompt that is shown when there is an incorrect primary authentication input.
-     */
-    int PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT = 9;
-
-    /**
-     * Prompt that is shown when there is an incorrect face biometric input.
-     */
-    int PROMPT_REASON_INCORRECT_FACE_INPUT = 10;
-
-    /**
-     * Prompt that is shown when there is an incorrect fingerprint biometric input.
-     */
-    int PROMPT_REASON_INCORRECT_FINGERPRINT_INPUT = 11;
-
-    /**
-     * Prompt that is shown when face authentication is in locked out state.
-     */
-    int PROMPT_REASON_FACE_LOCKED_OUT = 12;
-
-    /**
-     * Prompt that is shown when fingerprint authentication is in locked out state.
-     */
-    int PROMPT_REASON_FINGERPRINT_LOCKED_OUT = 13;
-
-    /**
-     * Default prompt that is shown on the bouncer.
-     */
-    int PROMPT_REASON_DEFAULT = 14;
-
-    /**
-     * Prompt that is shown when primary authentication is in locked out state after too many
-     * attempts
-     */
-    int PROMPT_REASON_PRIMARY_AUTH_LOCKED_OUT = 15;
-
-    /**
      * Strong auth is required because the device has just booted because of an automatic
      * mainline update.
      */
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java
index 74f9006..44db01e 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.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 f18504c..ec2999f 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.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;
 
@@ -139,12 +139,12 @@
                             onViewInflatedListener.onViewInflated(childController);
 
                             // Single bouncer constrains are default
-                            if (mFeatureFlags.isEnabled(LOCKSCREEN_ENABLE_LANDSCAPE)
-                                    &&
-                                    getResources().getBoolean(R.bool.update_bouncer_constraints)) {
+                            if (mFeatureFlags.isEnabled(LOCKSCREEN_ENABLE_LANDSCAPE)) {
                                 boolean useSplitBouncer =
-                                        getResources().getConfiguration().orientation
+                                        getResources().getBoolean(R.bool.update_bouncer_constraints)
+                                        && getResources().getConfiguration().orientation
                                                 == ORIENTATION_LANDSCAPE;
+
                                 updateConstraints(useSplitBouncer);
                             }
                         }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewTransition.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewTransition.kt
index e1c060f..db191c6 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.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 7c8d91f..392abf2 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.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 9d17015..bacd0c2 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.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 1fc88ab..8717a53 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
@@ -39,7 +39,7 @@
 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 @@
             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 5f45fe3..151ca8a 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.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 49d786f..248b7af 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
@@ -36,7 +36,7 @@
 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 @@
             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 b4f124a..7b5325d 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.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 e7da2b9..11b1a7d 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.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 5774e42..d848602 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.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 c314586..8d0d299 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.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 ca64ae0..7170be61 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUnfoldTransition.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUnfoldTransition.kt
@@ -18,7 +18,7 @@
 
 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 abab5e6..51308b8 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.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 5f3ba72..04e8a97 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.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 b793fd2..f746459 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.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 c522881..1d2d77f 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconView.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconView.java
@@ -37,7 +37,7 @@
 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 214b122..165c4bb 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.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 5c2f3b3..76f93e1 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
@@ -30,7 +30,7 @@
 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 466d154..871d57d 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
@@ -36,7 +36,7 @@
 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 9a2ffe0..85f8b48 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.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 4496dc31..8d1bbb2 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 7c129b4..5e9eed9 100644
--- a/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java
+++ b/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java
@@ -29,7 +29,7 @@
 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 5f33ef9..8c987e3 100644
--- a/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java
+++ b/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java
@@ -40,7 +40,7 @@
 
 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 83fc278..9716d98 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.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 893239b..afea224 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 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 8762769..37600da 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 b8841ed..7575f0e 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 @@
 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 4c16d41c..72fa2b0 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.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 eee705d..2d2ebe9 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.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 5e96379..2010a70 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.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 2b8d3e0..22d0bc9 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.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 7c377d2..086713f 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.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 e6d5719..ab431d0 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.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 104b71f..4541384 100644
--- a/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
+++ b/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
@@ -24,6 +24,7 @@
 
 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 7a6b1c3..161cb43 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.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 d631cf3..0643d02 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.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 1bb0329..b9e412c 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.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 ff395da..4af2c74 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.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 @@
         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 @@
         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 6f99a24..67012cb 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.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 3ca74ac..954129e 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.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 38298cf..bf44517 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.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 2b468cf..872b005 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.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 6cf9eff..76c2282 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.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 f817c3c..84f1395 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 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 859e183..ee7781d 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 @@
                 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 6de3e93..443441f 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.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 ed6fbec..bc469ee 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.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 69041d3..59b85d1 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 @@
         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 @@
         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 d061c8e..9dd1454 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.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 773241e..c095aa8 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 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 7c11311..c03e403 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 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 ecfe4ca..83ad3c2 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 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 5ec024e..1ff9eb4 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 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 14517ba..9c22a77 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.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 3e2b06b..bf121fb 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 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 df2c05d..89ce065 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 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 6ba40d6..b6e8997 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 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 0ef256d..2d2f2956 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.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 d491975..a5c5bec 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.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 4416b19..0e339dd 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.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 1c98099..1ee06cc 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 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 9b441ad..5765f3a 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.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 ac39ed5..4d89231 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 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 523378e..fa9676b 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.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 b81d7fc..b8de117 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.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 6ca1c3d..f25f994 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 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 b6f47e9..5b840b5 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 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 ea8f5d3..3f2da5e 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.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 fb22c6b..09eabf2 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 @@
 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 683541b..0ad3848 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 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 c7d7fe3..85122ba 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.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 b752c3b..a64e862 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 @@
             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 @@
             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 @@
 
         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 167067e..bc0c8c8 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.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 141983b..c09e68d 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.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 3e6508c..2962be8 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.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 dc874d8..d6a4cbb 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 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;
@@ -29,8 +31,10 @@
 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.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;
@@ -39,10 +43,12 @@
 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;
 
+import java.util.Optional;
+
 import javax.inject.Inject;
 
 /**
@@ -66,6 +72,9 @@
     private final Handler mHandler;
     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;
@@ -102,26 +111,53 @@
                         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;
                     }
                 }
             };
 
+    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) {
+    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;
         mHandler = handler;
         mNotificationManager = notificationManager;
         mBroadcastReceiver = biometricNotificationBroadcastReceiver;
+        mFingerprintReEnrollNotification = fingerprintReEnrollNotification.orElse(
+                new FingerprintReEnrollNotificationImpl());
+        mFingerprintManager = fingerprintManager;
+        mFaceManager = faceManager;
     }
 
     @Override
@@ -135,12 +171,19 @@
         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(
@@ -153,6 +196,7 @@
     }
 
     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/src/com/android/systemui/biometrics/FaceAuthAccessibilityDelegate.kt b/packages/SystemUI/src/com/android/systemui/biometrics/FaceAuthAccessibilityDelegate.kt
index a24a47b..bbdcadb 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.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 320e362..b015f70 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 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/FingerprintReEnrollNotification.java b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintReEnrollNotification.java
new file mode 100644
index 0000000..9050f26
--- /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 0000000..1f86bc6
--- /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/biometrics/SideFpsController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
index 017ac60..c1f6259 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.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/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 0264356..46d3c8a 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -580,7 +580,9 @@
                     + mOverlay.getRequestId());
             return false;
         }
-        if (mLockscreenShadeTransitionController.getQSDragProgress() != 0f
+
+        if ((mLockscreenShadeTransitionController.getQSDragProgress() != 0f
+                && !mAlternateBouncerInteractor.isVisibleState())
                 || mPrimaryBouncerInteractor.isInTransit()) {
             return false;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
index 941df687..34a0d8a 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 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 16dc42a..abbfa01 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.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 511b4e3..c16dfb1 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.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 5dafa61..0838855 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.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 8497879..99da660 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.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 84a746c..8ce98a9 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 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 b916810c..36a42f9 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 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 54e6215..6ce6172 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.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/data/repository/DisplayStateRepository.kt b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/DisplayStateRepository.kt
index 7a9efcf..c4c52e8b 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/DisplayStateRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/DisplayStateRepository.kt
@@ -41,6 +41,12 @@
 
 /** Repository for the current state of the display */
 interface DisplayStateRepository {
+    /**
+     * Whether or not the direction rotation is applied to get to an application's requested
+     * orientation is reversed.
+     */
+    val isReverseDefaultRotation: Boolean
+
     /** Provides the current rear display state. */
     val isInRearDisplayMode: StateFlow<Boolean>
 
@@ -59,6 +65,9 @@
     @Main handler: Handler,
     @Main mainExecutor: Executor
 ) : DisplayStateRepository {
+    override val isReverseDefaultRotation =
+        context.resources.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation)
+
     override val isInRearDisplayMode: StateFlow<Boolean> =
         conflatedCallbackFlow {
                 val sendRearDisplayStateUpdate = { state: Boolean ->
@@ -94,7 +103,11 @@
     private fun getDisplayRotation(): DisplayRotation {
         val cachedDisplayInfo = DisplayInfo()
         context.display?.getDisplayInfo(cachedDisplayInfo)
-        return cachedDisplayInfo.rotation.toDisplayRotation()
+        var rotation = cachedDisplayInfo.rotation
+        if (isReverseDefaultRotation) {
+            rotation = (rotation + 1) % 4
+        }
+        return rotation.toDisplayRotation()
     }
 
     override val currentRotation: StateFlow<DisplayRotation> =
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 2a02667..191533c 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 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 fb246cd..cef0be0 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.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 a7ecf38..56e3f39 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.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 02847c2..c29efc0 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.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 b9af031..7e16d1e 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.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 996b62e..0ad07ba 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 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 b692ad3..eff6987 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.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 931946a..ce52e1d 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 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 906206c..05fdb2f 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 @@
 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/binder/PromptFingerprintIconViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptFingerprintIconViewBinder.kt
index 188c82b..d28f1dc 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptFingerprintIconViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptFingerprintIconViewBinder.kt
@@ -17,7 +17,6 @@
 
 package com.android.systemui.biometrics.ui.binder
 
-import android.view.DisplayInfo
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
 import com.airbnb.lottie.LottieAnimationView
@@ -33,14 +32,14 @@
     fun bind(view: LottieAnimationView, viewModel: PromptFingerprintIconViewModel) {
         view.repeatWhenAttached {
             repeatOnLifecycle(Lifecycle.State.STARTED) {
-                val displayInfo = DisplayInfo()
-                view.context.display?.getDisplayInfo(displayInfo)
-                viewModel.setRotation(displayInfo.rotation)
                 viewModel.onConfigurationChanged(view.context.resources.configuration)
                 launch {
                     viewModel.iconAsset.collect { iconAsset ->
                         if (iconAsset != -1) {
                             view.setAnimation(iconAsset)
+                            // TODO: must replace call below once non-sfps asset logic and
+                            // shouldAnimateIconView logic is migrated to this ViewModel.
+                            view.playAnimation()
                         }
                     }
                 }
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 6212ef0..03c5c53 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.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 b406ea4..dfd3a9b 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
@@ -19,10 +19,10 @@
 
 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.DisplayRotation
 import com.android.systemui.biometrics.shared.model.FingerprintSensorType
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
@@ -35,19 +35,21 @@
     private val displayStateInteractor: DisplayStateInteractor,
     promptSelectorInteractor: PromptSelectorInteractor,
 ) {
-    /** Current device rotation. */
-    private var rotation: Int = Surface.ROTATION_0
-
     /** Current BiometricPromptLayout.iconView asset. */
     val iconAsset: Flow<Int> =
         combine(
+            displayStateInteractor.currentRotation,
             displayStateInteractor.isFolded,
             displayStateInteractor.isInRearDisplayMode,
             promptSelectorInteractor.sensorType,
-        ) { isFolded: Boolean, isInRearDisplayMode: Boolean, sensorType: FingerprintSensorType ->
+        ) {
+            rotation: DisplayRotation,
+            isFolded: Boolean,
+            isInRearDisplayMode: Boolean,
+            sensorType: FingerprintSensorType ->
             when (sensorType) {
                 FingerprintSensorType.POWER_BUTTON ->
-                    getSideFpsAnimationAsset(isFolded, isInRearDisplayMode)
+                    getSideFpsAnimationAsset(rotation, isFolded, isInRearDisplayMode)
                 // Replace below when non-SFPS iconAsset logic is migrated to this ViewModel
                 else -> -1
             }
@@ -55,11 +57,12 @@
 
     @RawRes
     private fun getSideFpsAnimationAsset(
+        rotation: DisplayRotation,
         isDeviceFolded: Boolean,
         isInRearDisplayMode: Boolean,
     ): Int =
         when (rotation) {
-            Surface.ROTATION_90 ->
+            DisplayRotation.ROTATION_90 ->
                 if (isInRearDisplayMode) {
                     R.raw.biometricprompt_rear_portrait_reverse_base
                 } else if (isDeviceFolded) {
@@ -67,7 +70,7 @@
                 } else {
                     R.raw.biometricprompt_portrait_base_topleft
                 }
-            Surface.ROTATION_270 ->
+            DisplayRotation.ROTATION_270 ->
                 if (isInRearDisplayMode) {
                     R.raw.biometricprompt_rear_portrait_base
                 } else if (isDeviceFolded) {
@@ -89,8 +92,4 @@
     fun onConfigurationChanged(newConfig: Configuration) {
         displayStateInteractor.onConfigurationChanged(newConfig)
     }
-
-    fun setRotation(newRotation: Int) {
-        rotation = newRotation
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialog.java b/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialog.java
index 83e61d6..00e9527 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.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
deleted file mode 100644
index 64bf688..0000000
--- a/packages/SystemUI/src/com/android/systemui/bouncer/data/factory/BouncerMessageFactory.kt
+++ /dev/null
@@ -1,390 +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.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.bouncer.data.factory
-
-import android.annotation.IntDef
-import com.android.keyguard.KeyguardSecurityModel
-import com.android.keyguard.KeyguardSecurityModel.SecurityMode
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_AFTER_LOCKOUT
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_DEFAULT
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_DEVICE_ADMIN
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_FACE_LOCKED_OUT
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_FINGERPRINT_LOCKED_OUT
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_INCORRECT_FACE_INPUT
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_INCORRECT_FINGERPRINT_INPUT
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_NONE
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_PREPARE_FOR_UPDATE
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_PRIMARY_AUTH_LOCKED_OUT
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_RESTART
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_RESTART_FOR_MAINLINE_UPDATE
-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.bouncer.shared.model.BouncerMessageModel
-import com.android.systemui.bouncer.shared.model.Message
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository
-import javax.inject.Inject
-
-@SysUISingleton
-class BouncerMessageFactory
-@Inject
-constructor(
-    private val biometricSettingsRepository: BiometricSettingsRepository,
-    private val securityModel: KeyguardSecurityModel,
-) {
-
-    fun createFromPromptReason(
-        @BouncerPromptReason reason: Int,
-        userId: Int,
-        secondaryMsgOverride: String? = null
-    ): BouncerMessageModel? {
-        val pair =
-            getBouncerMessage(
-                reason,
-                securityModel.getSecurityMode(userId),
-                biometricSettingsRepository.isFingerprintAuthCurrentlyAllowed.value
-            )
-        return pair?.let {
-            BouncerMessageModel(
-                message = Message(messageResId = pair.first, animate = false),
-                secondaryMessage =
-                    secondaryMsgOverride?.let {
-                        Message(message = secondaryMsgOverride, animate = false)
-                    }
-                        ?: Message(messageResId = pair.second, animate = false)
-            )
-        }
-    }
-
-    /**
-     * Helper method that provides the relevant bouncer message that should be shown for different
-     * scenarios indicated by [reason]. [securityMode] & [fpAuthIsAllowed] parameters are used to
-     * provide a more specific message.
-     */
-    private fun getBouncerMessage(
-        @BouncerPromptReason reason: Int,
-        securityMode: SecurityMode,
-        fpAuthIsAllowed: Boolean = false
-    ): Pair<Int, Int>? {
-        return when (reason) {
-            // Primary auth locked out
-            PROMPT_REASON_PRIMARY_AUTH_LOCKED_OUT -> primaryAuthLockedOut(securityMode)
-            // Primary auth required reasons
-            PROMPT_REASON_RESTART -> authRequiredAfterReboot(securityMode)
-            PROMPT_REASON_TIMEOUT -> authRequiredAfterPrimaryAuthTimeout(securityMode)
-            PROMPT_REASON_DEVICE_ADMIN -> authRequiredAfterAdminLockdown(securityMode)
-            PROMPT_REASON_USER_REQUEST -> authRequiredAfterUserLockdown(securityMode)
-            PROMPT_REASON_PREPARE_FOR_UPDATE -> authRequiredForUnattendedUpdate(securityMode)
-            PROMPT_REASON_RESTART_FOR_MAINLINE_UPDATE -> authRequiredForMainlineUpdate(securityMode)
-            PROMPT_REASON_FINGERPRINT_LOCKED_OUT -> fingerprintUnlockUnavailable(securityMode)
-            PROMPT_REASON_AFTER_LOCKOUT -> biometricLockout(securityMode)
-            // Non strong auth not available reasons
-            PROMPT_REASON_FACE_LOCKED_OUT ->
-                if (fpAuthIsAllowed) faceLockedOutButFingerprintAvailable(securityMode)
-                else faceLockedOut(securityMode)
-            PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT ->
-                if (fpAuthIsAllowed) nonStrongAuthTimeoutWithFingerprintAllowed(securityMode)
-                else nonStrongAuthTimeout(securityMode)
-            PROMPT_REASON_TRUSTAGENT_EXPIRED ->
-                if (fpAuthIsAllowed) trustAgentDisabledWithFingerprintAllowed(securityMode)
-                else trustAgentDisabled(securityMode)
-            // Auth incorrect input reasons.
-            PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT ->
-                if (fpAuthIsAllowed) incorrectSecurityInputWithFingerprint(securityMode)
-                else incorrectSecurityInput(securityMode)
-            PROMPT_REASON_INCORRECT_FACE_INPUT ->
-                if (fpAuthIsAllowed) incorrectFaceInputWithFingerprintAllowed(securityMode)
-                else incorrectFaceInput(securityMode)
-            PROMPT_REASON_INCORRECT_FINGERPRINT_INPUT -> incorrectFingerprintInput(securityMode)
-            // Default message
-            PROMPT_REASON_DEFAULT ->
-                if (fpAuthIsAllowed) defaultMessageWithFingerprint(securityMode)
-                else defaultMessage(securityMode)
-            else -> null
-        }
-    }
-
-    fun emptyMessage(): BouncerMessageModel =
-        BouncerMessageModel(Message(message = ""), Message(message = ""))
-}
-
-@Retention(AnnotationRetention.SOURCE)
-@IntDef(
-    PROMPT_REASON_TIMEOUT,
-    PROMPT_REASON_DEVICE_ADMIN,
-    PROMPT_REASON_USER_REQUEST,
-    PROMPT_REASON_AFTER_LOCKOUT,
-    PROMPT_REASON_PREPARE_FOR_UPDATE,
-    PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT,
-    PROMPT_REASON_TRUSTAGENT_EXPIRED,
-    PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT,
-    PROMPT_REASON_INCORRECT_FACE_INPUT,
-    PROMPT_REASON_INCORRECT_FINGERPRINT_INPUT,
-    PROMPT_REASON_FACE_LOCKED_OUT,
-    PROMPT_REASON_FINGERPRINT_LOCKED_OUT,
-    PROMPT_REASON_DEFAULT,
-    PROMPT_REASON_NONE,
-    PROMPT_REASON_RESTART,
-    PROMPT_REASON_PRIMARY_AUTH_LOCKED_OUT,
-    PROMPT_REASON_RESTART_FOR_MAINLINE_UPDATE,
-)
-annotation class BouncerPromptReason
-
-private fun defaultMessage(securityMode: SecurityMode): Pair<Int, Int> {
-    return when (securityMode) {
-        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, 0)
-        SecurityMode.Password -> Pair(keyguard_enter_password, 0)
-        SecurityMode.PIN -> Pair(keyguard_enter_pin, 0)
-        else -> Pair(0, 0)
-    }
-}
-
-private fun defaultMessageWithFingerprint(securityMode: SecurityMode): Pair<Int, Int> {
-    return when (securityMode) {
-        SecurityMode.Pattern -> Pair(kg_unlock_with_pattern_or_fp, 0)
-        SecurityMode.Password -> Pair(kg_unlock_with_password_or_fp, 0)
-        SecurityMode.PIN -> Pair(kg_unlock_with_pin_or_fp, 0)
-        else -> Pair(0, 0)
-    }
-}
-
-private fun incorrectSecurityInput(securityMode: SecurityMode): Pair<Int, Int> {
-    return when (securityMode) {
-        SecurityMode.Pattern -> Pair(kg_wrong_pattern_try_again, 0)
-        SecurityMode.Password -> Pair(kg_wrong_password_try_again, 0)
-        SecurityMode.PIN -> Pair(kg_wrong_pin_try_again, 0)
-        else -> Pair(0, 0)
-    }
-}
-
-private fun incorrectSecurityInputWithFingerprint(securityMode: SecurityMode): Pair<Int, Int> {
-    return when (securityMode) {
-        SecurityMode.Pattern -> Pair(kg_wrong_pattern_try_again, kg_wrong_input_try_fp_suggestion)
-        SecurityMode.Password -> Pair(kg_wrong_password_try_again, kg_wrong_input_try_fp_suggestion)
-        SecurityMode.PIN -> Pair(kg_wrong_pin_try_again, kg_wrong_input_try_fp_suggestion)
-        else -> Pair(0, 0)
-    }
-}
-
-private fun incorrectFingerprintInput(securityMode: SecurityMode): Pair<Int, Int> {
-    return when (securityMode) {
-        SecurityMode.Pattern -> Pair(kg_fp_not_recognized, kg_bio_try_again_or_pattern)
-        SecurityMode.Password -> Pair(kg_fp_not_recognized, kg_bio_try_again_or_password)
-        SecurityMode.PIN -> Pair(kg_fp_not_recognized, kg_bio_try_again_or_pin)
-        else -> Pair(0, 0)
-    }
-}
-
-private fun incorrectFaceInput(securityMode: SecurityMode): Pair<Int, Int> {
-    return when (securityMode) {
-        SecurityMode.Pattern -> Pair(bouncer_face_not_recognized, kg_bio_try_again_or_pattern)
-        SecurityMode.Password -> Pair(bouncer_face_not_recognized, kg_bio_try_again_or_password)
-        SecurityMode.PIN -> Pair(bouncer_face_not_recognized, kg_bio_try_again_or_pin)
-        else -> Pair(0, 0)
-    }
-}
-
-private fun incorrectFaceInputWithFingerprintAllowed(securityMode: SecurityMode): Pair<Int, Int> {
-    return when (securityMode) {
-        SecurityMode.Pattern -> Pair(kg_unlock_with_pattern_or_fp, bouncer_face_not_recognized)
-        SecurityMode.Password -> Pair(kg_unlock_with_password_or_fp, bouncer_face_not_recognized)
-        SecurityMode.PIN -> Pair(kg_unlock_with_pin_or_fp, bouncer_face_not_recognized)
-        else -> Pair(0, 0)
-    }
-}
-
-private fun biometricLockout(securityMode: SecurityMode): Pair<Int, Int> {
-    return when (securityMode) {
-        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_bio_too_many_attempts_pattern)
-        SecurityMode.Password -> Pair(keyguard_enter_password, kg_bio_too_many_attempts_password)
-        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_bio_too_many_attempts_pin)
-        else -> Pair(0, 0)
-    }
-}
-
-private fun authRequiredAfterReboot(securityMode: SecurityMode): Pair<Int, Int> {
-    return when (securityMode) {
-        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_reason_restart_pattern)
-        SecurityMode.Password -> Pair(keyguard_enter_password, kg_prompt_reason_restart_password)
-        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_prompt_reason_restart_pin)
-        else -> Pair(0, 0)
-    }
-}
-
-private fun authRequiredAfterAdminLockdown(securityMode: SecurityMode): Pair<Int, Int> {
-    return when (securityMode) {
-        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_after_dpm_lock)
-        SecurityMode.Password -> Pair(keyguard_enter_password, kg_prompt_after_dpm_lock)
-        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_prompt_after_dpm_lock)
-        else -> Pair(0, 0)
-    }
-}
-
-private fun authRequiredAfterUserLockdown(securityMode: SecurityMode): Pair<Int, Int> {
-    return when (securityMode) {
-        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_after_user_lockdown_pattern)
-        SecurityMode.Password ->
-            Pair(keyguard_enter_password, kg_prompt_after_user_lockdown_password)
-        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_prompt_after_user_lockdown_pin)
-        else -> Pair(0, 0)
-    }
-}
-
-private fun authRequiredForUnattendedUpdate(securityMode: SecurityMode): Pair<Int, Int> {
-    return when (securityMode) {
-        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_unattended_update)
-        SecurityMode.Password -> Pair(keyguard_enter_password, kg_prompt_unattended_update)
-        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_prompt_unattended_update)
-        else -> Pair(0, 0)
-    }
-}
-
-private fun authRequiredForMainlineUpdate(securityMode: SecurityMode): Pair<Int, Int> {
-    return when (securityMode) {
-        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_after_update_pattern)
-        SecurityMode.Password -> Pair(keyguard_enter_password, kg_prompt_after_update_password)
-        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_prompt_after_update_pin)
-        else -> Pair(0, 0)
-    }
-}
-
-private fun authRequiredAfterPrimaryAuthTimeout(securityMode: SecurityMode): Pair<Int, Int> {
-    return when (securityMode) {
-        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_pattern_auth_timeout)
-        SecurityMode.Password -> Pair(keyguard_enter_password, kg_prompt_password_auth_timeout)
-        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_prompt_pin_auth_timeout)
-        else -> Pair(0, 0)
-    }
-}
-
-private fun nonStrongAuthTimeout(securityMode: SecurityMode): Pair<Int, Int> {
-    return when (securityMode) {
-        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_auth_timeout)
-        SecurityMode.Password -> Pair(keyguard_enter_password, kg_prompt_auth_timeout)
-        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_prompt_auth_timeout)
-        else -> Pair(0, 0)
-    }
-}
-
-private fun nonStrongAuthTimeoutWithFingerprintAllowed(securityMode: SecurityMode): Pair<Int, Int> {
-    return when (securityMode) {
-        SecurityMode.Pattern -> Pair(kg_unlock_with_pattern_or_fp, kg_prompt_auth_timeout)
-        SecurityMode.Password -> Pair(kg_unlock_with_password_or_fp, kg_prompt_auth_timeout)
-        SecurityMode.PIN -> Pair(kg_unlock_with_pin_or_fp, kg_prompt_auth_timeout)
-        else -> Pair(0, 0)
-    }
-}
-
-private fun faceLockedOut(securityMode: SecurityMode): Pair<Int, Int> {
-    return when (securityMode) {
-        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_face_locked_out)
-        SecurityMode.Password -> Pair(keyguard_enter_password, kg_face_locked_out)
-        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_face_locked_out)
-        else -> Pair(0, 0)
-    }
-}
-
-private fun faceLockedOutButFingerprintAvailable(securityMode: SecurityMode): Pair<Int, Int> {
-    return when (securityMode) {
-        SecurityMode.Pattern -> Pair(kg_unlock_with_pattern_or_fp, kg_face_locked_out)
-        SecurityMode.Password -> Pair(kg_unlock_with_password_or_fp, kg_face_locked_out)
-        SecurityMode.PIN -> Pair(kg_unlock_with_pin_or_fp, kg_face_locked_out)
-        else -> Pair(0, 0)
-    }
-}
-
-private fun fingerprintUnlockUnavailable(securityMode: SecurityMode): Pair<Int, Int> {
-    return when (securityMode) {
-        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_fp_locked_out)
-        SecurityMode.Password -> Pair(keyguard_enter_password, kg_fp_locked_out)
-        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_fp_locked_out)
-        else -> Pair(0, 0)
-    }
-}
-
-private fun trustAgentDisabled(securityMode: SecurityMode): Pair<Int, Int> {
-    return when (securityMode) {
-        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_trust_agent_disabled)
-        SecurityMode.Password -> Pair(keyguard_enter_password, kg_trust_agent_disabled)
-        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_trust_agent_disabled)
-        else -> Pair(0, 0)
-    }
-}
-
-private fun trustAgentDisabledWithFingerprintAllowed(securityMode: SecurityMode): Pair<Int, Int> {
-    return when (securityMode) {
-        SecurityMode.Pattern -> Pair(kg_unlock_with_pattern_or_fp, kg_trust_agent_disabled)
-        SecurityMode.Password -> Pair(kg_unlock_with_password_or_fp, kg_trust_agent_disabled)
-        SecurityMode.PIN -> Pair(kg_unlock_with_pin_or_fp, kg_trust_agent_disabled)
-        else -> Pair(0, 0)
-    }
-}
-
-private fun primaryAuthLockedOut(securityMode: SecurityMode): Pair<Int, Int> {
-    return when (securityMode) {
-        SecurityMode.Pattern ->
-            Pair(kg_too_many_failed_attempts_countdown, kg_primary_auth_locked_out_pattern)
-        SecurityMode.Password ->
-            Pair(kg_too_many_failed_attempts_countdown, kg_primary_auth_locked_out_password)
-        SecurityMode.PIN ->
-            Pair(kg_too_many_failed_attempts_countdown, kg_primary_auth_locked_out_pin)
-        else -> Pair(0, 0)
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/BouncerMessageRepository.kt b/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/BouncerMessageRepository.kt
index 97c1bdb..094dc0a 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/BouncerMessageRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/BouncerMessageRepository.kt
@@ -16,315 +16,26 @@
 
 package com.android.systemui.bouncer.data.repository
 
-import android.hardware.biometrics.BiometricSourceType
-import android.hardware.biometrics.BiometricSourceType.FACE
-import android.hardware.biometrics.BiometricSourceType.FINGERPRINT
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_DEVICE_ADMIN
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_FACE_LOCKED_OUT
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_FINGERPRINT_LOCKED_OUT
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_INCORRECT_FACE_INPUT
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_INCORRECT_FINGERPRINT_INPUT
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_NONE
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_PREPARE_FOR_UPDATE
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_RESTART
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_RESTART_FOR_MAINLINE_UPDATE
-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.keyguard.KeyguardUpdateMonitor
-import com.android.keyguard.KeyguardUpdateMonitorCallback
-import com.android.systemui.bouncer.data.factory.BouncerMessageFactory
 import com.android.systemui.bouncer.shared.model.BouncerMessageModel
-import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
-import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.flags.SystemPropertiesHelper
-import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository
-import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository
-import com.android.systemui.keyguard.data.repository.TrustRepository
-import com.android.systemui.user.data.repository.UserRepository
 import javax.inject.Inject
-import kotlinx.coroutines.channels.awaitClose
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.onStart
 
 /** Provide different sources of messages that needs to be shown on the bouncer. */
 interface BouncerMessageRepository {
-    /**
-     * Messages that are shown in response to the incorrect security attempts on the bouncer and
-     * primary authentication method being locked out, along with countdown messages before primary
-     * auth is active again.
-     */
-    val primaryAuthMessage: Flow<BouncerMessageModel?>
+    val bouncerMessage: Flow<BouncerMessageModel>
 
-    /**
-     * Help messages that are shown to the user on how to successfully perform authentication using
-     * face.
-     */
-    val faceAcquisitionMessage: Flow<BouncerMessageModel?>
-
-    /**
-     * Help messages that are shown to the user on how to successfully perform authentication using
-     * fingerprint.
-     */
-    val fingerprintAcquisitionMessage: Flow<BouncerMessageModel?>
-
-    /** Custom message that is displayed when the bouncer is being shown to launch an app. */
-    val customMessage: Flow<BouncerMessageModel?>
-
-    /**
-     * Messages that are shown in response to biometric authentication attempts through face or
-     * fingerprint.
-     */
-    val biometricAuthMessage: Flow<BouncerMessageModel?>
-
-    /** Messages that are shown when certain auth flags are set. */
-    val authFlagsMessage: Flow<BouncerMessageModel?>
-
-    /** Messages that are show after biometrics are locked out temporarily or permanently */
-    val biometricLockedOutMessage: Flow<BouncerMessageModel?>
-
-    /** Set the value for [primaryAuthMessage] */
-    fun setPrimaryAuthMessage(value: BouncerMessageModel?)
-
-    /** Set the value for [faceAcquisitionMessage] */
-    fun setFaceAcquisitionMessage(value: BouncerMessageModel?)
-    /** Set the value for [fingerprintAcquisitionMessage] */
-    fun setFingerprintAcquisitionMessage(value: BouncerMessageModel?)
-
-    /** Set the value for [customMessage] */
-    fun setCustomMessage(value: BouncerMessageModel?)
-
-    /**
-     * Clear any previously set messages for [primaryAuthMessage], [faceAcquisitionMessage],
-     * [fingerprintAcquisitionMessage] & [customMessage]
-     */
-    fun clearMessage()
+    fun setMessage(message: BouncerMessageModel)
 }
 
-private const val SYS_BOOT_REASON_PROP = "sys.boot.reason.last"
-private const val REBOOT_MAINLINE_UPDATE = "reboot,mainline_update"
-
 @SysUISingleton
-class BouncerMessageRepositoryImpl
-@Inject
-constructor(
-    trustRepository: TrustRepository,
-    biometricSettingsRepository: BiometricSettingsRepository,
-    updateMonitor: KeyguardUpdateMonitor,
-    private val bouncerMessageFactory: BouncerMessageFactory,
-    private val userRepository: UserRepository,
-    private val systemPropertiesHelper: SystemPropertiesHelper,
-    fingerprintAuthRepository: DeviceEntryFingerprintAuthRepository,
-) : BouncerMessageRepository {
+class BouncerMessageRepositoryImpl @Inject constructor() : BouncerMessageRepository {
 
-    private val isAnyBiometricsEnabledAndEnrolled =
-        or(
-            biometricSettingsRepository.isFaceAuthEnrolledAndEnabled,
-            biometricSettingsRepository.isFingerprintEnrolledAndEnabled,
-        )
+    private val _bouncerMessage = MutableStateFlow(BouncerMessageModel())
+    override val bouncerMessage: Flow<BouncerMessageModel> = _bouncerMessage
 
-    private val wasRebootedForMainlineUpdate
-        get() = systemPropertiesHelper.get(SYS_BOOT_REASON_PROP) == REBOOT_MAINLINE_UPDATE
-
-    private val authFlagsBasedPromptReason: Flow<Int> =
-        combine(
-                biometricSettingsRepository.authenticationFlags,
-                trustRepository.isCurrentUserTrustManaged,
-                isAnyBiometricsEnabledAndEnrolled,
-                ::Triple
-            )
-            .map { (flags, isTrustManaged, biometricsEnrolledAndEnabled) ->
-                val trustOrBiometricsAvailable = (isTrustManaged || biometricsEnrolledAndEnabled)
-                return@map if (
-                    trustOrBiometricsAvailable && flags.isPrimaryAuthRequiredAfterReboot
-                ) {
-                    if (wasRebootedForMainlineUpdate) PROMPT_REASON_RESTART_FOR_MAINLINE_UPDATE
-                    else PROMPT_REASON_RESTART
-                } else if (trustOrBiometricsAvailable && flags.isPrimaryAuthRequiredAfterTimeout) {
-                    PROMPT_REASON_TIMEOUT
-                } else if (flags.isPrimaryAuthRequiredAfterDpmLockdown) {
-                    PROMPT_REASON_DEVICE_ADMIN
-                } else if (isTrustManaged && flags.someAuthRequiredAfterUserRequest) {
-                    PROMPT_REASON_TRUSTAGENT_EXPIRED
-                } else if (isTrustManaged && flags.someAuthRequiredAfterTrustAgentExpired) {
-                    PROMPT_REASON_TRUSTAGENT_EXPIRED
-                } else if (trustOrBiometricsAvailable && flags.isInUserLockdown) {
-                    PROMPT_REASON_USER_REQUEST
-                } else if (
-                    trustOrBiometricsAvailable && flags.primaryAuthRequiredForUnattendedUpdate
-                ) {
-                    PROMPT_REASON_PREPARE_FOR_UPDATE
-                } else if (
-                    trustOrBiometricsAvailable &&
-                        flags.strongerAuthRequiredAfterNonStrongBiometricsTimeout
-                ) {
-                    PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT
-                } else {
-                    PROMPT_REASON_NONE
-                }
-            }
-
-    private val biometricAuthReason: Flow<Int> =
-        conflatedCallbackFlow {
-                val callback =
-                    object : KeyguardUpdateMonitorCallback() {
-                        override fun onBiometricAuthFailed(
-                            biometricSourceType: BiometricSourceType?
-                        ) {
-                            val promptReason =
-                                if (biometricSourceType == FINGERPRINT)
-                                    PROMPT_REASON_INCORRECT_FINGERPRINT_INPUT
-                                else if (
-                                    biometricSourceType == FACE && !updateMonitor.isFaceLockedOut
-                                ) {
-                                    PROMPT_REASON_INCORRECT_FACE_INPUT
-                                } else PROMPT_REASON_NONE
-                            trySendWithFailureLogging(promptReason, TAG, "onBiometricAuthFailed")
-                        }
-
-                        override fun onBiometricsCleared() {
-                            trySendWithFailureLogging(
-                                PROMPT_REASON_NONE,
-                                TAG,
-                                "onBiometricsCleared"
-                            )
-                        }
-
-                        override fun onBiometricAcquired(
-                            biometricSourceType: BiometricSourceType?,
-                            acquireInfo: Int
-                        ) {
-                            trySendWithFailureLogging(
-                                PROMPT_REASON_NONE,
-                                TAG,
-                                "clearBiometricPrompt for new auth session."
-                            )
-                        }
-
-                        override fun onBiometricAuthenticated(
-                            userId: Int,
-                            biometricSourceType: BiometricSourceType?,
-                            isStrongBiometric: Boolean
-                        ) {
-                            trySendWithFailureLogging(
-                                PROMPT_REASON_NONE,
-                                TAG,
-                                "onBiometricAuthenticated"
-                            )
-                        }
-                    }
-                updateMonitor.registerCallback(callback)
-                awaitClose { updateMonitor.removeCallback(callback) }
-            }
-            .distinctUntilChanged()
-
-    private val _primaryAuthMessage = MutableStateFlow<BouncerMessageModel?>(null)
-    override val primaryAuthMessage: Flow<BouncerMessageModel?> = _primaryAuthMessage
-
-    private val _faceAcquisitionMessage = MutableStateFlow<BouncerMessageModel?>(null)
-    override val faceAcquisitionMessage: Flow<BouncerMessageModel?> = _faceAcquisitionMessage
-
-    private val _fingerprintAcquisitionMessage = MutableStateFlow<BouncerMessageModel?>(null)
-    override val fingerprintAcquisitionMessage: Flow<BouncerMessageModel?> =
-        _fingerprintAcquisitionMessage
-
-    private val _customMessage = MutableStateFlow<BouncerMessageModel?>(null)
-    override val customMessage: Flow<BouncerMessageModel?> = _customMessage
-
-    override val biometricAuthMessage: Flow<BouncerMessageModel?> =
-        biometricAuthReason
-            .map {
-                if (it == PROMPT_REASON_NONE) null
-                else
-                    bouncerMessageFactory.createFromPromptReason(
-                        it,
-                        userRepository.getSelectedUserInfo().id
-                    )
-            }
-            .onStart { emit(null) }
-            .distinctUntilChanged()
-
-    override val authFlagsMessage: Flow<BouncerMessageModel?> =
-        authFlagsBasedPromptReason
-            .map {
-                if (it == PROMPT_REASON_NONE) null
-                else
-                    bouncerMessageFactory.createFromPromptReason(
-                        it,
-                        userRepository.getSelectedUserInfo().id
-                    )
-            }
-            .onStart { emit(null) }
-            .distinctUntilChanged()
-
-    // TODO (b/262838215): Replace with DeviceEntryFaceAuthRepository when the new face auth system
-    // has been launched.
-    private val faceLockedOut: Flow<Boolean> = conflatedCallbackFlow {
-        val callback =
-            object : KeyguardUpdateMonitorCallback() {
-                override fun onLockedOutStateChanged(biometricSourceType: BiometricSourceType?) {
-                    if (biometricSourceType == FACE) {
-                        trySendWithFailureLogging(
-                            updateMonitor.isFaceLockedOut,
-                            TAG,
-                            "face lock out state changed."
-                        )
-                    }
-                }
-            }
-        updateMonitor.registerCallback(callback)
-        trySendWithFailureLogging(updateMonitor.isFaceLockedOut, TAG, "face lockout initial value")
-        awaitClose { updateMonitor.removeCallback(callback) }
-    }
-
-    override val biometricLockedOutMessage: Flow<BouncerMessageModel?> =
-        combine(fingerprintAuthRepository.isLockedOut, faceLockedOut) { fp, face ->
-            return@combine if (fp) {
-                bouncerMessageFactory.createFromPromptReason(
-                    PROMPT_REASON_FINGERPRINT_LOCKED_OUT,
-                    userRepository.getSelectedUserInfo().id
-                )
-            } else if (face) {
-                bouncerMessageFactory.createFromPromptReason(
-                    PROMPT_REASON_FACE_LOCKED_OUT,
-                    userRepository.getSelectedUserInfo().id
-                )
-            } else null
-        }
-
-    override fun setPrimaryAuthMessage(value: BouncerMessageModel?) {
-        _primaryAuthMessage.value = value
-    }
-
-    override fun setFaceAcquisitionMessage(value: BouncerMessageModel?) {
-        _faceAcquisitionMessage.value = value
-    }
-
-    override fun setFingerprintAcquisitionMessage(value: BouncerMessageModel?) {
-        _fingerprintAcquisitionMessage.value = value
-    }
-
-    override fun setCustomMessage(value: BouncerMessageModel?) {
-        _customMessage.value = value
-    }
-
-    override fun clearMessage() {
-        _fingerprintAcquisitionMessage.value = null
-        _faceAcquisitionMessage.value = null
-        _primaryAuthMessage.value = null
-        _customMessage.value = null
-    }
-
-    companion object {
-        const val TAG = "BouncerDetailedMessageRepository"
+    override fun setMessage(message: BouncerMessageModel) {
+        _bouncerMessage.value = message
     }
 }
-
-private fun or(flow: Flow<Boolean>, anotherFlow: Flow<Boolean>) =
-    flow.combine(anotherFlow) { a, b -> a || b }
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 abddb0a..9b2f2ba 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
@@ -225,6 +225,20 @@
         repository.setMessage(errorMessage(authenticationInteractor.getAuthenticationMethod()))
     }
 
+    /** If the bouncer is showing, hides the bouncer and return to the lockscreen scene. */
+    fun hide(
+        loggingReason: String,
+    ) {
+        if (sceneInteractor.desiredScene.value.key != SceneKey.Bouncer) {
+            return
+        }
+
+        sceneInteractor.changeScene(
+            scene = SceneModel(SceneKey.Lockscreen),
+            loggingReason = loggingReason,
+        )
+    }
+
     private fun promptMessage(authMethod: AuthenticationMethodModel): String {
         return when (authMethod) {
             is AuthenticationMethodModel.Pin ->
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerMessageAuditLogger.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerMessageAuditLogger.kt
index 497747f..aecfe1d2 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerMessageAuditLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerMessageAuditLogger.kt
@@ -16,16 +16,13 @@
 
 package com.android.systemui.bouncer.domain.interactor
 
-import android.os.Build
 import android.util.Log
 import com.android.systemui.CoreStartable
 import com.android.systemui.bouncer.data.repository.BouncerMessageRepository
-import com.android.systemui.bouncer.shared.model.BouncerMessageModel
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.launch
 
 private val TAG = BouncerMessageAuditLogger::class.simpleName!!
@@ -37,24 +34,8 @@
 constructor(
     @Application private val scope: CoroutineScope,
     private val repository: BouncerMessageRepository,
-    private val interactor: BouncerMessageInteractor,
 ) : CoreStartable {
     override fun start() {
-        if (Build.isDebuggable()) {
-            collectAndLog(repository.biometricAuthMessage, "biometricMessage: ")
-            collectAndLog(repository.primaryAuthMessage, "primaryAuthMessage: ")
-            collectAndLog(repository.customMessage, "customMessage: ")
-            collectAndLog(repository.faceAcquisitionMessage, "faceAcquisitionMessage: ")
-            collectAndLog(
-                repository.fingerprintAcquisitionMessage,
-                "fingerprintAcquisitionMessage: "
-            )
-            collectAndLog(repository.authFlagsMessage, "authFlagsMessage: ")
-            collectAndLog(interactor.bouncerMessage, "interactor.bouncerMessage: ")
-        }
-    }
-
-    private fun collectAndLog(flow: Flow<BouncerMessageModel?>, context: String) {
-        scope.launch { flow.collect { Log.d(TAG, context + it) } }
+        scope.launch { repository.bouncerMessage.collect { Log.d(TAG, "bouncerMessage: $it") } }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerMessageInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerMessageInteractor.kt
index fe01d08..f612f9a 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerMessageInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerMessageInteractor.kt
@@ -16,55 +16,234 @@
 
 package com.android.systemui.bouncer.domain.interactor
 
+import android.hardware.biometrics.BiometricSourceType
 import android.os.CountDownTimer
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_DEFAULT
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_PRIMARY_AUTH_LOCKED_OUT
-import com.android.systemui.bouncer.data.factory.BouncerMessageFactory
+import com.android.keyguard.KeyguardSecurityModel
+import com.android.keyguard.KeyguardSecurityModel.SecurityMode
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.keyguard.KeyguardUpdateMonitorCallback
+import com.android.systemui.biometrics.data.repository.FacePropertyRepository
+import com.android.systemui.biometrics.shared.model.SensorStrength
 import com.android.systemui.bouncer.data.repository.BouncerMessageRepository
 import com.android.systemui.bouncer.shared.model.BouncerMessageModel
+import com.android.systemui.bouncer.shared.model.Message
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags.REVAMPED_BOUNCER_MESSAGES
+import com.android.systemui.flags.SystemPropertiesHelper
+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.TrustRepository
+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_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.user.data.repository.UserRepository
+import com.android.systemui.util.kotlin.Quint
 import javax.inject.Inject
 import kotlin.math.roundToInt
+import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.filterNotNull
+import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.flow.stateIn
+
+private const val SYS_BOOT_REASON_PROP = "sys.boot.reason.last"
+private const val REBOOT_MAINLINE_UPDATE = "reboot,mainline_update"
+private const val TAG = "BouncerMessageInteractor"
 
 @SysUISingleton
 class BouncerMessageInteractor
 @Inject
 constructor(
     private val repository: BouncerMessageRepository,
-    private val factory: BouncerMessageFactory,
     private val userRepository: UserRepository,
     private val countDownTimerUtil: CountDownTimerUtil,
     private val featureFlags: FeatureFlags,
+    private val updateMonitor: KeyguardUpdateMonitor,
+    trustRepository: TrustRepository,
+    biometricSettingsRepository: BiometricSettingsRepository,
+    private val systemPropertiesHelper: SystemPropertiesHelper,
+    primaryBouncerInteractor: PrimaryBouncerInteractor,
+    @Application private val applicationScope: CoroutineScope,
+    private val facePropertyRepository: FacePropertyRepository,
+    deviceEntryFingerprintAuthRepository: DeviceEntryFingerprintAuthRepository,
+    faceAuthRepository: DeviceEntryFaceAuthRepository,
+    private val securityModel: KeyguardSecurityModel,
 ) {
+
+    private val isFingerprintAuthCurrentlyAllowed =
+        deviceEntryFingerprintAuthRepository.isLockedOut
+            .isFalse()
+            .and(biometricSettingsRepository.isFingerprintAuthCurrentlyAllowed)
+            .stateIn(applicationScope, SharingStarted.Eagerly, false)
+
+    private val currentSecurityMode
+        get() = securityModel.getSecurityMode(currentUserId)
+    private val currentUserId
+        get() = userRepository.getSelectedUserInfo().id
+
+    private val kumCallback =
+        object : KeyguardUpdateMonitorCallback() {
+            override fun onBiometricAuthFailed(biometricSourceType: BiometricSourceType?) {
+                repository.setMessage(
+                    when (biometricSourceType) {
+                        BiometricSourceType.FINGERPRINT ->
+                            incorrectFingerprintInput(currentSecurityMode)
+                        BiometricSourceType.FACE ->
+                            incorrectFaceInput(
+                                currentSecurityMode,
+                                isFingerprintAuthCurrentlyAllowed.value
+                            )
+                        else ->
+                            defaultMessage(
+                                currentSecurityMode,
+                                isFingerprintAuthCurrentlyAllowed.value
+                            )
+                    }
+                )
+            }
+
+            override fun onBiometricAcquired(
+                biometricSourceType: BiometricSourceType?,
+                acquireInfo: Int
+            ) {
+                super.onBiometricAcquired(biometricSourceType, acquireInfo)
+            }
+
+            override fun onBiometricAuthenticated(
+                userId: Int,
+                biometricSourceType: BiometricSourceType?,
+                isStrongBiometric: Boolean
+            ) {
+                repository.setMessage(defaultMessage)
+            }
+        }
+
+    private val isAnyBiometricsEnabledAndEnrolled =
+        biometricSettingsRepository.isFaceAuthEnrolledAndEnabled.or(
+            biometricSettingsRepository.isFingerprintEnrolledAndEnabled
+        )
+
+    private val wasRebootedForMainlineUpdate
+        get() = systemPropertiesHelper.get(SYS_BOOT_REASON_PROP) == REBOOT_MAINLINE_UPDATE
+
+    private val isFaceAuthClass3
+        get() = facePropertyRepository.sensorInfo.value?.strength == SensorStrength.STRONG
+
+    private val initialBouncerMessage: Flow<BouncerMessageModel> =
+        combine(
+                biometricSettingsRepository.authenticationFlags,
+                trustRepository.isCurrentUserTrustManaged,
+                isAnyBiometricsEnabledAndEnrolled,
+                deviceEntryFingerprintAuthRepository.isLockedOut,
+                faceAuthRepository.isLockedOut,
+                ::Quint
+            )
+            .map { (flags, _, biometricsEnrolledAndEnabled, fpLockedOut, faceLockedOut) ->
+                val isTrustUsuallyManaged = trustRepository.isCurrentUserTrustUsuallyManaged.value
+                val trustOrBiometricsAvailable =
+                    (isTrustUsuallyManaged || biometricsEnrolledAndEnabled)
+                return@map if (
+                    trustOrBiometricsAvailable && flags.isPrimaryAuthRequiredAfterReboot
+                ) {
+                    if (wasRebootedForMainlineUpdate) {
+                        authRequiredForMainlineUpdate(currentSecurityMode)
+                    } else {
+                        authRequiredAfterReboot(currentSecurityMode)
+                    }
+                } else if (trustOrBiometricsAvailable && flags.isPrimaryAuthRequiredAfterTimeout) {
+                    authRequiredAfterPrimaryAuthTimeout(currentSecurityMode)
+                } else if (flags.isPrimaryAuthRequiredAfterDpmLockdown) {
+                    authRequiredAfterAdminLockdown(currentSecurityMode)
+                } else if (
+                    trustOrBiometricsAvailable && flags.primaryAuthRequiredForUnattendedUpdate
+                ) {
+                    authRequiredForUnattendedUpdate(currentSecurityMode)
+                } else if (fpLockedOut) {
+                    class3AuthLockedOut(currentSecurityMode)
+                } else if (faceLockedOut) {
+                    if (isFaceAuthClass3) {
+                        class3AuthLockedOut(currentSecurityMode)
+                    } else {
+                        faceLockedOut(currentSecurityMode, isFingerprintAuthCurrentlyAllowed.value)
+                    }
+                } else if (
+                    trustOrBiometricsAvailable &&
+                        flags.strongerAuthRequiredAfterNonStrongBiometricsTimeout
+                ) {
+                    nonStrongAuthTimeout(
+                        currentSecurityMode,
+                        isFingerprintAuthCurrentlyAllowed.value
+                    )
+                } else if (isTrustUsuallyManaged && flags.someAuthRequiredAfterUserRequest) {
+                    trustAgentDisabled(currentSecurityMode, isFingerprintAuthCurrentlyAllowed.value)
+                } else if (isTrustUsuallyManaged && flags.someAuthRequiredAfterTrustAgentExpired) {
+                    trustAgentDisabled(currentSecurityMode, isFingerprintAuthCurrentlyAllowed.value)
+                } else if (trustOrBiometricsAvailable && flags.isInUserLockdown) {
+                    authRequiredAfterUserLockdown(currentSecurityMode)
+                } else {
+                    defaultMessage
+                }
+            }
+
     fun onPrimaryAuthLockedOut(secondsBeforeLockoutReset: Long) {
         if (!featureFlags.isEnabled(REVAMPED_BOUNCER_MESSAGES)) return
 
         val callback =
             object : CountDownTimerCallback {
                 override fun onFinish() {
-                    repository.clearMessage()
+                    repository.setMessage(defaultMessage)
                 }
 
                 override fun onTick(millisUntilFinished: Long) {
                     val secondsRemaining = (millisUntilFinished / 1000.0).roundToInt()
-                    val message =
-                        factory.createFromPromptReason(
-                            reason = PROMPT_REASON_PRIMARY_AUTH_LOCKED_OUT,
-                            userId = userRepository.getSelectedUserInfo().id
-                        )
-                    message?.message?.animate = false
-                    message?.message?.formatterArgs =
+                    val message = primaryAuthLockedOut(currentSecurityMode)
+                    message.message?.animate = false
+                    message.message?.formatterArgs =
                         mutableMapOf<String, Any>(Pair("count", secondsRemaining))
-                    repository.setPrimaryAuthMessage(message)
+                    repository.setMessage(message)
                 }
             }
         countDownTimerUtil.startNewTimer(secondsBeforeLockoutReset * 1000, 1000, callback)
@@ -73,104 +252,58 @@
     fun onPrimaryAuthIncorrectAttempt() {
         if (!featureFlags.isEnabled(REVAMPED_BOUNCER_MESSAGES)) return
 
-        repository.setPrimaryAuthMessage(
-            factory.createFromPromptReason(
-                PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT,
-                userRepository.getSelectedUserInfo().id
-            )
+        repository.setMessage(
+            incorrectSecurityInput(currentSecurityMode, isFingerprintAuthCurrentlyAllowed.value)
         )
     }
 
     fun setFingerprintAcquisitionMessage(value: String?) {
         if (!featureFlags.isEnabled(REVAMPED_BOUNCER_MESSAGES)) return
-
-        repository.setFingerprintAcquisitionMessage(
-            if (value != null) {
-                factory.createFromPromptReason(
-                    PROMPT_REASON_DEFAULT,
-                    userRepository.getSelectedUserInfo().id,
-                    secondaryMsgOverride = value
-                )
-            } else {
-                null
-            }
+        repository.setMessage(
+            defaultMessage(currentSecurityMode, value, isFingerprintAuthCurrentlyAllowed.value)
         )
     }
 
     fun setFaceAcquisitionMessage(value: String?) {
         if (!featureFlags.isEnabled(REVAMPED_BOUNCER_MESSAGES)) return
-
-        repository.setFaceAcquisitionMessage(
-            if (value != null) {
-                factory.createFromPromptReason(
-                    PROMPT_REASON_DEFAULT,
-                    userRepository.getSelectedUserInfo().id,
-                    secondaryMsgOverride = value
-                )
-            } else {
-                null
-            }
+        repository.setMessage(
+            defaultMessage(currentSecurityMode, value, isFingerprintAuthCurrentlyAllowed.value)
         )
     }
 
     fun setCustomMessage(value: String?) {
         if (!featureFlags.isEnabled(REVAMPED_BOUNCER_MESSAGES)) return
 
-        repository.setCustomMessage(
-            if (value != null) {
-                factory.createFromPromptReason(
-                    PROMPT_REASON_DEFAULT,
-                    userRepository.getSelectedUserInfo().id,
-                    secondaryMsgOverride = value
-                )
-            } else {
-                null
-            }
+        repository.setMessage(
+            defaultMessage(currentSecurityMode, value, isFingerprintAuthCurrentlyAllowed.value)
         )
     }
 
+    private val defaultMessage: BouncerMessageModel
+        get() = defaultMessage(currentSecurityMode, isFingerprintAuthCurrentlyAllowed.value)
+
     fun onPrimaryBouncerUserInput() {
         if (!featureFlags.isEnabled(REVAMPED_BOUNCER_MESSAGES)) return
-
-        repository.clearMessage()
+        repository.setMessage(defaultMessage)
     }
 
-    fun onBouncerBeingHidden() {
-        if (!featureFlags.isEnabled(REVAMPED_BOUNCER_MESSAGES)) return
+    val bouncerMessage = repository.bouncerMessage
 
-        repository.clearMessage()
+    init {
+        updateMonitor.registerCallback(kumCallback)
+
+        combine(primaryBouncerInteractor.isShowing, initialBouncerMessage) { showing, bouncerMessage
+                ->
+                if (showing) {
+                    bouncerMessage
+                } else {
+                    null
+                }
+            }
+            .filterNotNull()
+            .onEach { repository.setMessage(it) }
+            .launchIn(applicationScope)
     }
-
-    private fun firstNonNullMessage(
-        oneMessageModel: Flow<BouncerMessageModel?>,
-        anotherMessageModel: Flow<BouncerMessageModel?>
-    ): Flow<BouncerMessageModel?> {
-        return oneMessageModel.combine(anotherMessageModel) { a, b -> a ?: b }
-    }
-
-    // Null if feature flag is enabled which gets ignored always or empty bouncer message model that
-    // always maps to an empty string.
-    private fun nullOrEmptyMessage() =
-        flowOf(
-            if (featureFlags.isEnabled(REVAMPED_BOUNCER_MESSAGES)) null else factory.emptyMessage()
-        )
-
-    val bouncerMessage =
-        listOf(
-                nullOrEmptyMessage(),
-                repository.primaryAuthMessage,
-                repository.biometricAuthMessage,
-                repository.fingerprintAcquisitionMessage,
-                repository.faceAcquisitionMessage,
-                repository.customMessage,
-                repository.authFlagsMessage,
-                repository.biometricLockedOutMessage,
-                userRepository.selectedUserInfo.map {
-                    factory.createFromPromptReason(PROMPT_REASON_DEFAULT, it.id)
-                },
-            )
-            .reduce(::firstNonNullMessage)
-            .distinctUntilChanged()
 }
 
 interface CountDownTimerCallback {
@@ -199,3 +332,272 @@
             .start()
     }
 }
+
+private fun Flow<Boolean>.or(anotherFlow: Flow<Boolean>) =
+    this.combine(anotherFlow) { a, b -> a || b }
+
+private fun Flow<Boolean>.and(anotherFlow: Flow<Boolean>) =
+    this.combine(anotherFlow) { a, b -> a && b }
+
+private fun Flow<Boolean>.isFalse() = this.map { !it }
+
+private fun defaultMessage(
+    securityMode: SecurityMode,
+    secondaryMessage: String?,
+    fpAuthIsAllowed: Boolean
+): BouncerMessageModel {
+    return BouncerMessageModel(
+        message =
+            Message(
+                messageResId = defaultMessage(securityMode, fpAuthIsAllowed).message?.messageResId,
+                animate = false
+            ),
+        secondaryMessage = Message(message = secondaryMessage, animate = false)
+    )
+}
+
+private fun defaultMessage(
+    securityMode: SecurityMode,
+    fpAuthIsAllowed: Boolean
+): BouncerMessageModel {
+    return if (fpAuthIsAllowed) {
+        defaultMessageWithFingerprint(securityMode)
+    } else
+        when (securityMode) {
+            SecurityMode.Pattern -> Pair(keyguard_enter_pattern, 0)
+            SecurityMode.Password -> Pair(keyguard_enter_password, 0)
+            SecurityMode.PIN -> Pair(keyguard_enter_pin, 0)
+            else -> Pair(0, 0)
+        }.toMessage()
+}
+
+private fun defaultMessageWithFingerprint(securityMode: SecurityMode): BouncerMessageModel {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(kg_unlock_with_pattern_or_fp, 0)
+        SecurityMode.Password -> Pair(kg_unlock_with_password_or_fp, 0)
+        SecurityMode.PIN -> Pair(kg_unlock_with_pin_or_fp, 0)
+        else -> Pair(0, 0)
+    }.toMessage()
+}
+
+private fun incorrectSecurityInput(
+    securityMode: SecurityMode,
+    fpAuthIsAllowed: Boolean
+): BouncerMessageModel {
+    return if (fpAuthIsAllowed) {
+        incorrectSecurityInputWithFingerprint(securityMode)
+    } else
+        when (securityMode) {
+            SecurityMode.Pattern -> Pair(kg_wrong_pattern_try_again, 0)
+            SecurityMode.Password -> Pair(kg_wrong_password_try_again, 0)
+            SecurityMode.PIN -> Pair(kg_wrong_pin_try_again, 0)
+            else -> Pair(0, 0)
+        }.toMessage()
+}
+
+private fun incorrectSecurityInputWithFingerprint(securityMode: SecurityMode): BouncerMessageModel {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(kg_wrong_pattern_try_again, kg_wrong_input_try_fp_suggestion)
+        SecurityMode.Password -> Pair(kg_wrong_password_try_again, kg_wrong_input_try_fp_suggestion)
+        SecurityMode.PIN -> Pair(kg_wrong_pin_try_again, kg_wrong_input_try_fp_suggestion)
+        else -> Pair(0, 0)
+    }.toMessage()
+}
+
+private fun incorrectFingerprintInput(securityMode: SecurityMode): BouncerMessageModel {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(kg_fp_not_recognized, kg_bio_try_again_or_pattern)
+        SecurityMode.Password -> Pair(kg_fp_not_recognized, kg_bio_try_again_or_password)
+        SecurityMode.PIN -> Pair(kg_fp_not_recognized, kg_bio_try_again_or_pin)
+        else -> Pair(0, 0)
+    }.toMessage()
+}
+
+private fun incorrectFaceInput(
+    securityMode: SecurityMode,
+    fpAuthIsAllowed: Boolean
+): BouncerMessageModel {
+    return if (fpAuthIsAllowed) incorrectFaceInputWithFingerprintAllowed(securityMode)
+    else
+        when (securityMode) {
+            SecurityMode.Pattern -> Pair(bouncer_face_not_recognized, kg_bio_try_again_or_pattern)
+            SecurityMode.Password -> Pair(bouncer_face_not_recognized, kg_bio_try_again_or_password)
+            SecurityMode.PIN -> Pair(bouncer_face_not_recognized, kg_bio_try_again_or_pin)
+            else -> Pair(0, 0)
+        }.toMessage()
+}
+
+private fun incorrectFaceInputWithFingerprintAllowed(
+    securityMode: SecurityMode
+): BouncerMessageModel {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(kg_unlock_with_pattern_or_fp, bouncer_face_not_recognized)
+        SecurityMode.Password -> Pair(kg_unlock_with_password_or_fp, bouncer_face_not_recognized)
+        SecurityMode.PIN -> Pair(kg_unlock_with_pin_or_fp, bouncer_face_not_recognized)
+        else -> Pair(0, 0)
+    }.toMessage()
+}
+
+private fun biometricLockout(securityMode: SecurityMode): BouncerMessageModel {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_bio_too_many_attempts_pattern)
+        SecurityMode.Password -> Pair(keyguard_enter_password, kg_bio_too_many_attempts_password)
+        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_bio_too_many_attempts_pin)
+        else -> Pair(0, 0)
+    }.toMessage()
+}
+
+private fun authRequiredAfterReboot(securityMode: SecurityMode): BouncerMessageModel {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_reason_restart_pattern)
+        SecurityMode.Password -> Pair(keyguard_enter_password, kg_prompt_reason_restart_password)
+        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_prompt_reason_restart_pin)
+        else -> Pair(0, 0)
+    }.toMessage()
+}
+
+private fun authRequiredAfterAdminLockdown(securityMode: SecurityMode): BouncerMessageModel {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_after_dpm_lock)
+        SecurityMode.Password -> Pair(keyguard_enter_password, kg_prompt_after_dpm_lock)
+        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_prompt_after_dpm_lock)
+        else -> Pair(0, 0)
+    }.toMessage()
+}
+
+private fun authRequiredAfterUserLockdown(securityMode: SecurityMode): BouncerMessageModel {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_after_user_lockdown_pattern)
+        SecurityMode.Password ->
+            Pair(keyguard_enter_password, kg_prompt_after_user_lockdown_password)
+        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_prompt_after_user_lockdown_pin)
+        else -> Pair(0, 0)
+    }.toMessage()
+}
+
+private fun authRequiredForUnattendedUpdate(securityMode: SecurityMode): BouncerMessageModel {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_unattended_update)
+        SecurityMode.Password -> Pair(keyguard_enter_password, kg_prompt_unattended_update)
+        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_prompt_unattended_update)
+        else -> Pair(0, 0)
+    }.toMessage()
+}
+
+private fun authRequiredForMainlineUpdate(securityMode: SecurityMode): BouncerMessageModel {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_after_update_pattern)
+        SecurityMode.Password -> Pair(keyguard_enter_password, kg_prompt_after_update_password)
+        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_prompt_after_update_pin)
+        else -> Pair(0, 0)
+    }.toMessage()
+}
+
+private fun authRequiredAfterPrimaryAuthTimeout(securityMode: SecurityMode): BouncerMessageModel {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_pattern_auth_timeout)
+        SecurityMode.Password -> Pair(keyguard_enter_password, kg_prompt_password_auth_timeout)
+        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_prompt_pin_auth_timeout)
+        else -> Pair(0, 0)
+    }.toMessage()
+}
+
+private fun nonStrongAuthTimeout(
+    securityMode: SecurityMode,
+    fpAuthIsAllowed: Boolean
+): BouncerMessageModel {
+    return if (fpAuthIsAllowed) {
+        nonStrongAuthTimeoutWithFingerprintAllowed(securityMode)
+    } else
+        when (securityMode) {
+            SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_auth_timeout)
+            SecurityMode.Password -> Pair(keyguard_enter_password, kg_prompt_auth_timeout)
+            SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_prompt_auth_timeout)
+            else -> Pair(0, 0)
+        }.toMessage()
+}
+
+fun nonStrongAuthTimeoutWithFingerprintAllowed(securityMode: SecurityMode): BouncerMessageModel {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(kg_unlock_with_pattern_or_fp, kg_prompt_auth_timeout)
+        SecurityMode.Password -> Pair(kg_unlock_with_password_or_fp, kg_prompt_auth_timeout)
+        SecurityMode.PIN -> Pair(kg_unlock_with_pin_or_fp, kg_prompt_auth_timeout)
+        else -> Pair(0, 0)
+    }.toMessage()
+}
+
+private fun faceLockedOut(
+    securityMode: SecurityMode,
+    fpAuthIsAllowed: Boolean
+): BouncerMessageModel {
+    return if (fpAuthIsAllowed) faceLockedOutButFingerprintAvailable(securityMode)
+    else
+        when (securityMode) {
+            SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_face_locked_out)
+            SecurityMode.Password -> Pair(keyguard_enter_password, kg_face_locked_out)
+            SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_face_locked_out)
+            else -> Pair(0, 0)
+        }.toMessage()
+}
+
+private fun faceLockedOutButFingerprintAvailable(securityMode: SecurityMode): BouncerMessageModel {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(kg_unlock_with_pattern_or_fp, kg_face_locked_out)
+        SecurityMode.Password -> Pair(kg_unlock_with_password_or_fp, kg_face_locked_out)
+        SecurityMode.PIN -> Pair(kg_unlock_with_pin_or_fp, kg_face_locked_out)
+        else -> Pair(0, 0)
+    }.toMessage()
+}
+
+private fun class3AuthLockedOut(securityMode: SecurityMode): BouncerMessageModel {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_bio_too_many_attempts_pattern)
+        SecurityMode.Password -> Pair(keyguard_enter_password, kg_bio_too_many_attempts_password)
+        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_bio_too_many_attempts_pin)
+        else -> Pair(0, 0)
+    }.toMessage()
+}
+
+private fun trustAgentDisabled(
+    securityMode: SecurityMode,
+    fpAuthIsAllowed: Boolean
+): BouncerMessageModel {
+    return if (fpAuthIsAllowed) trustAgentDisabledWithFingerprintAllowed(securityMode)
+    else
+        when (securityMode) {
+            SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_trust_agent_disabled)
+            SecurityMode.Password -> Pair(keyguard_enter_password, kg_trust_agent_disabled)
+            SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_trust_agent_disabled)
+            else -> Pair(0, 0)
+        }.toMessage()
+}
+
+private fun trustAgentDisabledWithFingerprintAllowed(
+    securityMode: SecurityMode
+): BouncerMessageModel {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(kg_unlock_with_pattern_or_fp, kg_trust_agent_disabled)
+        SecurityMode.Password -> Pair(kg_unlock_with_password_or_fp, kg_trust_agent_disabled)
+        SecurityMode.PIN -> Pair(kg_unlock_with_pin_or_fp, kg_trust_agent_disabled)
+        else -> Pair(0, 0)
+    }.toMessage()
+}
+
+private fun primaryAuthLockedOut(securityMode: SecurityMode): BouncerMessageModel {
+    return when (securityMode) {
+        SecurityMode.Pattern ->
+            Pair(kg_too_many_failed_attempts_countdown, kg_primary_auth_locked_out_pattern)
+        SecurityMode.Password ->
+            Pair(kg_too_many_failed_attempts_countdown, kg_primary_auth_locked_out_password)
+        SecurityMode.PIN ->
+            Pair(kg_too_many_failed_attempts_countdown, kg_primary_auth_locked_out_pin)
+        else -> Pair(0, 0)
+    }.toMessage()
+}
+
+private fun Pair<Int, Int>.toMessage(): BouncerMessageModel {
+    return BouncerMessageModel(
+        message = Message(messageResId = this.first, animate = false),
+        secondaryMessage = Message(messageResId = this.second, animate = false)
+    )
+}
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 579f0b7..6e26fe9 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.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
@@ -38,8 +38,6 @@
 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 @@
     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 @@
 
     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 @@
             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/bouncer/shared/model/BouncerMessageModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/shared/model/BouncerMessageModel.kt
index 0e9e962..7b169f4 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/shared/model/BouncerMessageModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/shared/model/BouncerMessageModel.kt
@@ -22,7 +22,10 @@
  * Represents the message displayed on the bouncer. It has two parts, primary and a secondary
  * message
  */
-data class BouncerMessageModel(val message: Message? = null, val secondaryMessage: Message? = null)
+data class BouncerMessageModel(
+    val message: Message? = null,
+    val secondaryMessage: Message? = null,
+)
 
 /**
  * Representation of a single message on the bouncer. It can be either a string or a string resource
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 6486802..79a11ee 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 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/binder/KeyguardBouncerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/KeyguardBouncerViewBinder.kt
index e29d6bd..36e5db4 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/KeyguardBouncerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/KeyguardBouncerViewBinder.kt
@@ -144,7 +144,6 @@
                                     )
                                 }
                             } else {
-                                bouncerMessageInteractor.onBouncerBeingHidden()
                                 securityContainerController.onBouncerVisibilityChanged(
                                     /* isVisible= */ false
                                 )
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt
index d95b70c..4546bea 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.bouncer.ui.viewmodel
 
+import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.asStateFlow
@@ -28,6 +29,7 @@
      * being able to attempt to unlock the device.
      */
     val isInputEnabled: StateFlow<Boolean>,
+    private val interactor: BouncerInteractor,
 ) {
 
     private val _animateFailure = MutableStateFlow(false)
@@ -37,6 +39,9 @@
      */
     val animateFailure: StateFlow<Boolean> = _animateFailure.asStateFlow()
 
+    /** Whether the input method editor (for example, the software keyboard) is visible. */
+    private var isImeVisible: Boolean = false
+
     /**
      * Notifies that the failure animation has been shown. This should be called to consume a `true`
      * value in [animateFailure].
@@ -45,6 +50,21 @@
         _animateFailure.value = false
     }
 
+    /**
+     * Notifies that the input method editor (for example, the software keyboard) has been shown or
+     * hidden.
+     */
+    fun onImeVisibilityChanged(isVisible: Boolean) {
+        if (isImeVisible && !isVisible) {
+            // The IME has gone from visible to invisible, dismiss the bouncer.
+            interactor.hide(
+                loggingReason = "IME hidden",
+            )
+        }
+
+        isImeVisible = isVisible
+    }
+
     /** Ask the UI to show the failure animation. */
     protected fun showFailureAnimation() {
         _animateFailure.value = true
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 f6794d4..15d1dae 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/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt
index d214797..9e10f29 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt
@@ -31,6 +31,7 @@
 ) :
     AuthMethodBouncerViewModel(
         isInputEnabled = isInputEnabled,
+        interactor = interactor,
     ) {
 
     private val _password = MutableStateFlow("")
@@ -60,6 +61,10 @@
     /** Notifies that the user has pressed the key for attempting to authenticate the password. */
     fun onAuthenticateKeyPressed() {
         val password = _password.value.toCharArray().toList()
+        if (password.isEmpty()) {
+            return
+        }
+
         _password.value = ""
 
         applicationScope.launch {
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt
index 1985c37..497276b 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt
@@ -42,6 +42,7 @@
 ) :
     AuthMethodBouncerViewModel(
         isInputEnabled = isInputEnabled,
+        interactor = interactor,
     ) {
 
     /** The number of columns in the dot grid. */
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt
index dc5c528..8e6421e 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt
@@ -37,6 +37,7 @@
 ) :
     AuthMethodBouncerViewModel(
         isInputEnabled = isInputEnabled,
+        interactor = interactor,
     ) {
 
     val pinShapes = PinShapeAdapter(applicationContext)
diff --git a/packages/SystemUI/src/com/android/systemui/camera/CameraIntents.kt b/packages/SystemUI/src/com/android/systemui/camera/CameraIntents.kt
index cc43e7e..1e17059 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.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 ddb09749..718ef51 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.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 7bf8f4d..047d15d 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 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 0a1aed6..2729b7b 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 @@
 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 0542e13..e83a825 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.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 789833c..12597a7 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.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 ffd836b..70736ae 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 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 758a656..2406d61 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.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 a76d2ea..2af49cf 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 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 e9daa46..0a4d76e 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 @@
 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 1ffbe32..bb201b6 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.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 d58fab4..a18b4c8 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.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 09b2e44..0fd34bd 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.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 f362831..7fe0032 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.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 1b6d3a8..65bf4b3 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 @@
 
 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 560f4fa..039078e 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 @@
 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 8640c97..c3e8a96 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.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 e1dd1a6..20b2494 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 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 a7d017dd..712213a 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 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 87c3b2f..099e3fc 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.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 2b5aa7c..08d0595 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.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 f15a586..c0a292c 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 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 776c972..92fdb1e 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 @@
 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 e627b68..e9b5930 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.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 adb0bf3..97b4c94 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.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 6e17bc9..21458e8 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.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 0249060..05ff7b7 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 3fe0f03..72483bb 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 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 ec76f43..f034851 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.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 b447d66..a534097 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 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 4c9dbe0..41edb4a 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.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 8bae667..2ea4303 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.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 d5b8693..10a0117 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.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 86bde5c..d7a68b3 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.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 6f87aa9..5df26b3 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 @@
 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 5977d37..7e56077 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.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 4aef209..4e935df 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 @@
 
 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 501bcf0..4e391b7 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.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 a13f717..7e039cd 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.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 abe3423..fdb9971 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 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 8341964..955a5a3 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.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 d6cfb79..2ad6014 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 @@
 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 f7c8e96..252f02e 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.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 3cdf9ab..be9a299 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.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 98f17f4..9b93522 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.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 db009dc..1b0d032 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.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 dbbda9a..ac589eb 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.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 3c2bfa0..0706a96 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.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 39d6970..2c9eb3e 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.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 d011dd4..4190788 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.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 dc7247c..4f47012 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.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 0d570d2..e34a94b 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.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 9dd0f53..580a615 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.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/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 58ba3c9..a325ee2 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.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;
@@ -299,6 +300,9 @@
     @BindsOptionalOf
     abstract SystemStatusAnimationScheduler optionalSystemStatusAnimationScheduler();
 
+    @BindsOptionalOf
+    abstract FingerprintReEnrollNotification optionalFingerprintReEnrollNotification();
+
     @SysUISingleton
     @Binds
     abstract SystemClock bindSystemClock(SystemClockImpl systemClock);
diff --git a/packages/SystemUI/src/com/android/systemui/decor/CutoutDecorProviderImpl.kt b/packages/SystemUI/src/com/android/systemui/decor/CutoutDecorProviderImpl.kt
index ded0fb7..dbe6b0b 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.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 ac0d3c8..31a5d37 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 @@
     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 8cfd391..14ecc66 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.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 0ffb4fb..2f2c952f 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 8156797..0ee11ae 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.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 c64766a..0314b0fe 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.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 f730935..7510cf6c 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.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 55df779..8e542b5 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.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 d408472..db0c3c6 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.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 01fb522..4cfed33 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.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 78ac453..d0f2559 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 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 02a8b39a..409b196 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 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 1865c38..8e77079 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 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 a6401b6..8d8702e 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 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 95c225d..6fd6f4e 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 4bafe32..5ebb2dd 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 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 51eefd6..34dd1008 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.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 5f03743..8cf11a9 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.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 9e0ae41..94fe4bd 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 @@
 
 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 b70edcc..7a441d6 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 @@
 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 02575eb..ecad9d7 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 @@
 
 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
@@ -124,6 +124,11 @@
     val NOTIFICATION_GROUP_EXPANSION_CHANGE =
             unreleasedFlag("notification_group_expansion_change")
 
+    // TODO(b/301955929)
+    @JvmField
+    val NOTIF_LS_BACKGROUND_THREAD =
+            unreleasedFlag("notification_lockscreen_mgr_bg_thread")
+
     // 200 - keyguard/lockscreen
     // ** Flag retired **
     // public static final BooleanFlag KEYGUARD_LAYOUT =
@@ -250,10 +255,6 @@
     // 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 */
 
     /**
@@ -390,13 +391,15 @@
     // 600- status bar
 
     // TODO(b/291315866): Tracking Bug
-    @JvmField val SIGNAL_CALLBACK_DEPRECATION = unreleasedFlag("signal_callback_deprecation")
+    @JvmField val SIGNAL_CALLBACK_DEPRECATION =
+        unreleasedFlag("signal_callback_deprecation", teamfood = true)
 
     // TODO(b/265892345): Tracking Bug
     val PLUG_IN_STATUS_BAR_CHIP = releasedFlag("plug_in_status_bar_chip")
 
     // 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 =
@@ -757,7 +760,7 @@
         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
 
@@ -795,11 +798,12 @@
 
     // 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
-    val BLUETOOTH_QS_TILE_DIALOG = unreleasedFlag("bluetooth_qs_tile_dialog")
+    val BLUETOOTH_QS_TILE_DIALOG = unreleasedFlag("bluetooth_qs_tile_dialog", teamfood = true)
 
     // TODO(b/300995746): Tracking Bug
     /** Enable communal hub features. */
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsColumnLayout.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsColumnLayout.java
index 5907028..a3065d3 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.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 3eb1740..ac40230 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 @@
      */
     @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 @@
 
         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 @@
     @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 @@
 
     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 @@
     @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 @@
                 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 @@
                 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 @@
     }
 
     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 @@
                 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 @@
         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 @@
             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 @@
         }
 
         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 @@
             });
             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 @@
                     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 @@
         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 83046ef..bc1e13f 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 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 @@
     }
 
     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 e1462d1..2272b8a 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 @@
     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 183ee45..6afefb0 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 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 42230ae..9b318a2 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 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 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 6d083f6..b9a6a55 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.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 caa88a3..b8bf142 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 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 @@
         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 68dc1b3..51978ec 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 @@
         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 @@
                         (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 @@
                         | 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 @@
         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/haptics/slider/SeekableSliderTracker.kt b/packages/SystemUI/src/com/android/systemui/haptics/slider/SeekableSliderTracker.kt
new file mode 100644
index 0000000..d9b2c39
--- /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.
+ * @param[mainDispatcher] [CoroutineDispatcher] used to launch coroutines for the collection of
+ *   slider events and the launch of timer jobs.
+ * @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 0000000..cb0f43b
--- /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/SliderHapticFeedbackConfig.kt b/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderHapticFeedbackConfig.kt
new file mode 100644
index 0000000..20d99d1
--- /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 0000000..e6de156
--- /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/SliderState.kt b/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderState.kt
new file mode 100644
index 0000000..fe092e6
--- /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/SliderStateListener.kt b/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderStateListener.kt
new file mode 100644
index 0000000..9c99c90
--- /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/haptics/slider/SliderTracker.kt b/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderTracker.kt
new file mode 100644
index 0000000..002b5aa
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderTracker.kt
@@ -0,0 +1,94 @@
+/*
+ * 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].
+ *
+ * @property[scope] [CoroutineScope] to launch the collection of [SliderEvent] and state machine
+ *   logic.
+ * @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/src/com/android/systemui/keyboard/KeyboardUI.java b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
index ad7973e..1cdbe6f 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.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 6f25f7c..e16bb0b 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 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 732102e..1f69cc0 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 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 22bcf0a..fb02c7d 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.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 394bed4..b506a36 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.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;
@@ -3243,7 +3243,11 @@
                         + "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;
             }
 
@@ -3794,6 +3798,13 @@
     }
 
     /**
+     * Notify whether keyguard has created a remote animation runner for next app launch.
+     */
+    public void launchingActivityOverLockscreen(boolean isLaunchingActivityOverLockscreen) {
+        mKeyguardTransitions.setLaunchingActivityOverLockscreen(isLaunchingActivityOverLockscreen);
+    }
+
+    /**
      * Implementation of RemoteAnimationRunner that creates a new
      * {@link ActivityLaunchAnimator.Runner} whenever onAnimationStart is called, delegating the
      * remote animation methods to that runner.
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java b/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java
index ffd8a02..d5316cd 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 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/WindowManagerLockscreenVisibilityManager.kt b/packages/SystemUI/src/com/android/systemui/keyguard/WindowManagerLockscreenVisibilityManager.kt
index 75677f2..8ebcece 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 @@
     /**
      * 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 @@
 
         // 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 @@
         }
     }
 
+    /**
+     * 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 @@
     }
 
     companion object {
-        private val TAG = this::class.java.simpleName
+        private val TAG = WindowManagerLockscreenVisibilityManager::class.java.simpleName
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java
index 82be009..09875a5 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.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 5e5caba..77e8179 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.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 16385ec..9b5f461 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.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 ed8823a..a7999c1 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 f3fc809..cc36961 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.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
@@ -78,6 +78,7 @@
             component.getControlsListingController().getOrNull()?.getCurrentServices()
         val hasFavorites =
             component.getControlsController().getOrNull()?.getFavorites()?.isNotEmpty() == true
+        val hasPanels = currentServices?.any { it.panelActivity != null } == true
         val componentPackageName = component.getPackageName()
         when {
             currentServices.isNullOrEmpty() && !componentPackageName.isNullOrEmpty() -> {
@@ -100,8 +101,8 @@
                         ),
                 )
             }
-            !hasFavorites -> {
-                // Home app installed but no favorites selected.
+            !hasFavorites && !hasPanels -> {
+                // Home app installed but no favorites selected or panel activities available.
                 val activityClass = component.getControlsUiController().get().resolveActivity()
                 return disabledPickerState(
                     explanation =
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 320d158..1cf6183 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.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 4dad179..deedbdb 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 @@
 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 2503568..1fe94d5 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.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 45277b8..a503541 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 23f50ea..7337292 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.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 1ccc689..bbdd903 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.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 682e841..06cf723 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.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 233acd9..fd048ff 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,14 +18,13 @@
 
 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
 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
@@ -47,6 +46,7 @@
 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 @@
                     authCancellationSignal,
                     faceAuthCallback,
                     null,
-                    FaceAuthenticateOptions.Builder().setUserId(currentUserId).build()
+                    SysUiFaceAuthenticateOptions(
+                            currentUserId,
+                            uiEvent,
+                            wakeReason = uiEvent.extraInfo
+                        )
+                        .toFaceAuthenticateOptions()
                 )
             }
         } else if (canRunDetection.value) {
@@ -587,7 +592,7 @@
                     uiEvent,
                     "face auth gating check is false, falling back to detection."
                 )
-                detect()
+                detect(uiEvent)
             } else {
                 faceAuthLogger.ignoredFaceAuthTrigger(
                     uiEvent = uiEvent,
@@ -602,7 +607,7 @@
         }
     }
 
-    suspend fun detect() {
+    suspend fun detect(uiEvent: FaceAuthUiEvent) {
         if (!isDetectionSupported) {
             faceAuthLogger.detectionNotSupported(faceManager, faceManager?.sensorPropertiesInternal)
             return
@@ -619,7 +624,8 @@
             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/data/repository/KeyguardQuickAffordanceRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt
index 34f6b4d..698328e 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.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 1c0b73f..af01626 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.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/data/repository/TrustRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt
index 00036ce..6522439 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt
@@ -29,6 +29,7 @@
 import com.android.systemui.user.data.repository.UserRepository
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.channels.awaitClose
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.SharingStarted
@@ -36,6 +37,8 @@
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.onStart
@@ -44,19 +47,25 @@
 
 /** Encapsulates any state relevant to trust agents and trust grants. */
 interface TrustRepository {
+    /** Flow representing whether the current user has enabled any trust agents. */
+    val isCurrentUserTrustUsuallyManaged: StateFlow<Boolean>
+
     /** Flow representing whether the current user is trusted. */
     val isCurrentUserTrusted: Flow<Boolean>
 
     /** Flow representing whether active unlock is running for the current user. */
     val isCurrentUserActiveUnlockRunning: Flow<Boolean>
 
-    /** Reports that whether trust is managed has changed for the current user. */
+    /**
+     * Reports whether a trust agent is currently enabled and managing the trust of the current user
+     */
     val isCurrentUserTrustManaged: StateFlow<Boolean>
 
     /** A trust agent is requesting to dismiss the keyguard from a trust change. */
     val trustAgentRequestingToDismissKeyguard: Flow<TrustModel>
 }
 
+@OptIn(ExperimentalCoroutinesApi::class)
 @SysUISingleton
 class TrustRepositoryImpl
 @Inject
@@ -174,6 +183,11 @@
                 }
                 .map { it!! }
 
+    override val isCurrentUserTrustUsuallyManaged: StateFlow<Boolean> =
+        userRepository.selectedUserInfo
+            .flatMapLatest { flowOf(trustManager.isTrustUsuallyManaged(it.id)) }
+            .stateIn(applicationScope, started = SharingStarted.Eagerly, false)
+
     private fun isUserTrustManaged(userId: Int) =
         trustManagedForUser[userId]?.isTrustManaged ?: false
 
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 ac936b1..b2e436c 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 @@
 
 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/FromLockscreenTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
index 9c6a1b1..8f39431 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 @@
                                 !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/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
index 5727857..338f994 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.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 a257f52..299c8cf 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 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 7f43cbc..de791aa 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.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 f0df3a2e..20e55e5 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,9 +19,10 @@
 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
+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
@@ -31,8 +32,10 @@
 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.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 @@
     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 @@
                 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 c8a04fd..3602be8 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 @@
 /** 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 @@
                 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/keyguard/ui/binder/KeyguardAmbientIndicationAreaViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardAmbientIndicationAreaViewBinder.kt
index 5c072fb..5900a24 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.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 a9c71ad..dd7eee9 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.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 dc51944..f20a666 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.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 7685345..125e2da 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.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 83b5463..eeb4ac3 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.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 4b76821..f564d00 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 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 82610e6..6beef8e 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 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 3bb01f2..aabb3f4 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 667abae..a0e0da4 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 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 85a2fd5..2ad74fb 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.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 890d565..78099d9 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.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 5aba229..28e6a95 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.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 ac11ba5..669db34 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.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 d046a19..a4137ac 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.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 ce86e97..9371d4e 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.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 a45223c..623eac0 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.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 100099d..9409036 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 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 7fff43b..afa49bd 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.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 b25f9af..6fd13e0 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.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 13ef985..a679120 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.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 d6c69b3..f713d5e 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.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 1cb10bd..1a9f021 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.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 5e3ea05..c869771 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 @@
 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 63d165d..33718c41 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 @@
 
 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 c36da9d..66ceded 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 667c2f1..c10a463 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 dd58607..54abc5b 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 @@
 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/log/FaceAuthenticationLogger.kt b/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt
index 8143f99..66af36a 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 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 @@
 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 @@
         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/src/com/android/systemui/logcat/LogAccessDialogActivity.java b/packages/SystemUI/src/com/android/systemui/logcat/LogAccessDialogActivity.java
index 2cfe5a7..d01917a 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 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 be48756..88bc064 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.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 d403788..4de6278 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.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 5315067..f5f5d38 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.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 b7a2522..b98e9c2 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.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 8b74263..1b14f75 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.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 6eaff3f..3f4f347 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.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 258284e..8ac8a2d 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.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 e79fc74..0f3e0ac 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.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 c90a3c1..1fe93ed 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.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 b9cc772..5aa6824 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 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 646d1d0..6ee072d 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 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 38a6a8f..e59fc15 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.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 ec0c40e..1261152 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 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 a12bc2c..cce4cda 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.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 0b30e59..ae3c912 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 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 1dd969f..b436f5d 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.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 ea943be..20ea60f 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.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 875a010..fbb84de 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 @@
 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 26a7d04..ff9495d 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 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 d8824983..5958b0a 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 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 3a1d8b0..0c5a14f 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.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 11a16a4..ac64300 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.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 7011ad9..426a497 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.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 e5a6bb5..4640a5d 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 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 2680a2f..87c9cd0 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.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 0ba5f28..9de2b4f 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.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 b29b588..2f0e129 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.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 da8e106..6e9485e 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.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 fbf7e25..fbd7fd3 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.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 d3efae4..339145c 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.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 87d0098..e827a1e 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.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 829b0dd..950b695 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.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 cbb7e1d..fd1a683 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.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 0c77054..412c006 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.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 a09935b..3fe040a 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.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 6af50a0..78dbd92 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.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 a6b3da0..fc45228 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 a437139..7840da9 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.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 62b22c5..cb52a5f 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.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 2a7704f..c1d98c9 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 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 f6bfd6c..3ef5094 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.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 1d73bc20..3e34318 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.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 79e7b71..4d6d95a 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.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 ac7baf5..939c096 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.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 9305d05..bd3a0c1 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.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 702be72..686facc 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.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 3529142..dcf1a8e 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.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 8ff7b7a..d780f7c 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 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 b21b001..3dfd292 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 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 9ddb78a..439b7e1 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 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 ff22398..380846e 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 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 913b6528..5a22c38 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.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 88622aa..b55de27 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.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 be3168c..c216337 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.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 ea8eb36..093d098 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.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 63d4634..9785446 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.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 f02d362..6d55d05 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.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 36b435b0..59c76ad 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.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 c6c9aca..188e867 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.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 67e9664..733383e 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.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 46c8d35..c567d56 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.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 e27bfb3..ed7c21b 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.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 fbf1a0e..1f66b84 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.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 03d1f15..1cd5d91 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.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 a765702..38204ab 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.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 e1e1aae..1534653 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.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 310d234..8e1b00d 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.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 eec69f98..4952d8d 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 35a7cf1..ac9a590 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.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 c202f14..b26ae6c 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.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 8b41000..d09fbb3 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 afce69e..1b22f98 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.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 a3b901b..6f35cfb 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_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 e822dd5..4770d52 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 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 ddd9463..826f75f 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 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 768598a..f040435 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.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 37e750b..b0f54ee 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.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 26399d8..235fc0d1f 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 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 61905ae..c908e6e 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.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 85f557b..ffbd06f 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.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 596d024..fd81e9a 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 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 4e914a5..1ab64b7 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.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 b936c41..3227f75 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 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 001cbba..77a5ce3 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 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 b70b94b..5c96e98 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.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 4c292e7..9a9626d 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 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 1501379..6c32ed3 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 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 585136a..099d19d8 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 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 691a1a1..67c4208 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.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 1ba11ef..b52554d 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 @@
 
 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 19bf018..9dc6aee 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 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 d511d8a..7888f4c 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.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 4002ac3..ce504b2 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.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 e890170..c9a24d6a 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 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 1e426ad..92f17f9 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 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 d9f4484..a6226b3 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 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 ce6b8d4..bcd9803 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.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 1caab5a..8b6d914 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 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 d2c51e5..1659c3e 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.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 d9e5580..899d0e2 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.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 e969d4c6..5fa75ad 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.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 3c53d77..d09b210 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.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 32146b5..769cb1f 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.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 18f59b1..47c99f2 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.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 b1c7433..83c8bc3 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 @@
 
 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 58a31bc..88d7f06 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.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 88c8e81..d04e4f5 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.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 966d941..5a9c0a1 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 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 f672e51..168fa08 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 30765f7..fb71cef 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 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 c709969..d98141f 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 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 9f10e6f..18d472b 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 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 83b09be..d862f56 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -39,9 +39,11 @@
 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.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.qs.QSTile.BooleanState;
@@ -50,6 +52,7 @@
 import com.android.systemui.qs.QsEventLogger;
 import com.android.systemui.qs.logging.QSLogger;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
+import com.android.systemui.qs.tiles.dialog.bluetooth.BluetoothTileDialogViewModel;
 import com.android.systemui.statusbar.policy.BluetoothController;
 
 import java.util.List;
@@ -72,6 +75,10 @@
 
     private final Executor mExecutor;
 
+    private final BluetoothTileDialogViewModel mDialogViewModel;
+
+    private final FeatureFlags mFeatureFlags;
+
     @Inject
     public BluetoothTile(
             QSHost host,
@@ -83,13 +90,17 @@
             StatusBarStateController statusBarStateController,
             ActivityStarter activityStarter,
             QSLogger qsLogger,
-            BluetoothController bluetoothController
+            BluetoothController bluetoothController,
+            FeatureFlags featureFlags,
+            BluetoothTileDialogViewModel dialogViewModel
     ) {
         super(host, uiEventLogger, backgroundLooper, mainHandler, falsingManager, metricsLogger,
                 statusBarStateController, activityStarter, qsLogger);
         mController = bluetoothController;
         mController.observe(getLifecycle(), mCallback);
         mExecutor = new HandlerExecutor(mainHandler);
+        mFeatureFlags = featureFlags;
+        mDialogViewModel = dialogViewModel;
     }
 
     @Override
@@ -99,11 +110,15 @@
 
     @Override
     protected void handleClick(@Nullable View view) {
-        // Secondary clicks are header clicks, just toggle.
-        final boolean isEnabled = mState.value;
-        // Immediately enter transient enabling state when turning bluetooth on.
-        refreshState(isEnabled ? null : ARG_SHOW_TRANSIENT_ENABLING);
-        mController.setBluetoothEnabled(!isEnabled);
+        if (mFeatureFlags.isEnabled(Flags.BLUETOOTH_QS_TILE_DIALOG)) {
+            mDialogViewModel.showDialog(mContext, view);
+        } else {
+            // Secondary clicks are header clicks, just toggle.
+            final boolean isEnabled = mState.value;
+            // Immediately enter transient enabling state when turning bluetooth on.
+            refreshState(isEnabled ? null : ARG_SHOW_TRANSIENT_ENABLING);
+            mController.setBluetoothEnabled(!isEnabled);
+        }
     }
 
     @Override
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 65ef6b9..b393f39 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.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 e9a2428..5c6e902 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.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 cf9e346..ee57b2b 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 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 4ecde61..993ada6 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 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 e769b5e..ccf7afb 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.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 5578558..c15289f 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 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 ddaff3b..91b2d97 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 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 9bb192b..0617b30 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.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 b5e6a0f..a08b3fc 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.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 2c986da..9fab51f 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 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 1f9979a..64e3f16 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.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 7c76c1a..9ee417e 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 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 fb2f2ce..1b504a8 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.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 956e7ab..8103152 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.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 8b69f61..9ddcf295 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 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 86a6a8c..7a7dbbc 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.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 29ccb76..a239c28 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 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 405e139..7e0fa07 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 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 5b0237f..78af976 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 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 1ba377b..f70e27d 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 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 e382eca..3a247c5 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 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 2e04afb..b9d902a 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 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 2d9f7dd..ea162fa 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 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 2d4652d..959afd8 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 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 7c4f097..5832217 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.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 9ffcba6..300cc56 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 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 5840a3d..7426615 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 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 b6b657e..32deb30 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.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 c8c3c30..7a9384a 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 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 176983e..b866dda 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 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 c67078f..2350b5d 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.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 f026d20..f516f55 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.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/tiles/dialog/bluetooth/BluetoothStateInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothStateInteractor.kt
new file mode 100644
index 0000000..efad9ec
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothStateInteractor.kt
@@ -0,0 +1,80 @@
+/*
+ * 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.qs.tiles.dialog.bluetooth
+
+import android.bluetooth.BluetoothAdapter.STATE_OFF
+import android.bluetooth.BluetoothAdapter.STATE_ON
+import com.android.settingslib.bluetooth.BluetoothCallback
+import com.android.settingslib.bluetooth.LocalBluetoothManager
+import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
+import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.stateIn
+
+/** Holds business logic for the Bluetooth Dialog's bluetooth and device connection state */
+@SysUISingleton
+internal class BluetoothStateInteractor
+@Inject
+constructor(
+    private val localBluetoothManager: LocalBluetoothManager?,
+    @Application private val coroutineScope: CoroutineScope,
+) {
+
+    internal val updateBluetoothStateFlow: StateFlow<Boolean?> =
+        conflatedCallbackFlow {
+                val listener =
+                    object : BluetoothCallback {
+                        override fun onBluetoothStateChanged(bluetoothState: Int) {
+                            if (bluetoothState == STATE_ON || bluetoothState == STATE_OFF) {
+                                super.onBluetoothStateChanged(bluetoothState)
+                                trySendWithFailureLogging(
+                                    bluetoothState == STATE_ON,
+                                    TAG,
+                                    "onBluetoothStateChanged"
+                                )
+                            }
+                        }
+                    }
+                localBluetoothManager?.eventManager?.registerCallback(listener)
+                awaitClose { localBluetoothManager?.eventManager?.unregisterCallback(listener) }
+            }
+            .stateIn(
+                coroutineScope,
+                SharingStarted.WhileSubscribed(replayExpirationMillis = 0),
+                initialValue = null
+            )
+
+    internal var isBluetoothEnabled: Boolean
+        get() = localBluetoothManager?.bluetoothAdapter?.isEnabled == true
+        set(value) {
+            if (isBluetoothEnabled != value) {
+                localBluetoothManager?.bluetoothAdapter?.apply {
+                    if (value) enable() else disable()
+                }
+            }
+        }
+
+    companion object {
+        private const val TAG = "BtStateInteractor"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialog.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialog.kt
new file mode 100644
index 0000000..6815a73
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialog.kt
@@ -0,0 +1,207 @@
+/*
+ * 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.qs.tiles.dialog.bluetooth
+
+import android.content.Context
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.View.GONE
+import android.view.View.VISIBLE
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.Switch
+import android.widget.TextView
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.android.internal.logging.UiEventLogger
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.phone.SystemUIDialog
+import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asSharedFlow
+import kotlinx.coroutines.flow.asStateFlow
+
+/** Dialog for showing active, connected and saved bluetooth devices. */
+@SysUISingleton
+internal class BluetoothTileDialog
+constructor(
+    private val bluetoothToggleInitialValue: Boolean,
+    private val bluetoothTileDialogCallback: BluetoothTileDialogCallback,
+    private val uiEventLogger: UiEventLogger,
+    context: Context,
+) : SystemUIDialog(context, DEFAULT_THEME, DEFAULT_DISMISS_ON_DEVICE_LOCK) {
+
+    private val mutableBluetoothStateSwitchedFlow: MutableStateFlow<Boolean> =
+        MutableStateFlow(bluetoothToggleInitialValue)
+    internal val bluetoothStateSwitchedFlow
+        get() = mutableBluetoothStateSwitchedFlow.asStateFlow()
+
+    private val mutableClickedFlow: MutableSharedFlow<Pair<DeviceItem, Int>> =
+        MutableSharedFlow(extraBufferCapacity = 1)
+    internal val deviceItemClickedFlow
+        get() = mutableClickedFlow.asSharedFlow()
+
+    private val deviceItemAdapter: Adapter = Adapter(bluetoothTileDialogCallback)
+
+    private lateinit var toggleView: Switch
+    private lateinit var doneButton: View
+    private lateinit var seeAllViewGroup: View
+    private lateinit var pairNewDeviceViewGroup: View
+    private lateinit var seeAllText: View
+    private lateinit var pairNewDeviceText: View
+    private lateinit var deviceListView: RecyclerView
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        uiEventLogger.log(BluetoothTileDialogUiEvent.BLUETOOTH_TILE_DIALOG_SHOWN)
+
+        setContentView(LayoutInflater.from(context).inflate(R.layout.bluetooth_tile_dialog, null))
+
+        toggleView = requireViewById(R.id.bluetooth_toggle)
+        doneButton = requireViewById(R.id.done_button)
+        seeAllViewGroup = requireViewById(R.id.see_all_layout_group)
+        pairNewDeviceViewGroup = requireViewById(R.id.pair_new_device_layout_group)
+        seeAllText = requireViewById(R.id.see_all_text)
+        pairNewDeviceText = requireViewById(R.id.pair_new_device_text)
+        deviceListView = requireViewById<RecyclerView>(R.id.device_list)
+
+        setupToggle()
+        setupRecyclerView()
+
+        doneButton.setOnClickListener { dismiss() }
+        seeAllText.setOnClickListener { bluetoothTileDialogCallback.onSeeAllClicked(it) }
+        pairNewDeviceText.setOnClickListener {
+            bluetoothTileDialogCallback.onPairNewDeviceClicked(it)
+        }
+    }
+
+    // TODO(b/298124674): use DiffUtil or AsyncListDiffer to avoid updating the whole list
+    internal fun onDeviceItemUpdated(
+        deviceItem: List<DeviceItem>,
+        showSeeAll: Boolean,
+        showPairNewDevice: Boolean
+    ) {
+        seeAllViewGroup.visibility = if (showSeeAll) VISIBLE else GONE
+        pairNewDeviceViewGroup.visibility = if (showPairNewDevice) VISIBLE else GONE
+        deviceItemAdapter.refreshDeviceItemList(deviceItem)
+    }
+
+    internal fun onDeviceItemUpdatedAtPosition(deviceItem: DeviceItem, position: Int) {
+        deviceItemAdapter.refreshDeviceItem(deviceItem, position)
+    }
+
+    internal fun onBluetoothStateUpdated(isEnabled: Boolean) {
+        toggleView.isChecked = isEnabled
+    }
+
+    private fun setupToggle() {
+        toggleView.isChecked = bluetoothToggleInitialValue
+        toggleView.setOnCheckedChangeListener { _, isChecked ->
+            mutableBluetoothStateSwitchedFlow.value = isChecked
+            uiEventLogger.log(BluetoothTileDialogUiEvent.BLUETOOTH_TOGGLE_CLICKED)
+        }
+    }
+
+    private fun setupRecyclerView() {
+        deviceListView.apply {
+            layoutManager = LinearLayoutManager(context)
+            adapter = deviceItemAdapter
+        }
+    }
+
+    internal inner class Adapter(private val onClickCallback: BluetoothTileDialogCallback) :
+        RecyclerView.Adapter<Adapter.DeviceItemViewHolder>() {
+
+        private val deviceItem: MutableList<DeviceItem> = mutableListOf()
+
+        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DeviceItemViewHolder {
+            val view =
+                LayoutInflater.from(parent.context)
+                    .inflate(R.layout.bluetooth_device_item, parent, false)
+            return DeviceItemViewHolder(view)
+        }
+
+        override fun getItemCount() = deviceItem.size
+
+        override fun onBindViewHolder(holder: DeviceItemViewHolder, position: Int) {
+            val item = getItem(position)
+            holder.bind(item, position, onClickCallback)
+        }
+
+        internal fun getItem(position: Int) = deviceItem[position]
+
+        internal fun refreshDeviceItemList(updated: List<DeviceItem>) {
+            deviceItem.clear()
+            deviceItem.addAll(updated)
+            notifyDataSetChanged()
+        }
+
+        internal fun refreshDeviceItem(updated: DeviceItem, position: Int) {
+            deviceItem[position] = updated
+            notifyItemChanged(position)
+        }
+
+        internal inner class DeviceItemViewHolder(view: View) : RecyclerView.ViewHolder(view) {
+            private val container = view.requireViewById<View>(R.id.bluetooth_device_row)
+            private val deviceView = view.requireViewById<View>(R.id.bluetooth_device)
+            private val nameView = view.requireViewById<TextView>(R.id.bluetooth_device_name)
+            private val summaryView = view.requireViewById<TextView>(R.id.bluetooth_device_summary)
+            private val iconView = view.requireViewById<ImageView>(R.id.bluetooth_device_icon)
+            private val gearView = view.requireViewById<View>(R.id.gear_icon)
+
+            internal fun bind(
+                item: DeviceItem,
+                position: Int,
+                deviceItemOnClickCallback: BluetoothTileDialogCallback
+            ) {
+                container.apply {
+                    isEnabled = item.isEnabled
+                    alpha = item.alpha
+                    background = item.background
+                }
+                deviceView.setOnClickListener {
+                    mutableClickedFlow.tryEmit(Pair(item, position))
+                    uiEventLogger.log(BluetoothTileDialogUiEvent.DEVICE_CLICKED)
+                }
+                nameView.text = item.deviceName
+                summaryView.text = item.connectionSummary
+                iconView.apply {
+                    item.iconWithDescription?.let {
+                        setImageDrawable(it.first)
+                        contentDescription = it.second
+                    }
+                }
+                gearView.setOnClickListener {
+                    deviceItemOnClickCallback.onDeviceItemGearClicked(item, it)
+                }
+            }
+        }
+    }
+
+    internal companion object {
+        const val ENABLED_ALPHA = 1.0f
+        const val DISABLED_ALPHA = 0.3f
+        const val MAX_DEVICE_ITEM_ENTRY = 3
+        const val ACTION_BLUETOOTH_DEVICE_DETAILS =
+            "com.android.settings.BLUETOOTH_DEVICE_DETAIL_SETTINGS"
+        const val ACTION_PREVIOUSLY_CONNECTED_DEVICE =
+            "com.android.settings.PREVIOUSLY_CONNECTED_DEVICE"
+        const val ACTION_PAIR_NEW_DEVICE = "android.settings.BLUETOOTH_PAIRING_SETTINGS"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogRepository.kt
new file mode 100644
index 0000000..ea51bee
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogRepository.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.qs.tiles.dialog.bluetooth
+
+import android.bluetooth.BluetoothAdapter
+import com.android.settingslib.bluetooth.CachedBluetoothDevice
+import com.android.settingslib.bluetooth.LocalBluetoothManager
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+
+/** Repository to get CachedBluetoothDevices for the Bluetooth Dialog. */
+@SysUISingleton
+internal class BluetoothTileDialogRepository
+@Inject
+constructor(
+    private val localBluetoothManager: LocalBluetoothManager?,
+    private val bluetoothAdapter: BluetoothAdapter? = BluetoothAdapter.getDefaultAdapter()
+) {
+    internal val cachedDevices: Collection<CachedBluetoothDevice>
+        get() {
+            return if (
+                localBluetoothManager == null ||
+                    bluetoothAdapter == null ||
+                    !bluetoothAdapter.isEnabled
+            ) {
+                emptyList()
+            } else {
+                localBluetoothManager.cachedDeviceManager.cachedDevicesCopy
+            }
+        }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogUiEvent.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogUiEvent.kt
new file mode 100644
index 0000000..2865ad7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogUiEvent.kt
@@ -0,0 +1,34 @@
+/*
+ * 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.qs.tiles.dialog.bluetooth
+
+import com.android.internal.logging.UiEvent
+import com.android.internal.logging.UiEventLogger
+
+/** UI Events for the bluetooth tile dialog. */
+enum class BluetoothTileDialogUiEvent(val metricId: Int) : UiEventLogger.UiEventEnum {
+    @UiEvent(doc = "The bluetooth tile dialog is shown") BLUETOOTH_TILE_DIALOG_SHOWN(1493),
+    @UiEvent(doc = "The master toggle is clicked") BLUETOOTH_TOGGLE_CLICKED(1494),
+    @UiEvent(doc = "Pair new device is clicked") PAIR_NEW_DEVICE_CLICKED(1495),
+    @UiEvent(doc = "See all is clicked") SEE_ALL_CLICKED(1496),
+    @UiEvent(doc = "Gear icon clicked") DEVICE_GEAR_CLICKED(1497),
+    @UiEvent(doc = "Device clicked") DEVICE_CLICKED(1498),
+    @UiEvent(doc = "Connected device clicked to active") CONNECTED_DEVICE_SET_ACTIVE(1499),
+    @UiEvent(doc = "Saved clicked to connect") SAVED_DEVICE_CONNECT(1500);
+
+    override fun getId() = metricId
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModel.kt
new file mode 100644
index 0000000..012484f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModel.kt
@@ -0,0 +1,184 @@
+/*
+ * 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.qs.tiles.dialog.bluetooth
+
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import android.view.View
+import androidx.annotation.VisibleForTesting
+import com.android.internal.logging.UiEventLogger
+import com.android.systemui.animation.DialogLaunchAnimator
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.qs.tiles.dialog.bluetooth.BluetoothTileDialog.Companion.ACTION_BLUETOOTH_DEVICE_DETAILS
+import com.android.systemui.qs.tiles.dialog.bluetooth.BluetoothTileDialog.Companion.ACTION_PAIR_NEW_DEVICE
+import com.android.systemui.qs.tiles.dialog.bluetooth.BluetoothTileDialog.Companion.ACTION_PREVIOUSLY_CONNECTED_DEVICE
+import com.android.systemui.qs.tiles.dialog.bluetooth.BluetoothTileDialog.Companion.MAX_DEVICE_ITEM_ENTRY
+import com.android.systemui.statusbar.phone.SystemUIDialog
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.flow.filterNotNull
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.launch
+
+/** ViewModel for Bluetooth Dialog after clicking on the Bluetooth QS tile. */
+@SysUISingleton
+internal class BluetoothTileDialogViewModel
+@Inject
+constructor(
+    private val deviceItemInteractor: DeviceItemInteractor,
+    private val bluetoothStateInteractor: BluetoothStateInteractor,
+    private val dialogLaunchAnimator: DialogLaunchAnimator,
+    private val activityStarter: ActivityStarter,
+    private val uiEventLogger: UiEventLogger,
+    @Application private val coroutineScope: CoroutineScope,
+    @Main private val mainDispatcher: CoroutineDispatcher,
+) : BluetoothTileDialogCallback {
+
+    private var job: Job? = null
+
+    @VisibleForTesting internal var dialog: BluetoothTileDialog? = null
+
+    /**
+     * Shows the dialog.
+     *
+     * @param context The context in which the dialog is displayed.
+     * @param view The view from which the dialog is shown.
+     */
+    fun showDialog(context: Context, view: View?) {
+        dismissDialog()
+
+        var updateDeviceItemJob: Job? = null
+
+        job =
+            coroutineScope.launch(mainDispatcher) {
+                dialog = createBluetoothTileDialog(context)
+                view?.let { dialogLaunchAnimator.showFromView(dialog!!, it) } ?: dialog!!.show()
+                updateDeviceItemJob?.cancel()
+                updateDeviceItemJob = launch { deviceItemInteractor.updateDeviceItems(context) }
+
+                bluetoothStateInteractor.updateBluetoothStateFlow
+                    .filterNotNull()
+                    .onEach {
+                        dialog!!.onBluetoothStateUpdated(it)
+                        updateDeviceItemJob?.cancel()
+                        updateDeviceItemJob = launch {
+                            deviceItemInteractor.updateDeviceItems(context)
+                        }
+                    }
+                    .launchIn(this)
+
+                deviceItemInteractor.updateDeviceItemsFlow
+                    .onEach {
+                        updateDeviceItemJob?.cancel()
+                        updateDeviceItemJob = launch {
+                            deviceItemInteractor.updateDeviceItems(context)
+                        }
+                    }
+                    .launchIn(this)
+
+                deviceItemInteractor.deviceItemFlow
+                    .filterNotNull()
+                    .onEach {
+                        dialog!!.onDeviceItemUpdated(
+                            it.take(MAX_DEVICE_ITEM_ENTRY),
+                            showSeeAll = it.size > MAX_DEVICE_ITEM_ENTRY,
+                            showPairNewDevice = bluetoothStateInteractor.isBluetoothEnabled
+                        )
+                    }
+                    .launchIn(this)
+
+                dialog!!
+                    .bluetoothStateSwitchedFlow
+                    .onEach { bluetoothStateInteractor.isBluetoothEnabled = it }
+                    .launchIn(this)
+
+                dialog!!
+                    .deviceItemClickedFlow
+                    .onEach {
+                        if (deviceItemInteractor.updateDeviceItemOnClick(it.first)) {
+                            dialog!!.onDeviceItemUpdatedAtPosition(it.first, it.second)
+                        }
+                    }
+                    .launchIn(this)
+            }
+    }
+
+    private fun createBluetoothTileDialog(context: Context): BluetoothTileDialog {
+        return BluetoothTileDialog(
+                bluetoothStateInteractor.isBluetoothEnabled,
+                this@BluetoothTileDialogViewModel,
+                uiEventLogger,
+                context
+            )
+            .apply { SystemUIDialog.registerDismissListener(this) { dismissDialog() } }
+    }
+
+    override fun onDeviceItemGearClicked(deviceItem: DeviceItem, view: View) {
+        uiEventLogger.log(BluetoothTileDialogUiEvent.DEVICE_GEAR_CLICKED)
+        val intent =
+            Intent(ACTION_BLUETOOTH_DEVICE_DETAILS).apply {
+                putExtra(
+                    ":settings:show_fragment_args",
+                    Bundle().apply {
+                        putString("device_address", deviceItem.cachedBluetoothDevice.address)
+                    }
+                )
+            }
+        startSettingsActivity(intent, view)
+    }
+
+    override fun onSeeAllClicked(view: View) {
+        uiEventLogger.log(BluetoothTileDialogUiEvent.SEE_ALL_CLICKED)
+        startSettingsActivity(Intent(ACTION_PREVIOUSLY_CONNECTED_DEVICE), view)
+    }
+
+    override fun onPairNewDeviceClicked(view: View) {
+        uiEventLogger.log(BluetoothTileDialogUiEvent.PAIR_NEW_DEVICE_CLICKED)
+        startSettingsActivity(Intent(ACTION_PAIR_NEW_DEVICE), view)
+    }
+
+    private fun dismissDialog() {
+        job?.cancel()
+        job = null
+        dialog?.dismiss()
+        dialog = null
+    }
+
+    private fun startSettingsActivity(intent: Intent, view: View) {
+        dialog?.run {
+            intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
+            activityStarter.postStartActivityDismissingKeyguard(
+                intent,
+                0,
+                dialogLaunchAnimator.createActivityLaunchController(view)
+            )
+        }
+    }
+}
+
+internal interface BluetoothTileDialogCallback {
+    fun onDeviceItemGearClicked(deviceItem: DeviceItem, view: View)
+    fun onSeeAllClicked(view: View)
+    fun onPairNewDeviceClicked(view: View)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItem.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItem.kt
new file mode 100644
index 0000000..03ae5e8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItem.kt
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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.qs.tiles.dialog.bluetooth
+
+import android.graphics.drawable.Drawable
+import com.android.settingslib.bluetooth.CachedBluetoothDevice
+import com.android.systemui.qs.tiles.dialog.bluetooth.BluetoothTileDialog.Companion.ENABLED_ALPHA
+
+enum class DeviceItemType {
+    AVAILABLE_MEDIA_BLUETOOTH_DEVICE,
+    CONNECTED_BLUETOOTH_DEVICE,
+    SAVED_BLUETOOTH_DEVICE,
+}
+
+data class DeviceItem(
+    val type: DeviceItemType,
+    val cachedBluetoothDevice: CachedBluetoothDevice,
+    val deviceName: String = "",
+    val connectionSummary: String = "",
+    val iconWithDescription: Pair<Drawable, String>? = null,
+    val background: Drawable? = null,
+    var isEnabled: Boolean = true,
+    var alpha: Float = ENABLED_ALPHA
+)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemFactory.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemFactory.kt
new file mode 100644
index 0000000..a16a9f1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemFactory.kt
@@ -0,0 +1,121 @@
+/*
+ * 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.qs.tiles.dialog.bluetooth
+
+import android.bluetooth.BluetoothDevice
+import android.content.Context
+import android.media.AudioManager
+import com.android.settingslib.bluetooth.BluetoothUtils
+import com.android.settingslib.bluetooth.CachedBluetoothDevice
+import com.android.systemui.res.R
+
+private val backgroundOn = R.drawable.settingslib_switch_bar_bg_on
+private val connected = R.string.quick_settings_bluetooth_device_connected
+private val saved = R.string.quick_settings_bluetooth_device_saved
+
+/** Factories to create different types of Bluetooth device items from CachedBluetoothDevice. */
+internal abstract class DeviceItemFactory {
+    abstract fun isFilterMatched(
+        cachedDevice: CachedBluetoothDevice,
+        audioManager: AudioManager?
+    ): Boolean
+
+    abstract fun create(context: Context, cachedDevice: CachedBluetoothDevice): DeviceItem
+}
+
+internal class AvailableMediaDeviceItemFactory : DeviceItemFactory() {
+    override fun isFilterMatched(
+        cachedDevice: CachedBluetoothDevice,
+        audioManager: AudioManager?
+    ): Boolean {
+        return BluetoothUtils.isAvailableMediaBluetoothDevice(cachedDevice, audioManager)
+    }
+
+    // TODO(b/298124674): move create() to the abstract class to reduce duplicate code
+    override fun create(context: Context, cachedDevice: CachedBluetoothDevice): DeviceItem {
+        return DeviceItem(
+            type = DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE,
+            cachedBluetoothDevice = cachedDevice,
+            deviceName = cachedDevice.name,
+            connectionSummary = cachedDevice.connectionSummary.takeUnless { it.isNullOrEmpty() }
+                    ?: context.getString(connected),
+            iconWithDescription =
+                BluetoothUtils.getBtClassDrawableWithDescription(context, cachedDevice).let { p ->
+                    Pair(p.first, p.second)
+                },
+            background = context.getDrawable(backgroundOn),
+            isEnabled = !cachedDevice.isBusy,
+            alpha =
+                if (cachedDevice.isBusy) BluetoothTileDialog.DISABLED_ALPHA
+                else BluetoothTileDialog.ENABLED_ALPHA,
+        )
+    }
+}
+
+internal class ConnectedDeviceItemFactory : DeviceItemFactory() {
+    override fun isFilterMatched(
+        cachedDevice: CachedBluetoothDevice,
+        audioManager: AudioManager?
+    ): Boolean {
+        return BluetoothUtils.isConnectedBluetoothDevice(cachedDevice, audioManager)
+    }
+
+    override fun create(context: Context, cachedDevice: CachedBluetoothDevice): DeviceItem {
+        return DeviceItem(
+            type = DeviceItemType.CONNECTED_BLUETOOTH_DEVICE,
+            cachedBluetoothDevice = cachedDevice,
+            deviceName = cachedDevice.name,
+            connectionSummary = cachedDevice.connectionSummary.takeUnless { it.isNullOrEmpty() }
+                    ?: context.getString(connected),
+            iconWithDescription =
+                BluetoothUtils.getBtClassDrawableWithDescription(context, cachedDevice).let { p ->
+                    Pair(p.first, p.second)
+                },
+            isEnabled = !cachedDevice.isBusy,
+            alpha =
+                if (cachedDevice.isBusy) BluetoothTileDialog.DISABLED_ALPHA
+                else BluetoothTileDialog.ENABLED_ALPHA,
+        )
+    }
+}
+
+internal class SavedDeviceItemFactory : DeviceItemFactory() {
+    override fun isFilterMatched(
+        cachedDevice: CachedBluetoothDevice,
+        audioManager: AudioManager?
+    ): Boolean {
+        return cachedDevice.bondState == BluetoothDevice.BOND_BONDED && !cachedDevice.isConnected
+    }
+
+    override fun create(context: Context, cachedDevice: CachedBluetoothDevice): DeviceItem {
+        return DeviceItem(
+            type = DeviceItemType.SAVED_BLUETOOTH_DEVICE,
+            cachedBluetoothDevice = cachedDevice,
+            deviceName = cachedDevice.name,
+            connectionSummary = cachedDevice.connectionSummary.takeUnless { it.isNullOrEmpty() }
+                    ?: context.getString(saved),
+            iconWithDescription =
+                BluetoothUtils.getBtClassDrawableWithDescription(context, cachedDevice).let { p ->
+                    Pair(p.first, p.second)
+                },
+            isEnabled = !cachedDevice.isBusy,
+            alpha =
+                if (cachedDevice.isBusy) BluetoothTileDialog.DISABLED_ALPHA
+                else BluetoothTileDialog.ENABLED_ALPHA,
+        )
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractor.kt
new file mode 100644
index 0000000..fcd0ce6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractor.kt
@@ -0,0 +1,181 @@
+/*
+ * 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.qs.tiles.dialog.bluetooth
+
+import android.bluetooth.BluetoothAdapter
+import android.bluetooth.BluetoothDevice
+import android.content.Context
+import android.media.AudioManager
+import com.android.internal.logging.UiEventLogger
+import com.android.settingslib.bluetooth.BluetoothCallback
+import com.android.settingslib.bluetooth.BluetoothUtils
+import com.android.settingslib.bluetooth.CachedBluetoothDevice
+import com.android.settingslib.bluetooth.LocalBluetoothManager
+import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
+import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharedFlow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.shareIn
+import kotlinx.coroutines.withContext
+
+/** Holds business logic for the Bluetooth Dialog after clicking on the Bluetooth QS tile. */
+@SysUISingleton
+internal class DeviceItemInteractor
+@Inject
+constructor(
+    private val bluetoothTileDialogRepository: BluetoothTileDialogRepository,
+    private val audioManager: AudioManager,
+    private val bluetoothAdapter: BluetoothAdapter? = BluetoothAdapter.getDefaultAdapter(),
+    private val localBluetoothManager: LocalBluetoothManager?,
+    private val uiEventLogger: UiEventLogger,
+    @Application private val coroutineScope: CoroutineScope,
+    @Background private val backgroundDispatcher: CoroutineDispatcher,
+) {
+
+    private val mutableDeviceItemFlow: MutableStateFlow<List<DeviceItem>?> = MutableStateFlow(null)
+    internal val deviceItemFlow
+        get() = mutableDeviceItemFlow.asStateFlow()
+
+    internal val updateDeviceItemsFlow: SharedFlow<Unit> =
+        conflatedCallbackFlow {
+                val listener =
+                    object : BluetoothCallback {
+                        override fun onActiveDeviceChanged(
+                            activeDevice: CachedBluetoothDevice?,
+                            bluetoothProfile: Int
+                        ) {
+                            super.onActiveDeviceChanged(activeDevice, bluetoothProfile)
+                            trySendWithFailureLogging(Unit, TAG, "onActiveDeviceChanged")
+                        }
+
+                        override fun onConnectionStateChanged(
+                            cachedDevice: CachedBluetoothDevice?,
+                            state: Int
+                        ) {
+                            super.onConnectionStateChanged(cachedDevice, state)
+                            trySendWithFailureLogging(Unit, TAG, "onConnectionStateChanged")
+                        }
+
+                        override fun onDeviceAdded(cachedDevice: CachedBluetoothDevice) {
+                            super.onDeviceAdded(cachedDevice)
+                            trySendWithFailureLogging(Unit, TAG, "onDeviceAdded")
+                        }
+
+                        override fun onProfileConnectionStateChanged(
+                            cachedDevice: CachedBluetoothDevice,
+                            state: Int,
+                            bluetoothProfile: Int
+                        ) {
+                            super.onProfileConnectionStateChanged(
+                                cachedDevice,
+                                state,
+                                bluetoothProfile
+                            )
+                            trySendWithFailureLogging(Unit, TAG, "onProfileConnectionStateChanged")
+                        }
+                    }
+                localBluetoothManager?.eventManager?.registerCallback(listener)
+                awaitClose { localBluetoothManager?.eventManager?.unregisterCallback(listener) }
+            }
+            .shareIn(coroutineScope, SharingStarted.WhileSubscribed(replayExpirationMillis = 0))
+
+    private var deviceItemFactoryList: List<DeviceItemFactory> =
+        listOf(
+            AvailableMediaDeviceItemFactory(),
+            ConnectedDeviceItemFactory(),
+            SavedDeviceItemFactory()
+        )
+
+    private var displayPriority: List<DeviceItemType> =
+        listOf(
+            DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE,
+            DeviceItemType.CONNECTED_BLUETOOTH_DEVICE,
+            DeviceItemType.SAVED_BLUETOOTH_DEVICE,
+        )
+
+    internal suspend fun updateDeviceItems(context: Context) {
+        withContext(backgroundDispatcher) {
+            val mostRecentlyConnectedDevices = bluetoothAdapter?.mostRecentlyConnectedDevices
+
+            mutableDeviceItemFlow.value =
+                bluetoothTileDialogRepository.cachedDevices
+                    .mapNotNull { cachedDevice ->
+                        deviceItemFactoryList
+                            .firstOrNull { it.isFilterMatched(cachedDevice, audioManager) }
+                            ?.create(context, cachedDevice)
+                    }
+                    .sort(displayPriority, mostRecentlyConnectedDevices)
+        }
+    }
+
+    private fun List<DeviceItem>.sort(
+        displayPriority: List<DeviceItemType>,
+        mostRecentlyConnectedDevices: List<BluetoothDevice>?
+    ): List<DeviceItem> {
+        return this.sortedWith(
+            compareBy<DeviceItem> { displayPriority.indexOf(it.type) }
+                .thenBy {
+                    mostRecentlyConnectedDevices?.indexOf(it.cachedBluetoothDevice.device) ?: 0
+                }
+        )
+    }
+
+    internal fun updateDeviceItemOnClick(deviceItem: DeviceItem): Boolean {
+        var isClicked = false
+        when (deviceItem.type) {
+            DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE -> {
+                if (!BluetoothUtils.isActiveMediaDevice(deviceItem.cachedBluetoothDevice)) {
+                    deviceItem.cachedBluetoothDevice.setActive()
+                    uiEventLogger.log(BluetoothTileDialogUiEvent.CONNECTED_DEVICE_SET_ACTIVE)
+                    isClicked = true
+                }
+            }
+            DeviceItemType.CONNECTED_BLUETOOTH_DEVICE -> {}
+            DeviceItemType.SAVED_BLUETOOTH_DEVICE -> {
+                deviceItem.cachedBluetoothDevice.connect()
+                uiEventLogger.log(BluetoothTileDialogUiEvent.SAVED_DEVICE_CONNECT)
+                isClicked = true
+            }
+        }
+        if (isClicked) {
+            deviceItem.isEnabled = false
+            deviceItem.alpha = BluetoothTileDialog.DISABLED_ALPHA
+        }
+        return isClicked
+    }
+
+    internal fun setDeviceItemFactoryListForTesting(list: List<DeviceItemFactory>) {
+        deviceItemFactoryList = list
+    }
+
+    internal fun setDisplayPriorityForTesting(list: List<DeviceItemType>) {
+        displayPriority = list
+    }
+
+    companion object {
+        private const val TAG = "DeviceItemInteractor"
+    }
+}
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 4c9c99c..acd7510 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 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 6912114..4b21e44 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 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 f57bfad..77a4b9f7 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 @@
 
 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 3577c00..3e574e7 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 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/shared/flag/SceneContainerFlags.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt
index 291d273..f0650d3 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 @@
                 Flags.MIGRATE_LOCK_ICON,
                 Flags.MIGRATE_NSSL,
                 Flags.MIGRATE_KEYGUARD_STATUS_VIEW,
+                Flags.NOTIFICATION_SHELF_REFACTOR,
+                Flags.MIGRATE_KEYGUARD_STATUS_BAR_VIEW,
             )
     }
 
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 3e76607..3fb886d 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.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 ef688a8..7cff7ff 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.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 8dd25bc..64006fe 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.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 8cbc4aab..47e28d8 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 @@
 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 2c4555a..7cdb655 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 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 91e3b60..f0ce8a4 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 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 56d732e..b5b7043 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.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 9962c91..eb58b2f 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.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 ab2a8d9..8e9769ab 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.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 6f2256e..2f411ea 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.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 bdbc470..b55bba9 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 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 bf536a4..9325e18 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 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 7873732..0c543cd 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 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 b4ffabd..5cbea90 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.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 9e8ea3a..0588fe2 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.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 cfd9a49..31086d8 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 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 87f6e44..f08eb14 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.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 253f07d..be39d2e 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.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 35f2a39..4344fd1 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.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 522f729..070fb1e 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.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 03e1e15..31c9284 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 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 32df5121b..0be2265 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 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 798c490..c801ca5 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.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 2f96f6c..aa23d6b 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 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 dce8c81..06c0b8b 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 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 6e5cef4..a31b301 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.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 71c5fad..9d1278f 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.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 38b1f14..6783afa 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 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 d0d37c4..b715237 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;
@@ -28,14 +30,21 @@
 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.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 @@
     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 @@
     BrightnessSliderController(
             BrightnessSliderView brightnessSliderView,
             FalsingManager falsingManager,
-            UiEventLogger uiEventLogger) {
+            UiEventLogger uiEventLogger,
+            BrightnessSliderHapticPlugin brightnessSliderHapticPlugin) {
         super(brightnessSliderView);
         mFalsingManager = falsingManager;
         mUiEventLogger = uiEventLogger;
+        mBrightnessSliderHapticPlugin = brightnessSliderHapticPlugin;
     }
 
     /**
@@ -93,6 +113,7 @@
     protected void onViewAttached() {
         mView.setOnSeekBarChangeListener(mSeekListener);
         mView.setOnInterceptListener(mOnInterceptListener);
+        mBrightnessSliderHapticPlugin.start();
     }
 
     @Override
@@ -100,6 +121,7 @@
         mView.setOnSeekBarChangeListener(null);
         mView.setOnDispatchTouchEventListener(null);
         mView.setOnInterceptListener(null);
+        mBrightnessSliderHapticPlugin.stop();
     }
 
     @Override
@@ -204,6 +226,11 @@
         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 @@
             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 @@
             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 @@
 
         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 @@
             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 0000000..f775114
--- /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 0000000..32561f0
--- /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/src/com/android/systemui/settings/brightness/BrightnessSliderView.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java
index 38cb441..c885492 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 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 a9b3d0a..b2e4736 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 @@
 
 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 5850a84..14659e7 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 @@
 
 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 92ccdb5..d5934e6 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.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 2dbcbc9..c803e6f 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 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 96fae14..6cf4ff5 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.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 3873ac4..cc46b23 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.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 292cf8e..af44c4e 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.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 3eec7fa0e..1fcb70c 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 @@
 
 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 d653cb4..e8be40e 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.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 19a4ee8..25bd8e7 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 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 3f7512a..38b358f 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.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 8612cdf..6ca0ad4 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 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 68561d1..e84fb48 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.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 98d8a53..3349345 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 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 c6c664d..51276c6 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.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 ba92c45..f54d0e7 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.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 5209767..2281ea0 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.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 a0cbdf3..6bbd4a5 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.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 2f385d0..b1acc64 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.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 76636ab8..4c0f6f0 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.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 c1ebf12..d24f9d8 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 @@
 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 24c66eb..33c42e0 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 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 4d933d9..0715dfc 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 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 a7ec02f..95768e5 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.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 5377dee..3e854a4 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.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 ec66e99..68c48b9 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.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 ae3d41e..61eaff9 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.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 1a32d70..1198d1b 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.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 feb0258..2f1b589 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -84,7 +84,6 @@
 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.biometrics.AuthController;
 import com.android.systemui.biometrics.FaceHelpMessageDeferral;
 import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
@@ -103,6 +102,7 @@
 import com.android.systemui.log.core.LogLevel;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.res.R;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
@@ -309,7 +309,7 @@
         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 @@
                             .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;
@@ -1256,8 +1256,6 @@
             if (biometricSourceType == FACE) {
                 mFaceAcquiredMessageDeferral.reset();
             }
-            mBouncerMessageInteractor.setFaceAcquisitionMessage(null);
-            mBouncerMessageInteractor.setFingerprintAcquisitionMessage(null);
         }
 
         @Override
@@ -1278,8 +1276,6 @@
             } else if (biometricSourceType == FINGERPRINT) {
                 onFingerprintAuthError(msgId, errString);
             }
-            mBouncerMessageInteractor.setFaceAcquisitionMessage(null);
-            mBouncerMessageInteractor.setFingerprintAcquisitionMessage(null);
         }
 
         private void onFaceAuthError(int msgId, String errString) {
@@ -1351,8 +1347,6 @@
                     showActionToUnlock();
                 }
             }
-            mBouncerMessageInteractor.setFaceAcquisitionMessage(null);
-            mBouncerMessageInteractor.setFingerprintAcquisitionMessage(null);
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt
index 238317c..62c9980 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 @@
 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 5f3d757..4d0552e 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.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 af4a1aa..77a0960 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 @@
 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 29ca0f4..143e620 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 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 8089fd9..befc64d 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 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 c760227..09ad55e 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 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 2c0741e..3640ae0 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 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 006b219..2b7e9c5 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.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 f1e51e2..603e863 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 @@
 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 3d574ca..e47c914 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.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 fbbee53..8baab25 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.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 99297b2..e632214 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.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/TEST_MAPPING b/packages/SystemUI/src/com/android/systemui/statusbar/TEST_MAPPING
index 8849d6e..10e7573 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/TEST_MAPPING
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/TEST_MAPPING
@@ -13,7 +13,7 @@
           "exclude-annotation": "org.junit.Ignore"
         },
         {
-          "exclude-annotation": "android.platform.test.annotations.LargeTest"
+          "exclude-annotation": "androidx.test.filters.LargeTest"
         },
         {
           "exclude-annotation": "androidx.test.filters.LargeTest"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/VibratorHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/VibratorHelper.java
index 645595c..d089252 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/VibratorHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/VibratorHelper.java
@@ -118,6 +118,16 @@
     }
 
     /**
+     * @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()
      */
     public boolean hasVibrator() {
@@ -154,6 +164,17 @@
     }
 
     /**
+     * @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/src/com/android/systemui/statusbar/ViewTransformationHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/ViewTransformationHelper.java
index 67ab060..092e5b4 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.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 196aad9..9734e26 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 c523d22..d6df987 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.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 f381b37..9db61c6 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.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 f84b96c..08defcc 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.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 80274bd..4056e7b 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 d1e0a71..5af7cfc 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.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 1ad4620..dccc23f 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.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 2403920..7d866df 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.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 d667b91..0190d5c 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 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 fcff437..8cefc56d 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.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 420dd3f..24088d2 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 @@
         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 0c1891e1..f3067c1 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.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 b09b9f4..2ffbe4b 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.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 11582d7..ad9e312 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 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 2ee2153..1f4f04c 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.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 a045698..167efc7 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.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 43e45b1..552bfb2 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.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 fb71210..eb1be67 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.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 8029f48..328a741 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 @@
 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 90eb630..aa7a63e 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.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 1b43922..af4df32 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.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 93a34af..94cc7e9 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 82c7aae..6b70a08 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 8de0381..70fabc0 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 @@
 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 49990d9..c2b6f32 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.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 75801a8..ca43591 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 @@
 
 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 5664a2a..8ee0de6 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 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 98e167f..84678aa 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.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 26dfe3e..a54687c 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.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 cb21291..c61258b 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.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/BigPictureIconManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BigPictureIconManager.kt
index 88dbb4c..a5b32b8 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 @@
             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 ->
@@ -119,12 +120,6 @@
             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()
@@ -144,7 +139,7 @@
     private fun loadImageOrPlaceHolderSync(icon: Icon?): Drawable? {
         icon ?: return null
 
-        if (viewShown) {
+        if (viewShown || skipLazyLoading(icon)) {
             return loadImageSync(icon)
         }
 
@@ -228,6 +223,19 @@
             }
         )
 
+    /**
+     * 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()}")
@@ -242,15 +250,6 @@
         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/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt
index 0de3246..4114eb2 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.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 9c4aa07..2cfd075 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.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 acece33..fb8024c 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.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 b950187..77f5717 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 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 c8f13a6..2599231 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.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 c4c116b..5aae488 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 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 3f4fd50..42c80ed 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 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 0989df6..26db5f2 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 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 99a24cb..43d99a0 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.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 3e10f2a..ddd9bdd 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.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 ce6dd89..892a635 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 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 1fd4d12..b95e053 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.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 f805183..f186e66 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 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 065828b..a27a305 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 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 7134f15..62b268b 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 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 047db20..b86d1d9 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 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 44ead26..1dd3739 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.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 99a7755..d8f31d4 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.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 5a129fc..a317f95 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 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 d5d7f75..3443da1 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.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 ac97e77..06c3b79 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.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 6feffe6..8e974c2 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 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 bb43b95..2d94694 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.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 10753f2..b4411f1 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.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 fdff12d..45c35d8 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.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 87205e2..bd7f766 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 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 4592fde..ba1deed 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.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 199692b..875a409 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 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 38a368e..cb671447 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 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 d73bbeb..33473a6 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.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 a8d8a8e..5d46f52 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.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 626f851..a929e4f 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 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 e8521d1..28f0a0c 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.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;
@@ -569,6 +569,7 @@
     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 @@
         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 @@
         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 @@
         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/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
index 24104d2..30708b7 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.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 baf09c7..722c28c 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.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 90e10a7..f2d5394 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 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 2742a23..4e81d0c 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 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 f4605be..f097d06 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 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 51b6c75..57cea5d 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 e52d604..b4f578f 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.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 45ae4e0..dee3973 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 baeae79..07d3a1c 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.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 5eafa9e..697d297 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.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 4590712..f62a79f 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 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 3b9afa1..023efdd 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.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 c9db153..485ab32 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.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 6b260ff..6f69ea81 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.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 @@
         }
 
         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() {
@@ -3429,6 +3429,7 @@
     @Override
     public void setIsLaunchingActivityOverLockscreen(boolean isLaunchingActivityOverLockscreen) {
         mIsLaunchingActivityOverLockscreen = isLaunchingActivityOverLockscreen;
+        mKeyguardViewMediator.launchingActivityOverLockscreen(mIsLaunchingActivityOverLockscreen);
     }
 
     @Override
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 374543d..de9854a 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.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 ae715b3..7730f7d9 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 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 efc2891..92b0f3f 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.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 a1f12b8..270c40e 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 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 4f0cd80..a5ea142 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.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 5de0d15..25e634a 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.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 924aac4..430b0e9 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.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 fc3c85a..fb5a530 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 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 29a249f..c6690c9 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 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 @@
 
     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 914e0c0..7efa705 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 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 16413d2..fc9ecb3 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.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 d22ed38..4bfce4c 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.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 46a2457..572b7f1 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 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 365fbac..ec7767b 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.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 3770c1d..7cbaf63 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 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 79151fd..54d81b8 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 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 cc38405..ae3f923 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.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 1966033..b53939e 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 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 fc5f915..e1096e2 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.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 40432ee..5b55264 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.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 ad18170..6a24174 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 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 4878d45..ffeb1a8 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 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 53662f4..fb7f9d1 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 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 344e56c..30a445f 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.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 5773612..40bd8d3 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 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 d83664f..7910e6f 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.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 881741a..640ec28 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.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 69510ce..9d627af 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 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 52e0e8a..a033e1d 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 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 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 1b93c16..c6d2eca 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.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 66f0f59..babd435 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.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 b845bad..48a9e0f 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 @@
 ): 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 5903fa3..e73063b 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.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 cd6ccb5..07c23d1 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 @@
 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 230bb58..4b1e7a4 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 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 1259477..387b970 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.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 3709e4c..b0b6b32 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 67b04db..74a849a 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 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 7ec8e12..f0470ca 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.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 f407127..fbd074d 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.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 68d02de..900a920 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 @@
 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 0fe5329..9ea167f 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 @@
 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 7076f34..4227f9e 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 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/model/InternetTileModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/model/InternetTileModel.kt
index 1f076ed..1886590 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.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 @@
     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 @@
             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 @@
         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 @@
         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/view/ModernStatusBarView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarView.kt
index a1b96dd..fe69d81 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.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 b6f1677..a80ea90 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,8 @@
 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
 import com.android.systemui.dagger.qualifiers.Application
@@ -61,16 +62,21 @@
     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 @@
                     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 @@
             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 @@
             ) { 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 @@
             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/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiConstants.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiConstants.kt
index 8bea772..2da76d4 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 @@
 
 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 e593575..a9ac51d 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 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 668c5b3..efa092b 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.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 f23e102..4cd3484 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.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 27e40e0..a078dd5 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.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 6186c43..13f76fe 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.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 f7b601b..b06ebe9 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.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 b7ae233..713283e 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 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 b5bd1d8..74e02d7 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.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 ffb743f..1224275 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.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 d472c35..e59ec04 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.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 feef029..f4a1975 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.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 a4821e0..4b97197 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 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 880e0d2..62e2381 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.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 63dcad9..1c88289 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.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 e1ec94f..012408e 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 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 2d04ffa..bb074ac 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.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 1d9d33d..5ed207cc3 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.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 e00365d..53fed3d 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.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 736b145..a50fd6f 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.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 e71c972..c302d6a 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 03656f0..4a4d4e1 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 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 52a6bca..7ac3e9c 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.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 1776e5b..616992e 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.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 fb6ba85..b46f52c 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 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 9f61574..0d36b48 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.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 ab4a8af..43905c5 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 a593d51..2ed9d15 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 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 cd1dcd5..2f171bb 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.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/policy/dagger/StatusBarPolicyModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java
index 927024f..a77c692 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 @@
         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);
     }
 }
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 f4cc0ed..e4e9554 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.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 874217a..1c7debc 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 c1ac800..fa9256f 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.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 b9c2487..ccd8e48 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.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 f0aae0f..fc414b6 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 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 f24d526..4449f8d0 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.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 7fa90df..e78eba4 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 @@
 
 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 29f16c7..d97cae2 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 @@
         }
 
         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 @@
             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 8187956..8b5fd0b 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 @@
     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 @@
 
         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 919f150..5ae4cdf 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.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 2464886..a43524a 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 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 4dbceac..771a8c8 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.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 87d2063..ec6f862 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.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 7239c8a..32b1b26 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 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 4999515..7635a84 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 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 80f9de6..ce1a2e9 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 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 2475890..20ce230 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 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 0be793e..386b7bb 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 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 11e1f27..5b34052 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.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 ecaf792..14d7281 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.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 989462a..9cc526a 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 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 ccc0a79..8087a87 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 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 71355bb..1c441b3 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 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 3a7ac9c..c1eb5b6 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 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 e06353b..7e9c5e9 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.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 534049b..7ede21a 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.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 941cd77..e7e907a 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 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 2871263..ea871be 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 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 55dec5f..44dee72 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 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 02a7637..080a9dc 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 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 08b0c64..562feb2e 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 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 5ad9630..6df02e8 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.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 ee84580..1fa4872 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.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 8cfa555..f404549 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.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 a3e648d..e489499 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.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 03a7470..93573fa 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.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 1ac86ce..8957fe1 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 @@
 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 59f2cdb..c578702 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.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 e78807e..8fc1b25 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.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 fdf13be..b88f9fb 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 @@
             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 b8ae257..4058215 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.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 aeed5fc..61952ba 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 516efc0..947746c 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 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 8b90547..ef9340a3 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 @@
 
 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 9b241a7..bbfdaa3 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 904a98b..8a6f79d 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 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 e0daa070..760fe6a 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.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 47a2d35..577d18e 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.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 58cffa7..de392d3 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 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 96980b8..7934ab1 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 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 c62c957..bcf34f8 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 @@
 
 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 ae23ca6..ac41a50 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.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 fb5a71c..eb0bf46 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 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 89bc757..d9593bd 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.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 9cc3cdb..ea4d31b 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 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 dcc0525..727d649 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.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 96936e3..6050387 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.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 2371402..d7669d4 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.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 1de5585..2143771 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 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 0b3521b..3451ae0 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.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 de9b5ee..0e6df6b 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.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 e5c55b0..e90d9e2 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.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 2491e2b..750b6f9 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.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 b7c8b49..02a764c 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.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 fc1adc3..7b50a65 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.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 3197976..c33a805 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 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 6fd0a4d..d21ccc9 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 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 cab47a3..f498520 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 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 1c7a9b5..f8ffab0 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 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 f9f14e0..972d3c0 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 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 3c418ed..ec0414e 100644
--- a/packages/SystemUI/tests/Android.bp
+++ b/packages/SystemUI/tests/Android.bp
@@ -20,6 +20,7 @@
 
 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 188dff2..205168e 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 @@
 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 9016220..9ce9bd6 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.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 6c5620d..94c34a5 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 @@
 
     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 c894d91..42f65f6 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.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 00f88bf..8401e67 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 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 3d87196..00a2efe 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.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 @@
         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 65c677e..e54b184 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.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 ee67348..f943acd 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.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 0ef9f45..e090093 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.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 2b90e7c..8322b37 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 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 a9f044c..2f08804 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 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 62906f3..f3a1b68 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 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 929604b..f6649bd 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.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 3e330d65..aad11d9 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.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 19bc818..b02b1f9 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.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 4db5f35..d0bb5a9 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.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 47ff3b9..59cd26c 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.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 77302ce..6654a6c 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.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 210f3cb..86439e5 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.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 bb03f28..3afca59 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.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 1d7c328..47be236 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 @@
         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 @@
                 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 08185af..c674053 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 @@
 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 0e4b3c9..21a2822 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.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 42e12df..835c9ff5 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.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 c04fd39..d431731 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.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 d1573c3..532c59a 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 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 f81ef10..af88df7 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.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 79dc057..8fd2bd6a 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 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 09d0eeb..22ebd99 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.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 39fe6fb..187f098 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.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 91c4748..95e21cf 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.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 afd5f77..403385f 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 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 46c930f..43ebeee 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 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 42b610a..9b81947 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 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 1b0a10e..5764839 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.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 7b99314..83bee93 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.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/animation/ActivityLaunchAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt
index cc00436..59c7e76 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 @@
 
     @Before
     fun setup() {
-        activityLaunchAnimator = ActivityLaunchAnimator(testLaunchAnimator, testLaunchAnimator)
+        activityLaunchAnimator =
+            ActivityLaunchAnimator(testLaunchAnimator, testLaunchAnimator, disableWmTimeout = true)
         activityLaunchAnimator.callback = callback
         activityLaunchAnimator.addListener(listener)
     }
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 dd9683f..957443a 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 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 ec8be8e..323f15a 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 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 f0f4ca7..4ab7ab4 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.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 52bf350..215d635 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 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 969a011..f899e2f 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.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 d0b3833..2bc0171 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 @@
         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/BiometricNotificationServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationServiceTest.java
index b0d0063..3c10678 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 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;
 
@@ -52,6 +55,8 @@
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 
+import java.util.Optional;
+
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
@@ -65,11 +70,20 @@
     KeyguardStateController mKeyguardStateController;
     @Mock
     NotificationManager mNotificationManager;
+    @Mock
+    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;
     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);
@@ -77,39 +91,61 @@
     private KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback;
     private KeyguardStateController.Callback mKeyguardStateControllerCallback;
     private BiometricNotificationService mBiometricNotificationService;
+    private BiometricStateListener mFaceStateListener;
+    private BiometricStateListener mFingerprintStateListener;
 
     @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,
+                        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.onBiometricError(
-                BiometricFingerprintConstants.BIOMETRIC_ERROR_RE_ENROLL,
+        mKeyguardUpdateMonitorCallback.onBiometricHelp(
+                FINGERPRINT_ACQUIRED_RE_ENROLL,
                 "Testing Fingerprint Re-enrollment" /* errString */,
                 BiometricSourceType.FINGERPRINT
         );
@@ -127,7 +163,7 @@
                 .isEqualTo(ACTION_SHOW_FINGERPRINT_REENROLL_DIALOG);
     }
     @Test
-    public void testShowFaceReEnrollNotification() {
+    public void testShowFaceReEnrollNotification_onErrorReEnroll() {
         when(mKeyguardStateController.isShowing()).thenReturn(false);
 
         mKeyguardUpdateMonitorCallback.onBiometricError(
@@ -150,6 +186,54 @@
     }
 
     @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/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
index 17928a3..57cf834 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.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 c735419..21e614f 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 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 b6bc7af..ee3bd0d 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 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;
@@ -1575,6 +1575,53 @@
                 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
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 1885f64..17f435b 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.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 @@
                 context,
                 mKeyguardUpdateMonitor,
                 FakeTrustRepository(),
-                FakeFeatureFlags().apply { set(Flags.DELAY_BOUNCER, true) },
                 testScope.backgroundScope,
             )
         mAlternateBouncerInteractor =
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 6d4588d..ebadfc7 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.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 @@
 
     @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/biometrics/data/repository/DisplayStateRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/DisplayStateRepositoryTest.kt
index c9c46cb..c825d2e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/DisplayStateRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/DisplayStateRepositoryTest.kt
@@ -82,6 +82,11 @@
             rearDisplayDeviceStates
         )
 
+        mContext.orCreateTestableResources.addOverride(
+            com.android.internal.R.bool.config_reverseDefaultRotation,
+            false
+        )
+
         mContext = spy(mContext)
         whenever(mContext.display).thenReturn(display)
 
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 6fa1916..eee0ed4 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.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/factory/BouncerMessageFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/data/factory/BouncerMessageFactoryTest.kt
deleted file mode 100644
index 8eb274a..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/data/factory/BouncerMessageFactoryTest.kt
+++ /dev/null
@@ -1,177 +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.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.bouncer.data.factory
-
-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.keyguard.KeyguardSecurityModel.SecurityMode.Password
-import com.android.keyguard.KeyguardSecurityModel.SecurityMode.Pattern
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_DEFAULT
-import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.bouncer.shared.model.BouncerMessageModel
-import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository
-import com.android.systemui.util.mockito.whenever
-import com.google.common.truth.StringSubject
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.test.TestScope
-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.MockitoAnnotations
-
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class BouncerMessageFactoryTest : SysuiTestCase() {
-    private lateinit var underTest: BouncerMessageFactory
-
-    @Mock private lateinit var biometricSettingsRepository: FakeBiometricSettingsRepository
-
-    @Mock private lateinit var securityModel: KeyguardSecurityModel
-
-    private lateinit var testScope: TestScope
-
-    @Before
-    fun setUp() {
-        MockitoAnnotations.initMocks(this)
-        testScope = TestScope()
-        biometricSettingsRepository = FakeBiometricSettingsRepository()
-        underTest = BouncerMessageFactory(biometricSettingsRepository, securityModel)
-    }
-
-    @Test
-    fun bouncerMessages_choosesTheRightMessage_basedOnSecurityModeAndFpAuthIsAllowed() =
-        testScope.runTest {
-            primaryMessage(PROMPT_REASON_DEFAULT, mode = PIN, fpAuthAllowed = false)
-                .isEqualTo("Enter PIN")
-            primaryMessage(PROMPT_REASON_DEFAULT, mode = PIN, fpAuthAllowed = true)
-                .isEqualTo("Unlock with PIN or fingerprint")
-
-            primaryMessage(PROMPT_REASON_DEFAULT, mode = Password, fpAuthAllowed = false)
-                .isEqualTo("Enter password")
-            primaryMessage(PROMPT_REASON_DEFAULT, mode = Password, fpAuthAllowed = true)
-                .isEqualTo("Unlock with password or fingerprint")
-
-            primaryMessage(PROMPT_REASON_DEFAULT, mode = Pattern, fpAuthAllowed = false)
-                .isEqualTo("Draw pattern")
-            primaryMessage(PROMPT_REASON_DEFAULT, mode = Pattern, fpAuthAllowed = true)
-                .isEqualTo("Unlock with pattern or fingerprint")
-        }
-
-    @Test
-    fun bouncerMessages_overridesSecondaryMessageValue() =
-        testScope.runTest {
-            val bouncerMessageModel =
-                bouncerMessageModel(
-                    PIN,
-                    true,
-                    PROMPT_REASON_DEFAULT,
-                    secondaryMessageOverride = "face acquisition message"
-                )!!
-            assertThat(context.resources.getString(bouncerMessageModel.message!!.messageResId!!))
-                .isEqualTo("Unlock with PIN or fingerprint")
-            assertThat(bouncerMessageModel.secondaryMessage!!.message!!)
-                .isEqualTo("face acquisition message")
-        }
-
-    @Test
-    fun bouncerMessages_setsPrimaryAndSecondaryMessage_basedOnSecurityModeAndFpAuthIsAllowed() =
-        testScope.runTest {
-            primaryMessage(
-                    PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT,
-                    mode = PIN,
-                    fpAuthAllowed = true
-                )
-                .isEqualTo("Wrong PIN. Try again.")
-            secondaryMessage(
-                    PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT,
-                    mode = PIN,
-                    fpAuthAllowed = true
-                )
-                .isEqualTo("Or unlock with fingerprint")
-
-            primaryMessage(
-                    PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT,
-                    mode = Password,
-                    fpAuthAllowed = true
-                )
-                .isEqualTo("Wrong password. Try again.")
-            secondaryMessage(
-                    PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT,
-                    mode = Password,
-                    fpAuthAllowed = true
-                )
-                .isEqualTo("Or unlock with fingerprint")
-
-            primaryMessage(
-                    PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT,
-                    mode = Pattern,
-                    fpAuthAllowed = true
-                )
-                .isEqualTo("Wrong pattern. Try again.")
-            secondaryMessage(
-                    PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT,
-                    mode = Pattern,
-                    fpAuthAllowed = true
-                )
-                .isEqualTo("Or unlock with fingerprint")
-        }
-
-    private fun primaryMessage(
-        reason: Int,
-        mode: KeyguardSecurityModel.SecurityMode,
-        fpAuthAllowed: Boolean
-    ): StringSubject {
-        return assertThat(
-            context.resources.getString(
-                bouncerMessageModel(mode, fpAuthAllowed, reason)!!.message!!.messageResId!!
-            )
-        )!!
-    }
-
-    private fun secondaryMessage(
-        reason: Int,
-        mode: KeyguardSecurityModel.SecurityMode,
-        fpAuthAllowed: Boolean
-    ): StringSubject {
-        return assertThat(
-            context.resources.getString(
-                bouncerMessageModel(mode, fpAuthAllowed, reason)!!.secondaryMessage!!.messageResId!!
-            )
-        )!!
-    }
-
-    private fun bouncerMessageModel(
-        mode: KeyguardSecurityModel.SecurityMode,
-        fpAuthAllowed: Boolean,
-        reason: Int,
-        secondaryMessageOverride: String? = null,
-    ): BouncerMessageModel? {
-        whenever(securityModel.getSecurityMode(0)).thenReturn(mode)
-        biometricSettingsRepository.setIsFingerprintAuthCurrentlyAllowed(fpAuthAllowed)
-
-        return underTest.createFromPromptReason(
-            reason,
-            0,
-            secondaryMsgOverride = secondaryMessageOverride
-        )
-    }
-}
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
deleted file mode 100644
index 562a8ef..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/data/repo/BouncerMessageRepositoryTest.kt
+++ /dev/null
@@ -1,380 +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.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.bouncer.data.repo
-
-import android.content.pm.UserInfo
-import android.hardware.biometrics.BiometricSourceType
-import android.testing.TestableLooper
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED
-import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST
-import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED
-import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT
-import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW
-import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT
-import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT
-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.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE
-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.SysuiTestCase
-import com.android.systemui.bouncer.data.factory.BouncerMessageFactory
-import com.android.systemui.bouncer.data.repository.BouncerMessageRepository
-import com.android.systemui.bouncer.data.repository.BouncerMessageRepositoryImpl
-import com.android.systemui.bouncer.shared.model.BouncerMessageModel
-import com.android.systemui.bouncer.shared.model.Message
-import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.flags.SystemPropertiesHelper
-import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository
-import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository
-import com.android.systemui.keyguard.data.repository.FakeTrustRepository
-import com.android.systemui.keyguard.shared.model.AuthenticationFlags
-import com.android.systemui.user.data.repository.FakeUserRepository
-import com.android.systemui.util.mockito.whenever
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.runCurrent
-import kotlinx.coroutines.test.runTest
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.ArgumentCaptor
-import org.mockito.Captor
-import org.mockito.Mock
-import org.mockito.Mockito.verify
-import org.mockito.MockitoAnnotations
-
-@OptIn(ExperimentalCoroutinesApi::class)
-@SmallTest
-@TestableLooper.RunWithLooper(setAsMainLooper = true)
-@RunWith(AndroidJUnit4::class)
-class BouncerMessageRepositoryTest : SysuiTestCase() {
-
-    @Mock private lateinit var updateMonitor: KeyguardUpdateMonitor
-    @Mock private lateinit var securityModel: KeyguardSecurityModel
-    @Mock private lateinit var systemPropertiesHelper: SystemPropertiesHelper
-    @Captor
-    private lateinit var updateMonitorCallback: ArgumentCaptor<KeyguardUpdateMonitorCallback>
-
-    private lateinit var underTest: BouncerMessageRepository
-    private lateinit var trustRepository: FakeTrustRepository
-    private lateinit var biometricSettingsRepository: FakeBiometricSettingsRepository
-    private lateinit var userRepository: FakeUserRepository
-    private lateinit var fingerprintRepository: FakeDeviceEntryFingerprintAuthRepository
-    private lateinit var testScope: TestScope
-
-    @Before
-    fun setUp() {
-        MockitoAnnotations.initMocks(this)
-        trustRepository = FakeTrustRepository()
-        biometricSettingsRepository = FakeBiometricSettingsRepository()
-        userRepository = FakeUserRepository()
-        userRepository.setUserInfos(listOf(PRIMARY_USER))
-        fingerprintRepository = FakeDeviceEntryFingerprintAuthRepository()
-        testScope = TestScope()
-
-        biometricSettingsRepository.setIsFingerprintAuthCurrentlyAllowed(false)
-        whenever(securityModel.getSecurityMode(PRIMARY_USER_ID)).thenReturn(PIN)
-        underTest =
-            BouncerMessageRepositoryImpl(
-                trustRepository = trustRepository,
-                biometricSettingsRepository = biometricSettingsRepository,
-                updateMonitor = updateMonitor,
-                bouncerMessageFactory =
-                    BouncerMessageFactory(biometricSettingsRepository, securityModel),
-                userRepository = userRepository,
-                fingerprintAuthRepository = fingerprintRepository,
-                systemPropertiesHelper = systemPropertiesHelper
-            )
-    }
-
-    @Test
-    fun setCustomMessage_propagatesState() =
-        testScope.runTest {
-            underTest.setCustomMessage(message("not empty"))
-
-            val customMessage = collectLastValue(underTest.customMessage)
-
-            assertThat(customMessage()).isEqualTo(message("not empty"))
-        }
-
-    @Test
-    fun setFaceMessage_propagatesState() =
-        testScope.runTest {
-            underTest.setFaceAcquisitionMessage(message("not empty"))
-
-            val faceAcquisitionMessage = collectLastValue(underTest.faceAcquisitionMessage)
-
-            assertThat(faceAcquisitionMessage()).isEqualTo(message("not empty"))
-        }
-
-    @Test
-    fun setFpMessage_propagatesState() =
-        testScope.runTest {
-            underTest.setFingerprintAcquisitionMessage(message("not empty"))
-
-            val fpAcquisitionMsg = collectLastValue(underTest.fingerprintAcquisitionMessage)
-
-            assertThat(fpAcquisitionMsg()).isEqualTo(message("not empty"))
-        }
-
-    @Test
-    fun setPrimaryAuthMessage_propagatesState() =
-        testScope.runTest {
-            underTest.setPrimaryAuthMessage(message("not empty"))
-
-            val primaryAuthMessage = collectLastValue(underTest.primaryAuthMessage)
-
-            assertThat(primaryAuthMessage()).isEqualTo(message("not empty"))
-        }
-
-    @Test
-    fun biometricAuthMessage_propagatesBiometricAuthMessages() =
-        testScope.runTest {
-            userRepository.setSelectedUserInfo(PRIMARY_USER)
-            val biometricAuthMessage = collectLastValue(underTest.biometricAuthMessage)
-            runCurrent()
-
-            verify(updateMonitor).registerCallback(updateMonitorCallback.capture())
-
-            updateMonitorCallback.value.onBiometricAuthFailed(BiometricSourceType.FINGERPRINT)
-
-            assertThat(biometricAuthMessage())
-                .isEqualTo(message(R.string.kg_fp_not_recognized, R.string.kg_bio_try_again_or_pin))
-
-            updateMonitorCallback.value.onBiometricAuthFailed(BiometricSourceType.FACE)
-
-            assertThat(biometricAuthMessage())
-                .isEqualTo(
-                    message(R.string.bouncer_face_not_recognized, R.string.kg_bio_try_again_or_pin)
-                )
-
-            updateMonitorCallback.value.onBiometricAcquired(BiometricSourceType.FACE, 0)
-
-            assertThat(biometricAuthMessage()).isNull()
-        }
-
-    @Test
-    fun onFaceLockout_propagatesState() =
-        testScope.runTest {
-            userRepository.setSelectedUserInfo(PRIMARY_USER)
-            val lockoutMessage = collectLastValue(underTest.biometricLockedOutMessage)
-            runCurrent()
-            verify(updateMonitor).registerCallback(updateMonitorCallback.capture())
-
-            whenever(updateMonitor.isFaceLockedOut).thenReturn(true)
-            updateMonitorCallback.value.onLockedOutStateChanged(BiometricSourceType.FACE)
-
-            assertThat(lockoutMessage())
-                .isEqualTo(message(keyguard_enter_pin, R.string.kg_face_locked_out))
-
-            whenever(updateMonitor.isFaceLockedOut).thenReturn(false)
-            updateMonitorCallback.value.onLockedOutStateChanged(BiometricSourceType.FACE)
-            assertThat(lockoutMessage()).isNull()
-        }
-
-    @Test
-    fun onFingerprintLockout_propagatesState() =
-        testScope.runTest {
-            userRepository.setSelectedUserInfo(PRIMARY_USER)
-            val lockedOutMessage = collectLastValue(underTest.biometricLockedOutMessage)
-            runCurrent()
-
-            fingerprintRepository.setLockedOut(true)
-
-            assertThat(lockedOutMessage())
-                .isEqualTo(message(keyguard_enter_pin, R.string.kg_fp_locked_out))
-
-            fingerprintRepository.setLockedOut(false)
-            assertThat(lockedOutMessage()).isNull()
-        }
-
-    @Test
-    fun onRestartForMainlineUpdate_shouldProvideRelevantMessage() =
-        testScope.runTest {
-            whenever(systemPropertiesHelper.get("sys.boot.reason.last"))
-                .thenReturn("reboot,mainline_update")
-            userRepository.setSelectedUserInfo(PRIMARY_USER)
-            biometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(true)
-
-            verifyMessagesForAuthFlag(
-                STRONG_AUTH_REQUIRED_AFTER_BOOT to
-                    Pair(keyguard_enter_pin, R.string.kg_prompt_after_update_pin),
-            )
-        }
-
-    @Test
-    fun onAuthFlagsChanged_withTrustNotManagedAndNoBiometrics_isANoop() =
-        testScope.runTest {
-            userRepository.setSelectedUserInfo(PRIMARY_USER)
-            trustRepository.setCurrentUserTrustManaged(false)
-            biometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(false)
-            biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
-
-            verifyMessagesForAuthFlag(
-                STRONG_AUTH_NOT_REQUIRED to null,
-                STRONG_AUTH_REQUIRED_AFTER_BOOT to null,
-                SOME_AUTH_REQUIRED_AFTER_USER_REQUEST to null,
-                STRONG_AUTH_REQUIRED_AFTER_LOCKOUT to null,
-                STRONG_AUTH_REQUIRED_AFTER_TIMEOUT to null,
-                STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN to null,
-                STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT to null,
-                SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED to null,
-                STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE to null,
-                STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW to
-                    Pair(keyguard_enter_pin, kg_prompt_after_dpm_lock),
-            )
-        }
-
-    @Test
-    fun authFlagsChanges_withTrustManaged_providesDifferentMessages() =
-        testScope.runTest {
-            userRepository.setSelectedUserInfo(PRIMARY_USER)
-            biometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(false)
-            biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
-
-            trustRepository.setCurrentUserTrustManaged(true)
-
-            verifyMessagesForAuthFlag(
-                STRONG_AUTH_NOT_REQUIRED to null,
-                STRONG_AUTH_REQUIRED_AFTER_LOCKOUT to null,
-                STRONG_AUTH_REQUIRED_AFTER_BOOT to
-                    Pair(keyguard_enter_pin, kg_prompt_reason_restart_pin),
-                STRONG_AUTH_REQUIRED_AFTER_TIMEOUT to
-                    Pair(keyguard_enter_pin, kg_prompt_pin_auth_timeout),
-                STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW to
-                    Pair(keyguard_enter_pin, kg_prompt_after_dpm_lock),
-                SOME_AUTH_REQUIRED_AFTER_USER_REQUEST to
-                    Pair(keyguard_enter_pin, kg_trust_agent_disabled),
-                SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED to
-                    Pair(keyguard_enter_pin, kg_trust_agent_disabled),
-                STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN to
-                    Pair(keyguard_enter_pin, kg_prompt_after_user_lockdown_pin),
-                STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE to
-                    Pair(keyguard_enter_pin, kg_prompt_unattended_update),
-                STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT to
-                    Pair(keyguard_enter_pin, kg_prompt_auth_timeout),
-            )
-        }
-
-    @Test
-    fun authFlagsChanges_withFaceEnrolled_providesDifferentMessages() =
-        testScope.runTest {
-            userRepository.setSelectedUserInfo(PRIMARY_USER)
-            trustRepository.setCurrentUserTrustManaged(false)
-            biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
-
-            biometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(true)
-
-            verifyMessagesForAuthFlag(
-                STRONG_AUTH_NOT_REQUIRED to null,
-                STRONG_AUTH_REQUIRED_AFTER_LOCKOUT to null,
-                SOME_AUTH_REQUIRED_AFTER_USER_REQUEST to null,
-                SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED to null,
-                STRONG_AUTH_REQUIRED_AFTER_BOOT to
-                    Pair(keyguard_enter_pin, kg_prompt_reason_restart_pin),
-                STRONG_AUTH_REQUIRED_AFTER_TIMEOUT to
-                    Pair(keyguard_enter_pin, kg_prompt_pin_auth_timeout),
-                STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW to
-                    Pair(keyguard_enter_pin, kg_prompt_after_dpm_lock),
-                STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN to
-                    Pair(keyguard_enter_pin, kg_prompt_after_user_lockdown_pin),
-                STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE to
-                    Pair(keyguard_enter_pin, kg_prompt_unattended_update),
-                STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT to
-                    Pair(keyguard_enter_pin, kg_prompt_auth_timeout),
-            )
-        }
-
-    @Test
-    fun authFlagsChanges_withFingerprintEnrolled_providesDifferentMessages() =
-        testScope.runTest {
-            userRepository.setSelectedUserInfo(PRIMARY_USER)
-            trustRepository.setCurrentUserTrustManaged(false)
-            biometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(false)
-
-            biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
-
-            verifyMessagesForAuthFlag(
-                STRONG_AUTH_NOT_REQUIRED to null,
-                STRONG_AUTH_REQUIRED_AFTER_LOCKOUT to null,
-                SOME_AUTH_REQUIRED_AFTER_USER_REQUEST to null,
-                SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED to null,
-                STRONG_AUTH_REQUIRED_AFTER_BOOT to
-                    Pair(keyguard_enter_pin, kg_prompt_reason_restart_pin),
-                STRONG_AUTH_REQUIRED_AFTER_TIMEOUT to
-                    Pair(keyguard_enter_pin, kg_prompt_pin_auth_timeout),
-                STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW to
-                    Pair(keyguard_enter_pin, kg_prompt_after_dpm_lock),
-                STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN to
-                    Pair(keyguard_enter_pin, kg_prompt_after_user_lockdown_pin),
-                STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE to
-                    Pair(keyguard_enter_pin, kg_prompt_unattended_update),
-                STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT to
-                    Pair(keyguard_enter_pin, kg_prompt_auth_timeout),
-            )
-        }
-
-    private fun TestScope.verifyMessagesForAuthFlag(
-        vararg authFlagToExpectedMessages: Pair<Int, Pair<Int, Int>?>
-    ) {
-        val authFlagsMessage = collectLastValue(underTest.authFlagsMessage)
-
-        authFlagToExpectedMessages.forEach { (flag, messagePair) ->
-            biometricSettingsRepository.setAuthenticationFlags(
-                AuthenticationFlags(PRIMARY_USER_ID, flag)
-            )
-
-            assertThat(authFlagsMessage())
-                .isEqualTo(messagePair?.let { message(it.first, it.second) })
-        }
-    }
-
-    private fun message(primaryResId: Int, secondaryResId: Int): BouncerMessageModel {
-        return BouncerMessageModel(
-            message = Message(messageResId = primaryResId, animate = false),
-            secondaryMessage = Message(messageResId = secondaryResId, animate = false)
-        )
-    }
-    private fun message(value: String): BouncerMessageModel {
-        return BouncerMessageModel(message = Message(message = value))
-    }
-
-    companion object {
-        private const val PRIMARY_USER_ID = 0
-        private val PRIMARY_USER =
-            UserInfo(
-                /* id= */ PRIMARY_USER_ID,
-                /* name= */ "primary user",
-                /* flags= */ UserInfo.FLAG_PRIMARY
-            )
-    }
-}
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 86e0c75..77d8102 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
@@ -353,6 +353,34 @@
             assertThat(throttling).isEqualTo(AuthenticationThrottlingModel())
         }
 
+    @Test
+    fun hide_whenOnBouncerScene_hidesBouncerAndGoesToLockscreenScene() =
+        testScope.runTest {
+            sceneInteractor.changeScene(SceneModel(SceneKey.Bouncer), "")
+            sceneInteractor.onSceneChanged(SceneModel(SceneKey.Bouncer), "")
+            val currentScene by collectLastValue(sceneInteractor.desiredScene)
+            val bouncerSceneKey = currentScene?.key
+            assertThat(bouncerSceneKey).isEqualTo(SceneKey.Bouncer)
+
+            underTest.hide("")
+
+            assertThat(currentScene?.key).isEqualTo(SceneKey.Lockscreen)
+        }
+
+    @Test
+    fun hide_whenNotOnBouncerScene_doesNothing() =
+        testScope.runTest {
+            sceneInteractor.changeScene(SceneModel(SceneKey.Shade), "")
+            sceneInteractor.onSceneChanged(SceneModel(SceneKey.Shade), "")
+            val currentScene by collectLastValue(sceneInteractor.desiredScene)
+            val notBouncerSceneKey = currentScene?.key
+            assertThat(notBouncerSceneKey).isNotEqualTo(SceneKey.Bouncer)
+
+            underTest.hide("")
+
+            assertThat(currentScene?.key).isEqualTo(notBouncerSceneKey)
+        }
+
     private fun assertTryAgainMessage(
         message: String?,
         time: Int,
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 4089abe..cc4eca5 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
@@ -17,187 +17,216 @@
 package com.android.systemui.bouncer.domain.interactor
 
 import android.content.pm.UserInfo
+import android.os.Handler
 import android.testing.TestableLooper
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.internal.widget.LockPatternUtils
 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.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.bouncer.data.factory.BouncerMessageFactory
-import com.android.systemui.bouncer.data.repository.FakeBouncerMessageRepository
+import com.android.systemui.biometrics.data.repository.FaceSensorInfo
+import com.android.systemui.biometrics.data.repository.FakeFacePropertyRepository
+import com.android.systemui.biometrics.shared.model.SensorStrength
+import com.android.systemui.bouncer.data.repository.BouncerMessageRepositoryImpl
+import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository
 import com.android.systemui.bouncer.shared.model.BouncerMessageModel
-import com.android.systemui.bouncer.shared.model.Message
-import com.android.systemui.coroutines.FlowValue
+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.flags.SystemPropertiesHelper
+import com.android.systemui.keyguard.DismissCallbackRegistry
 import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository
+import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFaceAuthRepository
+import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository
+import com.android.systemui.keyguard.data.repository.FakeTrustRepository
+import com.android.systemui.keyguard.shared.model.AuthenticationFlags
+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.statusbar.policy.KeyguardStateController
 import com.android.systemui.user.data.repository.FakeUserRepository
 import com.android.systemui.util.mockito.KotlinArgumentCaptor
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers.eq
 import org.mockito.Mock
+import org.mockito.Mockito
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
+@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @RunWith(AndroidJUnit4::class)
 class BouncerMessageInteractorTest : SysuiTestCase() {
 
+    private val countDownTimerCallback = KotlinArgumentCaptor(CountDownTimerCallback::class.java)
+    private val repository = BouncerMessageRepositoryImpl()
+    private val userRepository = FakeUserRepository()
+    private val fakeTrustRepository = FakeTrustRepository()
+    private val fakeFacePropertyRepository = FakeFacePropertyRepository()
+    private val bouncerRepository = FakeKeyguardBouncerRepository()
+    private val fakeDeviceEntryFingerprintAuthRepository =
+        FakeDeviceEntryFingerprintAuthRepository()
+    private val fakeDeviceEntryFaceAuthRepository = FakeDeviceEntryFaceAuthRepository()
+    private val biometricSettingsRepository: FakeBiometricSettingsRepository =
+        FakeBiometricSettingsRepository()
+    @Mock private lateinit var updateMonitor: KeyguardUpdateMonitor
     @Mock private lateinit var securityModel: KeyguardSecurityModel
-    @Mock private lateinit var biometricSettingsRepository: FakeBiometricSettingsRepository
     @Mock private lateinit var countDownTimerUtil: CountDownTimerUtil
-    private lateinit var countDownTimerCallback: KotlinArgumentCaptor<CountDownTimerCallback>
-    private lateinit var underTest: BouncerMessageInteractor
-    private lateinit var repository: FakeBouncerMessageRepository
-    private lateinit var userRepository: FakeUserRepository
+    @Mock private lateinit var systemPropertiesHelper: SystemPropertiesHelper
+    @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
+
+    private lateinit var primaryBouncerInteractor: PrimaryBouncerInteractor
     private lateinit var testScope: TestScope
-    private lateinit var bouncerMessage: FlowValue<BouncerMessageModel?>
+    private lateinit var underTest: BouncerMessageInteractor
 
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
-        repository = FakeBouncerMessageRepository()
-        userRepository = FakeUserRepository()
         userRepository.setUserInfos(listOf(PRIMARY_USER))
         testScope = TestScope()
-        countDownTimerCallback = KotlinArgumentCaptor(CountDownTimerCallback::class.java)
-        biometricSettingsRepository = FakeBiometricSettingsRepository()
-
         allowTestableLooperAsMainThread()
         whenever(securityModel.getSecurityMode(PRIMARY_USER_ID)).thenReturn(PIN)
         biometricSettingsRepository.setIsFingerprintAuthCurrentlyAllowed(true)
+        overrideResource(kg_trust_agent_disabled, "Trust agent is unavailable")
     }
 
     suspend fun TestScope.init() {
         userRepository.setSelectedUserInfo(PRIMARY_USER)
-        val featureFlags = FakeFeatureFlags()
-        featureFlags.set(Flags.REVAMPED_BOUNCER_MESSAGES, true)
+        val featureFlags = FakeFeatureFlags().apply { set(Flags.REVAMPED_BOUNCER_MESSAGES, true) }
+        primaryBouncerInteractor =
+            PrimaryBouncerInteractor(
+                bouncerRepository,
+                Mockito.mock(BouncerView::class.java),
+                Mockito.mock(Handler::class.java),
+                Mockito.mock(KeyguardStateController::class.java),
+                Mockito.mock(KeyguardSecurityModel::class.java),
+                Mockito.mock(PrimaryBouncerCallbackInteractor::class.java),
+                Mockito.mock(FalsingCollector::class.java),
+                Mockito.mock(DismissCallbackRegistry::class.java),
+                context,
+                keyguardUpdateMonitor,
+                fakeTrustRepository,
+                testScope.backgroundScope,
+            )
         underTest =
             BouncerMessageInteractor(
                 repository = repository,
-                factory = BouncerMessageFactory(biometricSettingsRepository, securityModel),
                 userRepository = userRepository,
                 countDownTimerUtil = countDownTimerUtil,
-                featureFlags = featureFlags
+                featureFlags = featureFlags,
+                updateMonitor = updateMonitor,
+                biometricSettingsRepository = biometricSettingsRepository,
+                applicationScope = this.backgroundScope,
+                trustRepository = fakeTrustRepository,
+                systemPropertiesHelper = systemPropertiesHelper,
+                primaryBouncerInteractor = primaryBouncerInteractor,
+                facePropertyRepository = fakeFacePropertyRepository,
+                deviceEntryFingerprintAuthRepository = fakeDeviceEntryFingerprintAuthRepository,
+                faceAuthRepository = fakeDeviceEntryFaceAuthRepository,
+                securityModel = securityModel
             )
-        bouncerMessage = collectLastValue(underTest.bouncerMessage)
+        biometricSettingsRepository.setIsFingerprintAuthCurrentlyAllowed(true)
+        fakeDeviceEntryFingerprintAuthRepository.setLockedOut(false)
+        bouncerRepository.setPrimaryShow(true)
+        runCurrent()
     }
 
     @Test
-    fun onIncorrectSecurityInput_setsTheBouncerModelInTheRepository() =
+    fun onIncorrectSecurityInput_providesTheAppropriateValueForBouncerMessage() =
         testScope.runTest {
             init()
+            val bouncerMessage by collectLastValue(underTest.bouncerMessage)
             underTest.onPrimaryAuthIncorrectAttempt()
 
-            assertThat(repository.primaryAuthMessage).isNotNull()
-            assertThat(
-                    context.resources.getString(
-                        repository.primaryAuthMessage.value!!.message!!.messageResId!!
-                    )
-                )
-                .isEqualTo("Wrong PIN. Try again.")
+            assertThat(bouncerMessage).isNotNull()
+            assertThat(primaryResMessage(bouncerMessage)).isEqualTo("Wrong PIN. Try again.")
         }
 
     @Test
     fun onUserStartsPrimaryAuthInput_clearsAllSetBouncerMessages() =
         testScope.runTest {
             init()
-            repository.setCustomMessage(message("not empty"))
-            repository.setFaceAcquisitionMessage(message("not empty"))
-            repository.setFingerprintAcquisitionMessage(message("not empty"))
-            repository.setPrimaryAuthMessage(message("not empty"))
+            val bouncerMessage by collectLastValue(underTest.bouncerMessage)
+            underTest.onPrimaryAuthIncorrectAttempt()
+            assertThat(primaryResMessage(bouncerMessage)).isEqualTo("Wrong PIN. Try again.")
 
             underTest.onPrimaryBouncerUserInput()
 
-            assertThat(repository.customMessage.value).isNull()
-            assertThat(repository.faceAcquisitionMessage.value).isNull()
-            assertThat(repository.fingerprintAcquisitionMessage.value).isNull()
-            assertThat(repository.primaryAuthMessage.value).isNull()
+            assertThat(primaryResMessage(bouncerMessage))
+                .isEqualTo("Unlock with PIN or fingerprint")
         }
 
     @Test
-    fun onBouncerBeingHidden_clearsAllSetBouncerMessages() =
+    fun setCustomMessage_propagateValue() =
         testScope.runTest {
             init()
-            repository.setCustomMessage(message("not empty"))
-            repository.setFaceAcquisitionMessage(message("not empty"))
-            repository.setFingerprintAcquisitionMessage(message("not empty"))
-            repository.setPrimaryAuthMessage(message("not empty"))
-
-            underTest.onBouncerBeingHidden()
-
-            assertThat(repository.customMessage.value).isNull()
-            assertThat(repository.faceAcquisitionMessage.value).isNull()
-            assertThat(repository.fingerprintAcquisitionMessage.value).isNull()
-            assertThat(repository.primaryAuthMessage.value).isNull()
-        }
-
-    @Test
-    fun setCustomMessage_setsRepositoryValue() =
-        testScope.runTest {
-            init()
+            val bouncerMessage by collectLastValue(underTest.bouncerMessage)
 
             underTest.setCustomMessage("not empty")
 
-            val customMessage = repository.customMessage
-            assertThat(customMessage.value!!.message!!.messageResId)
-                .isEqualTo(kg_unlock_with_pin_or_fp)
-            assertThat(customMessage.value!!.secondaryMessage!!.message).isEqualTo("not empty")
+            assertThat(primaryResMessage(bouncerMessage))
+                .isEqualTo("Unlock with PIN or fingerprint")
+            assertThat(bouncerMessage?.secondaryMessage?.message).isEqualTo("not empty")
 
             underTest.setCustomMessage(null)
-            assertThat(customMessage.value).isNull()
+            assertThat(primaryResMessage(bouncerMessage))
+                .isEqualTo("Unlock with PIN or fingerprint")
+            assertThat(bouncerMessage?.secondaryMessage?.message).isNull()
         }
 
     @Test
-    fun setFaceMessage_setsRepositoryValue() =
+    fun setFaceMessage_propagateValue() =
         testScope.runTest {
             init()
+            val bouncerMessage by collectLastValue(underTest.bouncerMessage)
 
             underTest.setFaceAcquisitionMessage("not empty")
 
-            val faceAcquisitionMessage = repository.faceAcquisitionMessage
-
-            assertThat(faceAcquisitionMessage.value!!.message!!.messageResId)
-                .isEqualTo(kg_unlock_with_pin_or_fp)
-            assertThat(faceAcquisitionMessage.value!!.secondaryMessage!!.message)
-                .isEqualTo("not empty")
+            assertThat(primaryResMessage(bouncerMessage))
+                .isEqualTo("Unlock with PIN or fingerprint")
+            assertThat(bouncerMessage?.secondaryMessage?.message).isEqualTo("not empty")
 
             underTest.setFaceAcquisitionMessage(null)
-            assertThat(faceAcquisitionMessage.value).isNull()
+            assertThat(primaryResMessage(bouncerMessage))
+                .isEqualTo("Unlock with PIN or fingerprint")
+            assertThat(bouncerMessage?.secondaryMessage?.message).isNull()
         }
 
     @Test
-    fun setFingerprintMessage_setsRepositoryValue() =
+    fun setFingerprintMessage_propagateValue() =
         testScope.runTest {
             init()
+            val bouncerMessage by collectLastValue(underTest.bouncerMessage)
 
             underTest.setFingerprintAcquisitionMessage("not empty")
 
-            val fingerprintAcquisitionMessage = repository.fingerprintAcquisitionMessage
-
-            assertThat(fingerprintAcquisitionMessage.value!!.message!!.messageResId)
-                .isEqualTo(kg_unlock_with_pin_or_fp)
-            assertThat(fingerprintAcquisitionMessage.value!!.secondaryMessage!!.message)
-                .isEqualTo("not empty")
+            assertThat(primaryResMessage(bouncerMessage))
+                .isEqualTo("Unlock with PIN or fingerprint")
+            assertThat(bouncerMessage?.secondaryMessage?.message).isEqualTo("not empty")
 
             underTest.setFingerprintAcquisitionMessage(null)
-            assertThat(fingerprintAcquisitionMessage.value).isNull()
+            assertThat(primaryResMessage(bouncerMessage))
+                .isEqualTo("Unlock with PIN or fingerprint")
+            assertThat(bouncerMessage?.secondaryMessage?.message).isNull()
         }
 
     @Test
     fun onPrimaryAuthLockout_startsTimerForSpecifiedNumberOfSeconds() =
         testScope.runTest {
             init()
+            val bouncerMessage by collectLastValue(underTest.bouncerMessage)
 
             underTest.onPrimaryAuthLockedOut(3)
 
@@ -206,7 +235,7 @@
 
             countDownTimerCallback.value.onTick(2000L)
 
-            val primaryMessage = repository.primaryAuthMessage.value!!.message!!
+            val primaryMessage = bouncerMessage!!.message!!
             assertThat(primaryMessage.messageResId!!)
                 .isEqualTo(kg_too_many_failed_attempts_countdown)
             assertThat(primaryMessage.formatterArgs).isEqualTo(mapOf(Pair("count", 2)))
@@ -216,10 +245,7 @@
     fun onPrimaryAuthLockout_timerComplete_resetsRepositoryMessages() =
         testScope.runTest {
             init()
-            repository.setCustomMessage(message("not empty"))
-            repository.setFaceAcquisitionMessage(message("not empty"))
-            repository.setFingerprintAcquisitionMessage(message("not empty"))
-            repository.setPrimaryAuthMessage(message("not empty"))
+            val bouncerMessage by collectLastValue(underTest.bouncerMessage)
 
             underTest.onPrimaryAuthLockedOut(3)
 
@@ -228,59 +254,269 @@
 
             countDownTimerCallback.value.onFinish()
 
-            assertThat(repository.customMessage.value).isNull()
-            assertThat(repository.faceAcquisitionMessage.value).isNull()
-            assertThat(repository.fingerprintAcquisitionMessage.value).isNull()
-            assertThat(repository.primaryAuthMessage.value).isNull()
+            assertThat(primaryResMessage(bouncerMessage))
+                .isEqualTo("Unlock with PIN or fingerprint")
+            assertThat(bouncerMessage?.secondaryMessage?.message).isNull()
         }
 
     @Test
-    fun bouncerMessage_hasPriorityOrderOfMessages() =
+    fun onFaceLockout_propagatesState() =
         testScope.runTest {
             init()
-            repository.setBiometricAuthMessage(message("biometric message"))
-            repository.setFaceAcquisitionMessage(message("face acquisition message"))
-            repository.setFingerprintAcquisitionMessage(message("fingerprint acquisition message"))
-            repository.setPrimaryAuthMessage(message("primary auth message"))
-            repository.setAuthFlagsMessage(message("auth flags message"))
-            repository.setBiometricLockedOutMessage(message("biometrics locked out"))
-            repository.setCustomMessage(message("custom message"))
+            val lockoutMessage by collectLastValue(underTest.bouncerMessage)
 
-            assertThat(bouncerMessage()).isEqualTo(message("primary auth message"))
+            fakeDeviceEntryFaceAuthRepository.setLockedOut(true)
+            runCurrent()
 
-            repository.setPrimaryAuthMessage(null)
+            assertThat(primaryResMessage(lockoutMessage))
+                .isEqualTo("Unlock with PIN or fingerprint")
+            assertThat(secondaryResMessage(lockoutMessage))
+                .isEqualTo("Can’t unlock with face. Too many attempts.")
 
-            assertThat(bouncerMessage()).isEqualTo(message("biometric message"))
+            fakeDeviceEntryFaceAuthRepository.setLockedOut(false)
+            runCurrent()
 
-            repository.setBiometricAuthMessage(null)
-
-            assertThat(bouncerMessage()).isEqualTo(message("fingerprint acquisition message"))
-
-            repository.setFingerprintAcquisitionMessage(null)
-
-            assertThat(bouncerMessage()).isEqualTo(message("face acquisition message"))
-
-            repository.setFaceAcquisitionMessage(null)
-
-            assertThat(bouncerMessage()).isEqualTo(message("custom message"))
-
-            repository.setCustomMessage(null)
-
-            assertThat(bouncerMessage()).isEqualTo(message("auth flags message"))
-
-            repository.setAuthFlagsMessage(null)
-
-            assertThat(bouncerMessage()).isEqualTo(message("biometrics locked out"))
-
-            repository.setBiometricLockedOutMessage(null)
-
-            // sets the default message if everything else is null
-            assertThat(bouncerMessage()!!.message!!.messageResId)
-                .isEqualTo(kg_unlock_with_pin_or_fp)
+            assertThat(primaryResMessage(lockoutMessage))
+                .isEqualTo("Unlock with PIN or fingerprint")
+            assertThat(lockoutMessage?.secondaryMessage?.message).isNull()
         }
 
-    private fun message(value: String): BouncerMessageModel {
-        return BouncerMessageModel(message = Message(message = value))
+    @Test
+    fun onFaceLockout_whenItIsClass3_propagatesState() =
+        testScope.runTest {
+            init()
+            val lockoutMessage by collectLastValue(underTest.bouncerMessage)
+            fakeFacePropertyRepository.setSensorInfo(FaceSensorInfo(1, SensorStrength.STRONG))
+            fakeDeviceEntryFaceAuthRepository.setLockedOut(true)
+            runCurrent()
+
+            assertThat(primaryResMessage(lockoutMessage)).isEqualTo("Enter PIN")
+            assertThat(secondaryResMessage(lockoutMessage))
+                .isEqualTo("PIN is required after too many attempts")
+
+            fakeDeviceEntryFaceAuthRepository.setLockedOut(false)
+            runCurrent()
+
+            assertThat(primaryResMessage(lockoutMessage))
+                .isEqualTo("Unlock with PIN or fingerprint")
+            assertThat(lockoutMessage?.secondaryMessage?.message).isNull()
+        }
+
+    @Test
+    fun onFingerprintLockout_propagatesState() =
+        testScope.runTest {
+            init()
+            val lockedOutMessage by collectLastValue(underTest.bouncerMessage)
+
+            fakeDeviceEntryFingerprintAuthRepository.setLockedOut(true)
+            runCurrent()
+
+            assertThat(primaryResMessage(lockedOutMessage)).isEqualTo("Enter PIN")
+            assertThat(secondaryResMessage(lockedOutMessage))
+                .isEqualTo("PIN is required after too many attempts")
+
+            fakeDeviceEntryFingerprintAuthRepository.setLockedOut(false)
+            runCurrent()
+
+            assertThat(primaryResMessage(lockedOutMessage))
+                .isEqualTo("Unlock with PIN or fingerprint")
+            assertThat(lockedOutMessage?.secondaryMessage?.message).isNull()
+        }
+
+    @Test
+    fun onRestartForMainlineUpdate_shouldProvideRelevantMessage() =
+        testScope.runTest {
+            init()
+            whenever(systemPropertiesHelper.get("sys.boot.reason.last"))
+                .thenReturn("reboot,mainline_update")
+            biometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(true)
+
+            verifyMessagesForAuthFlag(
+                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT to
+                    Pair("Enter PIN", "Device updated. Enter PIN to continue.")
+            )
+        }
+
+    @Test
+    fun onAuthFlagsChanged_withTrustNotManagedAndNoBiometrics_isANoop() =
+        testScope.runTest {
+            init()
+            fakeTrustRepository.setTrustUsuallyManaged(false)
+            biometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(false)
+            biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
+
+            val defaultMessage = Pair("Enter PIN", null)
+
+            verifyMessagesForAuthFlag(
+                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT to
+                    defaultMessage,
+                LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST to
+                    defaultMessage,
+                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT to
+                    defaultMessage,
+                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT to
+                    defaultMessage,
+                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN to
+                    defaultMessage,
+                LockPatternUtils.StrongAuthTracker
+                    .STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT to defaultMessage,
+                LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED to
+                    defaultMessage,
+                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE to
+                    defaultMessage,
+                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW to
+                    Pair("Enter PIN", "For added security, device was locked by work policy")
+            )
+        }
+
+    @Test
+    fun authFlagsChanges_withTrustManaged_providesDifferentMessages() =
+        testScope.runTest {
+            init()
+
+            userRepository.setSelectedUserInfo(PRIMARY_USER)
+            biometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(false)
+            biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
+
+            fakeTrustRepository.setCurrentUserTrustManaged(true)
+            fakeTrustRepository.setTrustUsuallyManaged(true)
+
+            val defaultMessage = Pair("Enter PIN", null)
+
+            verifyMessagesForAuthFlag(
+                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED to defaultMessage,
+                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT to
+                    Pair("Enter PIN", "PIN is required after device restarts"),
+                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT to
+                    Pair("Enter PIN", "Added security required. PIN not used for a while."),
+                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW to
+                    Pair("Enter PIN", "For added security, device was locked by work policy"),
+                LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST to
+                    Pair("Enter PIN", "Trust agent is unavailable"),
+                LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED to
+                    Pair("Enter PIN", "Trust agent is unavailable"),
+                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN to
+                    Pair("Enter PIN", "PIN is required after lockdown"),
+                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE to
+                    Pair("Enter PIN", "Update will install when device not in use"),
+                LockPatternUtils.StrongAuthTracker
+                    .STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT to
+                    Pair(
+                        "Enter PIN",
+                        "Added security required. Device wasn’t unlocked for a while."
+                    ),
+            )
+        }
+
+    @Test
+    fun authFlagsChanges_withFaceEnrolled_providesDifferentMessages() =
+        testScope.runTest {
+            init()
+            userRepository.setSelectedUserInfo(PRIMARY_USER)
+            fakeTrustRepository.setTrustUsuallyManaged(false)
+            biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
+
+            biometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(true)
+            val defaultMessage = Pair("Enter PIN", null)
+
+            verifyMessagesForAuthFlag(
+                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED to defaultMessage,
+                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT to
+                    defaultMessage,
+                LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST to
+                    defaultMessage,
+                LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED to
+                    defaultMessage,
+                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT to
+                    Pair("Enter PIN", "PIN is required after device restarts"),
+                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT to
+                    Pair("Enter PIN", "Added security required. PIN not used for a while."),
+                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW to
+                    Pair("Enter PIN", "For added security, device was locked by work policy"),
+                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN to
+                    Pair("Enter PIN", "PIN is required after lockdown"),
+                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE to
+                    Pair("Enter PIN", "Update will install when device not in use"),
+                LockPatternUtils.StrongAuthTracker
+                    .STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT to
+                    Pair(
+                        "Enter PIN",
+                        "Added security required. Device wasn’t unlocked for a while."
+                    ),
+            )
+        }
+
+    @Test
+    fun authFlagsChanges_withFingerprintEnrolled_providesDifferentMessages() =
+        testScope.runTest {
+            init()
+            userRepository.setSelectedUserInfo(PRIMARY_USER)
+            fakeTrustRepository.setCurrentUserTrustManaged(false)
+            biometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(false)
+
+            biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
+            biometricSettingsRepository.setIsFingerprintAuthCurrentlyAllowed(true)
+
+            verifyMessagesForAuthFlag(
+                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED to
+                    Pair("Unlock with PIN or fingerprint", null)
+            )
+
+            biometricSettingsRepository.setIsFingerprintAuthCurrentlyAllowed(false)
+
+            verifyMessagesForAuthFlag(
+                LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST to
+                    Pair("Enter PIN", null),
+                LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED to
+                    Pair("Enter PIN", null),
+                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT to
+                    Pair("Enter PIN", "PIN is required after device restarts"),
+                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT to
+                    Pair("Enter PIN", "Added security required. PIN not used for a while."),
+                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW to
+                    Pair("Enter PIN", "For added security, device was locked by work policy"),
+                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN to
+                    Pair("Enter PIN", "PIN is required after lockdown"),
+                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE to
+                    Pair("Enter PIN", "Update will install when device not in use"),
+                LockPatternUtils.StrongAuthTracker
+                    .STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT to
+                    Pair(
+                        "Enter PIN",
+                        "Added security required. Device wasn’t unlocked for a while."
+                    ),
+            )
+        }
+
+    private fun primaryResMessage(bouncerMessage: BouncerMessageModel?) =
+        resString(bouncerMessage?.message?.messageResId)
+
+    private fun secondaryResMessage(bouncerMessage: BouncerMessageModel?) =
+        resString(bouncerMessage?.secondaryMessage?.messageResId)
+
+    private fun resString(msgResId: Int?): String? =
+        msgResId?.let { context.resources.getString(it) }
+
+    private fun TestScope.verifyMessagesForAuthFlag(
+        vararg authFlagToExpectedMessages: Pair<Int, Pair<String, String?>>
+    ) {
+        val authFlagsMessage by collectLastValue(underTest.bouncerMessage)
+
+        authFlagToExpectedMessages.forEach { (flag, messagePair) ->
+            biometricSettingsRepository.setAuthenticationFlags(
+                AuthenticationFlags(PRIMARY_USER_ID, flag)
+            )
+            runCurrent()
+
+            assertThat(primaryResMessage(authFlagsMessage)).isEqualTo(messagePair.first)
+            if (messagePair.second == null) {
+                assertThat(authFlagsMessage?.secondaryMessage?.messageResId).isEqualTo(0)
+                assertThat(authFlagsMessage?.secondaryMessage?.message).isNull()
+            } else {
+                assertThat(authFlagsMessage?.secondaryMessage?.messageResId).isNotEqualTo(0)
+                assertThat(secondaryResMessage(authFlagsMessage)).isEqualTo(messagePair.second)
+            }
+        }
     }
 
     companion object {
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 420fdba..9a5b4585 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 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
@@ -34,8 +34,6 @@
 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 @@
     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 @@
         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 @@
                 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 665456d..cb0b74f 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.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 @@
                 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/AuthMethodBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt
index 7af8a04..9011c2f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt
@@ -22,6 +22,8 @@
 import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.scene.SceneTestUtils
+import com.android.systemui.scene.shared.model.SceneKey
+import com.android.systemui.scene.shared.model.SceneModel
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.runTest
@@ -39,6 +41,7 @@
         utils.authenticationInteractor(
             utils.authenticationRepository(),
         )
+    private val sceneInteractor = utils.sceneInteractor()
     private val underTest =
         PinBouncerViewModel(
             applicationContext = context,
@@ -46,7 +49,7 @@
             interactor =
                 utils.bouncerInteractor(
                     authenticationInteractor = authenticationInteractor,
-                    sceneInteractor = utils.sceneInteractor(),
+                    sceneInteractor = sceneInteractor,
                 ),
             isInputEnabled = MutableStateFlow(true),
         )
@@ -75,4 +78,22 @@
             underTest.onAuthenticateButtonClicked()
             assertThat(animateFailure).isFalse()
         }
+
+    @Test
+    fun onImeVisibilityChanged() =
+        testScope.runTest {
+            val desiredScene by collectLastValue(sceneInteractor.desiredScene)
+            sceneInteractor.changeScene(SceneModel(SceneKey.Bouncer), "")
+            sceneInteractor.onSceneChanged(SceneModel(SceneKey.Bouncer), "")
+            assertThat(desiredScene?.key).isEqualTo(SceneKey.Bouncer)
+
+            underTest.onImeVisibilityChanged(false)
+            assertThat(desiredScene?.key).isEqualTo(SceneKey.Bouncer)
+
+            underTest.onImeVisibilityChanged(true)
+            assertThat(desiredScene?.key).isEqualTo(SceneKey.Bouncer)
+
+            underTest.onImeVisibilityChanged(false)
+            assertThat(desiredScene?.key).isEqualTo(SceneKey.Lockscreen)
+        }
 }
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 d4bba72..333bd21 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.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 @@
                 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/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
index 12090e5..3375184 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
@@ -157,6 +157,29 @@
         }
 
     @Test
+    fun onAuthenticateKeyPressed_whenEmpty() =
+        testScope.runTest {
+            val currentScene by collectLastValue(sceneInteractor.desiredScene)
+            val message by collectLastValue(bouncerViewModel.message)
+            val password by collectLastValue(underTest.password)
+            utils.authenticationRepository.setAuthenticationMethod(
+                AuthenticationMethodModel.Password
+            )
+            utils.authenticationRepository.setUnlocked(false)
+            sceneInteractor.changeScene(SceneModel(SceneKey.Bouncer), "reason")
+            sceneInteractor.onSceneChanged(SceneModel(SceneKey.Bouncer), "reason")
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+            underTest.onShown()
+            // Enter nothing.
+
+            underTest.onAuthenticateKeyPressed()
+
+            assertThat(password).isEqualTo("")
+            assertThat(message?.text).isEqualTo(ENTER_YOUR_PASSWORD)
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+        }
+
+    @Test
     fun onAuthenticateKeyPressed_correctAfterWrong() =
         testScope.runTest {
             val currentScene by collectLastValue(sceneInteractor.desiredScene)
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 8ce738c..102cfe2 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 a684221..35238ce 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 5a5c058..11756d5 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.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 673b5eb..db85522 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 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 662c89c..fb07e6e 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 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 f0006e5..98f7f59 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 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 69d8d0b..a78f0b7 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 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 bd4e8da..581e88b 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 @@
 
 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 bd3d09d..2a4524b 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.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 70d93a1..88d36af 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 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 74d0d21..6361e94 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.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 756f267..4e8f866 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 @@
 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 7ac1953..4828ba3 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 @@
 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 2ae342a..101b8ed 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.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 1e8cd41..8eebcee 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 @@
 
 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 df6fa11..48e3962 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.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 a400ff9..5a4ad01 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.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 588e34d..ac1f90c 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.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 8bf17d7..a1cffc1 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.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 171b767..e4ddc37 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.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 8f0b193..d1d4880 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.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 4feba7b..2bff7d2 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 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 46f7582..dcc15ae 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.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 ec9acdf..ea7467f 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 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 af2dab5..9566e81 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 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 16d665c..f89a0b6 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 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 ea47859..5a97b74 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 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 74e8cc2..a003e07 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 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 8f66344..76c3349 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.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/haptics/slider/FakeSliderEventProducer.kt b/packages/SystemUI/tests/src/com/android/systemui/haptics/slider/FakeSliderEventProducer.kt
new file mode 100644
index 0000000..9deabc7
--- /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 0000000..add601c
--- /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()
+    }
+}
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 0000000..0ee348e
--- /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/keyguard/CustomizationProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
index f3c9432..6c990e45 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.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 d84a4f7..49168d0 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 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 b6dffff..c3e28ae 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 @@
 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 1815ea9..477f455 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 @@
 
 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
@@ -176,7 +176,7 @@
                     !isFeatureEnabled ->
                         KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice::class
                             .java
-                    hasServiceInfos && hasFavorites ->
+                    hasServiceInfos && (hasFavorites || hasPanels) ->
                         KeyguardQuickAffordanceConfig.PickerScreenState.Default::class.java
                     else -> KeyguardQuickAffordanceConfig.PickerScreenState.Disabled::class.java
                 }
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 2fd4947..ef56a98 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 @@
 
 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 7941a23..bd4525b 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 @@
 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 de3bb6f..4f071bd 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.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 edaff44..bd0b71d 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.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 b9c0b7f..613c4ce 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.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 a6930d5..360fa56 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_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 6b194f2..5a95ebe 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_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
@@ -39,7 +42,7 @@
 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
@@ -102,7 +105,6 @@
 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 @@
 
     @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 @@
             underTest = createDeviceEntryFaceAuthRepositoryImpl()
             initCollectors()
 
-            underTest.detect()
+            underTest.detect(FACE_AUTH_TRIGGERED_NOTIFICATION_PANEL_CLICKED)
             faceDetectIsCalled()
 
             detectionCallback.value.onFaceDetected(1, 1, true)
@@ -421,6 +424,8 @@
             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 @@
             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 @@
 
             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 @@
 
             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 @@
             .detectFace(
                 cancellationSignal.capture(),
                 detectionCallback.capture(),
-                eq(FaceAuthenticateOptions.Builder().setUserId(primaryUserId).build())
+                faceAuthenticateOptions.capture(),
             )
     }
 
@@ -1251,7 +1260,7 @@
                 cancellationSignal.capture(),
                 authenticationCallback.capture(),
                 isNull(),
-                eq(FaceAuthenticateOptions.Builder().setUserId(primaryUserId).build())
+                faceAuthenticateOptions.capture(),
             )
     }
 
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 6b5be58b..126b841 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.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/data/repository/TrustRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt
index 29d7500..7f784d8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt
@@ -28,6 +28,7 @@
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.LogcatEchoTracker
 import com.android.systemui.user.data.repository.FakeUserRepository
+import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
@@ -260,4 +261,19 @@
             listener.value.onIsActiveUnlockRunningChanged(true, users[0].id)
             assertThat(isCurrentUserActiveUnlockRunning).isTrue()
         }
+
+    @Test
+    fun isTrustUsuallyManaged_providesTheValueForCurrentUser() =
+        testScope.runTest {
+            runCurrent()
+            val trustUsuallyManaged by collectLastValue(underTest.isCurrentUserTrustUsuallyManaged)
+            whenever(trustManager.isTrustUsuallyManaged(users[0].id)).thenReturn(true)
+            whenever(trustManager.isTrustUsuallyManaged(users[1].id)).thenReturn(false)
+
+            userRepository.setSelectedUserInfo(users[0])
+
+            assertThat(trustUsuallyManaged).isTrue()
+            userRepository.setSelectedUserInfo(users[1])
+            assertThat(trustUsuallyManaged).isFalse()
+        }
 }
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 2ed9de2..518b3cc 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 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.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 @@
     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 @@
         fakeUserRepository = FakeUserRepository()
         fakeUserRepository.setUserInfos(listOf(primaryUser, secondaryUser))
         facePropertyRepository = FakeFacePropertyRepository()
+        fakeKeyguardRepository = FakeKeyguardRepository()
         underTest =
             SystemUIKeyguardFaceAuthInteractor(
                 mContext,
@@ -126,7 +135,6 @@
                     context,
                     keyguardUpdateMonitor,
                     FakeTrustRepository(),
-                    FakeFeatureFlags().apply { set(Flags.DELAY_BOUNCER, true) },
                     testScope.backgroundScope,
                 ),
                 AlternateBouncerInteractor(
@@ -144,6 +152,8 @@
                 fakeDeviceEntryFingerprintAuthRepository,
                 fakeUserRepository,
                 facePropertyRepository,
+                fakeKeyguardRepository,
+                faceWakeUpTriggersConfig,
             )
     }
 
@@ -152,6 +162,18 @@
         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 +210,18 @@
         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,
@@ -204,10 +238,51 @@
         }
 
     @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,
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 0bbeeff..13025a0 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 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 e8542aad..8c13bb4 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 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/domain/interactor/KeyguardTransitionScenariosTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
index d457605..f2636c5 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.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.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.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 @@
  * 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 @@
     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 @@
             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/src/com/android/systemui/keyguard/domain/interactor/OccludingAppDeviceEntryInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/OccludingAppDeviceEntryInteractorTest.kt
index b81a3d4..4736545 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 @@
         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 @@
                     context,
                     keyguardUpdateMonitor,
                     trustRepository,
-                    featureFlags,
                     testScope.backgroundScope,
                 ),
                 AlternateBouncerInteractor(
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 623c877..7a17435 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 @@
         underTest.setLockscreenShown(true)
         underTest.setAodVisible(true)
 
+        verify(activityTaskManagerService).setLockScreenShown(true, false)
         verify(activityTaskManagerService).setLockScreenShown(true, true)
         verifyNoMoreInteractions(activityTaskManagerService)
     }
@@ -76,6 +77,7 @@
         underTest.setLockscreenShown(true)
         underTest.setAodVisible(true)
 
+        verify(activityTaskManagerService).setLockScreenShown(true, false)
         verify(activityTaskManagerService).setLockScreenShown(true, true)
         verifyNoMoreInteractions(activityTaskManagerService)
 
@@ -97,4 +99,12 @@
 
         verifyNoMoreInteractions(activityTaskManagerService)
     }
+
+    @Test
+    fun testAodVisible_noLockscreenShownCallYet_defaultsToShowLockscreen() {
+        underTest.setAodVisible(false)
+
+        verify(activityTaskManagerService).setLockScreenShown(true, false)
+        verifyNoMoreInteractions(activityTaskManagerService)
+    }
 }
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 4e31af22..8b8c59b 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 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 1c3b5e61..7495637 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.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 06bf7f0..32d28a3 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 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 b935e1d..1c6cc87 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.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 bd17de3..9ab9b3d 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 @@
     @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 0ad14d0..4f970d7 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 @@
     @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 1d7d5df..eed7ecd 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.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 d6ceea1..043dae6 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.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 670f117..f7c20ac 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.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 5939bb5..fb0a4be 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.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 0c57e7b..85d3fba 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.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 3961a94..a4c2a08 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.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 9a90a5c..d6e2e97 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 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 @@
     @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 @@
     @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 @@
         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 @@
                     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 @@
         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 @@
         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 @@
                     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 @@
                             .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 @@
                     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 @@
                             .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 33ed01f..25faeef 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.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 ba97df9..1f99303 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.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 e4f89a2..2f057a2 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 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 @@
     @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 @@
     @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 db00e09..9dfb5a5 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.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 f25454c..e7400e7 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.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 1931580..ce999cb 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.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 bfc8c83..379136b 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.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 b09fc55..53e9dc8 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 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 6c3d6f5..5c6d913 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.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 2b66e7b..e2be4cb 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 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 c7a74da..83145bd 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 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 b396caf..d0c6d7c 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.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 baac9e0..06127a7 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.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 b50032f..cf43b2e 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 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 58c762e..119ffd2 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.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 bd913ba..30d66dc 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 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 e6b960d..d0e8cce 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 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 e669d06..a63b221 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 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 b9ee19b..2bdad2b 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.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 1d687b1..b754145 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.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 f4644a5..6c01ba5 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.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 bf237ab..8c5d99a 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.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 d9db60d..98e803f 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 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 8afe095..c4c233c 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.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 24cd3e7..e2ac7bc 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.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 4cb19444..5e4c954 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.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 1df504a..cc48640 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.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 2dc78a3..fbf3724 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 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 64d3b82..b595e8d 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 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 9bd3b79..2db79c2 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 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 4a15d74..f809259 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 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 a5dead0..6cad985 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 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 2eed38f..bde3038 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.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 244f627..126dd63 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.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 ec8552b..b8e6403 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 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 fb17fc0..365e8a5 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.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 d647d6a..4ada44c 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 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 aef5faf..1c28e4c 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 @@
 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 6e579d4..15e401d 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 @@
 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 8036cb4..5ce15fa 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.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 780c56c..e0fff9c 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.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 b8d018f..f2400ec 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 @@
 
 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 c60cecb..e2a3fac6 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.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 ff6814c..605dc14 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.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 e5c55d8..82ee99a 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,9 +11,10 @@
 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.flags.FeatureFlagsClassic
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.plugins.qs.QSTile
@@ -22,6 +23,7 @@
 import com.android.systemui.qs.QsEventLogger
 import com.android.systemui.qs.logging.QSLogger
 import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.qs.tiles.dialog.bluetooth.BluetoothTileDialogViewModel
 import com.android.systemui.statusbar.policy.BluetoothController
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.eq
@@ -50,6 +52,8 @@
     @Mock private lateinit var activityStarter: ActivityStarter
     @Mock private lateinit var bluetoothController: BluetoothController
     @Mock private lateinit var uiEventLogger: QsEventLogger
+    @Mock private lateinit var featureFlags: FeatureFlagsClassic
+    @Mock private lateinit var bluetoothTileDialogViewModel: BluetoothTileDialogViewModel
 
     private lateinit var testableLooper: TestableLooper
     private lateinit var tile: FakeBluetoothTile
@@ -73,6 +77,8 @@
                 activityStarter,
                 qsLogger,
                 bluetoothController,
+                featureFlags,
+                bluetoothTileDialogViewModel
             )
 
         tile.initialize()
@@ -220,6 +226,8 @@
         activityStarter: ActivityStarter,
         qsLogger: QSLogger,
         bluetoothController: BluetoothController,
+        featureFlags: FeatureFlagsClassic,
+        bluetoothTileDialogViewModel: BluetoothTileDialogViewModel
     ) :
         BluetoothTile(
             qsHost,
@@ -232,6 +240,8 @@
             activityStarter,
             qsLogger,
             bluetoothController,
+            featureFlags,
+            bluetoothTileDialogViewModel
         ) {
         var restrictionChecked: String? = null
 
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 70d82fd..c4cf342 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.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 2e02bbe..c93ff4b 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 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 176b33f..51e95be 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.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 1346069..bce4c06 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 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 77a4436..5dd297c 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.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 f231c6e..a0c1073 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 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 73aa699..c1a0928 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.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 73f61d06..14dfdea 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 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 @@
 
         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 @@
 
         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 b6cf459..83f8f18 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.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 7957c6a..c1f1964 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 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 0bf0b38..62a50e3 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.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 ceff546..3511bb3 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.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 763a7e5..118ad2c 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 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 6c8f76b..a1d9e414 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.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 71aa7a8..7b3171d 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 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 dd55bad..2d18f92 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 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 d244594..c5721ff 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 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 41545fc..df6993d 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.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 fff2b8f..5b3d45b 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 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 79147e7..47fc3ec 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.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 18e40f6..f9d69c2 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 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 df037c0..8004c6d 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 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 25684ce2..6dc7a06 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.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 @@
         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 2c74d4f..039e58a 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 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/qs/tiles/dialog/bluetooth/BluetoothStateInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothStateInteractorTest.kt
new file mode 100644
index 0000000..fc2b7a64
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothStateInteractorTest.kt
@@ -0,0 +1,95 @@
+/*
+ * 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.qs.tiles.dialog.bluetooth
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.settingslib.bluetooth.LocalBluetoothAdapter
+import com.android.settingslib.bluetooth.LocalBluetoothManager
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
+import org.mockito.junit.MockitoJUnit
+import org.mockito.junit.MockitoRule
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+class BluetoothStateInteractorTest : SysuiTestCase() {
+    @get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
+    private val testScope = TestScope()
+
+    private lateinit var bluetoothStateInteractor: BluetoothStateInteractor
+
+    @Mock private lateinit var bluetoothAdapter: LocalBluetoothAdapter
+    @Mock private lateinit var localBluetoothManager: LocalBluetoothManager
+
+    @Before
+    fun setUp() {
+        bluetoothStateInteractor =
+            BluetoothStateInteractor(localBluetoothManager, testScope.backgroundScope)
+        `when`(localBluetoothManager.bluetoothAdapter).thenReturn(bluetoothAdapter)
+    }
+
+    @Test
+    fun testGet_isBluetoothEnabled() {
+        testScope.runTest {
+            `when`(bluetoothAdapter.isEnabled).thenReturn(true)
+
+            assertThat(bluetoothStateInteractor.isBluetoothEnabled).isTrue()
+        }
+    }
+
+    @Test
+    fun testGet_isBluetoothDisabled() {
+        testScope.runTest {
+            `when`(bluetoothAdapter.isEnabled).thenReturn(false)
+
+            assertThat(bluetoothStateInteractor.isBluetoothEnabled).isFalse()
+        }
+    }
+
+    @Test
+    fun testSet_bluetoothEnabled() {
+        testScope.runTest {
+            `when`(bluetoothAdapter.isEnabled).thenReturn(false)
+
+            bluetoothStateInteractor.isBluetoothEnabled = true
+            verify(bluetoothAdapter).enable()
+        }
+    }
+
+    @Test
+    fun testSet_bluetoothNoChange() {
+        testScope.runTest {
+            `when`(bluetoothAdapter.isEnabled).thenReturn(false)
+
+            bluetoothStateInteractor.isBluetoothEnabled = false
+            verify(bluetoothAdapter, never()).enable()
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogRepositoryTest.kt
new file mode 100644
index 0000000..da8f60a
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogRepositoryTest.kt
@@ -0,0 +1,79 @@
+/*
+ * 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.qs.tiles.dialog.bluetooth
+
+import android.bluetooth.BluetoothAdapter
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.settingslib.bluetooth.CachedBluetoothDevice
+import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager
+import com.android.settingslib.bluetooth.LocalBluetoothManager
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.`when`
+import org.mockito.junit.MockitoJUnit
+import org.mockito.junit.MockitoRule
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+class BluetoothTileDialogRepositoryTest : SysuiTestCase() {
+
+    @get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
+
+    @Mock private lateinit var localBluetoothManager: LocalBluetoothManager
+
+    @Mock private lateinit var bluetoothAdapter: BluetoothAdapter
+
+    @Mock private lateinit var cachedDeviceManager: CachedBluetoothDeviceManager
+
+    @Mock private lateinit var cachedDevicesCopy: Collection<CachedBluetoothDevice>
+
+    private lateinit var repository: BluetoothTileDialogRepository
+
+    @Before
+    fun setUp() {
+        `when`(localBluetoothManager.cachedDeviceManager).thenReturn(cachedDeviceManager)
+        `when`(cachedDeviceManager.cachedDevicesCopy).thenReturn(cachedDevicesCopy)
+
+        repository = BluetoothTileDialogRepository(localBluetoothManager, bluetoothAdapter)
+    }
+
+    @Test
+    fun testCachedDevices_bluetoothOff_emptyList() {
+        `when`(bluetoothAdapter.isEnabled).thenReturn(false)
+
+        val result = repository.cachedDevices
+
+        assertThat(result).isEmpty()
+    }
+
+    @Test
+    fun testCachedDevices_bluetoothOn_returnDevice() {
+        `when`(bluetoothAdapter.isEnabled).thenReturn(true)
+
+        val result = repository.cachedDevices
+
+        assertThat(result).isEqualTo(cachedDevicesCopy)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogTest.kt
new file mode 100644
index 0000000..89fa55b3
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogTest.kt
@@ -0,0 +1,183 @@
+/*
+ * 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.qs.tiles.dialog.bluetooth
+
+import android.graphics.drawable.Drawable
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.LayoutInflater
+import android.view.View
+import android.view.View.GONE
+import android.view.View.VISIBLE
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.UiEventLogger
+import com.android.settingslib.bluetooth.CachedBluetoothDevice
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.qs.tiles.dialog.bluetooth.BluetoothTileDialog.Companion.DISABLED_ALPHA
+import com.android.systemui.qs.tiles.dialog.bluetooth.BluetoothTileDialog.Companion.ENABLED_ALPHA
+import com.android.systemui.res.R
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.`when`
+import org.mockito.junit.MockitoJUnit
+import org.mockito.junit.MockitoRule
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+class BluetoothTileDialogTest : SysuiTestCase() {
+    companion object {
+        const val DEVICE_NAME = "device"
+        const val DEVICE_CONNECTION_SUMMARY = "active"
+        const val ENABLED = true
+    }
+
+    @get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
+
+    @Mock private lateinit var cachedBluetoothDevice: CachedBluetoothDevice
+
+    @Mock private lateinit var bluetoothTileDialogCallback: BluetoothTileDialogCallback
+
+    @Mock private lateinit var drawable: Drawable
+
+    @Mock private lateinit var uiEventLogger: UiEventLogger
+
+    private lateinit var icon: Pair<Drawable, String>
+    private lateinit var bluetoothTileDialog: BluetoothTileDialog
+    private lateinit var deviceItem: DeviceItem
+
+    @Before
+    fun setUp() {
+        bluetoothTileDialog =
+            BluetoothTileDialog(ENABLED, bluetoothTileDialogCallback, uiEventLogger, mContext)
+        icon = Pair(drawable, DEVICE_NAME)
+        deviceItem =
+            DeviceItem(
+                type = DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE,
+                cachedBluetoothDevice = cachedBluetoothDevice,
+                deviceName = DEVICE_NAME,
+                connectionSummary = DEVICE_CONNECTION_SUMMARY,
+                iconWithDescription = icon,
+                background = null
+            )
+        `when`(cachedBluetoothDevice.isBusy).thenReturn(false)
+    }
+
+    @Test
+    fun testShowDialog_createRecyclerViewWithAdapter() {
+        bluetoothTileDialog.show()
+
+        val recyclerView = bluetoothTileDialog.requireViewById<RecyclerView>(R.id.device_list)
+
+        assertThat(bluetoothTileDialog.isShowing).isTrue()
+        assertThat(recyclerView).isNotNull()
+        assertThat(recyclerView?.visibility).isEqualTo(VISIBLE)
+        assertThat(recyclerView?.adapter).isNotNull()
+        assertThat(recyclerView?.layoutManager is LinearLayoutManager).isTrue()
+    }
+
+    @Test
+    fun testShowDialog_displayBluetoothDevice() {
+        bluetoothTileDialog =
+            BluetoothTileDialog(ENABLED, bluetoothTileDialogCallback, uiEventLogger, mContext)
+        bluetoothTileDialog.show()
+        bluetoothTileDialog.onDeviceItemUpdated(
+            listOf(deviceItem),
+            showSeeAll = false,
+            showPairNewDevice = false
+        )
+
+        val recyclerView = bluetoothTileDialog.requireViewById<RecyclerView>(R.id.device_list)
+        val adapter = recyclerView?.adapter as BluetoothTileDialog.Adapter
+        assertThat(adapter.itemCount).isEqualTo(1)
+        assertThat(adapter.getItem(0).deviceName).isEqualTo(DEVICE_NAME)
+        assertThat(adapter.getItem(0).connectionSummary).isEqualTo(DEVICE_CONNECTION_SUMMARY)
+        assertThat(adapter.getItem(0).iconWithDescription).isEqualTo(icon)
+    }
+
+    @Test
+    fun testDeviceItemViewHolder_cachedDeviceNotBusy() {
+        deviceItem.isEnabled = true
+        deviceItem.alpha = ENABLED_ALPHA
+
+        val view =
+            LayoutInflater.from(mContext).inflate(R.layout.bluetooth_device_item, null, false)
+        val viewHolder =
+            BluetoothTileDialog(ENABLED, bluetoothTileDialogCallback, uiEventLogger, mContext)
+                .Adapter(bluetoothTileDialogCallback)
+                .DeviceItemViewHolder(view)
+        viewHolder.bind(deviceItem, 0, bluetoothTileDialogCallback)
+        val container = view.requireViewById<View>(R.id.bluetooth_device)
+        val deviceView = view.requireViewById<View>(R.id.bluetooth_device)
+
+        assertThat(container).isNotNull()
+        assertThat(container.isEnabled).isTrue()
+        assertThat(container.alpha).isEqualTo(ENABLED_ALPHA)
+        assertThat(deviceView.hasOnClickListeners()).isTrue()
+    }
+
+    @Test
+    fun testDeviceItemViewHolder_cachedDeviceBusy() {
+        deviceItem.isEnabled = false
+        deviceItem.alpha = DISABLED_ALPHA
+
+        val view =
+            LayoutInflater.from(mContext).inflate(R.layout.bluetooth_device_item, null, false)
+        val viewHolder =
+            BluetoothTileDialog(ENABLED, bluetoothTileDialogCallback, uiEventLogger, mContext)
+                .Adapter(bluetoothTileDialogCallback)
+                .DeviceItemViewHolder(view)
+        viewHolder.bind(deviceItem, 0, bluetoothTileDialogCallback)
+        val container = view.requireViewById<View>(R.id.bluetooth_device_row)
+        val deviceView = view.requireViewById<View>(R.id.bluetooth_device)
+
+        assertThat(container).isNotNull()
+        assertThat(container.isEnabled).isFalse()
+        assertThat(container.alpha).isEqualTo(DISABLED_ALPHA)
+        assertThat(deviceView.hasOnClickListeners()).isTrue()
+    }
+
+    @Test
+    fun testOnDeviceUpdated_hideSeeAll_showPairNew() {
+        bluetoothTileDialog =
+            BluetoothTileDialog(ENABLED, bluetoothTileDialogCallback, uiEventLogger, mContext)
+        bluetoothTileDialog.show()
+        bluetoothTileDialog.onDeviceItemUpdated(
+            listOf(deviceItem),
+            showSeeAll = false,
+            showPairNewDevice = true
+        )
+
+        val seeAllLayout = bluetoothTileDialog.requireViewById<View>(R.id.see_all_layout_group)
+        val pairNewLayout =
+            bluetoothTileDialog.requireViewById<View>(R.id.pair_new_device_layout_group)
+        val recyclerView = bluetoothTileDialog.requireViewById<RecyclerView>(R.id.device_list)
+        val adapter = recyclerView?.adapter as BluetoothTileDialog.Adapter
+
+        assertThat(seeAllLayout).isNotNull()
+        assertThat(seeAllLayout.visibility).isEqualTo(GONE)
+        assertThat(pairNewLayout).isNotNull()
+        assertThat(pairNewLayout.visibility).isEqualTo(VISIBLE)
+        assertThat(adapter.itemCount).isEqualTo(1)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModelTest.kt
new file mode 100644
index 0000000..7157cce
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModelTest.kt
@@ -0,0 +1,171 @@
+/*
+ * 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.qs.tiles.dialog.bluetooth
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.View
+import android.widget.LinearLayout
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.UiEventLogger
+import com.android.settingslib.bluetooth.CachedBluetoothDevice
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.DialogLaunchAnimator
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.nullable
+import com.android.systemui.util.time.FakeSystemClock
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.test.TestCoroutineScheduler
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Mock
+import org.mockito.Mockito.anyBoolean
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
+import org.mockito.junit.MockitoJUnit
+import org.mockito.junit.MockitoRule
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+class BluetoothTileDialogViewModelTest : SysuiTestCase() {
+
+    @get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
+    private val fakeSystemClock = FakeSystemClock()
+    private val backgroundExecutor = FakeExecutor(fakeSystemClock)
+
+    private lateinit var bluetoothTileDialogViewModel: BluetoothTileDialogViewModel
+
+    @Mock private lateinit var bluetoothStateInteractor: BluetoothStateInteractor
+
+    @Mock private lateinit var deviceItemInteractor: DeviceItemInteractor
+
+    @Mock private lateinit var activityStarter: ActivityStarter
+
+    @Mock private lateinit var dialogLaunchAnimator: DialogLaunchAnimator
+
+    @Mock private lateinit var cachedBluetoothDevice: CachedBluetoothDevice
+
+    @Mock private lateinit var deviceItem: DeviceItem
+
+    @Mock private lateinit var uiEventLogger: UiEventLogger
+
+    private lateinit var scheduler: TestCoroutineScheduler
+    private lateinit var dispatcher: CoroutineDispatcher
+    private lateinit var testScope: TestScope
+
+    @Before
+    fun setUp() {
+        scheduler = TestCoroutineScheduler()
+        dispatcher = UnconfinedTestDispatcher(scheduler)
+        testScope = TestScope(dispatcher)
+        bluetoothTileDialogViewModel =
+            BluetoothTileDialogViewModel(
+                deviceItemInteractor,
+                bluetoothStateInteractor,
+                dialogLaunchAnimator,
+                activityStarter,
+                uiEventLogger,
+                testScope.backgroundScope,
+                dispatcher,
+            )
+        `when`(deviceItemInteractor.deviceItemFlow).thenReturn(MutableStateFlow(null).asStateFlow())
+        `when`(bluetoothStateInteractor.updateBluetoothStateFlow)
+            .thenReturn(MutableStateFlow(null).asStateFlow())
+        `when`(deviceItemInteractor.updateDeviceItemsFlow)
+            .thenReturn(MutableStateFlow(Unit).asStateFlow())
+        `when`(bluetoothStateInteractor.isBluetoothEnabled).thenReturn(true)
+    }
+
+    @Test
+    fun testShowDialog_noAnimation() {
+        testScope.runTest {
+            bluetoothTileDialogViewModel.showDialog(context, null)
+
+            assertThat(bluetoothTileDialogViewModel.dialog).isNotNull()
+            verify(dialogLaunchAnimator, never()).showFromView(any(), any(), any(), any())
+            assertThat(bluetoothTileDialogViewModel.dialog?.isShowing).isTrue()
+            verify(uiEventLogger).log(BluetoothTileDialogUiEvent.BLUETOOTH_TILE_DIALOG_SHOWN)
+        }
+    }
+
+    @Test
+    fun testShowDialog_animated() {
+        testScope.runTest {
+            bluetoothTileDialogViewModel.showDialog(mContext, LinearLayout(mContext))
+
+            assertThat(bluetoothTileDialogViewModel.dialog).isNotNull()
+            verify(dialogLaunchAnimator).showFromView(any(), any(), nullable(), anyBoolean())
+        }
+    }
+
+    @Test
+    fun testShowDialog_animated_callInBackgroundThread() {
+        testScope.runTest {
+            backgroundExecutor.execute {
+                bluetoothTileDialogViewModel.showDialog(mContext, LinearLayout(mContext))
+
+                assertThat(bluetoothTileDialogViewModel.dialog).isNotNull()
+                verify(dialogLaunchAnimator).showFromView(any(), any(), nullable(), anyBoolean())
+            }
+        }
+    }
+
+    @Test
+    fun testShowDialog_fetchDeviceItem() {
+        testScope.runTest {
+            bluetoothTileDialogViewModel.showDialog(context, null)
+
+            assertThat(bluetoothTileDialogViewModel.dialog).isNotNull()
+            verify(deviceItemInteractor).deviceItemFlow
+        }
+    }
+
+    @Test
+    fun testShowDialog_withBluetoothStateValue() {
+        testScope.runTest {
+            bluetoothTileDialogViewModel.showDialog(context, null)
+
+            assertThat(bluetoothTileDialogViewModel.dialog).isNotNull()
+            verify(bluetoothStateInteractor).updateBluetoothStateFlow
+        }
+    }
+
+    @Test
+    fun testStartSettingsActivity_activityLaunched_dialogDismissed() {
+        `when`(deviceItem.cachedBluetoothDevice).thenReturn(cachedBluetoothDevice)
+        bluetoothTileDialogViewModel.showDialog(context, null)
+
+        val clickedView = View(context)
+        bluetoothTileDialogViewModel.onPairNewDeviceClicked(clickedView)
+
+        verify(uiEventLogger).log(BluetoothTileDialogUiEvent.PAIR_NEW_DEVICE_CLICKED)
+        verify(activityStarter).postStartActivityDismissingKeyguard(any(), anyInt(), nullable())
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemFactoryTest.kt
new file mode 100644
index 0000000..3451902
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemFactoryTest.kt
@@ -0,0 +1,87 @@
+/*
+ * 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.qs.tiles.dialog.bluetooth
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.settingslib.bluetooth.CachedBluetoothDevice
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.`when`
+import org.mockito.junit.MockitoJUnit
+import org.mockito.junit.MockitoRule
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+class DeviceItemFactoryTest : SysuiTestCase() {
+
+    @get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
+
+    @Mock private lateinit var cachedDevice: CachedBluetoothDevice
+
+    private val availableMediaDeviceItemFactory = AvailableMediaDeviceItemFactory()
+    private val connectedDeviceItemFactory = ConnectedDeviceItemFactory()
+    private val savedDeviceItemFactory = SavedDeviceItemFactory()
+
+    @Before
+    fun setup() {
+        `when`(cachedDevice.name).thenReturn(DEVICE_NAME)
+        `when`(cachedDevice.connectionSummary).thenReturn(CONNECTION_SUMMARY)
+    }
+
+    @Test
+    fun testAvailableMediaDeviceItemFactory_createFromCachedDevice() {
+        val deviceItem = availableMediaDeviceItemFactory.create(context, cachedDevice)
+
+        assertDeviceItem(deviceItem, DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE)
+    }
+
+    @Test
+    fun testConnectedDeviceItemFactory_createFromCachedDevice() {
+        val deviceItem = connectedDeviceItemFactory.create(context, cachedDevice)
+
+        assertDeviceItem(deviceItem, DeviceItemType.CONNECTED_BLUETOOTH_DEVICE)
+    }
+
+    @Test
+    fun testSavedDeviceItemFactory_createFromCachedDevice() {
+        val deviceItem = savedDeviceItemFactory.create(context, cachedDevice)
+
+        assertDeviceItem(deviceItem, DeviceItemType.SAVED_BLUETOOTH_DEVICE)
+        assertThat(deviceItem.background).isNull()
+    }
+
+    private fun assertDeviceItem(deviceItem: DeviceItem?, deviceItemType: DeviceItemType) {
+        assertThat(deviceItem).isNotNull()
+        assertThat(deviceItem!!.type).isEqualTo(deviceItemType)
+        assertThat(deviceItem.cachedBluetoothDevice).isEqualTo(cachedDevice)
+        assertThat(deviceItem.deviceName).isEqualTo(DEVICE_NAME)
+        assertThat(deviceItem.connectionSummary).isEqualTo(CONNECTION_SUMMARY)
+    }
+
+    companion object {
+        const val DEVICE_NAME = "DeviceName"
+        const val CONNECTION_SUMMARY = "ConnectionSummary"
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractorTest.kt
new file mode 100644
index 0000000..07a95ae
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractorTest.kt
@@ -0,0 +1,221 @@
+/*
+ * 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.qs.tiles.dialog.bluetooth
+
+import android.bluetooth.BluetoothAdapter
+import android.bluetooth.BluetoothDevice
+import android.content.Context
+import android.media.AudioManager
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.UiEventLogger
+import com.android.settingslib.bluetooth.CachedBluetoothDevice
+import com.android.settingslib.bluetooth.LocalBluetoothManager
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.`when`
+import org.mockito.junit.MockitoJUnit
+import org.mockito.junit.MockitoRule
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+class DeviceItemInteractorTest : SysuiTestCase() {
+
+    @get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
+
+    @Mock private lateinit var bluetoothTileDialogRepository: BluetoothTileDialogRepository
+
+    @Mock private lateinit var cachedDevice1: CachedBluetoothDevice
+
+    @Mock private lateinit var cachedDevice2: CachedBluetoothDevice
+
+    @Mock private lateinit var device1: BluetoothDevice
+
+    @Mock private lateinit var device2: BluetoothDevice
+
+    @Mock private lateinit var deviceItem1: DeviceItem
+
+    @Mock private lateinit var deviceItem2: DeviceItem
+
+    @Mock private lateinit var audioManager: AudioManager
+
+    @Mock private lateinit var adapter: BluetoothAdapter
+
+    @Mock private lateinit var localBluetoothManager: LocalBluetoothManager
+
+    @Mock private lateinit var uiEventLogger: UiEventLogger
+
+    private lateinit var interactor: DeviceItemInteractor
+
+    private lateinit var dispatcher: CoroutineDispatcher
+
+    private lateinit var testScope: TestScope
+
+    @Before
+    fun setUp() {
+        dispatcher = StandardTestDispatcher()
+        testScope = TestScope(dispatcher)
+        interactor =
+            DeviceItemInteractor(
+                bluetoothTileDialogRepository,
+                audioManager,
+                adapter,
+                localBluetoothManager,
+                uiEventLogger,
+                testScope.backgroundScope,
+                dispatcher
+            )
+
+        `when`(deviceItem1.cachedBluetoothDevice).thenReturn(cachedDevice1)
+        `when`(deviceItem2.cachedBluetoothDevice).thenReturn(cachedDevice2)
+        `when`(cachedDevice1.device).thenReturn(device1)
+        `when`(cachedDevice2.device).thenReturn(device2)
+        `when`(bluetoothTileDialogRepository.cachedDevices)
+            .thenReturn(listOf(cachedDevice1, cachedDevice2))
+    }
+
+    @Test
+    fun testUpdateDeviceItems_noCachedDevice_returnEmpty() {
+        testScope.runTest {
+            `when`(bluetoothTileDialogRepository.cachedDevices).thenReturn(emptyList())
+            interactor.setDeviceItemFactoryListForTesting(
+                listOf(createFactory({ true }, deviceItem1))
+            )
+
+            interactor.updateDeviceItems(mContext)
+
+            assertThat(interactor.deviceItemFlow.value).isEmpty()
+        }
+    }
+
+    @Test
+    fun testUpdateDeviceItems_hasCachedDevice_filterNotMatch_returnEmpty() {
+        testScope.runTest {
+            `when`(bluetoothTileDialogRepository.cachedDevices).thenReturn(listOf(cachedDevice1))
+            interactor.setDeviceItemFactoryListForTesting(
+                listOf(createFactory({ false }, deviceItem1))
+            )
+
+            interactor.updateDeviceItems(mContext)
+
+            assertThat(interactor.deviceItemFlow.value).isEmpty()
+        }
+    }
+
+    @Test
+    fun testUpdateDeviceItems_hasCachedDevice_filterMatch_returnDeviceItem() {
+        testScope.runTest {
+            `when`(bluetoothTileDialogRepository.cachedDevices).thenReturn(listOf(cachedDevice1))
+            interactor.setDeviceItemFactoryListForTesting(
+                listOf(createFactory({ true }, deviceItem1))
+            )
+
+            interactor.updateDeviceItems(mContext)
+
+            assertThat(interactor.deviceItemFlow.value).hasSize(1)
+            assertThat(interactor.deviceItemFlow.value!![0]).isEqualTo(deviceItem1)
+        }
+    }
+
+    @Test
+    fun testUpdateDeviceItems_hasCachedDevice_filterMatch_returnMultipleDeviceItem() {
+        testScope.runTest {
+            `when`(adapter.mostRecentlyConnectedDevices).thenReturn(null)
+            interactor.setDeviceItemFactoryListForTesting(
+                listOf(createFactory({ false }, deviceItem1), createFactory({ true }, deviceItem2))
+            )
+
+            interactor.updateDeviceItems(mContext)
+
+            assertThat(interactor.deviceItemFlow.value).hasSize(2)
+            assertThat(interactor.deviceItemFlow.value!![0]).isEqualTo(deviceItem2)
+            assertThat(interactor.deviceItemFlow.value!![1]).isEqualTo(deviceItem2)
+        }
+    }
+
+    @Test
+    fun testUpdateDeviceItems_sortByDisplayPriority() {
+        testScope.runTest {
+            `when`(adapter.mostRecentlyConnectedDevices).thenReturn(null)
+            interactor.setDeviceItemFactoryListForTesting(
+                listOf(
+                    createFactory({ cachedDevice -> cachedDevice.device == device1 }, deviceItem1),
+                    createFactory({ cachedDevice -> cachedDevice.device == device2 }, deviceItem2)
+                )
+            )
+            interactor.setDisplayPriorityForTesting(
+                listOf(
+                    DeviceItemType.SAVED_BLUETOOTH_DEVICE,
+                    DeviceItemType.CONNECTED_BLUETOOTH_DEVICE
+                )
+            )
+            `when`(deviceItem1.type).thenReturn(DeviceItemType.CONNECTED_BLUETOOTH_DEVICE)
+            `when`(deviceItem2.type).thenReturn(DeviceItemType.SAVED_BLUETOOTH_DEVICE)
+
+            interactor.updateDeviceItems(mContext)
+
+            assertThat(interactor.deviceItemFlow.value).isEqualTo(listOf(deviceItem2, deviceItem1))
+        }
+    }
+
+    @Test
+    fun testUpdateDeviceItems_sameType_sortByRecentlyConnected() {
+        testScope.runTest {
+            `when`(adapter.mostRecentlyConnectedDevices).thenReturn(listOf(device2, device1))
+            interactor.setDeviceItemFactoryListForTesting(
+                listOf(
+                    createFactory({ cachedDevice -> cachedDevice.device == device1 }, deviceItem1),
+                    createFactory({ cachedDevice -> cachedDevice.device == device2 }, deviceItem2)
+                )
+            )
+            interactor.setDisplayPriorityForTesting(
+                listOf(DeviceItemType.CONNECTED_BLUETOOTH_DEVICE)
+            )
+            `when`(deviceItem1.type).thenReturn(DeviceItemType.CONNECTED_BLUETOOTH_DEVICE)
+            `when`(deviceItem2.type).thenReturn(DeviceItemType.CONNECTED_BLUETOOTH_DEVICE)
+
+            interactor.updateDeviceItems(mContext)
+
+            assertThat(interactor.deviceItemFlow.value).isEqualTo(listOf(deviceItem2, deviceItem1))
+        }
+    }
+
+    private fun createFactory(
+        isFilterMatchFunc: (CachedBluetoothDevice) -> Boolean,
+        deviceItem: DeviceItem
+    ): DeviceItemFactory {
+        return object : DeviceItemFactory() {
+            override fun isFilterMatched(
+                cachedDevice: CachedBluetoothDevice,
+                audioManager: AudioManager?
+            ) = isFilterMatchFunc(cachedDevice)
+
+            override fun create(context: Context, cachedDevice: CachedBluetoothDevice) = deviceItem
+        }
+    }
+}
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 55813f6..c108a80 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 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/scene/SceneFrameworkIntegrationTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
index 9c8d14d..6b918c6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
@@ -22,7 +22,6 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
 import com.android.systemui.authentication.domain.model.AuthenticationMethodModel as DomainLayerAuthenticationMethodModel
-import com.android.systemui.authentication.domain.model.AuthenticationMethodModel
 import com.android.systemui.bouncer.ui.viewmodel.PinBouncerViewModel
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.keyguard.shared.model.WakefulnessState
@@ -48,7 +47,9 @@
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
 import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.Job
 import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -159,6 +160,8 @@
             repository = keyguardRepository,
         )
 
+    private var bouncerSceneJob: Job? = null
+
     @Before
     fun setUp() {
         shadeHeaderViewModel =
@@ -288,7 +291,7 @@
     @Test
     fun withAuthMethodNone_deviceWakeUp_skipsLockscreen() =
         testScope.runTest {
-            setAuthMethod(AuthenticationMethodModel.None)
+            setAuthMethod(DomainLayerAuthenticationMethodModel.None)
             putDeviceToSleep(instantlyLockDevice = false)
             assertCurrentScene(SceneKey.Lockscreen)
 
@@ -299,7 +302,7 @@
     @Test
     fun withAuthMethodSwipe_deviceWakeUp_doesNotSkipLockscreen() =
         testScope.runTest {
-            setAuthMethod(AuthenticationMethodModel.Swipe)
+            setAuthMethod(DomainLayerAuthenticationMethodModel.Swipe)
             putDeviceToSleep(instantlyLockDevice = false)
             assertCurrentScene(SceneKey.Lockscreen)
 
@@ -364,6 +367,23 @@
             assertCurrentScene(SceneKey.Lockscreen)
         }
 
+    @Test
+    fun dismissingIme_whileOnPasswordBouncer_navigatesToLockscreen() =
+        testScope.runTest {
+            setAuthMethod(DomainLayerAuthenticationMethodModel.Password)
+            val upDestinationSceneKey by
+                collectLastValue(lockscreenSceneViewModel.upDestinationSceneKey)
+            assertThat(upDestinationSceneKey).isEqualTo(SceneKey.Bouncer)
+            emulateUserDrivenTransition(
+                to = upDestinationSceneKey,
+            )
+
+            dismissIme()
+
+            assertCurrentScene(SceneKey.Lockscreen)
+            emulateUiSceneTransition()
+        }
+
     /**
      * Asserts that the current scene in the view-model matches what's expected.
      *
@@ -396,7 +416,9 @@
         // Set the lockscreen enabled bit _before_ set the auth method as the code picks up on the
         // lockscreen enabled bit _after_ the auth method is changed and the lockscreen enabled bit
         // is not an observable that can trigger a new evaluation.
-        authenticationRepository.setLockscreenEnabled(authMethod !is AuthenticationMethodModel.None)
+        authenticationRepository.setLockscreenEnabled(
+            authMethod !is DomainLayerAuthenticationMethodModel.None
+        )
         authenticationRepository.setAuthenticationMethod(authMethod.toDataLayer())
         if (!authMethod.isSecure) {
             // When the auth method is not secure, the device is never considered locked.
@@ -455,6 +477,19 @@
         assertWithMessage("Visibility mismatch after scene transition from $from to ${to.key}!")
             .that(sceneContainerViewModel.isVisible.value)
             .isEqualTo(expectedVisible)
+
+        bouncerSceneJob =
+            if (to.key == SceneKey.Bouncer) {
+                testScope.backgroundScope.launch {
+                    bouncerViewModel.authMethod.collect {
+                        // Do nothing. Need this to turn this otherwise cold flow, hot.
+                    }
+                }
+            } else {
+                bouncerSceneJob?.cancel()
+                null
+            }
+        runCurrent()
     }
 
     /**
@@ -573,4 +608,16 @@
             lockDevice()
         }
     }
+
+    /** Emulates the dismissal of the IME (soft keyboard). */
+    private fun TestScope.dismissIme(
+        showImeBeforeDismissing: Boolean = true,
+    ) {
+        if (showImeBeforeDismissing) {
+            bouncerViewModel.authMethod.value?.onImeVisibilityChanged(true)
+        }
+
+        bouncerViewModel.authMethod.value?.onImeVisibilityChanged(false)
+        runCurrent()
+    }
 }
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 a6c25be..d470d24 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.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 ca4486b..36639d4 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.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 d672056..d4e8d37 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 @@
         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 31f7771..10bd6af 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 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 ab91d9f..0f33aaf 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.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 674ce9c..3d55527 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 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 ed1397f..152be65 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.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/settings/brightness/BrightnessSliderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderControllerTest.kt
index d75405f..707a297 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.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 @@
     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 @@
         whenever(motionEvent.copy()).thenReturn(motionEvent)
 
         mController =
-            BrightnessSliderController(brightnessSliderView, mFalsingManager, uiEventLogger)
+            BrightnessSliderController(
+                brightnessSliderView,
+                mFalsingManager,
+                uiEventLogger,
+                mBrightnessSliderHapticPlugin,
+            )
         mController.init()
         mController.setOnChangedListener(listener)
     }
@@ -94,6 +100,7 @@
         mController.onViewAttached()
 
         verify(brightnessSliderView).setOnSeekBarChangeListener(notNull())
+        verify(mBrightnessSliderHapticPlugin).start()
     }
 
     @Test
@@ -103,6 +110,7 @@
 
         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 0000000..51629b5
--- /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,
+            )
+    }
+}
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 0a1eca6..2b3588a 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.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 38a666e..bff408a 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.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 9130bc2..31c8a3d7 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.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 911cab4..37ec762 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 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 b0125f8..aead53e 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 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 dfd782b..2d00e8c 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 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 3da5f6a..9651072 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.shade
 
+import android.os.Handler
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
 import android.view.KeyEvent
@@ -24,29 +25,42 @@
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardMessageAreaController
 import com.android.keyguard.KeyguardSecurityContainerController
+import com.android.keyguard.KeyguardSecurityModel
+import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.LockIconViewController
 import com.android.keyguard.dagger.KeyguardBouncerComponent
-import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.back.domain.interactor.BackActionInteractor
-import com.android.systemui.bouncer.data.factory.BouncerMessageFactory
-import com.android.systemui.bouncer.data.repository.FakeBouncerMessageRepository
+import com.android.systemui.biometrics.data.repository.FakeFacePropertyRepository
+import com.android.systemui.bouncer.data.repository.BouncerMessageRepositoryImpl
+import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository
 import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor
 import com.android.systemui.bouncer.domain.interactor.CountDownTimerUtil
+import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerCallbackInteractor
+import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
+import com.android.systemui.bouncer.ui.BouncerView
 import com.android.systemui.bouncer.ui.viewmodel.KeyguardBouncerViewModel
+import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.classifier.FalsingCollectorFake
 import com.android.systemui.dock.DockManager
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.dump.logcatLogBuffer
 import com.android.systemui.flags.FakeFeatureFlags
 import com.android.systemui.flags.Flags
+import com.android.systemui.flags.SystemPropertiesHelper
 import com.android.systemui.keyevent.domain.interactor.KeyEventInteractor
+import com.android.systemui.keyguard.DismissCallbackRegistry
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController
+import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository
+import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFaceAuthRepository
+import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository
+import com.android.systemui.keyguard.data.repository.FakeTrustRepository
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.TransitionStep
 import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel
 import com.android.systemui.log.BouncerLogger
 import com.android.systemui.power.domain.interactor.PowerInteractor
+import com.android.systemui.res.R
 import com.android.systemui.shade.NotificationShadeWindowView.InteractionEventHandler
 import com.android.systemui.statusbar.DragDownHelper
 import com.android.systemui.statusbar.LockscreenShadeTransitionController
@@ -62,6 +76,7 @@
 import com.android.systemui.statusbar.phone.DozeServiceHost
 import com.android.systemui.statusbar.phone.PhoneStatusBarViewController
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
+import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.statusbar.window.StatusBarWindowStateController
 import com.android.systemui.unfold.UnfoldTransitionProgressProvider
 import com.android.systemui.user.data.repository.FakeUserRepository
@@ -201,11 +216,35 @@
                 featureFlags,
                 fakeClock,
                 BouncerMessageInteractor(
-                    FakeBouncerMessageRepository(),
-                    mock(BouncerMessageFactory::class.java),
-                    FakeUserRepository(),
-                    CountDownTimerUtil(),
-                    featureFlags
+                    repository = BouncerMessageRepositoryImpl(),
+                    userRepository = FakeUserRepository(),
+                    countDownTimerUtil = mock(CountDownTimerUtil::class.java),
+                    featureFlags = featureFlags,
+                    updateMonitor = mock(KeyguardUpdateMonitor::class.java),
+                    biometricSettingsRepository = FakeBiometricSettingsRepository(),
+                    applicationScope = testScope.backgroundScope,
+                    trustRepository = FakeTrustRepository(),
+                    systemPropertiesHelper = mock(SystemPropertiesHelper::class.java),
+                    primaryBouncerInteractor =
+                        PrimaryBouncerInteractor(
+                            FakeKeyguardBouncerRepository(),
+                            mock(BouncerView::class.java),
+                            mock(Handler::class.java),
+                            mock(KeyguardStateController::class.java),
+                            mock(KeyguardSecurityModel::class.java),
+                            mock(PrimaryBouncerCallbackInteractor::class.java),
+                            mock(FalsingCollector::class.java),
+                            mock(DismissCallbackRegistry::class.java),
+                            context,
+                            mock(KeyguardUpdateMonitor::class.java),
+                            FakeTrustRepository(),
+                            testScope.backgroundScope,
+                        ),
+                    facePropertyRepository = FakeFacePropertyRepository(),
+                    deviceEntryFingerprintAuthRepository =
+                        FakeDeviceEntryFingerprintAuthRepository(),
+                    faceAuthRepository = FakeDeviceEntryFaceAuthRepository(),
+                    securityModel = mock(KeyguardSecurityModel::class.java),
                 ),
                 BouncerLogger(logcatLogBuffer("BouncerLog")),
                 keyEventInteractor,
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 04c4b45..0023020 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
@@ -15,6 +15,7 @@
  */
 package com.android.systemui.shade
 
+import android.os.Handler
 import android.os.SystemClock
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
@@ -23,28 +24,41 @@
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardMessageAreaController
 import com.android.keyguard.KeyguardSecurityContainerController
+import com.android.keyguard.KeyguardSecurityModel
+import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.LockIconViewController
 import com.android.keyguard.dagger.KeyguardBouncerComponent
-import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.back.domain.interactor.BackActionInteractor
-import com.android.systemui.bouncer.data.factory.BouncerMessageFactory
-import com.android.systemui.bouncer.data.repository.FakeBouncerMessageRepository
+import com.android.systemui.biometrics.data.repository.FakeFacePropertyRepository
+import com.android.systemui.bouncer.data.repository.BouncerMessageRepositoryImpl
+import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository
 import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor
 import com.android.systemui.bouncer.domain.interactor.CountDownTimerUtil
+import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerCallbackInteractor
+import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
+import com.android.systemui.bouncer.ui.BouncerView
 import com.android.systemui.bouncer.ui.viewmodel.KeyguardBouncerViewModel
+import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.classifier.FalsingCollectorFake
 import com.android.systemui.dock.DockManager
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.dump.logcatLogBuffer
 import com.android.systemui.flags.FakeFeatureFlags
 import com.android.systemui.flags.Flags
+import com.android.systemui.flags.SystemPropertiesHelper
 import com.android.systemui.keyevent.domain.interactor.KeyEventInteractor
+import com.android.systemui.keyguard.DismissCallbackRegistry
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController
+import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository
+import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFaceAuthRepository
+import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository
+import com.android.systemui.keyguard.data.repository.FakeTrustRepository
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
 import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel
 import com.android.systemui.log.BouncerLogger
 import com.android.systemui.power.domain.interactor.PowerInteractor
+import com.android.systemui.res.R
 import com.android.systemui.shade.NotificationShadeWindowView.InteractionEventHandler
 import com.android.systemui.statusbar.DragDownHelper
 import com.android.systemui.statusbar.LockscreenShadeTransitionController
@@ -60,6 +74,7 @@
 import com.android.systemui.statusbar.phone.DozeScrimController
 import com.android.systemui.statusbar.phone.DozeServiceHost
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
+import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.statusbar.window.StatusBarWindowStateController
 import com.android.systemui.unfold.UnfoldTransitionProgressProvider
 import com.android.systemui.user.data.repository.FakeUserRepository
@@ -203,11 +218,35 @@
                 featureFlags,
                 FakeSystemClock(),
                 BouncerMessageInteractor(
-                    FakeBouncerMessageRepository(),
-                    Mockito.mock(BouncerMessageFactory::class.java),
-                    FakeUserRepository(),
-                    CountDownTimerUtil(),
-                    featureFlags
+                    repository = BouncerMessageRepositoryImpl(),
+                    userRepository = FakeUserRepository(),
+                    countDownTimerUtil = Mockito.mock(CountDownTimerUtil::class.java),
+                    featureFlags = featureFlags,
+                    updateMonitor = Mockito.mock(KeyguardUpdateMonitor::class.java),
+                    biometricSettingsRepository = FakeBiometricSettingsRepository(),
+                    applicationScope = testScope.backgroundScope,
+                    trustRepository = FakeTrustRepository(),
+                    systemPropertiesHelper = Mockito.mock(SystemPropertiesHelper::class.java),
+                    primaryBouncerInteractor =
+                        PrimaryBouncerInteractor(
+                            FakeKeyguardBouncerRepository(),
+                            Mockito.mock(BouncerView::class.java),
+                            Mockito.mock(Handler::class.java),
+                            Mockito.mock(KeyguardStateController::class.java),
+                            Mockito.mock(KeyguardSecurityModel::class.java),
+                            Mockito.mock(PrimaryBouncerCallbackInteractor::class.java),
+                            Mockito.mock(FalsingCollector::class.java),
+                            Mockito.mock(DismissCallbackRegistry::class.java),
+                            context,
+                            Mockito.mock(KeyguardUpdateMonitor::class.java),
+                            FakeTrustRepository(),
+                            testScope.backgroundScope,
+                        ),
+                    facePropertyRepository = FakeFacePropertyRepository(),
+                    deviceEntryFingerprintAuthRepository =
+                        FakeDeviceEntryFingerprintAuthRepository(),
+                    faceAuthRepository = FakeDeviceEntryFaceAuthRepository(),
+                    securityModel = Mockito.mock(KeyguardSecurityModel::class.java),
                 ),
                 BouncerLogger(logcatLogBuffer("BouncerLog")),
                 Mockito.mock(KeyEventInteractor::class.java),
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 e9e6d31..e70dbc7 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.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 6801f2f..ac8c924 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.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 8bb8f62..f7d2497 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.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 d421aca..2cd740d 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.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 849127e..fb0d4db 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.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 6d288e1..5ca45f3 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 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 7d5f68e..56061f6 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.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 dae9c97..a657edf 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 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 342b1c5..d018cbb 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 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 36f82c2..a844bff 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 @@
 
 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 f5a24ff..eb418fd 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.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 e92368d..7b0cd19 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.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 3f3faf7..bd3dae4 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.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 280897d..b98dc00 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 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 d44846e..63e46d1 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.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 1240f26..2bcad1d 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 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 673d63f..0b4de34 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 @@
 
 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 2c9dfcc..6e990a7 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.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 a258f67..68bc72b 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.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 c75aa81..544860e 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 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 8d016e3..1592c30 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 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/VibratorHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/VibratorHelperTest.kt
index aab4bc3..b905825 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/VibratorHelperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/VibratorHelperTest.kt
@@ -75,6 +75,18 @@
     }
 
     @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
         vibratorHelper.performHapticFeedback(view, constant)
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 2d29c80..44e3bb4 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 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 @@
     @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 35b9814..375ca063 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 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 88ddc2d..31e1fef 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_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 524ead2..a59ba07 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.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 470d340..d86f8bb 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.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 f0abf2f..c664c39 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.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 90f6201..ccc9dc0 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 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 daa45db..f05436f 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 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 3f61af0..ccef1d5 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.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 c650e01..d52cbce 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.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
@@ -70,7 +70,7 @@
     }
     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 @@
         }
 
     @Test
-    fun onIconUpdated_notSupportedType_fullImageLoaded() =
+    fun onIconUpdated_unsupportedType_fullImageLoaded() =
         testScope.runTest {
             // WHEN update with an unsupported icon
             iconManager.updateIcon(mockConsumer, unsupportedIcon).run()
@@ -112,6 +112,16 @@
         }
 
     @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 {
             // WHEN update with an invalid icon
@@ -153,6 +163,43 @@
         }
 
     @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 {
+            // GIVEN an unsupported icon is set
+            iconManager.updateIcon(mockConsumer, unsupportedIcon).run()
+            // AND the view is shown
+            iconManager.onViewShown(true)
+            runCurrent()
+            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 +296,10 @@
             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)
 
@@ -267,10 +312,45 @@
         }
 
     @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 {
+            // 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 +376,7 @@
             iconManager.onViewShown(true)
             runCurrent()
 
+            // THEN nothing happens
             verifyZeroInteractions(mockConsumer)
         }
 
@@ -303,7 +384,7 @@
     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()
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 cf1d2ca..c9b77c5 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.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 90cb734..b120c47 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 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 e52cb57..b0996ad 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 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 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 596e9a2..1763d9b 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 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 fdfb4f4..7f9471e 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.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 8dd0488..f0b4dd4 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 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 f8f7af0..0a15f0d 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.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 6386940..ac680e6 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.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 @@
         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 12c8fd5..e42ce27 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 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 0909ff2..f4e236e 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.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 1dc0ab0..957cb88 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.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 4307066..3a820e8 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 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;
@@ -154,6 +154,7 @@
         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,
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 bc12bb0..2b3f9d0 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.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 d9c3c3c..a52466d 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.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 7fc399b..198f278 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 @@
 
 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 bfc0910..e254dd0 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 @@
 
 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 e4a2236..416694b 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 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 26c0fd6..5c3dde5 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.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 bb20d18..1bc522d 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 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 4aac841..ab441e3 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.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 5d2b59b..03f5f00 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 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 79f8dbd..2b1ce0e 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.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 fe12051..e88fd95 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 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 47f15a1..c5abd02 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.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 b70c6dd..d25a06b 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 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 4af1b24..c4568a9 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 @@
 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 3a629e6..b7560ad 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.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 63508e1..1455693 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.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 b8f2cab..bcb34d6 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 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 ec074d7..f0a457e 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.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 c3326b2..7e25aa3 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.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 dc5d55e..32320b4 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.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 5784be3..6028712 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 @@
 
 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 59fc0ac..218fd33 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.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 6624ec2..15b9d61 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,8 +17,9 @@
 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
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.log.table.TableLogBuffer
@@ -42,6 +43,7 @@
 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 @@
     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 @@
                     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 @@
             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 @@
                 .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 @@
             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 @@
                 .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 @@
                 .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) {
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 bbf048d..a27f899 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.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 6557754..fb4ccb5 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 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 e5bbead..64ebcd9 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 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 dc08aba..3fae3f6 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 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 e431865..bf280c9 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.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 b86ca6f..1250228 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.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 1ab62d0..0bd6a68 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.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 cfb48a8..635d63e 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.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 79feb41..658e6b0 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 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 e4e0dc9..3555a74 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.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 ae38958e..4b6c68a 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 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 d212c02..5b9db4b 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 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 98bbb26..ae4dfbd 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 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 8c21fac..1e7e184 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.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 7593e84..85359ca 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 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 @@
 
         // 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 @@
 
         // 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 5a54aff..bbc49c8 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.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 @@
         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 aa9d62da..8e57dc1 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 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 53e5e7d..8263174 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 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 7595a54..d8511e8 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.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 @@
                 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 5ff57aa..2d76027 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.view.Display;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.systemui.res.R;
 
 import java.util.Set;
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeDisplayStateRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeDisplayStateRepository.kt
index 60291ee..3fdeb30 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeDisplayStateRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeDisplayStateRepository.kt
@@ -29,6 +29,8 @@
     private val _currentRotation = MutableStateFlow<DisplayRotation>(DisplayRotation.ROTATION_0)
     override val currentRotation: StateFlow<DisplayRotation> = _currentRotation.asStateFlow()
 
+    override val isReverseDefaultRotation = false
+
     fun setIsInRearDisplayMode(isInRearDisplayMode: Boolean) {
         _isInRearDisplayMode.value = isInRearDisplayMode
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/data/repository/FakeBouncerMessageRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/data/repository/FakeBouncerMessageRepository.kt
deleted file mode 100644
index d9b926d..0000000
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/data/repository/FakeBouncerMessageRepository.kt
+++ /dev/null
@@ -1,83 +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.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.bouncer.data.repository
-
-import com.android.systemui.bouncer.shared.model.BouncerMessageModel
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.StateFlow
-
-class FakeBouncerMessageRepository : BouncerMessageRepository {
-    private val _primaryAuthMessage = MutableStateFlow<BouncerMessageModel?>(null)
-    override val primaryAuthMessage: StateFlow<BouncerMessageModel?>
-        get() = _primaryAuthMessage
-
-    private val _faceAcquisitionMessage = MutableStateFlow<BouncerMessageModel?>(null)
-    override val faceAcquisitionMessage: StateFlow<BouncerMessageModel?>
-        get() = _faceAcquisitionMessage
-    private val _fingerprintAcquisitionMessage = MutableStateFlow<BouncerMessageModel?>(null)
-    override val fingerprintAcquisitionMessage: StateFlow<BouncerMessageModel?>
-        get() = _fingerprintAcquisitionMessage
-    private val _customMessage = MutableStateFlow<BouncerMessageModel?>(null)
-    override val customMessage: StateFlow<BouncerMessageModel?>
-        get() = _customMessage
-    private val _biometricAuthMessage = MutableStateFlow<BouncerMessageModel?>(null)
-    override val biometricAuthMessage: StateFlow<BouncerMessageModel?>
-        get() = _biometricAuthMessage
-    private val _authFlagsMessage = MutableStateFlow<BouncerMessageModel?>(null)
-    override val authFlagsMessage: StateFlow<BouncerMessageModel?>
-        get() = _authFlagsMessage
-
-    private val _biometricLockedOutMessage = MutableStateFlow<BouncerMessageModel?>(null)
-    override val biometricLockedOutMessage: Flow<BouncerMessageModel?>
-        get() = _biometricLockedOutMessage
-
-    override fun setPrimaryAuthMessage(value: BouncerMessageModel?) {
-        _primaryAuthMessage.value = value
-    }
-
-    override fun setFaceAcquisitionMessage(value: BouncerMessageModel?) {
-        _faceAcquisitionMessage.value = value
-    }
-
-    override fun setFingerprintAcquisitionMessage(value: BouncerMessageModel?) {
-        _fingerprintAcquisitionMessage.value = value
-    }
-
-    override fun setCustomMessage(value: BouncerMessageModel?) {
-        _customMessage.value = value
-    }
-
-    fun setBiometricAuthMessage(value: BouncerMessageModel?) {
-        _biometricAuthMessage.value = value
-    }
-
-    fun setAuthFlagsMessage(value: BouncerMessageModel?) {
-        _authFlagsMessage.value = value
-    }
-
-    fun setBiometricLockedOutMessage(value: BouncerMessageModel?) {
-        _biometricLockedOutMessage.value = value
-    }
-
-    override fun clearMessage() {
-        _primaryAuthMessage.value = null
-        _faceAcquisitionMessage.value = null
-        _fingerprintAcquisitionMessage.value = null
-        _customMessage.value = null
-    }
-}
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 16442bb..dd513db 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 @@
     }
 
     override fun startTransition(info: TransitionInfo, resetIfCanceled: Boolean): UUID? {
-        return null
+        return if (info.animator == null) UUID.randomUUID() else null
     }
 
     override fun updateTransition(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeTrustRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeTrustRepository.kt
index 9d98f94..482126d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeTrustRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeTrustRepository.kt
@@ -25,6 +25,9 @@
 import kotlinx.coroutines.flow.asStateFlow
 
 class FakeTrustRepository : TrustRepository {
+    private val _isTrustUsuallyManaged = MutableStateFlow(false)
+    override val isCurrentUserTrustUsuallyManaged: StateFlow<Boolean>
+        get() = _isTrustUsuallyManaged
     private val _isCurrentUserTrusted = MutableStateFlow(false)
     override val isCurrentUserTrusted: Flow<Boolean>
         get() = _isCurrentUserTrusted
@@ -55,4 +58,8 @@
     fun setRequestDismissKeyguard(trustModel: TrustModel) {
         _requestDismissKeyguard.value = trustModel
     }
+
+    fun setTrustUsuallyManaged(value: Boolean) {
+        _isTrustUsuallyManaged.value = value
+    }
 }
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 6dd41f4..ceab8e9 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 @@
         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 @@
                 context,
                 keyguardUpdateMonitor,
                 trustRepository,
-                featureFlags,
                 testScope.backgroundScope,
             )
         val alternateBouncerInteractor =
diff --git a/packages/SystemUI/unfold/Android.bp b/packages/SystemUI/unfold/Android.bp
index 1f0181f..81fd8ce 100644
--- a/packages/SystemUI/unfold/Android.bp
+++ b/packages/SystemUI/unfold/Android.bp
@@ -23,6 +23,7 @@
 
 android_library {
     name: "SystemUIUnfoldLib",
+    use_resource_processor: true,
     srcs: [
         "src/**/*.java",
         "src/**/*.kt",
diff --git a/services/Android.bp b/services/Android.bp
index 9264172..f237095 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -34,17 +34,18 @@
     },
 }
 
-// Opt-in config for optimizing and shrinking the services target using R8.
-// Enabled via `export SYSTEM_OPTIMIZE_JAVA=true`, or explicitly in Make via the
+// Config to control optimizing and shrinking the services target using R8.
+// Set via `export SYSTEM_OPTIMIZE_JAVA=true|false`, or explicitly in Make via the
 // `SOONG_CONFIG_ANDROID_SYSTEM_OPTIMIZE_JAVA` variable.
-// TODO(b/196084106): Enable optimizations by default after stabilizing and
-// building out retrace infrastructure.
 soong_config_module_type {
     name: "system_optimized_java_defaults",
     module_type: "java_defaults",
     config_namespace: "ANDROID",
     bool_variables: ["SYSTEM_OPTIMIZE_JAVA"],
-    properties: ["optimize"],
+    properties: [
+        "optimize",
+        "dxflags",
+    ],
 }
 
 system_optimized_java_defaults {
@@ -75,6 +76,9 @@
                     // permission subpackage to prune unused jarjar'ed Kotlin dependencies.
                     proguard_flags_files: ["proguard_permission.flags"],
                 },
+                // Explicitly configure R8 to preserve debug info, as this path should
+                // really only allow stripping of permission-specific code and deps.
+                dxflags: ["--debug"],
             },
         },
     },
diff --git a/services/accessibility/accessibility.aconfig b/services/accessibility/accessibility.aconfig
index 3709f47..0480c22 100644
--- a/services/accessibility/accessibility.aconfig
+++ b/services/accessibility/accessibility.aconfig
@@ -19,4 +19,11 @@
     namespace: "accessibility"
     description: "Whether to enable joystick controls for magnification"
     bug: "297211257"
+}
+
+flag {
+    name: "send_a11y_events_based_on_state"
+    namespace: "accessibility"
+    description: "Sends accessibility events in TouchExplorer#onAccessibilityEvent based on internal state to keep it consistent. This reduces test flakiness."
+bug: "295575684"
 }
\ No newline at end of file
diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
index 44ffb51..05b6eb4 100644
--- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
@@ -56,6 +56,7 @@
 import android.graphics.Region;
 import android.hardware.HardwareBuffer;
 import android.hardware.display.DisplayManager;
+import android.hardware.display.DisplayManagerInternal;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
@@ -97,6 +98,7 @@
 import com.android.internal.os.SomeArgs;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.function.pooled.PooledLambda;
+import com.android.server.LocalServices;
 import com.android.server.accessibility.AccessibilityWindowManager.RemoteAccessibilityConnection;
 import com.android.server.accessibility.magnification.MagnificationProcessor;
 import com.android.server.inputmethod.InputMethodManagerInternal;
@@ -1439,24 +1441,19 @@
                     AccessibilityService.ERROR_TAKE_SCREENSHOT_INVALID_DISPLAY, callback);
             return;
         }
+
         final long identity = Binder.clearCallingIdentity();
         try {
-            ScreenCapture.ScreenCaptureListener screenCaptureListener = new
-                    ScreenCapture.ScreenCaptureListener(
-                    (screenshotBuffer, result) -> {
-                        if (screenshotBuffer != null && result == 0) {
-                            sendScreenshotSuccess(screenshotBuffer, callback);
-                        } else {
-                            sendScreenshotFailure(
-                                    AccessibilityService.ERROR_TAKE_SCREENSHOT_INVALID_DISPLAY,
-                                    callback);
-                        }
-                    }
-            );
-            mWindowManagerService.captureDisplay(displayId, null, screenCaptureListener);
-        } catch (Exception e) {
-            sendScreenshotFailure(AccessibilityService.ERROR_TAKE_SCREENSHOT_INVALID_DISPLAY,
-                    callback);
+            mMainHandler.post(PooledLambda.obtainRunnable((nonArg) -> {
+                final ScreenshotHardwareBuffer screenshotBuffer = LocalServices
+                        .getService(DisplayManagerInternal.class).userScreenshot(displayId);
+                if (screenshotBuffer != null) {
+                    sendScreenshotSuccess(screenshotBuffer, callback);
+                } else {
+                    sendScreenshotFailure(
+                            AccessibilityService.ERROR_TAKE_SCREENSHOT_INVALID_DISPLAY, callback);
+                }
+            }, null).recycleOnUse());
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -1464,24 +1461,22 @@
 
     private void sendScreenshotSuccess(ScreenshotHardwareBuffer screenshotBuffer,
             RemoteCallback callback) {
-        mMainHandler.post(PooledLambda.obtainRunnable((nonArg) -> {
-            final HardwareBuffer hardwareBuffer = screenshotBuffer.getHardwareBuffer();
-            final ParcelableColorSpace colorSpace =
-                    new ParcelableColorSpace(screenshotBuffer.getColorSpace());
+        final HardwareBuffer hardwareBuffer = screenshotBuffer.getHardwareBuffer();
+        final ParcelableColorSpace colorSpace =
+                new ParcelableColorSpace(screenshotBuffer.getColorSpace());
 
-            final Bundle payload = new Bundle();
-            payload.putInt(KEY_ACCESSIBILITY_SCREENSHOT_STATUS,
-                    AccessibilityService.TAKE_SCREENSHOT_SUCCESS);
-            payload.putParcelable(KEY_ACCESSIBILITY_SCREENSHOT_HARDWAREBUFFER,
-                    hardwareBuffer);
-            payload.putParcelable(KEY_ACCESSIBILITY_SCREENSHOT_COLORSPACE, colorSpace);
-            payload.putLong(KEY_ACCESSIBILITY_SCREENSHOT_TIMESTAMP,
-                    SystemClock.uptimeMillis());
+        final Bundle payload = new Bundle();
+        payload.putInt(KEY_ACCESSIBILITY_SCREENSHOT_STATUS,
+                AccessibilityService.TAKE_SCREENSHOT_SUCCESS);
+        payload.putParcelable(KEY_ACCESSIBILITY_SCREENSHOT_HARDWAREBUFFER,
+                hardwareBuffer);
+        payload.putParcelable(KEY_ACCESSIBILITY_SCREENSHOT_COLORSPACE, colorSpace);
+        payload.putLong(KEY_ACCESSIBILITY_SCREENSHOT_TIMESTAMP,
+                SystemClock.uptimeMillis());
 
-            // Send back the result.
-            callback.sendResult(payload);
-            hardwareBuffer.close();
-        }, null).recycleOnUse());
+        // Send back the result.
+        callback.sendResult(payload);
+        hardwareBuffer.close();
     }
 
     private void sendScreenshotFailure(@AccessibilityService.ScreenshotErrorCode int errorCode,
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
index 8060d5a..c418485 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
@@ -58,6 +58,7 @@
 import com.android.server.accessibility.AccessibilityManagerService;
 import com.android.server.accessibility.BaseEventStreamTransformation;
 import com.android.server.accessibility.EventStreamTransformation;
+import com.android.server.accessibility.Flags;
 import com.android.server.policy.WindowManagerPolicy;
 
 import java.util.ArrayList;
@@ -352,16 +353,34 @@
         }
         // The event for gesture end should be strictly after the
         // last hover exit event.
-        if (mSendTouchExplorationEndDelayed.isPending()) {
-            mSendTouchExplorationEndDelayed.cancel();
-            mDispatcher.sendAccessibilityEvent(TYPE_TOUCH_EXPLORATION_GESTURE_END);
-        }
+        if (Flags.sendA11yEventsBasedOnState()) {
+            if (mSendTouchExplorationEndDelayed.isPending()) {
+                mSendTouchExplorationEndDelayed.cancel();
+            }
+            if (mState.isTouchExploring()) {
+                mDispatcher.sendAccessibilityEvent(TYPE_TOUCH_EXPLORATION_GESTURE_END);
+            }
 
-        // The event for touch interaction end should be strictly after the
-        // last hover exit and the touch exploration gesture end events.
-        if (mSendTouchInteractionEndDelayed.isPending()) {
-            mSendTouchInteractionEndDelayed.cancel();
-            mDispatcher.sendAccessibilityEvent(TYPE_TOUCH_INTERACTION_END);
+            // The event for touch interaction end should be strictly after the
+            // last hover exit and the touch exploration gesture end events.
+            if (mSendTouchInteractionEndDelayed.isPending()) {
+                mSendTouchInteractionEndDelayed.cancel();
+            }
+            if (mState.isTouchInteracting()) {
+                mDispatcher.sendAccessibilityEvent(TYPE_TOUCH_INTERACTION_END);
+            }
+        } else {
+            if (mSendTouchExplorationEndDelayed.isPending()) {
+                mSendTouchExplorationEndDelayed.cancel();
+                mDispatcher.sendAccessibilityEvent(TYPE_TOUCH_EXPLORATION_GESTURE_END);
+            }
+
+            // The event for touch interaction end should be strictly after the
+            // last hover exit and the touch exploration gesture end events.
+            if (mSendTouchInteractionEndDelayed.isPending()) {
+                mSendTouchInteractionEndDelayed.cancel();
+                mDispatcher.sendAccessibilityEvent(TYPE_TOUCH_INTERACTION_END);
+            }
         }
     }
 
diff --git a/services/autofill/java/com/android/server/autofill/FieldClassificationEventLogger.java b/services/autofill/java/com/android/server/autofill/FieldClassificationEventLogger.java
index ffb4632..db2e18a0 100644
--- a/services/autofill/java/com/android/server/autofill/FieldClassificationEventLogger.java
+++ b/services/autofill/java/com/android/server/autofill/FieldClassificationEventLogger.java
@@ -17,12 +17,19 @@
 package com.android.server.autofill;
 
 import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED__STATUS__STATUS_CANCELLED;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED__STATUS__STATUS_FAIL;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED__STATUS__STATUS_SUCCESS;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED__STATUS__STATUS_UNKNOWN;
 import static com.android.server.autofill.Helper.sVerbose;
 
+import android.annotation.IntDef;
 import android.util.Slog;
 
 import com.android.internal.util.FrameworkStatsLog;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.Optional;
 
 /**
@@ -36,6 +43,29 @@
         mEventInternal = Optional.empty();
     }
 
+    public static final int STATUS_SUCCESS =
+            AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED__STATUS__STATUS_SUCCESS;
+    public static final int STATUS_UNKNOWN =
+            AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED__STATUS__STATUS_UNKNOWN;
+    public static final int STATUS_FAIL =
+            AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED__STATUS__STATUS_FAIL;
+    public static final int STATUS_CANCELLED =
+            AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED__STATUS__STATUS_CANCELLED;
+
+    /**
+     * Status of the FieldClassification IPC request. These are wrappers around
+     * {@link com.android.os.AtomsProto.AutofillFieldClassificationEventReported.FieldClassificationRequestStatus}.
+     */
+    @IntDef(prefix = {"STATUS"}, value = {
+            STATUS_UNKNOWN,
+            STATUS_SUCCESS,
+            STATUS_FAIL,
+            STATUS_CANCELLED
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FieldClassificationStatus {
+    }
+
     /**
      * A factory constructor to create FieldClassificationEventLogger.
      */
@@ -56,7 +86,7 @@
     }
 
     /**
-     * Set latency as long as mEventInternal presents.
+     * Set latency_millis as long as mEventInternal presents.
      */
     public void maybeSetLatencyMillis(long timestamp) {
         mEventInternal.ifPresent(event -> {
@@ -65,6 +95,69 @@
     }
 
     /**
+     * Set count_classifications as long as mEventInternal presents.
+     */
+    public void maybeSetCountClassifications(int countClassifications) {
+        mEventInternal.ifPresent(event -> {
+            event.mCountClassifications = countClassifications;
+        });
+    }
+
+    /**
+     * Set session_id as long as mEventInternal presents.
+     */
+    public void maybeSetSessionId(int sessionId) {
+        mEventInternal.ifPresent(event -> {
+            event.mSessionId = sessionId;
+        });
+    }
+
+    /**
+     * Set request_id as long as mEventInternal presents.
+     */
+    public void maybeSetRequestId(int requestId) {
+        mEventInternal.ifPresent(event -> {
+            event.mRequestId = requestId;
+        });
+    }
+
+    /**
+     * Set next_fill_request_id as long as mEventInternal presents.
+     */
+    public void maybeSetNextFillRequestId(int nextFillRequestId) {
+        mEventInternal.ifPresent(event -> {
+            event.mNextFillRequestId = nextFillRequestId;
+        });
+    }
+
+    /**
+     * Set app_package_uid as long as mEventInternal presents.
+     */
+    public void maybeSetAppPackageUid(int uid) {
+        mEventInternal.ifPresent(event -> {
+            event.mAppPackageUid = uid;
+        });
+    }
+
+    /**
+     * Set status as long as mEventInternal presents.
+     */
+    public void maybeSetRequestStatus(@FieldClassificationStatus int status) {
+        mEventInternal.ifPresent(event -> {
+            event.mStatus = status;
+        });
+    }
+
+    /**
+     * Set is_session_gc as long as mEventInternal presents.
+     */
+    public void maybeSetSessionGc(boolean isSessionGc) {
+        mEventInternal.ifPresent(event -> {
+            event.mIsSessionGc = isSessionGc;
+        });
+    }
+
+    /**
      * Log an AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED event.
      */
     public void logAndEndEvent() {
@@ -77,16 +170,37 @@
         if (sVerbose) {
             Slog.v(TAG, "Log AutofillFieldClassificationEventReported:"
                     + " mLatencyClassificationRequestMillis="
-                    + event.mLatencyClassificationRequestMillis);
+                    + event.mLatencyClassificationRequestMillis
+                    + " mCountClassifications=" + event.mCountClassifications
+                    + " mSessionId=" + event.mSessionId
+                    + " mRequestId=" + event.mRequestId
+                    + " mNextFillRequestId=" + event.mNextFillRequestId
+                    + " mAppPackageUid=" + event.mAppPackageUid
+                    + " mStatus=" + event.mStatus
+                    + " mIsSessionGc=" + event.mIsSessionGc);
         }
         FrameworkStatsLog.write(
                 AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED,
-                event.mLatencyClassificationRequestMillis);
+                event.mLatencyClassificationRequestMillis,
+                event.mCountClassifications,
+                event.mSessionId,
+                event.mRequestId,
+                event.mNextFillRequestId,
+                event.mAppPackageUid,
+                event.mStatus,
+                event.mIsSessionGc);
         mEventInternal = Optional.empty();
     }
 
     private static final class FieldClassificationEventInternal {
         long mLatencyClassificationRequestMillis = -1;
+        int mCountClassifications = -1;
+        int mSessionId = -1;
+        int mRequestId = -1;
+        int mNextFillRequestId = -1;
+        int mAppPackageUid = -1;
+        int mStatus;
+        boolean mIsSessionGc;
 
         FieldClassificationEventInternal() {
         }
diff --git a/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java b/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
index 11b45db..6b0fdb5 100644
--- a/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
+++ b/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
@@ -211,15 +211,25 @@
     public static final int DETECTION_PREFER_PCC =
             AUTOFILL_FILL_RESPONSE_REPORTED__DETECTION_PREFERENCE__DETECTION_PREFER_PCC;
     private final int mSessionId;
+
+    /**
+     * For app_package_uid.
+     */
+    private final int mCallingAppUid;
     private Optional<PresentationStatsEventInternal> mEventInternal;
 
-    private PresentationStatsEventLogger(int sessionId) {
+    private PresentationStatsEventLogger(int sessionId, int callingAppUid) {
         mSessionId = sessionId;
+        mCallingAppUid = callingAppUid;
         mEventInternal = Optional.empty();
     }
 
-    public static PresentationStatsEventLogger forSessionId(int sessionId) {
-        return new PresentationStatsEventLogger(sessionId);
+    /**
+     * Create PresentationStatsEventLogger, populated with sessionId and the callingAppUid
+     */
+    public static PresentationStatsEventLogger createPresentationLog(
+            int sessionId, int callingAppUid) {
+        return new PresentationStatsEventLogger(sessionId, callingAppUid);
     }
 
     public void startNewEvent() {
@@ -508,6 +518,14 @@
         return PICK_REASON_UNKNOWN;
     }
 
+    /**
+     * Set field_classification_request_id as long as mEventInternal presents.
+     */
+    public void maybeSetFieldClassificationRequestId(int requestId) {
+        mEventInternal.ifPresent(event -> {
+            event.mFieldClassificationRequestId = requestId;
+        });
+    }
 
     public void logAndEndEvent() {
         if (!mEventInternal.isPresent()) {
@@ -547,7 +565,9 @@
                     + " mAvailablePccCount=" + event.mAvailablePccCount
                     + " mAvailablePccOnlyCount=" + event.mAvailablePccOnlyCount
                     + " mSelectedDatasetPickedReason=" + event.mSelectedDatasetPickedReason
-                    + " mDetectionPreference=" + event.mDetectionPreference);
+                    + " mDetectionPreference=" + event.mDetectionPreference
+                    + " mFieldClassificationRequestId=" + event.mFieldClassificationRequestId
+                    + " mAppPackageUid=" + mCallingAppUid);
         }
 
         // TODO(b/234185326): Distinguish empty responses from other no presentation reasons.
@@ -584,7 +604,9 @@
                 event.mAvailablePccCount,
                 event.mAvailablePccOnlyCount,
                 event.mSelectedDatasetPickedReason,
-                event.mDetectionPreference);
+                event.mDetectionPreference,
+                event.mFieldClassificationRequestId,
+                mCallingAppUid);
         mEventInternal = Optional.empty();
     }
 
@@ -617,6 +639,7 @@
         int mAvailablePccOnlyCount = -1;
         @DatasetPickedReason int mSelectedDatasetPickedReason = PICK_REASON_UNKNOWN;
         @DetectionPreference int mDetectionPreference = DETECTION_PREFER_UNKNOWN;
+        int mFieldClassificationRequestId = -1;
 
         PresentationStatsEventInternal() {}
     }
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFieldClassificationService.java b/services/autofill/java/com/android/server/autofill/RemoteFieldClassificationService.java
index bcca006..50fabfd 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFieldClassificationService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFieldClassificationService.java
@@ -69,6 +69,9 @@
         void onClassificationRequestFailure(int requestId, @Nullable CharSequence message);
         void onClassificationRequestTimeout(int requestId);
         void onServiceDied(@NonNull RemoteFieldClassificationService service);
+        void logFieldClassificationEvent(
+                long startTime, @NonNull FieldClassificationResponse response,
+                @FieldClassificationEventLogger.FieldClassificationStatus int status);
     }
 
     RemoteFieldClassificationService(Context context, ComponentName serviceName,
@@ -149,15 +152,24 @@
                                 new IFieldClassificationCallback.Stub() {
                                     @Override
                                     public void onCancellable(ICancellationSignal cancellation) {
-                                        logLatency(startTime);
                                         if (sDebug) {
                                             Log.d(TAG, "onCancellable");
                                         }
+                                        FieldClassificationServiceCallbacks
+                                                fieldClassificationServiceCallbacks =
+                                                Helper.weakDeref(
+                                                        fieldClassificationServiceCallbacksWeakRef,
+                                                        TAG, "onCancellable "
+                                                );
+                                        logFieldClassificationEvent(
+                                                startTime,
+                                                fieldClassificationServiceCallbacks,
+                                                FieldClassificationEventLogger.STATUS_CANCELLED,
+                                                null);
                                     }
 
                                     @Override
                                     public void onSuccess(FieldClassificationResponse response) {
-                                        logLatency(startTime);
                                         if (sDebug) {
                                             if (Build.IS_DEBUGGABLE) {
                                                 Slog.d(TAG, "onSuccess Response: " + response);
@@ -179,6 +191,11 @@
                                                                 fieldClassificationServiceCallbacksWeakRef,
                                                                 TAG, "onSuccess "
                                                         );
+                                        logFieldClassificationEvent(
+                                                startTime,
+                                                fieldClassificationServiceCallbacks,
+                                                FieldClassificationEventLogger.STATUS_SUCCESS,
+                                                response);
                                         if (fieldClassificationServiceCallbacks == null) {
                                             return;
                                         }
@@ -188,7 +205,6 @@
 
                                     @Override
                                     public void onFailure() {
-                                        logLatency(startTime);
                                         if (sDebug) {
                                             Slog.d(TAG, "onFailure");
                                         }
@@ -198,6 +214,11 @@
                                                                 fieldClassificationServiceCallbacksWeakRef,
                                                                 TAG, "onFailure "
                                                         );
+                                        logFieldClassificationEvent(
+                                                startTime,
+                                                fieldClassificationServiceCallbacks,
+                                                FieldClassificationEventLogger.STATUS_FAIL,
+                                                null);
                                         if (fieldClassificationServiceCallbacks == null) {
                                             return;
                                         }
@@ -215,11 +236,24 @@
                                 }));
     }
 
-    private void logLatency(long startTime) {
-        final FieldClassificationEventLogger logger = FieldClassificationEventLogger.createLogger();
-        logger.startNewLogForRequest();
-        logger.maybeSetLatencyMillis(
-                SystemClock.elapsedRealtime() - startTime);
-        logger.logAndEndEvent();
+    private void logFieldClassificationEvent(
+            long startTime,
+            @Nullable FieldClassificationServiceCallbacks fieldClassificationServiceCallbacks,
+            @FieldClassificationEventLogger.FieldClassificationStatus int status,
+            FieldClassificationResponse response) {
+        if (fieldClassificationServiceCallbacks == null) {
+            final FieldClassificationEventLogger logger =
+                    FieldClassificationEventLogger.createLogger();
+            logger.startNewLogForRequest();
+            logger.maybeSetLatencyMillis(
+                    SystemClock.elapsedRealtime() - startTime);
+            logger.maybeSetSessionGc(true);
+            logger.maybeSetRequestStatus(status);
+            logger.logAndEndEvent();
+        } else {
+            fieldClassificationServiceCallbacks.logFieldClassificationEvent(
+                    startTime, response, status);
+        }
+
     }
 }
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 1ae9125..4e5b058 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -229,6 +229,8 @@
 
     private static final String PCC_HINTS_DELIMITER = ",";
     public static final String EXTRA_KEY_DETECTIONS = "detections";
+    private static final int DEFAULT__FILL_REQUEST_ID_SNAPSHOT = -2;
+    private static final int DEFAULT__FIELD_CLASSIFICATION_REQUEST_ID_SNAPSHOT = -2;
 
     final Object mLock;
 
@@ -412,6 +414,20 @@
     @GuardedBy("mLock")
     private long mUiShownTime;
 
+    /**
+     * Tracks the value of the fill request id at the time of issuing request for field
+     * classification.
+     */
+    @GuardedBy("mLock")
+    private int mFillRequestIdSnapshot = DEFAULT__FILL_REQUEST_ID_SNAPSHOT;
+
+    /**
+     * Tracks the value of the field classification id at the time of issuing request for fill
+     * request.
+     */
+    @GuardedBy("mLock")
+    private int mFieldClassificationIdSnapshot = DEFAULT__FIELD_CLASSIFICATION_REQUEST_ID_SNAPSHOT;
+
     @GuardedBy("mLock")
     private final LocalLog mUiLatencyHistory;
 
@@ -673,6 +689,7 @@
             if (mPendingFillRequest == null) {
                 return;
             }
+            mFieldClassificationIdSnapshot = sIdCounterForPcc.get();
 
             if (mWaitForInlineRequest) {
                 if (mPendingInlineSuggestionsRequest == null) {
@@ -1239,6 +1256,8 @@
                     + ", flags=" + flags);
         }
         mPresentationStatsEventLogger.maybeSetRequestId(requestId);
+        mPresentationStatsEventLogger.maybeSetFieldClassificationRequestId(
+                mFieldClassificationIdSnapshot);
         mFillRequestEventLogger.maybeSetRequestId(requestId);
         mFillRequestEventLogger.maybeSetAutofillServiceUid(getAutofillServiceUid());
         if (mSessionFlags.mInlineSupportedByService) {
@@ -1327,6 +1346,7 @@
     @GuardedBy("mLock")
     private void requestAssistStructureForPccLocked(int flags) {
         if (!mClassificationState.shouldTriggerRequest()) return;
+        mFillRequestIdSnapshot = sIdCounter.get();
         mClassificationState.updatePendingRequest();
         // Get request id
         int requestId;
@@ -1411,7 +1431,8 @@
         mStartTime = SystemClock.elapsedRealtime();
         mLatencyBaseTime = mStartTime;
         mRequestCount = 0;
-        mPresentationStatsEventLogger = PresentationStatsEventLogger.forSessionId(sessionId);
+        mPresentationStatsEventLogger = PresentationStatsEventLogger.createPresentationLog(
+                sessionId, uid);
         mFillRequestEventLogger = FillRequestEventLogger.forSessionId(sessionId);
         mFillResponseEventLogger = FillResponseEventLogger.forSessionId(sessionId);
         mSessionCommittedEventLogger = SessionCommittedEventLogger.forSessionId(sessionId);
@@ -4301,6 +4322,8 @@
                 if (viewState.getResponse() != null) {
                     FillResponse response = viewState.getResponse();
                     mPresentationStatsEventLogger.maybeSetRequestId(response.getRequestId());
+                    mPresentationStatsEventLogger.maybeSetFieldClassificationRequestId(
+                            mFieldClassificationIdSnapshot);
                     mPresentationStatsEventLogger.maybeSetAvailableCount(
                             response.getDatasets(), mCurrentViewId);
                 }
@@ -4478,6 +4501,8 @@
     public void onFillReady(@NonNull FillResponse response, @NonNull AutofillId filledId,
             @Nullable AutofillValue value, int flags) {
         synchronized (mLock) {
+            mPresentationStatsEventLogger.maybeSetFieldClassificationRequestId(
+                    mFieldClassificationIdSnapshot);
             if (mDestroyed) {
                 Slog.w(TAG, "Call to Session#onFillReady() rejected - session: "
                         + id + " destroyed");
@@ -5389,6 +5414,7 @@
 
         List<Dataset> datasetList = newResponse.getDatasets();
 
+        mPresentationStatsEventLogger.maybeSetFieldClassificationRequestId(sIdCounterForPcc.get());
         mPresentationStatsEventLogger.maybeSetAvailableCount(datasetList, mCurrentViewId);
         mFillResponseEventLogger.maybeSetDatasetsCountAfterPotentialPccFiltering(datasetList);
 
@@ -6451,7 +6477,7 @@
         return serviceInfo == null ? Process.INVALID_UID : serviceInfo.applicationInfo.uid;
     }
 
-    // FieldClassificationServiceCallbacks
+    // FieldClassificationServiceCallbacks start
     public void onClassificationRequestSuccess(@Nullable FieldClassificationResponse response) {
         mClassificationState.updateResponseReceived(response);
     }
@@ -6472,6 +6498,28 @@
             // forceRemoveFromServiceLocked();
         }
     }
-    // DetectionServiceCallbacks end
+
+    @Override
+    public void logFieldClassificationEvent(
+            long startTime, FieldClassificationResponse response,
+            @FieldClassificationEventLogger.FieldClassificationStatus int status) {
+        final FieldClassificationEventLogger logger = FieldClassificationEventLogger.createLogger();
+        logger.startNewLogForRequest();
+        logger.maybeSetLatencyMillis(
+                SystemClock.elapsedRealtime() - startTime);
+        logger.maybeSetAppPackageUid(uid);
+        logger.maybeSetNextFillRequestId(mFillRequestIdSnapshot + 1);
+        logger.maybeSetRequestId(sIdCounterForPcc.get());
+        logger.maybeSetSessionId(id);
+        int count = -1;
+        if (response != null) {
+            count = response.getClassifications().size();
+        }
+        logger.maybeSetRequestStatus(status);
+        logger.maybeSetCountClassifications(count);
+        logger.logAndEndEvent();
+        mFillRequestIdSnapshot = DEFAULT__FILL_REQUEST_ID_SNAPSHOT;
+    }
+    // FieldClassificationServiceCallbacks end
 
 }
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 0000000..06bbc2b
--- /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 4488d86..5635dd5 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.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 @@
         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();
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
index 3b02be5..976504a 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
@@ -487,6 +487,13 @@
             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,
@@ -657,6 +664,13 @@
         // 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 +4195,19 @@
     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;
+        } 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))) {
             String line;
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 e04bf11..bbec79d 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 @@
         // 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 @@
             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 @@
             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 @@
 
             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 @@
             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 @@
             } 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 @@
         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 @@
             ++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 @@
                 // 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 @@
                     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 @@
         //
         // 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 @@
             // 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 @@
         } 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 @@
                         // 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 @@
                 // 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 @@
                 // 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 @@
         }
 
         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 @@
     @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 @@
                 // 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 0b55ca2..797aed9 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.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,27 @@
     // 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);
+    // 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 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
      * 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)
@@ -62,17 +84,22 @@
      * - 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()) {
+            // We only log data for the first 60 days since setup
+            return;
+        }
+
         if (eventBundle == null) {
             return;
         }
@@ -89,8 +116,19 @@
         }
         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();
+        }
+
+        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);) {
+             PrintWriter pw = new FastPrintWriter(out);) {
 
             int eventCategory = eventBundle.getInt(BackupManagerMonitor.EXTRA_LOG_EVENT_CATEGORY);
             int eventId = eventBundle.getInt(BackupManagerMonitor.EXTRA_LOG_EVENT_ID);
@@ -101,17 +139,16 @@
                 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);
         }
@@ -156,6 +193,37 @@
         }
     }
 
+    /**
+     * 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
      */
@@ -165,6 +233,13 @@
         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);
@@ -245,6 +320,32 @@
             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;
@@ -257,4 +358,128 @@
             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;
+    }
+
+    @VisibleForTesting
+    long getBMMEventsFileSizeLimit(){
+        return BMM_FILE_SIZE_LIMIT_BYTES;
+    }
+
+    /**
+     * 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/backup/java/com/android/server/backup/utils/BackupManagerMonitorEventSender.java b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorEventSender.java
index 92e3107..549d08c0 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 @@
         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/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
index 102c262..a3ccb16 100644
--- a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
+++ b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
@@ -133,6 +133,7 @@
 
     @GuardedBy("mGenericWindowPolicyControllerLock")
     private boolean mShowTasksInHostDeviceRecents;
+    @Nullable private final ComponentName mCustomHomeComponent;
 
     /**
      * Creates a window policy controller that is generic to the different use cases of virtual
@@ -157,6 +158,10 @@
      * @param intentListenerCallback Callback that is called to intercept intents when matching
      *   passed in filters.
      * @param showTasksInHostDeviceRecents whether to show activities in recents on the host device.
+     * @param customHomeComponent The component acting as a home activity on the virtual display. If
+     *   {@code null}, then the system-default secondary home activity will be used. This is only
+     *   applicable to displays that support home activities, i.e. they're created with the relevant
+     *   virtual display flag.
      */
     public GenericWindowPolicyController(
             int windowFlags,
@@ -172,7 +177,8 @@
             @Nullable SecureWindowCallback secureWindowCallback,
             @Nullable IntentListenerCallback intentListenerCallback,
             @NonNull Set<String> displayCategories,
-            boolean showTasksInHostDeviceRecents) {
+            boolean showTasksInHostDeviceRecents,
+            @Nullable ComponentName customHomeComponent) {
         super();
         mAllowedUsers = allowedUsers;
         mActivityLaunchAllowedByDefault = activityLaunchAllowedByDefault;
@@ -187,6 +193,7 @@
         mIntentListenerCallback = intentListenerCallback;
         mDisplayCategories = displayCategories;
         mShowTasksInHostDeviceRecents = showTasksInHostDeviceRecents;
+        mCustomHomeComponent = customHomeComponent;
     }
 
     /**
@@ -384,6 +391,11 @@
         return false;
     }
 
+    @Override
+    public @Nullable ComponentName getCustomHomeComponent() {
+        return mCustomHomeComponent;
+    }
+
     /**
      * Returns true if an app with the given UID has an activity running on the virtual display for
      * this controller.
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 3b13410..203a152 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.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.flags.Flags;
 import android.companion.virtual.sensor.VirtualSensor;
 import android.companion.virtual.sensor.VirtualSensorEvent;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledAfter;
 import android.content.AttributionSource;
 import android.content.ComponentName;
 import android.content.Context;
@@ -75,6 +78,7 @@
 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 @@
 
     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
+    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    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 @@
 
     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 @@
                             ? 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 @@
      * 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. */
@@ -905,6 +938,8 @@
                 mParams.getDefaultNavigationPolicy() == NAVIGATION_POLICY_DEFAULT_ALLOWED;
         final boolean showTasksInHostDeviceRecents =
                 getDevicePolicy(POLICY_TYPE_RECENTS) == DEVICE_POLICY_DEFAULT;
+        final ComponentName homeComponent =
+                Flags.vdmCustomHome() ? mParams.getHomeComponent() : null;
 
         final GenericWindowPolicyController gwpc = new GenericWindowPolicyController(
                 FLAG_SECURE,
@@ -922,7 +957,8 @@
                 this::onSecureWindowShown,
                 this::shouldInterceptIntent,
                 displayCategories,
-                showTasksInHostDeviceRecents);
+                showTasksInHostDeviceRecents,
+                homeComponent);
         gwpc.registerRunningAppsChangedListener(/* listener= */ this);
         return gwpc;
     }
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index d94f4f2..556eba6 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -167,6 +167,8 @@
     private int mBatteryNearlyFullLevel;
     private int mShutdownBatteryTemperature;
 
+    private static String sSystemUiPackage;
+
     private int mPlugType;
     private int mLastPlugType = -1; // Extra state so we can detect first run
 
@@ -228,6 +230,8 @@
                 com.android.internal.R.integer.config_lowBatteryCloseWarningBump);
         mShutdownBatteryTemperature = mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_shutdownBatteryTemperature);
+        sSystemUiPackage = mContext.getResources().getString(
+                com.android.internal.R.string.config_systemUi);
 
         mBatteryLevelsEventQueue = new ArrayDeque<>();
         mMetricsLogger = new MetricsLogger();
@@ -750,8 +754,21 @@
                     + ", info:" + mHealthInfo.toString());
         }
 
-        mHandler.post(() -> ActivityManager.broadcastStickyIntent(intent, AppOpsManager.OP_NONE,
-                mBatteryChangedOptions, UserHandle.USER_ALL));
+        mHandler.post(() -> broadcastBatteryChangedIntent(intent, mBatteryChangedOptions));
+    }
+
+    private static void broadcastBatteryChangedIntent(Intent intent, Bundle options) {
+        // TODO (293959093): It is important that SystemUI receives this broadcast as soon as
+        // possible. Ideally, it should be using binder callbacks but until then, dispatch this
+        // as a foreground broadcast to SystemUI.
+        final Intent fgIntent = new Intent(intent);
+        fgIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+        fgIntent.setPackage(sSystemUiPackage);
+        ActivityManager.broadcastStickyIntent(fgIntent, AppOpsManager.OP_NONE,
+                options, UserHandle.USER_ALL);
+
+        ActivityManager.broadcastStickyIntent(intent, new String[] {sSystemUiPackage},
+                AppOpsManager.OP_NONE, options, UserHandle.USER_ALL);
     }
 
     private void sendBatteryLevelChangedIntentLocked() {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index cbc9ff1..d3ce47c 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -315,7 +315,6 @@
 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;
@@ -15096,16 +15095,6 @@
             }
         }
 
-        // 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 a3dac6d..eb219a8 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.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;
@@ -1078,16 +1077,6 @@
                 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,
diff --git a/services/core/java/com/android/server/app/GameManagerService.java b/services/core/java/com/android/server/app/GameManagerService.java
index 905589f..824bdd4 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 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 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 @@
             }
 
             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 00ff489..ab57c4f 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 @@
                 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 @@
         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");
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 50d375c..35fc43a 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.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 @@
                 vendorCode,
                 getTargetUserId()));
 
-        if (error == BiometricConstants.BIOMETRIC_ERROR_RE_ENROLL) {
-            BiometricNotificationUtils.showReEnrollmentNotification(getContext());
-        }
         super.onError(error, vendorCode);
     }
 
diff --git a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
index 1012bc1..fac727f 100644
--- a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
+++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
@@ -37,7 +37,8 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
-import android.app.TaskStackListener;
+import android.app.ActivityManagerInternal;
+import android.app.IProcessObserver;
 import android.content.Context;
 import android.hardware.devicestate.DeviceStateInfo;
 import android.hardware.devicestate.DeviceStateManager;
@@ -184,7 +185,30 @@
     private final SystemPropertySetter mSystemPropertySetter;
 
     @VisibleForTesting
-    TaskStackListener mOverrideRequestTaskStackListener = new OverrideRequestTaskStackListener();
+    final IProcessObserver mProcessObserver = new IProcessObserver.Stub() {
+        @Override
+        public void onForegroundActivitiesChanged(int pid, int uid, boolean fg) {
+            synchronized (mLock) {
+                if (!shouldCancelOverrideRequestWhenRequesterNotOnTop()) {
+                    return;
+                }
+
+                OverrideRequest request = mActiveOverride.get();
+                if (pid != request.getPid() || uid != request.getUid()) {
+                    return;
+                }
+                if (!fg) {
+                    mOverrideRequestController.cancelRequest(request);
+                }
+            }
+        }
+
+        @Override
+        public void onProcessDied(int pid, int uid) {}
+
+        @Override
+        public void onForegroundServicesChanged(int pid, int uid, int serviceTypes) {}
+    };
     @VisibleForTesting
     ActivityTaskManagerInternal.ScreenObserver mOverrideRequestScreenObserver =
             new OverrideRequestScreenObserver();
@@ -239,8 +263,9 @@
             mFoldedDeviceStates = readFoldedStates();
         }
 
-        mActivityTaskManagerInternal.registerTaskStackListener(mOverrideRequestTaskStackListener);
         mActivityTaskManagerInternal.registerScreenObserver(mOverrideRequestScreenObserver);
+        LocalServices.getService(ActivityManagerInternal.class).registerProcessObserver(
+                mProcessObserver);
     }
 
     @VisibleForTesting
@@ -1288,23 +1313,6 @@
         return deviceState.hasFlag(DeviceState.FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP);
     }
 
-    private class OverrideRequestTaskStackListener extends TaskStackListener {
-        @Override
-        public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo)
-                throws RemoteException {
-            synchronized (mLock) {
-                if (!shouldCancelOverrideRequestWhenRequesterNotOnTop()) {
-                    return;
-                }
-
-                OverrideRequest request = mActiveOverride.get();
-                if (!isTopApp(request.getPid())) {
-                    mOverrideRequestController.cancelRequest(request);
-                }
-            }
-        }
-    }
-
     private class OverrideRequestScreenObserver implements
             ActivityTaskManagerInternal.ScreenObserver {
 
diff --git a/services/core/java/com/android/server/devicestate/DeviceStateNotificationController.java b/services/core/java/com/android/server/devicestate/DeviceStateNotificationController.java
index f4c84e7..f9aefd0 100644
--- a/services/core/java/com/android/server/devicestate/DeviceStateNotificationController.java
+++ b/services/core/java/com/android/server/devicestate/DeviceStateNotificationController.java
@@ -109,6 +109,7 @@
                     .setPackage(mContext.getPackageName());
             final PendingIntent pendingIntent = PendingIntent.getBroadcast(
                     mContext, 0 /* requestCode */, intent, PendingIntent.FLAG_IMMUTABLE);
+
             showNotification(
                     info.name, info.activeNotificationTitle,
                     String.format(info.activeNotificationContent, requesterApplicationLabel),
@@ -175,7 +176,7 @@
         if (getNotificationInfos().get(state) == null) {
             return;
         }
-        mNotificationManager.cancel(NOTIFICATION_TAG, NOTIFICATION_ID);
+        mHandler.post(() -> mNotificationManager.cancel(NOTIFICATION_TAG, NOTIFICATION_ID));
     }
 
     @Override
@@ -219,8 +220,10 @@
             builder.addAction(action);
         }
 
-        mNotificationManager.createNotificationChannel(channel);
-        mNotificationManager.notify(NOTIFICATION_TAG, NOTIFICATION_ID, builder.build());
+        mHandler.post(() -> {
+            mNotificationManager.createNotificationChannel(channel);
+            mNotificationManager.notify(NOTIFICATION_TAG, NOTIFICATION_ID, builder.build());
+        });
     }
 
     private SparseArray<NotificationInfo> getNotificationInfos() {
diff --git a/services/core/java/com/android/server/display/BrightnessRangeController.java b/services/core/java/com/android/server/display/BrightnessRangeController.java
index 21273e0..13ee47e 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 @@
 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 @@
             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 @@
                             displayDeviceConfig::getHdrBrightnessFromSdr);
                 }
         );
+        if (mUseHdrClamper) {
+            mHdrClamper.resetHdrConfig(displayDeviceConfig.getHdrBrightnessData());
+        }
     }
 
     void stop() {
@@ -128,8 +141,10 @@
     }
 
     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 @@
     }
 
     public float getHdrTransitionRate() {
-        return mHdrClamper.getTransitionRate();
+        return mUseHdrClamper ? mHdrClamper.getTransitionRate() : -1;
     }
 }
diff --git a/services/core/java/com/android/server/display/ColorFade.java b/services/core/java/com/android/server/display/ColorFade.java
index cd867f6..0d6635d 100644
--- a/services/core/java/com/android/server/display/ColorFade.java
+++ b/services/core/java/com/android/server/display/ColorFade.java
@@ -43,7 +43,6 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.LocalServices;
 import com.android.server.policy.WindowManagerPolicy;
-import com.android.server.wm.WindowManagerInternal;
 
 import libcore.io.Streams;
 
@@ -408,12 +407,6 @@
         }
     }
 
-    void stop() {
-        if (mEglContext != null && mEglDisplay != null) {
-            EGL14.eglDestroyContext(mEglDisplay, mEglContext);
-        }
-    }
-
     /**
      * Draws an animation frame showing the color fade activated at the
      * specified level.
@@ -574,21 +567,8 @@
     }
 
     private ScreenCapture.ScreenshotHardwareBuffer captureScreen() {
-        WindowManagerInternal windowManagerService = LocalServices.getService(
-                WindowManagerInternal.class);
-        ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer;
-        ScreenCapture.SynchronousScreenCaptureListener screenCaptureListener =
-                ScreenCapture.createSyncCaptureListener();
-        ScreenCapture.CaptureArgs captureArgs = new ScreenCapture.CaptureArgs.Builder<>()
-                .setCaptureSecureLayers(true)
-                .setAllowProtected(true)
-                .build();
-        try {
-            windowManagerService.captureDisplay(mDisplayId, captureArgs, screenCaptureListener);
-            screenshotBuffer = screenCaptureListener.getBuffer();
-        } catch (Exception e) {
-            screenshotBuffer = null;
-        }
+        ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer =
+                mDisplayManagerInternal.systemScreenshot(mDisplayId);
         if (screenshotBuffer == null) {
             Slog.e(TAG, "Failed to take screenshot. Buffer is null");
             return null;
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index 3a6e5f93..507ae26 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -303,6 +303,8 @@
  *
  *      <screenBrightnessRampIncreaseMaxMillis>2000</screenBrightnessRampIncreaseMaxMillis>
  *      <screenBrightnessRampDecreaseMaxMillis>3000</screenBrightnessRampDecreaseMaxMillis>
+ *      <screenBrightnessRampIncreaseMaxIdleMillis>2000</screenBrightnessRampIncreaseMaxIdleMillis>
+ *      <screenBrightnessRampDecreaseMaxIdleMillis>2000</screenBrightnessRampDecreaseMaxIdleMillis>
  *
  *      <lightSensor>
  *        <type>android.sensor.light</type>
@@ -619,6 +621,8 @@
     private float mBrightnessRampSlowIncreaseIdle = Float.NaN;
     private long mBrightnessRampDecreaseMaxMillis = 0;
     private long mBrightnessRampIncreaseMaxMillis = 0;
+    private long mBrightnessRampDecreaseMaxIdleMillis = 0;
+    private long mBrightnessRampIncreaseMaxIdleMillis = 0;
     private int mAmbientHorizonLong = AMBIENT_LIGHT_LONG_HORIZON_MILLIS;
     private int mAmbientHorizonShort = AMBIENT_LIGHT_SHORT_HORIZON_MILLIS;
     private float mScreenBrighteningMinThreshold = 0.0f;     // Retain behaviour as though there is
@@ -1078,6 +1082,14 @@
         return mBrightnessRampIncreaseMaxMillis;
     }
 
+    public long getBrightnessRampDecreaseMaxIdleMillis() {
+        return mBrightnessRampDecreaseMaxIdleMillis;
+    }
+
+    public long getBrightnessRampIncreaseMaxIdleMillis() {
+        return mBrightnessRampIncreaseMaxIdleMillis;
+    }
+
     public int getAmbientHorizonLong() {
         return mAmbientHorizonLong;
     }
@@ -1697,6 +1709,8 @@
                 + ", mBrightnessRampSlowIncreaseIdle=" + mBrightnessRampSlowIncreaseIdle
                 + ", mBrightnessRampDecreaseMaxMillis=" + mBrightnessRampDecreaseMaxMillis
                 + ", mBrightnessRampIncreaseMaxMillis=" + mBrightnessRampIncreaseMaxMillis
+                + ", mBrightnessRampDecreaseMaxIdleMillis=" + mBrightnessRampDecreaseMaxIdleMillis
+                + ", mBrightnessRampIncreaseMaxIdleMillis=" + mBrightnessRampIncreaseMaxIdleMillis
                 + "\n"
                 + "mAmbientHorizonLong=" + mAmbientHorizonLong
                 + ", mAmbientHorizonShort=" + mAmbientHorizonShort
@@ -1892,6 +1906,8 @@
         mBrightnessRampSlowIncreaseIdle = PowerManager.BRIGHTNESS_MAX;
         mBrightnessRampDecreaseMaxMillis = 0;
         mBrightnessRampIncreaseMaxMillis = 0;
+        mBrightnessRampDecreaseMaxIdleMillis = 0;
+        mBrightnessRampIncreaseMaxIdleMillis = 0;
         setSimpleMappingStrategyValues();
         loadAmbientLightSensorFromConfigXml();
         setProxSensorUnspecified();
@@ -2767,6 +2783,19 @@
             mBrightnessRampSlowDecreaseIdle = mBrightnessRampSlowDecrease;
             mBrightnessRampSlowIncreaseIdle = mBrightnessRampSlowIncrease;
         }
+
+        final BigInteger increaseMaxIdle = config.getScreenBrightnessRampIncreaseMaxIdleMillis();
+        if (increaseMaxIdle != null) {
+            mBrightnessRampIncreaseMaxIdleMillis = increaseMaxIdle.intValue();
+        } else {
+            mBrightnessRampIncreaseMaxIdleMillis = mBrightnessRampIncreaseMaxMillis;
+        }
+        final BigInteger decreaseMaxIdle = config.getScreenBrightnessRampDecreaseMaxIdleMillis();
+        if (decreaseMaxIdle != null) {
+            mBrightnessRampDecreaseMaxIdleMillis = decreaseMaxIdle.intValue();
+        } else {
+            mBrightnessRampDecreaseMaxIdleMillis = mBrightnessRampDecreaseMaxMillis;
+        }
     }
 
     private void loadBrightnessRampsFromConfigXml() {
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index df45001..46ef6c3 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -137,6 +137,7 @@
 import android.view.SurfaceControl;
 import android.view.SurfaceControl.RefreshRateRange;
 import android.window.DisplayWindowPolicyController;
+import android.window.ScreenCapture;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
@@ -2673,6 +2674,42 @@
         return null;
     }
 
+    private ScreenCapture.ScreenshotHardwareBuffer systemScreenshotInternal(int displayId) {
+        final ScreenCapture.DisplayCaptureArgs captureArgs;
+        synchronized (mSyncRoot) {
+            final IBinder token = getDisplayToken(displayId);
+            if (token == null) {
+                return null;
+            }
+            final LogicalDisplay logicalDisplay = mLogicalDisplayMapper.getDisplayLocked(displayId);
+            if (logicalDisplay == null) {
+                return null;
+            }
+
+            final DisplayInfo displayInfo = logicalDisplay.getDisplayInfoLocked();
+            captureArgs = new ScreenCapture.DisplayCaptureArgs.Builder(token)
+                    .setSize(displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight())
+                    .setCaptureSecureLayers(true)
+                    .setAllowProtected(true)
+                    .build();
+        }
+        return ScreenCapture.captureDisplay(captureArgs);
+    }
+
+    private ScreenCapture.ScreenshotHardwareBuffer userScreenshotInternal(int displayId) {
+        synchronized (mSyncRoot) {
+            final IBinder token = getDisplayToken(displayId);
+            if (token == null) {
+                return null;
+            }
+
+            final ScreenCapture.DisplayCaptureArgs captureArgs =
+                    new ScreenCapture.DisplayCaptureArgs.Builder(token)
+                            .build();
+            return ScreenCapture.captureDisplay(captureArgs);
+        }
+    }
+
     @VisibleForTesting
     DisplayedContentSamplingAttributes getDisplayedContentSamplingAttributesInternal(
             int displayId) {
@@ -4441,6 +4478,16 @@
         }
 
         @Override
+        public ScreenCapture.ScreenshotHardwareBuffer systemScreenshot(int displayId) {
+            return systemScreenshotInternal(displayId);
+        }
+
+        @Override
+        public ScreenCapture.ScreenshotHardwareBuffer userScreenshot(int displayId) {
+            return userScreenshotInternal(displayId);
+        }
+
+        @Override
         public DisplayInfo getDisplayInfo(int displayId) {
             return getDisplayInfoInternal(displayId, Process.myUid());
         }
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index f86b8ca..83f4df9 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -317,10 +317,14 @@
     private final Clock mClock;
     private final Injector mInjector;
 
-    //  Maximum time a ramp animation can take.
+    // Maximum time a ramp animation can take.
     private long mBrightnessRampIncreaseMaxTimeMillis;
     private long mBrightnessRampDecreaseMaxTimeMillis;
 
+    // Maximum time a ramp animation can take in idle mode.
+    private long mBrightnessRampIncreaseMaxTimeIdleMillis;
+    private long mBrightnessRampDecreaseMaxTimeIdleMillis;
+
     // The pending power request.
     // Initially null until the first call to requestPowerState.
     @GuardedBy("mLock")
@@ -585,6 +589,8 @@
 
     private boolean mBootCompleted;
 
+    private final DisplayManagerFlags mFlags;
+
     /**
      * Creates the display power controller.
      */
@@ -750,6 +756,8 @@
         mPendingAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT;
 
         mBootCompleted = bootCompleted;
+
+        mFlags = flags;
     }
 
     private void applyReduceBrightColorsSplineAdjustment() {
@@ -1057,11 +1065,7 @@
         loadNitsRange(mContext.getResources());
         setUpAutoBrightness(mContext.getResources(), mHandler);
         reloadReduceBrightColours();
-        if (mScreenBrightnessRampAnimator != null) {
-            mScreenBrightnessRampAnimator.setAnimationTimeLimits(
-                    mBrightnessRampIncreaseMaxTimeMillis,
-                    mBrightnessRampDecreaseMaxTimeMillis);
-        }
+        setAnimatorRampSpeeds(/* isIdleMode= */ false);
         mBrightnessRangeController.loadFromConfig(hbmMetadata, token, info, mDisplayDeviceConfig);
         mBrightnessThrottler.loadThermalBrightnessThrottlingDataFromDisplayDeviceConfig(
                 mDisplayDeviceConfig.getThermalBrightnessThrottlingDataMapByThrottlingId(),
@@ -1102,9 +1106,8 @@
         mScreenBrightnessRampAnimator = mInjector.getDualRampAnimator(mPowerState,
                 DisplayPowerState.SCREEN_BRIGHTNESS_FLOAT,
                 DisplayPowerState.SCREEN_SDR_BRIGHTNESS_FLOAT);
-        mScreenBrightnessRampAnimator.setAnimationTimeLimits(
-                mBrightnessRampIncreaseMaxTimeMillis,
-                mBrightnessRampDecreaseMaxTimeMillis);
+        setAnimatorRampSpeeds(mAutomaticBrightnessController != null
+                && mAutomaticBrightnessController.isInIdleMode());
         mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener);
 
         noteScreenState(mPowerState.getScreenState());
@@ -1323,6 +1326,10 @@
                 mDisplayDeviceConfig.getBrightnessRampDecreaseMaxMillis();
         mBrightnessRampIncreaseMaxTimeMillis =
                 mDisplayDeviceConfig.getBrightnessRampIncreaseMaxMillis();
+        mBrightnessRampDecreaseMaxTimeIdleMillis =
+                mDisplayDeviceConfig.getBrightnessRampDecreaseMaxIdleMillis();
+        mBrightnessRampIncreaseMaxTimeIdleMillis =
+                mDisplayDeviceConfig.getBrightnessRampIncreaseMaxIdleMillis();
     }
 
     private void loadNitsRange(Resources resources) {
@@ -1349,6 +1356,7 @@
             } else {
                 mAutomaticBrightnessController.switchToInteractiveScreenBrightnessMode();
             }
+            setAnimatorRampSpeeds(isIdle);
         }
 
         Message msg = mHandler.obtainMessage();
@@ -1357,6 +1365,21 @@
         mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
     }
 
+    private void setAnimatorRampSpeeds(boolean isIdle) {
+        if (mScreenBrightnessRampAnimator == null) {
+            return;
+        }
+        if (mFlags.isAdaptiveTone1Enabled() && isIdle) {
+            mScreenBrightnessRampAnimator.setAnimationTimeLimits(
+                    mBrightnessRampIncreaseMaxTimeIdleMillis,
+                    mBrightnessRampDecreaseMaxTimeIdleMillis);
+        } else {
+            mScreenBrightnessRampAnimator.setAnimationTimeLimits(
+                    mBrightnessRampIncreaseMaxTimeMillis,
+                    mBrightnessRampDecreaseMaxTimeMillis);
+        }
+    }
+
     private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() {
         @Override
         public void onAnimationStart(Animator animation) {
@@ -3554,8 +3577,7 @@
 
         DisplayPowerState getDisplayPowerState(DisplayBlanker blanker, ColorFade colorFade,
                 int displayId, int displayState) {
-            return new DisplayPowerState(blanker, colorFade, displayId, displayState,
-                    new Handler(/*async=*/ true));
+            return new DisplayPowerState(blanker, colorFade, displayId, displayState);
         }
 
         DualRampAnimator<DisplayPowerState> getDualRampAnimator(DisplayPowerState dps,
diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java
index da29981..b0d293a 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController2.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController2.java
@@ -285,10 +285,14 @@
     private final Clock mClock;
     private final Injector mInjector;
 
-    //  Maximum time a ramp animation can take.
+    // Maximum time a ramp animation can take.
     private long mBrightnessRampIncreaseMaxTimeMillis;
     private long mBrightnessRampDecreaseMaxTimeMillis;
 
+    // Maximum time a ramp animation can take in idle mode.
+    private long mBrightnessRampIncreaseMaxTimeIdleMillis;
+    private long mBrightnessRampDecreaseMaxTimeIdleMillis;
+
     // The pending power request.
     // Initially null until the first call to requestPowerState.
     @GuardedBy("mLock")
@@ -320,6 +324,8 @@
     // Must only be accessed on the handler thread.
     private DisplayPowerState mPowerState;
 
+
+
     // The currently active screen on unblocker.  This field is non-null whenever
     // we are waiting for a callback to release it and unblock the screen.
     private ScreenOnUnblocker mPendingScreenOnUnblocker;
@@ -465,6 +471,8 @@
 
     private boolean mBootCompleted;
 
+    private final DisplayManagerFlags mFlags;
+
     /**
      * Creates the display power controller.
      */
@@ -615,6 +623,7 @@
                 R.bool.config_displayBrightnessBucketsInDoze);
 
         mBootCompleted = bootCompleted;
+        mFlags = flags;
     }
 
     private void applyReduceBrightColorsSplineAdjustment() {
@@ -862,11 +871,7 @@
         loadNitsRange(mContext.getResources());
         setUpAutoBrightness(mContext.getResources(), mHandler);
         reloadReduceBrightColours();
-        if (mScreenBrightnessRampAnimator != null) {
-            mScreenBrightnessRampAnimator.setAnimationTimeLimits(
-                    mBrightnessRampIncreaseMaxTimeMillis,
-                    mBrightnessRampDecreaseMaxTimeMillis);
-        }
+        setAnimatorRampSpeeds(/* isIdleMode= */ false);
 
         mBrightnessRangeController.loadFromConfig(hbmMetadata, token, info, mDisplayDeviceConfig);
         mBrightnessThrottler.loadThermalBrightnessThrottlingDataFromDisplayDeviceConfig(
@@ -908,9 +913,8 @@
         mScreenBrightnessRampAnimator = mInjector.getDualRampAnimator(mPowerState,
                 DisplayPowerState.SCREEN_BRIGHTNESS_FLOAT,
                 DisplayPowerState.SCREEN_SDR_BRIGHTNESS_FLOAT);
-        mScreenBrightnessRampAnimator.setAnimationTimeLimits(
-                mBrightnessRampIncreaseMaxTimeMillis,
-                mBrightnessRampDecreaseMaxTimeMillis);
+        setAnimatorRampSpeeds(mAutomaticBrightnessController != null
+                && mAutomaticBrightnessController.isInIdleMode());
         mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener);
 
         noteScreenState(mPowerState.getScreenState());
@@ -1136,6 +1140,10 @@
                 mDisplayDeviceConfig.getBrightnessRampDecreaseMaxMillis();
         mBrightnessRampIncreaseMaxTimeMillis =
                 mDisplayDeviceConfig.getBrightnessRampIncreaseMaxMillis();
+        mBrightnessRampDecreaseMaxTimeIdleMillis =
+                mDisplayDeviceConfig.getBrightnessRampDecreaseMaxIdleMillis();
+        mBrightnessRampIncreaseMaxTimeIdleMillis =
+                mDisplayDeviceConfig.getBrightnessRampIncreaseMaxIdleMillis();
     }
 
     private void loadNitsRange(Resources resources) {
@@ -1162,6 +1170,7 @@
             } else {
                 mAutomaticBrightnessController.switchToInteractiveScreenBrightnessMode();
             }
+            setAnimatorRampSpeeds(isIdle);
         }
         Message msg = mHandler.obtainMessage();
         msg.what = MSG_SET_DWBC_STRONG_MODE;
@@ -1169,6 +1178,21 @@
         mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
     }
 
+    private void setAnimatorRampSpeeds(boolean isIdle) {
+        if (mScreenBrightnessRampAnimator == null) {
+            return;
+        }
+        if (mFlags.isAdaptiveTone1Enabled() && isIdle) {
+            mScreenBrightnessRampAnimator.setAnimationTimeLimits(
+                    mBrightnessRampIncreaseMaxTimeIdleMillis,
+                    mBrightnessRampDecreaseMaxTimeIdleMillis);
+        } else {
+            mScreenBrightnessRampAnimator.setAnimationTimeLimits(
+                    mBrightnessRampIncreaseMaxTimeMillis,
+                    mBrightnessRampDecreaseMaxTimeMillis);
+        }
+    }
+
     private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() {
         @Override
         public void onAnimationStart(Animator animation) {
@@ -2892,8 +2916,7 @@
 
         DisplayPowerState getDisplayPowerState(DisplayBlanker blanker, ColorFade colorFade,
                 int displayId, int displayState) {
-            return new DisplayPowerState(blanker, colorFade, displayId, displayState,
-                    new Handler(/*async=*/ true));
+            return new DisplayPowerState(blanker, colorFade, displayId, displayState);
         }
 
         DualRampAnimator<DisplayPowerState> getDualRampAnimator(DisplayPowerState dps,
diff --git a/services/core/java/com/android/server/display/DisplayPowerState.java b/services/core/java/com/android/server/display/DisplayPowerState.java
index 85c6a6d..2c257a1 100644
--- a/services/core/java/com/android/server/display/DisplayPowerState.java
+++ b/services/core/java/com/android/server/display/DisplayPowerState.java
@@ -74,9 +74,8 @@
     private volatile boolean mStopped;
 
     DisplayPowerState(
-            DisplayBlanker blanker, ColorFade colorFade, int displayId, int displayState,
-            Handler handler) {
-        mHandler = handler;
+            DisplayBlanker blanker, ColorFade colorFade, int displayId, int displayState) {
+        mHandler = new Handler(true /*async*/);
         mChoreographer = Choreographer.getInstance();
         mBlanker = blanker;
         mColorFade = colorFade;
@@ -318,7 +317,6 @@
         mStopped = true;
         mPhotonicModulator.interrupt();
         dismissColorFade();
-        stopColorFade();
         mCleanListener = null;
         mHandler.removeCallbacksAndMessages(null);
     }
@@ -378,11 +376,6 @@
         }
     }
 
-    // Clears up color fade resources.
-    private void stopColorFade() {
-        if (mColorFade != null) mColorFade.stop();
-    }
-
     private final Runnable mScreenUpdateRunnable = new Runnable() {
         @Override
         public void run() {
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 079a196..a514136 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;
 
+    @Nullable
+    private HdrBrightnessData mHdrBrightnessData = null;
+
+    private float mAmbientLux = Float.MAX_VALUE;
+
     private float mMaxBrightness = PowerManager.BRIGHTNESS_MAX;
+    private float mDesiredMaxBrightness = PowerManager.BRIGHTNESS_MAX;
 
     // brightness change speed, in units per seconds,
     private float mTransitionRate = -1f;
-
-    private float mDesiredMaxBrightness = PowerManager.BRIGHTNESS_MAX;
-
-    private float mDesiredTransitionDuration = -1; // in seconds
+    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 @@
         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 @@
         }
         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 06d3c5b..48d671d 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 @@
 
 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 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/Android.bp b/services/core/java/com/android/server/display/feature/Android.bp
index 27c48ed..a0ead38 100644
--- a/services/core/java/com/android/server/display/feature/Android.bp
+++ b/services/core/java/com/android/server/display/feature/Android.bp
@@ -5,8 +5,3 @@
         "*.aconfig",
     ],
 }
-
-java_aconfig_library {
-    name: "display_flags_lib",
-    aconfig_declarations: "display_flags",
-}
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 aebd8a0..3f6bf1a 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,14 @@
             Flags.FLAG_ENABLE_NBM_CONTROLLER,
             Flags::enableNbmController);
 
+    private final FlagState mHdrClamperFlagState = new FlagState(
+            Flags.FLAG_ENABLE_HDR_CLAMPER,
+            Flags::enableHdrClamper);
+
+    private final FlagState mAdaptiveToneImprovements1 = new FlagState(
+            Flags.FLAG_ENABLE_ADAPTIVE_TONE_IMPROVEMENTS_1,
+            Flags::enableAdaptiveToneImprovements1);
+
     /** Returns whether connected display management is enabled or not. */
     public boolean isConnectedDisplayManagementEnabled() {
         return mConnectedDisplayManagementFlagState.isEnabled();
@@ -49,6 +57,17 @@
         return mNbmControllerFlagState.isEnabled();
     }
 
+    public boolean isHdrClamperEnabled() {
+        return mHdrClamperFlagState.isEnabled();
+    }
+
+    /**
+     * Returns whether adaptive tone improvements are enabled
+     */
+    public boolean isAdaptiveTone1Enabled() {
+        return mAdaptiveToneImprovements1.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 12306b0..4d86004 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,23 @@
     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
+}
+
+flag {
+    name: "enable_adaptive_tone_improvements_1"
+    namespace: "display_manager"
+    description: "Feature flag for Adaptive Tone Improvements"
+    bug: "299550755"
+    is_fixed_read_only: true
+}
+
diff --git a/services/core/java/com/android/server/display/mode/VotesStorage.java b/services/core/java/com/android/server/display/mode/VotesStorage.java
index dadcebe..bdd2ab7 100644
--- a/services/core/java/com/android/server/display/mode/VotesStorage.java
+++ b/services/core/java/com/android/server/display/mode/VotesStorage.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.os.Trace;
 import android.util.Slog;
 import android.util.SparseArray;
 
@@ -104,6 +105,9 @@
                 votes.remove(priority);
             }
         }
+        Trace.traceCounter(Trace.TRACE_TAG_POWER,
+                TAG + "." + displayId + ":" + Vote.priorityToString(priority),
+                getMaxPhysicalRefreshRate(vote));
         if (mLoggingEnabled) {
             Slog.i(TAG, "Updated votes for display=" + displayId + " votes=" + votes);
         }
@@ -146,6 +150,15 @@
         }
     }
 
+    private int getMaxPhysicalRefreshRate(@Nullable Vote vote) {
+        if (vote == null) {
+            return -1;
+        } else if (vote.refreshRateRanges.physical.max == Float.POSITIVE_INFINITY) {
+            return 1000; // for visualisation, otherwise e.g. -1 -> 60 will be unnoticeable
+        }
+        return (int) vote.refreshRateRanges.physical.max;
+    }
+
     interface Listener {
         void onChanged();
     }
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java b/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java
index 7045e65..c01bc20 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java
@@ -868,6 +868,28 @@
     }
 
     @ServiceThreadOnly
+    void removeUnusedLocalDevices(ArrayList<HdmiCecLocalDevice> allocatedDevices) {
+        ArrayList<Integer> deviceTypesToRemove = new ArrayList<>();
+        for (int i = 0; i < mLocalDevices.size(); i++) {
+            int deviceType = mLocalDevices.keyAt(i);
+            boolean shouldRemoveLocalDevice = allocatedDevices.stream().noneMatch(
+                    localDevice -> localDevice.getDeviceInfo() != null
+                    && localDevice.getDeviceInfo().getDeviceType() == deviceType);
+            if (shouldRemoveLocalDevice) {
+                deviceTypesToRemove.add(deviceType);
+            }
+        }
+        for (Integer deviceType : deviceTypesToRemove) {
+            mLocalDevices.remove(deviceType);
+        }
+    }
+
+    @ServiceThreadOnly
+    void removeLocalDeviceWithType(int deviceType) {
+        mLocalDevices.remove(deviceType);
+    }
+
+    @ServiceThreadOnly
     public void clearDeviceList() {
         assertRunOnServiceThread();
         for (HdmiDeviceInfo info : HdmiUtils.sparseArrayToList(mDeviceInfos)) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 232bc47..429db5e 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -1313,9 +1313,6 @@
             localDevice.init();
             localDevices.add(localDevice);
         }
-        // It's now safe to flush existing local devices from mCecController since they were
-        // already moved to 'localDevices'.
-        clearCecLocalDevices();
         mHdmiCecNetwork.clearDeviceList();
         allocateLogicalAddress(localDevices, initiatedBy);
     }
@@ -1344,6 +1341,7 @@
                             if (logicalAddress == Constants.ADDR_UNREGISTERED) {
                                 Slog.e(TAG, "Failed to allocate address:[device_type:" + deviceType
                                         + "]");
+                                mHdmiCecNetwork.removeLocalDeviceWithType(deviceType);
                             } else {
                                 // Set POWER_STATUS_ON to all local devices because they share
                                 // lifetime
@@ -1352,6 +1350,8 @@
                                         deviceType,
                                         HdmiControlManager.POWER_STATUS_ON, getCecVersion());
                                 localDevice.setDeviceInfo(deviceInfo);
+                                // If a local device of the same type already exists, it will be
+                                // replaced.
                                 mHdmiCecNetwork.addLocalDevice(deviceType, localDevice);
                                 mHdmiCecNetwork.addCecDevice(localDevice.getDeviceInfo());
                                 mCecController.addLogicalAddress(logicalAddress);
@@ -1367,6 +1367,10 @@
                                     // since we reallocate the logical address only.
                                     onInitializeCecComplete(initiatedBy);
                                 }
+                                // We remove local devices here, instead of before the start of
+                                // address allocation, to prevent multiple local devices of the
+                                // same type from existing simultaneously.
+                                mHdmiCecNetwork.removeUnusedLocalDevices(allocatedDevices);
                                 mAddressAllocated = true;
                                 notifyAddressAllocated(allocatedDevices, initiatedBy);
                                 // Reinvoke the saved display status callback once the local
@@ -1386,9 +1390,19 @@
         }
     }
 
+    /**
+     * Notifies local devices that address allocation finished.
+     * @param devices - list of local devices allocated.
+     * @param initiatedBy - reason for the address allocation.
+     */
+    @VisibleForTesting
     @ServiceThreadOnly
-    private void notifyAddressAllocated(ArrayList<HdmiCecLocalDevice> devices, int initiatedBy) {
+    public void notifyAddressAllocated(ArrayList<HdmiCecLocalDevice> devices, int initiatedBy) {
         assertRunOnServiceThread();
+        if (devices == null || devices.isEmpty()) {
+            Slog.w(TAG, "No local device to notify.");
+            return;
+        }
         List<HdmiCecMessage> bufferedMessages = mCecMessageBuffer.getBuffer();
         for (HdmiCecLocalDevice device : devices) {
             int address = device.getDeviceInfo().getLogicalAddress();
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 032778c..d3ad6c4 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -3303,6 +3303,10 @@
         }
 
         // Changing to a different IME.
+        IInputMethodInvoker curMethod = getCurMethodLocked();
+        if (curMethod != null) {
+            curMethod.removeStylusHandwritingWindow();
+        }
         final long ident = Binder.clearCallingIdentity();
         try {
             // Set a subtype to this input method.
diff --git a/services/core/java/com/android/server/media/MediaKeyDispatcher.java b/services/core/java/com/android/server/media/MediaKeyDispatcher.java
index 55511ad..66cafab 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 @@
 
     /**
      * 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;
     }
 
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 0000000..75a0cf5
--- /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 0000000..2cc63eb
--- /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 bada816..802dfb1 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.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.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 @@
     private boolean mIsAutomotive;
     private boolean mNotificationEffectsEnabledForAutomotive;
     private DeviceConfig.OnPropertiesChangedListener mDeviceConfigChangedListener;
+    protected NotificationAttentionHelper mAttentionHelper;
 
     private int mWarnRemoteViewsSizeBytes;
     private int mStripRemoteViewsSizeBytes;
@@ -1167,12 +1170,16 @@
         @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 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 @@
                         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 @@
 
     };
 
+    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 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 @@
                             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 @@
             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 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 @@
 
         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 @@
             }
             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 @@
                     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 @@
             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 @@
                     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 @@
 
                     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 @@
                     || 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 @@
                 });
             }
 
-            // 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 @@
                             cancellationElapsedTimeMs);
                 }
             }
-            updateLightsLocked();
+            if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
+                mAttentionHelper.updateLightsLocked();
+            } else {
+                updateLightsLocked();
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/notification/TEST_MAPPING b/services/core/java/com/android/server/notification/TEST_MAPPING
index 59b2bc1..7db2e8b 100644
--- a/services/core/java/com/android/server/notification/TEST_MAPPING
+++ b/services/core/java/com/android/server/notification/TEST_MAPPING
@@ -13,7 +13,7 @@
           "exclude-annotation": "org.junit.Ignore"
         },
         {
-          "exclude-annotation": "android.platform.test.annotations.LargeTest"
+          "exclude-annotation": "androidx.test.filters.LargeTest"
         },
         {
           "exclude-annotation": "androidx.test.filters.LargeTest"
@@ -33,7 +33,7 @@
           "exclude-annotation": "org.junit.Ignore"
         },
         {
-          "exclude-annotation": "android.platform.test.annotations.LargeTest"
+          "exclude-annotation": "androidx.test.filters.LargeTest"
         },
         {
           "exclude-annotation": "androidx.test.filters.LargeTest"
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index 316c4ac..6baa889 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 @@
                 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 @@
         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 803b6e4..f59188e 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.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 @@
         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 @@
     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/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 700fae9..33cb85c 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -4681,9 +4681,12 @@
             @UserIdInt int userId, @NonNull String recentCallingPackage,
             @NonNull String debugInfo) {
         synchronized (mLock) {
-            final PackageUserStateInternal userState = mSettings.getPackageLPr(
-                    packageName).getUserStateOrDefault(userId);
-            if (userState.isQuarantined()) {
+            final PackageSetting pkgSetting = mSettings.getPackageLPr(packageName);
+            // If the package doesn't exist, don't need to proceed to setPackageStoppedState.
+            if (pkgSetting == null) {
+                return;
+            }
+            if (pkgSetting.getUserStateOrDefault(userId).isQuarantined()) {
                 Slog.i(TAG,
                         "Component is quarantined+suspended but being used: "
                                 + packageName + " by " + recentCallingPackage + ", debugInfo: "
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 72a7370..7264e2e 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -4568,6 +4568,10 @@
                 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);
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 cc8e624..d16a812 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 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 @@
             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/core/java/com/android/server/pm/permission/OneTimePermissionUserManager.java b/services/core/java/com/android/server/pm/permission/OneTimePermissionUserManager.java
index 3296c1f..150ca9b 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 @@
         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 @@
                 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 @@
 
         private final int mUid;
         private final @NonNull String mPackageName;
+        private final int mDeviceId;
         private long mTimeout;
         private long mRevokeAfterKilledDelay;
 
@@ -191,14 +193,15 @@
             }
         };
 
-        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 @@
                                 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 @@
 
         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 @@
                         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 @@
                     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 @@
             }
 
             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 @@
         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 @@
             }
             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 @@
         @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 44eb28f..9610d05 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 @@
 
     @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/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index b001c6a..dc75a98 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -1983,6 +1983,7 @@
             public void run() {
                 if (mPendingHomeKeyEvent != null) {
                     handleShortPressOnHome(mPendingHomeKeyEvent);
+                    mPendingHomeKeyEvent.recycle();
                     mPendingHomeKeyEvent = null;
                 }
             }
@@ -2027,7 +2028,7 @@
                     if (mDoubleTapOnHomeBehavior != DOUBLE_TAP_HOME_PIP_MENU
                             || mPictureInPictureVisible) {
                         mHandler.removeCallbacks(mHomeDoubleTapTimeoutRunnable); // just in case
-                        mPendingHomeKeyEvent = event;
+                        mPendingHomeKeyEvent = KeyEvent.obtain(event);
                         mHandler.postDelayed(mHomeDoubleTapTimeoutRunnable,
                                 ViewConfiguration.getDoubleTapTimeout());
                         return true;
@@ -2035,7 +2036,11 @@
                 }
 
                 // Post to main thread to avoid blocking input pipeline.
-                mHandler.post(() -> handleShortPressOnHome(event));
+                final KeyEvent shortPressEvent = KeyEvent.obtain(event);
+                mHandler.post(() -> {
+                    handleShortPressOnHome(shortPressEvent);
+                    shortPressEvent.recycle();
+                });
                 return true;
             }
 
@@ -2062,9 +2067,14 @@
             if (repeatCount == 0) {
                 mHomePressed = true;
                 if (mPendingHomeKeyEvent != null) {
+                    mPendingHomeKeyEvent.recycle();
                     mPendingHomeKeyEvent = null;
                     mHandler.removeCallbacks(mHomeDoubleTapTimeoutRunnable);
-                    mHandler.post(() -> handleDoubleTapOnHome(event));
+                    final KeyEvent doublePressEvent = KeyEvent.obtain(event);
+                    mHandler.post(() -> {
+                        handleDoubleTapOnHome(doublePressEvent);
+                        doublePressEvent.recycle();
+                    });
                 // TODO(multi-display): Remove display id check once we support recents on
                 // multi-display
                 } else if (mDoubleTapOnHomeBehavior == DOUBLE_TAP_HOME_RECENT_SYSTEM_UI
@@ -2074,7 +2084,11 @@
             } else if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
                 if (!keyguardOn) {
                     // Post to main thread to avoid blocking input pipeline.
-                    mHandler.post(() -> handleLongPressOnHome(event));
+                    final KeyEvent longPressEvent = KeyEvent.obtain(event);
+                    mHandler.post(() -> {
+                        handleLongPressOnHome(longPressEvent);
+                        longPressEvent.recycle();
+                    });
                 }
             }
             return true;
@@ -3972,15 +3986,15 @@
      */
     private int handleTransitionForKeyguardLw(boolean startKeyguardExitAnimation,
             boolean notifyOccluded) {
+        int redoLayout = 0;
         if (notifyOccluded) {
-            final int redoLayout = applyKeyguardOcclusionChange();
-            if (redoLayout != 0) return redoLayout;
+            redoLayout = applyKeyguardOcclusionChange();
         }
         if (startKeyguardExitAnimation) {
             if (DEBUG_KEYGUARD) Slog.d(TAG, "Starting keyguard exit animation");
             startKeyguardExitAnimation(SystemClock.uptimeMillis());
         }
-        return 0;
+        return redoLayout;
     }
 
     // There are several different flavors of "assistant" that can be launched from
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index d824534..a0c7870 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -2887,7 +2887,7 @@
         final boolean animate;
         if (mStartingData != null) {
             if (mStartingData.mWaitForSyncTransactionCommit
-                    || mTransitionController.inCollectingTransition(startingWindow)) {
+                    || mTransitionController.isCollecting(this)) {
                 mStartingData.mRemoveAfterTransaction = AFTER_TRANSACTION_REMOVE_DIRECTLY;
                 mStartingData.mPrepareRemoveAnimation = prepareAnimation;
                 return;
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index f38f6b0..237bc92 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 @@
                 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
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index 1ad5798..901975b 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -795,10 +795,19 @@
             return false;
         }
 
-        // Try pausing the existing resumed activity in the Task if any.
         final Task task = r.getTask();
-        if (task.pauseActivityIfNeeded(r, "realStart")) {
-            return false;
+        if (andResume) {
+            // Try pausing the existing resumed activity in the Task if any.
+            if (task.pauseActivityIfNeeded(r, "realStart")) {
+                return false;
+            }
+            final TaskFragment taskFragment = r.getTaskFragment();
+            if (taskFragment != null && taskFragment.getResumedActivity() != null) {
+                if (taskFragment.startPausing(mUserLeaving, false /* uiSleeping */, r,
+                        "realStart")) {
+                    return false;
+                }
+            }
         }
 
         final Task rootTask = task.getRootTask();
diff --git a/services/core/java/com/android/server/wm/ContentRecorder.java b/services/core/java/com/android/server/wm/ContentRecorder.java
index b499dad..06448d0 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.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;
@@ -48,11 +47,6 @@
 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.
      */
     @NonNull
@@ -411,14 +405,6 @@
                 // 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/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 4309e72..ca42400 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -2160,6 +2160,16 @@
     }
 
     /**
+     * @see DisplayWindowPolicyController#getCustomHomeComponent() ()
+     */
+    @Nullable ComponentName getCustomHomeComponent() {
+        if (!supportsSystemDecorations() || mDwpcHelper == null) {
+            return null;
+        }
+        return mDwpcHelper.getCustomHomeComponent();
+    }
+
+    /**
      * Applies the rotation transaction. This must be called after {@link #updateRotationUnchecked}
      * (if it returned {@code true}) to actually finish the rotation.
      *
diff --git a/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java b/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java
index 6b33746..e0d69b0 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.WindowConfiguration;
+import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.os.Process;
@@ -200,6 +201,17 @@
         return mDisplayWindowPolicyController.isEnteringPipAllowed(uid);
     }
 
+    /**
+     * @see DisplayWindowPolicyController#getCustomHomeComponent
+     */
+    @Nullable
+    public ComponentName getCustomHomeComponent() {
+        if (mDisplayWindowPolicyController == null) {
+            return null;
+        }
+        return mDisplayWindowPolicyController.getCustomHomeComponent();
+    }
+
     void dump(String prefix, PrintWriter pw) {
         if (mDisplayWindowPolicyController != null) {
             pw.println();
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 2fdfec0..2a33918 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -1513,10 +1513,30 @@
             throw new IllegalArgumentException(
                     "resolveSecondaryHomeActivity: Should not be default task container");
         }
-        // Resolve activities in the same package as currently selected primary home activity.
+
         Intent homeIntent = mService.getHomeIntent();
         ActivityInfo aInfo = resolveHomeActivity(userId, homeIntent);
-        if (aInfo != null) {
+        boolean lookForSecondaryHomeActivityInPrimaryHomePackage = aInfo != null;
+
+        if (android.companion.virtual.flags.Flags.vdmCustomHome()) {
+            // Resolve the externally set home activity for this display, if any. If it is unset or
+            // we fail to resolve it, fallback to the default secondary home activity.
+            final ComponentName customHomeComponent =
+                    taskDisplayArea.getDisplayContent() != null
+                            ? taskDisplayArea.getDisplayContent().getCustomHomeComponent()
+                            : null;
+            if (customHomeComponent != null) {
+                homeIntent.setComponent(customHomeComponent);
+                ActivityInfo customHomeActivityInfo = resolveHomeActivity(userId, homeIntent);
+                if (customHomeActivityInfo != null) {
+                    aInfo = customHomeActivityInfo;
+                    lookForSecondaryHomeActivityInPrimaryHomePackage = false;
+                }
+            }
+        }
+
+        if (lookForSecondaryHomeActivityInPrimaryHomePackage) {
+            // Resolve activities in the same package as currently selected primary home activity.
             if (ResolverActivity.class.getName().equals(aInfo.name)) {
                 // Always fallback to secondary home component if default home is not set.
                 aInfo = null;
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index 2c142cb..bbb8563 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -40,9 +40,11 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.hardware.HardwareBuffer;
+import android.os.IBinder;
 import android.os.Trace;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
+import android.view.DisplayAddress;
 import android.view.DisplayInfo;
 import android.view.Surface;
 import android.view.Surface.OutOfResourcesException;
@@ -55,6 +57,7 @@
 import com.android.internal.R;
 import com.android.internal.policy.TransitionAnimation;
 import com.android.internal.protolog.common.ProtoLog;
+import com.android.server.display.DisplayControl;
 import com.android.server.wm.SurfaceAnimator.AnimationType;
 import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
 
@@ -168,10 +171,32 @@
         try {
             final ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer;
             if (isSizeChanged) {
+                final DisplayAddress address = displayInfo.address;
+                if (!(address instanceof DisplayAddress.Physical)) {
+                    Slog.e(TAG, "Display does not have a physical address: " + displayId);
+                    return;
+                }
+                final DisplayAddress.Physical physicalAddress =
+                        (DisplayAddress.Physical) address;
+                final IBinder displayToken = DisplayControl.getPhysicalDisplayToken(
+                        physicalAddress.getPhysicalDisplayId());
+                if (displayToken == null) {
+                    Slog.e(TAG, "Display token is null.");
+                    return;
+                }
                 // Temporarily not skip screenshot for the rounded corner overlays and screenshot
                 // the whole display to include the rounded corner overlays.
                 setSkipScreenshotForRoundedCornerOverlays(false, t);
-            }
+                mRoundedCornerOverlay = displayContent.findRoundedCornerOverlays();
+                final ScreenCapture.DisplayCaptureArgs captureArgs =
+                        new ScreenCapture.DisplayCaptureArgs.Builder(displayToken)
+                                .setSourceCrop(new Rect(0, 0, width, height))
+                                .setAllowProtected(true)
+                                .setCaptureSecureLayers(true)
+                                .setHintForSeamlessTransition(true)
+                                .build();
+                screenshotBuffer = ScreenCapture.captureDisplay(captureArgs);
+            } else {
                 ScreenCapture.LayerCaptureArgs captureArgs =
                         new ScreenCapture.LayerCaptureArgs.Builder(
                                 displayContent.getSurfaceControl())
@@ -181,6 +206,7 @@
                                 .setHintForSeamlessTransition(true)
                                 .build();
                 screenshotBuffer = ScreenCapture.captureLayers(captureArgs);
+            }
 
             if (screenshotBuffer == null) {
                 Slog.w(TAG, "Unable to take screenshot of display " + displayId);
diff --git a/services/core/java/com/android/server/wm/StartingData.java b/services/core/java/com/android/server/wm/StartingData.java
index 2d281c4..07ffa69e 100644
--- a/services/core/java/com/android/server/wm/StartingData.java
+++ b/services/core/java/com/android/server/wm/StartingData.java
@@ -108,4 +108,13 @@
     boolean hasImeSurface() {
         return false;
     }
+
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + "{"
+                + Integer.toHexString(System.identityHashCode(this))
+                + " waitForSyncTransactionCommit=" + mWaitForSyncTransactionCommit
+                + " removeAfterTransaction= " + mRemoveAfterTransaction
+                + "}";
+    }
 }
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index b4b8a74..261fc2e 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -3494,6 +3494,7 @@
         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();
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index a4d43d8..9f1bccb 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -45,7 +45,6 @@
 import android.view.WindowInfo;
 import android.view.WindowManager.DisplayImePolicy;
 import android.view.inputmethod.ImeTracker;
-import android.window.ScreenCapture;
 
 import com.android.internal.policy.KeyInterceptionInfo;
 import com.android.server.input.InputManagerService;
@@ -957,14 +956,6 @@
     public abstract SurfaceControl getA11yOverlayLayer(int displayId);
 
     /**
-     * Captures the entire display specified by the displayId using the args provided. If the args
-     * are null or if the sourceCrop is invalid or null, the entire display bounds will be captured.
-     */
-    public abstract void captureDisplay(int displayId,
-                                        @Nullable ScreenCapture.CaptureArgs captureArgs,
-                                        ScreenCapture.ScreenCaptureListener listener);
-
-    /**
      * Device has a software navigation bar (separate from the status bar) on specific display.
      *
      * @param displayId the id of display to check if there is a software navigation bar.
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 8fe104c..9a1920d 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -8415,12 +8415,6 @@
         }
 
         @Override
-        public void captureDisplay(int displayId, @Nullable ScreenCapture.CaptureArgs captureArgs,
-                                   ScreenCapture.ScreenCaptureListener listener) {
-            WindowManagerService.this.captureDisplay(displayId, captureArgs, listener);
-        }
-
-        @Override
         public boolean hasNavigationBar(int displayId) {
             return WindowManagerService.this.hasNavigationBar(displayId);
         }
diff --git a/services/core/jni/TEST_MAPPING b/services/core/jni/TEST_MAPPING
index ea44d06..eb9db70 100644
--- a/services/core/jni/TEST_MAPPING
+++ b/services/core/jni/TEST_MAPPING
@@ -6,7 +6,7 @@
       ],
       "name": "CtsVibratorTestCases",
       "options": [
-        {"exclude-annotation": "android.platform.test.annotations.LargeTest"},
+        {"exclude-annotation": "androidx.test.filters.LargeTest"},
         {"exclude-annotation": "android.platform.test.annotations.FlakyTest"},
         {"exclude-annotation": "androidx.test.filters.FlakyTest"},
         {"exclude-annotation": "org.junit.Ignore"}
diff --git a/services/core/xsd/display-device-config/display-device-config.xsd b/services/core/xsd/display-device-config/display-device-config.xsd
index 4203e89..d0a9c45 100644
--- a/services/core/xsd/display-device-config/display-device-config.xsd
+++ b/services/core/xsd/display-device-config/display-device-config.xsd
@@ -96,6 +96,16 @@
                 <xs:element type="xs:nonNegativeInteger" name="screenBrightnessRampDecreaseMaxMillis">
                     <xs:annotation name="final"/>
                 </xs:element>
+                <!-- Maximum time in milliseconds that a brightness increase animation
+                     can take in idle mode. -->
+                <xs:element type="xs:nonNegativeInteger" name="screenBrightnessRampIncreaseMaxIdleMillis">
+                    <xs:annotation name="final"/>
+                </xs:element>
+                <!-- Maximum time in milliseconds that a brightness decrease animation
+                     can take in idle mode. -->
+                <xs:element type="xs:nonNegativeInteger" name="screenBrightnessRampDecreaseMaxIdleMillis">
+                    <xs:annotation name="final"/>
+                </xs:element>
                 <xs:element type="sensorDetails" name="lightSensor">
                     <xs:annotation name="final"/>
                 </xs:element>
diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt
index ebd9b1c..949b1f2 100644
--- a/services/core/xsd/display-device-config/schema/current.txt
+++ b/services/core/xsd/display-device-config/schema/current.txt
@@ -111,9 +111,11 @@
     method public com.android.server.display.config.RefreshRateConfigs getRefreshRate();
     method @NonNull public final java.math.BigDecimal getScreenBrightnessDefault();
     method @NonNull public final com.android.server.display.config.NitsMap getScreenBrightnessMap();
+    method public final java.math.BigInteger getScreenBrightnessRampDecreaseMaxIdleMillis();
     method public final java.math.BigInteger getScreenBrightnessRampDecreaseMaxMillis();
     method public final java.math.BigDecimal getScreenBrightnessRampFastDecrease();
     method public final java.math.BigDecimal getScreenBrightnessRampFastIncrease();
+    method public final java.math.BigInteger getScreenBrightnessRampIncreaseMaxIdleMillis();
     method public final java.math.BigInteger getScreenBrightnessRampIncreaseMaxMillis();
     method public final java.math.BigDecimal getScreenBrightnessRampSlowDecrease();
     method public final java.math.BigDecimal getScreenBrightnessRampSlowDecreaseIdle();
@@ -141,9 +143,11 @@
     method public void setRefreshRate(com.android.server.display.config.RefreshRateConfigs);
     method public final void setScreenBrightnessDefault(@NonNull java.math.BigDecimal);
     method public final void setScreenBrightnessMap(@NonNull com.android.server.display.config.NitsMap);
+    method public final void setScreenBrightnessRampDecreaseMaxIdleMillis(java.math.BigInteger);
     method public final void setScreenBrightnessRampDecreaseMaxMillis(java.math.BigInteger);
     method public final void setScreenBrightnessRampFastDecrease(java.math.BigDecimal);
     method public final void setScreenBrightnessRampFastIncrease(java.math.BigDecimal);
+    method public final void setScreenBrightnessRampIncreaseMaxIdleMillis(java.math.BigInteger);
     method public final void setScreenBrightnessRampIncreaseMaxMillis(java.math.BigInteger);
     method public final void setScreenBrightnessRampSlowDecrease(java.math.BigDecimal);
     method public final void setScreenBrightnessRampSlowDecreaseIdle(java.math.BigDecimal);
diff --git a/services/devicepolicy/TEST_MAPPING b/services/devicepolicy/TEST_MAPPING
index 72bba11..fccd1ec 100644
--- a/services/devicepolicy/TEST_MAPPING
+++ b/services/devicepolicy/TEST_MAPPING
@@ -7,7 +7,7 @@
           "exclude-annotation": "android.platform.test.annotations.FlakyTest"
         },
         {
-          "exclude-annotation": "android.platform.test.annotations.LargeTest"
+          "exclude-annotation": "androidx.test.filters.LargeTest"
         }
       ]
     }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 84d1a45..f604932 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -16017,16 +16017,20 @@
     }
 
     @Override
-    public PackagePolicy getCredentialManagerPolicy() {
+    public PackagePolicy getCredentialManagerPolicy(int userId) {
         if (!mHasFeature) {
             return null;
         }
         final CallerIdentity caller = getCallerIdentity();
         Preconditions.checkCallAuthorization(
                 canWriteCredentialManagerPolicy(caller) || canQueryAdminPolicy(caller));
+        if (userId != caller.getUserId()) {
+            Preconditions.checkCallAuthorization(
+                    hasCallingOrSelfPermission(permission.INTERACT_ACROSS_USERS));
+        }
 
         synchronized (getLockObject()) {
-            ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId());
+            ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(userId);
             return (admin != null) ? admin.mCredentialManagerPolicy : null;
         }
     }
diff --git a/services/foldables/devicestateprovider/OWNERS b/services/foldables/devicestateprovider/OWNERS
new file mode 100644
index 0000000..b2dcd0c
--- /dev/null
+++ b/services/foldables/devicestateprovider/OWNERS
@@ -0,0 +1,6 @@
+akulian@google.com
+kennethford@google.com
+jiamingliu@google.com
+kchyn@google.com
+nickchameyev@google.com
+nicomazz@google.com
\ No newline at end of file
diff --git a/services/incremental/TEST_MAPPING b/services/incremental/TEST_MAPPING
index 4af880d..4c9403c 100644
--- a/services/incremental/TEST_MAPPING
+++ b/services/incremental/TEST_MAPPING
@@ -12,7 +12,7 @@
       "name": "CtsPackageManagerIncrementalStatsHostTestCases",
       "options": [
         {
-          "exclude-annotation": "android.platform.test.annotations.LargeTest"
+          "exclude-annotation": "androidx.test.filters.LargeTest"
         }
       ]
     },
@@ -55,7 +55,7 @@
       "name": "CtsPackageManagerIncrementalStatsHostTestCases",
       "options": [
         {
-          "include-annotation": "android.platform.test.annotations.LargeTest"
+          "include-annotation": "androidx.test.filters.LargeTest"
         }
       ]
     }
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 b2733d4..240585c 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 @@
         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 @@
         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()) {
diff --git a/services/tests/displayservicetests/Android.bp b/services/tests/displayservicetests/Android.bp
index e28028f9..0275c7d 100644
--- a/services/tests/displayservicetests/Android.bp
+++ b/services/tests/displayservicetests/Android.bp
@@ -29,6 +29,7 @@
     static_libs: [
         "androidx.test.ext.junit",
         "androidx.test.rules",
+        "flag-junit",
         "frameworks-base-testutils",
         "junit",
         "junit-params",
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
index 7374901..6ef150c 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
@@ -103,12 +103,6 @@
         assertEquals(mDisplayDeviceConfig.getName(), "Example Display");
         assertEquals(mDisplayDeviceConfig.getAmbientHorizonLong(), 5000);
         assertEquals(mDisplayDeviceConfig.getAmbientHorizonShort(), 50);
-        assertEquals(mDisplayDeviceConfig.getBrightnessRampDecreaseMaxMillis(), 3000);
-        assertEquals(mDisplayDeviceConfig.getBrightnessRampIncreaseMaxMillis(), 2000);
-        assertEquals(mDisplayDeviceConfig.getBrightnessRampFastDecrease(), 0.01f, ZERO_DELTA);
-        assertEquals(mDisplayDeviceConfig.getBrightnessRampFastIncrease(), 0.02f, ZERO_DELTA);
-        assertEquals(mDisplayDeviceConfig.getBrightnessRampSlowIncrease(), 0.04f, ZERO_DELTA);
-        assertEquals(mDisplayDeviceConfig.getBrightnessRampSlowDecrease(), 0.03f, ZERO_DELTA);
         assertEquals(mDisplayDeviceConfig.getBrightnessDefault(), 0.5f, ZERO_DELTA);
         assertArrayEquals(mDisplayDeviceConfig.getBrightness(), BRIGHTNESS, ZERO_DELTA);
         assertArrayEquals(mDisplayDeviceConfig.getNits(), NITS, ZERO_DELTA);
@@ -235,7 +229,8 @@
     @Test
     public void testInvalidLuxThrottling() throws Exception {
         setupDisplayDeviceConfigFromDisplayConfigFile(
-                getContent(getInvalidLuxThrottling(), getValidProxSensor()));
+                getContent(getInvalidLuxThrottling(), getValidProxSensor(),
+                        /* includeIdleMode= */ true));
 
         Map<DisplayDeviceConfig.BrightnessLimitMapType, Map<Float, Float>> luxThrottlingData =
                 mDisplayDeviceConfig.getLuxThrottlingData();
@@ -258,6 +253,10 @@
 
         // We should fall back to the config resource
         verifyConfigValuesFromConfigResource();
+        assertEquals(3000, mDisplayDeviceConfig.getAutoBrightnessBrighteningLightDebounce());
+        assertEquals(4000, mDisplayDeviceConfig.getAutoBrightnessDarkeningLightDebounce());
+        assertEquals(3000, mDisplayDeviceConfig.getAutoBrightnessBrighteningLightDebounceIdle());
+        assertEquals(4000, mDisplayDeviceConfig.getAutoBrightnessDarkeningLightDebounceIdle());
     }
 
     @Test
@@ -438,7 +437,8 @@
     @Test
     public void testProximitySensorWithEmptyValuesFromDisplayConfig() throws IOException {
         setupDisplayDeviceConfigFromDisplayConfigFile(
-                getContent(getValidLuxThrottling(), getProxSensorWithEmptyValues()));
+                getContent(getValidLuxThrottling(), getProxSensorWithEmptyValues(),
+                        /* includeIdleMode= */ true));
         assertNull(mDisplayDeviceConfig.getProximitySensor());
     }
 
@@ -577,6 +577,39 @@
         assertEquals(mDisplayDeviceConfig.getAutoBrightnessDarkeningLightDebounceIdle(), 1500);
     }
 
+    @Test
+    public void testBrightnessRamps() throws IOException {
+        setupDisplayDeviceConfigFromDisplayConfigFile();
+
+        assertEquals(mDisplayDeviceConfig.getBrightnessRampDecreaseMaxMillis(), 3000);
+        assertEquals(mDisplayDeviceConfig.getBrightnessRampIncreaseMaxMillis(), 2000);
+        assertEquals(mDisplayDeviceConfig.getBrightnessRampDecreaseMaxIdleMillis(), 5000);
+        assertEquals(mDisplayDeviceConfig.getBrightnessRampIncreaseMaxIdleMillis(), 4000);
+        assertEquals(mDisplayDeviceConfig.getBrightnessRampFastDecrease(), 0.01f, ZERO_DELTA);
+        assertEquals(mDisplayDeviceConfig.getBrightnessRampFastIncrease(), 0.02f, ZERO_DELTA);
+        assertEquals(mDisplayDeviceConfig.getBrightnessRampSlowDecrease(), 0.03f, ZERO_DELTA);
+        assertEquals(mDisplayDeviceConfig.getBrightnessRampSlowIncrease(), 0.04f, ZERO_DELTA);
+        assertEquals(mDisplayDeviceConfig.getBrightnessRampSlowDecreaseIdle(), 0.05f, ZERO_DELTA);
+        assertEquals(mDisplayDeviceConfig.getBrightnessRampSlowIncreaseIdle(), 0.06f, ZERO_DELTA);
+    }
+
+    @Test
+    public void testBrightnessRamps_IdleFallsBackToConfigInteractive() throws IOException {
+        setupDisplayDeviceConfigFromDisplayConfigFile(getContent(getValidLuxThrottling(),
+                getValidProxSensor(), /* includeIdleMode= */ false));
+
+        assertEquals(mDisplayDeviceConfig.getBrightnessRampDecreaseMaxMillis(), 3000);
+        assertEquals(mDisplayDeviceConfig.getBrightnessRampIncreaseMaxMillis(), 2000);
+        assertEquals(mDisplayDeviceConfig.getBrightnessRampDecreaseMaxIdleMillis(), 3000);
+        assertEquals(mDisplayDeviceConfig.getBrightnessRampIncreaseMaxIdleMillis(), 2000);
+        assertEquals(mDisplayDeviceConfig.getBrightnessRampFastDecrease(), 0.01f, ZERO_DELTA);
+        assertEquals(mDisplayDeviceConfig.getBrightnessRampFastIncrease(), 0.02f, ZERO_DELTA);
+        assertEquals(mDisplayDeviceConfig.getBrightnessRampSlowDecrease(), 0.03f, ZERO_DELTA);
+        assertEquals(mDisplayDeviceConfig.getBrightnessRampSlowIncrease(), 0.04f, ZERO_DELTA);
+        assertEquals(mDisplayDeviceConfig.getBrightnessRampSlowDecreaseIdle(), 0.03f, ZERO_DELTA);
+        assertEquals(mDisplayDeviceConfig.getBrightnessRampSlowIncreaseIdle(), 0.04f, ZERO_DELTA);
+    }
+
     private String getValidLuxThrottling() {
         return "<luxThrottling>\n"
                 + "    <brightnessLimitMap>\n"
@@ -731,11 +764,103 @@
               + "</hdrBrightnessConfig>";
     }
 
-    private String getContent() {
-        return getContent(getValidLuxThrottling(), getValidProxSensor());
+    private String getRampSpeedsIdle() {
+        return "<brighteningLightDebounceIdleMillis>"
+                +           "2500"
+                +       "</brighteningLightDebounceIdleMillis>\n"
+                +       "<darkeningLightDebounceIdleMillis>"
+                +           "1500"
+                +       "</darkeningLightDebounceIdleMillis>\n";
     }
 
-    private String getContent(String brightnessCapConfig, String proxSensor) {
+    private String getThresholdsIdle() {
+        return  "<ambientBrightnessChangeThresholdsIdle>\n"
+                +       "<brighteningThresholds>\n"
+                +           "<minimum>20</minimum>\n"
+                +           "<brightnessThresholdPoints>\n"
+                +               "<brightnessThresholdPoint>\n"
+                +                   "<threshold>0</threshold><percentage>21</percentage>\n"
+                +               "</brightnessThresholdPoint>\n"
+                +               "<brightnessThresholdPoint>\n"
+                +                   "<threshold>500</threshold><percentage>22</percentage>\n"
+                +               "</brightnessThresholdPoint>\n"
+                +               "<brightnessThresholdPoint>\n"
+                +                   "<threshold>600</threshold><percentage>23</percentage>\n"
+                +               "</brightnessThresholdPoint>\n"
+                +           "</brightnessThresholdPoints>\n"
+                +       "</brighteningThresholds>\n"
+                +       "<darkeningThresholds>\n"
+                +           "<minimum>40</minimum>\n"
+                +           "<brightnessThresholdPoints>\n"
+                +               "<brightnessThresholdPoint>\n"
+                +                   "<threshold>0</threshold><percentage>23</percentage>\n"
+                +               "</brightnessThresholdPoint>\n"
+                +               "<brightnessThresholdPoint>\n"
+                +                   "<threshold>700</threshold><percentage>24</percentage>\n"
+                +               "</brightnessThresholdPoint>\n"
+                +               "<brightnessThresholdPoint>\n"
+                +                   "<threshold>800</threshold><percentage>25</percentage>\n"
+                +               "</brightnessThresholdPoint>\n"
+                +           "</brightnessThresholdPoints>\n"
+                +       "</darkeningThresholds>\n"
+                +   "</ambientBrightnessChangeThresholdsIdle>\n"
+                +   "<displayBrightnessChangeThresholdsIdle>\n"
+                +       "<brighteningThresholds>\n"
+                +           "<minimum>0.2</minimum>\n"
+                +           "<brightnessThresholdPoints>\n"
+                +               "<brightnessThresholdPoint>\n"
+                +                   "<threshold>0</threshold><percentage>17</percentage>\n"
+                +               "</brightnessThresholdPoint>\n"
+                +               "<brightnessThresholdPoint>\n"
+                +                   "<threshold>0.12</threshold><percentage>18</percentage>\n"
+                +               "</brightnessThresholdPoint>\n"
+                +               "<brightnessThresholdPoint>\n"
+                +                   "<threshold>0.22</threshold><percentage>19</percentage>\n"
+                +               "</brightnessThresholdPoint>\n"
+                +           "</brightnessThresholdPoints>\n"
+                +       "</brighteningThresholds>\n"
+                +       "<darkeningThresholds>\n"
+                +           "<minimum>0.4</minimum>\n"
+                +           "<brightnessThresholdPoints>\n"
+                +               "<brightnessThresholdPoint>\n"
+                +                   "<threshold>0</threshold><percentage>19</percentage>\n"
+                +               "</brightnessThresholdPoint>\n"
+                +               "<brightnessThresholdPoint>\n"
+                +                   "<threshold>0.13</threshold><percentage>20</percentage>\n"
+                +               "</brightnessThresholdPoint>\n"
+                +               "<brightnessThresholdPoint>\n"
+                +                   "<threshold>0.23</threshold><percentage>21</percentage>\n"
+                +               "</brightnessThresholdPoint>\n"
+                +           "</brightnessThresholdPoints>\n"
+                +       "</darkeningThresholds>\n"
+                +   "</displayBrightnessChangeThresholdsIdle>\n";
+    }
+
+    private String getScreenBrightnessRampSlowIdle() {
+        return "<screenBrightnessRampSlowDecreaseIdle>"
+                +       "0.05"
+                +   "</screenBrightnessRampSlowDecreaseIdle>\n"
+                +   "<screenBrightnessRampSlowIncreaseIdle>"
+                +       "0.06"
+                +   "</screenBrightnessRampSlowIncreaseIdle>\n";
+    }
+
+    private String getScreenBrightnessRampCapsIdle() {
+        return "<screenBrightnessRampIncreaseMaxIdleMillis>"
+                +       "4000"
+                +   "</screenBrightnessRampIncreaseMaxIdleMillis>\n"
+                +   "<screenBrightnessRampDecreaseMaxIdleMillis>"
+                +       "5000"
+                +   "</screenBrightnessRampDecreaseMaxIdleMillis>\n";
+
+    }
+    private String getContent() {
+        return getContent(getValidLuxThrottling(), getValidProxSensor(),
+                /* includeIdleMode= */ true);
+    }
+
+    private String getContent(String brightnessCapConfig, String proxSensor,
+            boolean includeIdleMode) {
         return "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
                 + "<displayConfiguration>\n"
                 +   "<name>Example Display</name>\n"
@@ -778,12 +903,7 @@
                 +   "<autoBrightness>\n"
                 +       "<brighteningLightDebounceMillis>2000</brighteningLightDebounceMillis>\n"
                 +       "<darkeningLightDebounceMillis>1000</darkeningLightDebounceMillis>\n"
-                +       "<brighteningLightDebounceIdleMillis>"
-                +           "2500"
-                +       "</brighteningLightDebounceIdleMillis>\n"
-                +       "<darkeningLightDebounceIdleMillis>"
-                +           "1500"
-                +       "</darkeningLightDebounceIdleMillis>\n"
+                + (includeIdleMode ? getRampSpeedsIdle() : "")
                 +       "<displayBrightnessMapping>\n"
                 +            "<displayBrightnessPoint>\n"
                 +                "<lux>50</lux>\n"
@@ -899,76 +1019,19 @@
                 +           "</brightnessThresholdPoints>\n"
                 +       "</darkeningThresholds>\n"
                 +   "</displayBrightnessChangeThresholds>\n"
-                +   "<ambientBrightnessChangeThresholdsIdle>\n"
-                +       "<brighteningThresholds>\n"
-                +           "<minimum>20</minimum>\n"
-                +           "<brightnessThresholdPoints>\n"
-                +               "<brightnessThresholdPoint>\n"
-                +                   "<threshold>0</threshold><percentage>21</percentage>\n"
-                +               "</brightnessThresholdPoint>\n"
-                +               "<brightnessThresholdPoint>\n"
-                +                   "<threshold>500</threshold><percentage>22</percentage>\n"
-                +               "</brightnessThresholdPoint>\n"
-                +               "<brightnessThresholdPoint>\n"
-                +                   "<threshold>600</threshold><percentage>23</percentage>\n"
-                +               "</brightnessThresholdPoint>\n"
-                +           "</brightnessThresholdPoints>\n"
-                +       "</brighteningThresholds>\n"
-                +       "<darkeningThresholds>\n"
-                +           "<minimum>40</minimum>\n"
-                +           "<brightnessThresholdPoints>\n"
-                +               "<brightnessThresholdPoint>\n"
-                +                   "<threshold>0</threshold><percentage>23</percentage>\n"
-                +               "</brightnessThresholdPoint>\n"
-                +               "<brightnessThresholdPoint>\n"
-                +                   "<threshold>700</threshold><percentage>24</percentage>\n"
-                +               "</brightnessThresholdPoint>\n"
-                +               "<brightnessThresholdPoint>\n"
-                +                   "<threshold>800</threshold><percentage>25</percentage>\n"
-                +               "</brightnessThresholdPoint>\n"
-                +           "</brightnessThresholdPoints>\n"
-                +       "</darkeningThresholds>\n"
-                +   "</ambientBrightnessChangeThresholdsIdle>\n"
-                +   "<displayBrightnessChangeThresholdsIdle>\n"
-                +       "<brighteningThresholds>\n"
-                +           "<minimum>0.2</minimum>\n"
-                +           "<brightnessThresholdPoints>\n"
-                +               "<brightnessThresholdPoint>\n"
-                +                   "<threshold>0</threshold><percentage>17</percentage>\n"
-                +               "</brightnessThresholdPoint>\n"
-                +               "<brightnessThresholdPoint>\n"
-                +                   "<threshold>0.12</threshold><percentage>18</percentage>\n"
-                +               "</brightnessThresholdPoint>\n"
-                +               "<brightnessThresholdPoint>\n"
-                +                   "<threshold>0.22</threshold><percentage>19</percentage>\n"
-                +               "</brightnessThresholdPoint>\n"
-                +           "</brightnessThresholdPoints>\n"
-                +       "</brighteningThresholds>\n"
-                +       "<darkeningThresholds>\n"
-                +           "<minimum>0.4</minimum>\n"
-                +           "<brightnessThresholdPoints>\n"
-                +               "<brightnessThresholdPoint>\n"
-                +                   "<threshold>0</threshold><percentage>19</percentage>\n"
-                +               "</brightnessThresholdPoint>\n"
-                +               "<brightnessThresholdPoint>\n"
-                +                   "<threshold>0.13</threshold><percentage>20</percentage>\n"
-                +               "</brightnessThresholdPoint>\n"
-                +               "<brightnessThresholdPoint>\n"
-                +                   "<threshold>0.23</threshold><percentage>21</percentage>\n"
-                +               "</brightnessThresholdPoint>\n"
-                +           "</brightnessThresholdPoints>\n"
-                +       "</darkeningThresholds>\n"
-                +   "</displayBrightnessChangeThresholdsIdle>\n"
-                +   "<screenBrightnessRampFastDecrease>0.01</screenBrightnessRampFastDecrease> "
-                +   "<screenBrightnessRampFastIncrease>0.02</screenBrightnessRampFastIncrease>  "
-                +   "<screenBrightnessRampSlowDecrease>0.03</screenBrightnessRampSlowDecrease>"
-                +   "<screenBrightnessRampSlowIncrease>0.04</screenBrightnessRampSlowIncrease>"
+                + (includeIdleMode ?  getThresholdsIdle() : "")
+                +   "<screenBrightnessRampFastDecrease>0.01</screenBrightnessRampFastDecrease>\n"
+                +   "<screenBrightnessRampFastIncrease>0.02</screenBrightnessRampFastIncrease>\n"
+                +   "<screenBrightnessRampSlowDecrease>0.03</screenBrightnessRampSlowDecrease>\n"
+                +   "<screenBrightnessRampSlowIncrease>0.04</screenBrightnessRampSlowIncrease>\n"
+                + (includeIdleMode ? getScreenBrightnessRampSlowIdle() : "")
                 +   "<screenBrightnessRampIncreaseMaxMillis>"
                 +       "2000"
-                +   "</screenBrightnessRampIncreaseMaxMillis>"
+                +   "</screenBrightnessRampIncreaseMaxMillis>\n"
                 +   "<screenBrightnessRampDecreaseMaxMillis>"
                 +       "3000"
-                +   "</screenBrightnessRampDecreaseMaxMillis>"
+                +   "</screenBrightnessRampDecreaseMaxMillis>\n"
+                + (includeIdleMode ?  getScreenBrightnessRampCapsIdle() : "")
                 +   "<ambientLightHorizonLong>5000</ambientLightHorizonLong>\n"
                 +   "<ambientLightHorizonShort>50</ambientLightHorizonShort>\n"
                 +   "<screenBrightnessRampIncreaseMaxMillis>"
@@ -1201,6 +1264,13 @@
         when(mResources.getString(com.android.internal.R.string.config_displayLightSensorType))
                 .thenReturn("test_light_sensor");
 
+        when(mResources.getInteger(
+                R.integer.config_autoBrightnessBrighteningLightDebounce))
+                .thenReturn(3000);
+        when(mResources.getInteger(
+                R.integer.config_autoBrightnessDarkeningLightDebounce))
+                .thenReturn(4000);
+
         mDisplayDeviceConfig = DisplayDeviceConfig.create(mContext, 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 d6b2c87..a56b59a 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java
@@ -53,6 +53,10 @@
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.test.TestLooper;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.provider.Settings;
 import android.testing.TestableContext;
 import android.util.FloatProperty;
@@ -71,6 +75,7 @@
 import com.android.server.display.brightness.clamper.HdrClamper;
 import com.android.server.display.color.ColorDisplayService;
 import com.android.server.display.feature.DisplayManagerFlags;
+import com.android.server.display.feature.flags.Flags;
 import com.android.server.display.layout.Layout;
 import com.android.server.display.whitebalance.DisplayWhiteBalanceController;
 import com.android.server.policy.WindowManagerPolicy;
@@ -108,12 +113,16 @@
     private static final float BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE = 0.5f;
     private static final float BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE = 0.6f;
 
+    private static final long BRIGHTNESS_RAMP_INCREASE_MAX = 1000;
+    private static final long BRIGHTNESS_RAMP_DECREASE_MAX = 2000;
+    private static final long BRIGHTNESS_RAMP_INCREASE_MAX_IDLE = 3000;
+    private static final long BRIGHTNESS_RAMP_DECREASE_MAX_IDLE = 4000;
+
     private OffsettableClock mClock;
     private TestLooper mTestLooper;
     private Handler mHandler;
     private DisplayPowerControllerHolder mHolder;
     private Sensor mProxSensor;
-
     @Mock
     private DisplayPowerCallbacks mDisplayPowerCallbacksMock;
     @Mock
@@ -130,6 +139,8 @@
     private ColorDisplayService.ColorDisplayServiceInternal mCdsiMock;
     @Mock
     private DisplayWhiteBalanceController mDisplayWhiteBalanceControllerMock;
+    @Mock
+    private DisplayManagerFlags mDisplayManagerFlagsMock;
     @Captor
     private ArgumentCaptor<SensorEventListener> mSensorEventListenerCaptor;
 
@@ -145,6 +156,9 @@
                     .spyStatic(BatteryStatsService.class)
                     .build();
 
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+
     @Before
     public void setUp() throws Exception {
         mClock = new OffsettableClock.Stopped();
@@ -1241,24 +1255,35 @@
     }
 
     @Test
-    public void testPowerStateStopsOnDpcStop() {
-        // Set up
+    public void testRampRateForHdrContent_HdrClamperOff() {
+        float hdrBrightness = 0.8f;
+        float clampedBrightness = 0.6f;
+        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);
+        advanceTime(1); // Run updatePowerState
 
-        // Stop dpc
-        mHolder.dpc.stop();
-        advanceTime(1);
-
-        // Ensure dps has stopped
-        verify(mHolder.displayPowerState, times(1)).stop();
+        verify(mHolder.animator, atLeastOnce()).animateTo(eq(hdrBrightness), anyFloat(),
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
     }
 
     @Test
-    public void testRampRateForHdrContent() {
+    public void testRampRateForHdrContent_HdrClamperOn() {
         float clampedBrightness = 0.6f;
-        float transitionRate = 35.5f;
+        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);
@@ -1277,6 +1302,113 @@
                 eq(transitionRate), eq(true));
     }
 
+    @Test
+    @RequiresFlagsDisabled(Flags.FLAG_ENABLE_ADAPTIVE_TONE_IMPROVEMENTS_1)
+    public void testRampMaxTimeInteractiveThenIdle() {
+        // Send a display power request
+        DisplayPowerRequest dpr = new DisplayPowerRequest();
+        dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
+        dpr.useProximitySensor = true;
+        mHolder.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */);
+
+        // Run updatePowerState
+        advanceTime(1);
+
+        setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class),
+                mHolder.config, /* isEnabled= */ true);
+        verify(mHolder.animator).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX,
+                BRIGHTNESS_RAMP_DECREASE_MAX);
+
+        // switch to idle mode
+        mHolder.dpc.setAutomaticScreenBrightnessMode(/* idle= */ true);
+        advanceTime(1);
+
+        // A second time, when switching to idle mode.
+        verify(mHolder.animator, times(2)).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX,
+                BRIGHTNESS_RAMP_DECREASE_MAX);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_ADAPTIVE_TONE_IMPROVEMENTS_1)
+    public void testRampMaxTimeInteractiveThenIdle_DifferentValues() {
+        DisplayManagerFlags flags = mock(DisplayManagerFlags.class);
+        when(flags.isAdaptiveTone1Enabled()).thenReturn(true);
+        mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID, /* isEnabled= */ true, flags);
+
+        // Send a display power request
+        DisplayPowerRequest dpr = new DisplayPowerRequest();
+        dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
+        dpr.useProximitySensor = true;
+        mHolder.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */);
+
+        // Run updatePowerState
+        advanceTime(1);
+
+        setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class),
+                mHolder.config, /* isEnabled= */ true);
+        verify(mHolder.animator).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX,
+                BRIGHTNESS_RAMP_DECREASE_MAX);
+
+        // switch to idle mode
+        mHolder.dpc.setAutomaticScreenBrightnessMode(/* idle= */ true);
+        advanceTime(1);
+
+        // A second time, when switching to idle mode.
+        verify(mHolder.animator).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX_IDLE,
+                BRIGHTNESS_RAMP_DECREASE_MAX_IDLE);
+    }
+
+    @Test
+    @RequiresFlagsDisabled(Flags.FLAG_ENABLE_ADAPTIVE_TONE_IMPROVEMENTS_1)
+    public void testRampMaxTimeIdle() {
+        // Send a display power request
+        DisplayPowerRequest dpr = new DisplayPowerRequest();
+        dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
+        dpr.useProximitySensor = true;
+        mHolder.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */);
+        // Run updatePowerState
+        advanceTime(1);
+        // Once on setup
+        verify(mHolder.animator).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX,
+                BRIGHTNESS_RAMP_DECREASE_MAX);
+
+        setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class),
+                mHolder.config, /* isEnabled= */ true);
+
+        // switch to idle mode
+        mHolder.dpc.setAutomaticScreenBrightnessMode(true);
+
+        // A second time when switching to idle mode.
+        verify(mHolder.animator, times(2)).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX,
+                BRIGHTNESS_RAMP_DECREASE_MAX);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_ADAPTIVE_TONE_IMPROVEMENTS_1)
+    public void testRampMaxTimeIdle_DifferentValues() {
+        DisplayManagerFlags flags = mock(DisplayManagerFlags.class);
+        when(flags.isAdaptiveTone1Enabled()).thenReturn(true);
+        mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID, /* isEnabled= */ true, flags);
+
+        // Send a display power request
+        DisplayPowerRequest dpr = new DisplayPowerRequest();
+        dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
+        dpr.useProximitySensor = true;
+        mHolder.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */);
+
+        // Run updatePowerState
+        advanceTime(1);
+
+        setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class),
+                mHolder.config, /* isEnabled= */ true);
+
+        // switch to idle mode
+        mHolder.dpc.setAutomaticScreenBrightnessMode(true);
+
+        verify(mHolder.animator).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX_IDLE,
+                BRIGHTNESS_RAMP_DECREASE_MAX_IDLE);
+    }
+
     /**
      * Creates a mock and registers it to {@link LocalServices}.
      */
@@ -1340,6 +1472,7 @@
                 });
         when(displayDeviceConfigMock.getScreenOffBrightnessSensorValueToLux())
                 .thenReturn(new int[0]);
+
         when(displayDeviceConfigMock.getBrightnessRampFastDecrease())
                 .thenReturn(BRIGHTNESS_RAMP_RATE_FAST_DECREASE);
         when(displayDeviceConfigMock.getBrightnessRampFastIncrease())
@@ -1352,6 +1485,15 @@
                 .thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE);
         when(displayDeviceConfigMock.getBrightnessRampSlowDecreaseIdle())
                 .thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE);
+
+        when(displayDeviceConfigMock.getBrightnessRampIncreaseMaxMillis())
+                .thenReturn(BRIGHTNESS_RAMP_INCREASE_MAX);
+        when(displayDeviceConfigMock.getBrightnessRampDecreaseMaxMillis())
+                .thenReturn(BRIGHTNESS_RAMP_DECREASE_MAX);
+        when(displayDeviceConfigMock.getBrightnessRampIncreaseMaxIdleMillis())
+                .thenReturn(BRIGHTNESS_RAMP_INCREASE_MAX_IDLE);
+        when(displayDeviceConfigMock.getBrightnessRampDecreaseMaxIdleMillis())
+                .thenReturn(BRIGHTNESS_RAMP_DECREASE_MAX_IDLE);
     }
 
     private DisplayPowerControllerHolder createDisplayPowerController(int displayId,
@@ -1361,6 +1503,12 @@
 
     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 +1521,6 @@
                 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);
 
@@ -1393,13 +1540,14 @@
         final DisplayPowerController2 dpc = new DisplayPowerController2(
                 mContext, injector, mDisplayPowerCallbacksMock, mHandler,
                 mSensorManagerMock, mDisplayBlankerMock, display,
-                mBrightnessTrackerMock, brightnessSetting, () -> {},
+                mBrightnessTrackerMock, brightnessSetting, () -> {
+        },
                 hbmMetadata, /* bootCompleted= */ false, flags);
 
         return new DisplayPowerControllerHolder(dpc, display, displayPowerState, brightnessSetting,
                 animator, automaticBrightnessController, wakelockController,
                 screenOffBrightnessSensorController, hbmController, hdrClamper, hbmMetadata,
-                brightnessMappingStrategy, injector);
+                brightnessMappingStrategy, injector, config);
     }
 
     /**
@@ -1421,6 +1569,7 @@
         public final HighBrightnessModeMetadata hbmMetadata;
         public final BrightnessMappingStrategy brightnessMappingStrategy;
         public final DisplayPowerController2.Injector injector;
+        public final DisplayDeviceConfig config;
 
         DisplayPowerControllerHolder(DisplayPowerController2 dpc, LogicalDisplay display,
                 DisplayPowerState displayPowerState, BrightnessSetting brightnessSetting,
@@ -1432,7 +1581,8 @@
                 HdrClamper hdrClamper,
                 HighBrightnessModeMetadata hbmMetadata,
                 BrightnessMappingStrategy brightnessMappingStrategy,
-                DisplayPowerController2.Injector injector) {
+                DisplayPowerController2.Injector injector,
+                DisplayDeviceConfig config) {
             this.dpc = dpc;
             this.display = display;
             this.displayPowerState = displayPowerState;
@@ -1446,6 +1596,7 @@
             this.hbmMetadata = hbmMetadata;
             this.brightnessMappingStrategy = brightnessMappingStrategy;
             this.injector = injector;
+            this.config = config;
         }
     }
 
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 c53e763..0572117 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -53,6 +53,10 @@
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.test.TestLooper;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.provider.Settings;
 import android.testing.TestableContext;
 import android.util.FloatProperty;
@@ -71,6 +75,7 @@
 import com.android.server.display.brightness.BrightnessEvent;
 import com.android.server.display.color.ColorDisplayService;
 import com.android.server.display.feature.DisplayManagerFlags;
+import com.android.server.display.feature.flags.Flags;
 import com.android.server.display.layout.Layout;
 import com.android.server.display.whitebalance.DisplayWhiteBalanceController;
 import com.android.server.policy.WindowManagerPolicy;
@@ -107,6 +112,11 @@
     private static final float BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE = 0.5f;
     private static final float BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE = 0.6f;
 
+    private static final long BRIGHTNESS_RAMP_INCREASE_MAX = 1000;
+    private static final long BRIGHTNESS_RAMP_DECREASE_MAX = 2000;
+    private static final long BRIGHTNESS_RAMP_INCREASE_MAX_IDLE = 3000;
+    private static final long BRIGHTNESS_RAMP_DECREASE_MAX_IDLE = 4000;
+
     private OffsettableClock mClock;
     private TestLooper mTestLooper;
     private Handler mHandler;
@@ -129,6 +139,9 @@
     private ColorDisplayService.ColorDisplayServiceInternal mCdsiMock;
     @Mock
     private DisplayWhiteBalanceController mDisplayWhiteBalanceControllerMock;
+    @Mock
+    private DisplayManagerFlags mDisplayManagerFlagsMock;
+
     @Captor
     private ArgumentCaptor<SensorEventListener> mSensorEventListenerCaptor;
 
@@ -147,6 +160,9 @@
     @Rule
     public LocalServiceKeeperRule mLocalServiceKeeperRule = new LocalServiceKeeperRule();
 
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+
     @Before
     public void setUp() throws Exception {
         mClock = new OffsettableClock.Stopped();
@@ -1175,21 +1191,6 @@
     }
 
     @Test
-    public void testPowerStateStopsOnDpcStop() {
-        // Set up
-        DisplayPowerRequest dpr = new DisplayPowerRequest();
-        mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
-        advanceTime(1);
-
-        // Stop dpc
-        mHolder.dpc.stop();
-        advanceTime(1);
-
-        // Ensure dps has stopped
-        verify(mHolder.displayPowerState, times(1)).stop();
-    }
-
-    @Test
     public void testDisplayBrightnessHdr_SkipAnimationOnHdrAppearance() {
         Settings.System.putInt(mContext.getContentResolver(),
                 Settings.System.SCREEN_BRIGHTNESS_MODE,
@@ -1260,6 +1261,110 @@
                 eq(BRIGHTNESS_RAMP_RATE_MINIMUM), eq(false));
     }
 
+    @Test
+    @RequiresFlagsDisabled(Flags.FLAG_ENABLE_ADAPTIVE_TONE_IMPROVEMENTS_1)
+    public void testRampMaxTimeInteractiveThenIdle() {
+        // Send a display power request
+        DisplayPowerRequest dpr = new DisplayPowerRequest();
+        dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
+        dpr.useProximitySensor = true;
+        mHolder.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */);
+
+        // Run updatePowerState
+        advanceTime(1);
+
+        setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class),
+                mHolder.config, /* isEnabled= */ true);
+
+        verify(mHolder.animator).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX,
+                BRIGHTNESS_RAMP_DECREASE_MAX);
+
+        // switch to idle
+        mHolder.dpc.setAutomaticScreenBrightnessMode(/* idle= */ true);
+        advanceTime(1);
+
+        verify(mHolder.animator, times(2)).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX,
+                BRIGHTNESS_RAMP_DECREASE_MAX);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_ADAPTIVE_TONE_IMPROVEMENTS_1)
+    public void testRampMaxTimeInteractiveThenIdle_DifferentValues() {
+        when(mDisplayManagerFlagsMock.isAdaptiveTone1Enabled()).thenReturn(true);
+        // Send a display power request
+        DisplayPowerRequest dpr = new DisplayPowerRequest();
+        dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
+        dpr.useProximitySensor = true;
+        mHolder.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */);
+
+        // Run updatePowerState
+        advanceTime(1);
+
+        setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class),
+                mHolder.config, /* isEnabled= */ true);
+
+        verify(mHolder.animator).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX,
+                BRIGHTNESS_RAMP_DECREASE_MAX);
+
+        // switch to idle
+        mHolder.dpc.setAutomaticScreenBrightnessMode(/* idle= */ true);
+        advanceTime(1);
+
+        verify(mHolder.animator).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX_IDLE,
+                BRIGHTNESS_RAMP_DECREASE_MAX_IDLE);
+    }
+
+    @Test
+    @RequiresFlagsDisabled(Flags.FLAG_ENABLE_ADAPTIVE_TONE_IMPROVEMENTS_1)
+    public void testRampMaxTimeIdle() {
+        // Send a display power request
+        DisplayPowerRequest dpr = new DisplayPowerRequest();
+        dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
+        dpr.useProximitySensor = true;
+        mHolder.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */);
+
+        // Run updatePowerState
+        advanceTime(1);
+
+        // once on setup
+        verify(mHolder.animator).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX,
+                BRIGHTNESS_RAMP_DECREASE_MAX);
+
+        setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class),
+                mHolder.config, /* isEnabled= */ true);
+
+        // switch to idle mode
+        mHolder.dpc.setAutomaticScreenBrightnessMode(true);
+
+        // second time when switching to idle screen brightness mode
+        verify(mHolder.animator, times(2)).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX,
+                BRIGHTNESS_RAMP_DECREASE_MAX);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_ADAPTIVE_TONE_IMPROVEMENTS_1)
+    public void testRampMaxTimeIdle_DifferentValues() {
+        when(mDisplayManagerFlagsMock.isAdaptiveTone1Enabled()).thenReturn(true);
+
+        // Send a display power request
+        DisplayPowerRequest dpr = new DisplayPowerRequest();
+        dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
+        dpr.useProximitySensor = true;
+        mHolder.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */);
+
+        // Run updatePowerState
+        advanceTime(1);
+
+        setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class),
+                mHolder.config, /* isEnabled= */ true);
+
+        // switch to idle mode
+        mHolder.dpc.setAutomaticScreenBrightnessMode(true);
+
+        verify(mHolder.animator).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX_IDLE,
+                BRIGHTNESS_RAMP_DECREASE_MAX_IDLE);
+    }
+
     private void advanceTime(long timeMs) {
         mClock.fastForward(timeMs);
         mTestLooper.dispatchAll();
@@ -1315,6 +1420,7 @@
                 });
         when(displayDeviceConfigMock.getScreenOffBrightnessSensorValueToLux())
                 .thenReturn(new int[0]);
+
         when(displayDeviceConfigMock.getBrightnessRampFastDecrease())
                 .thenReturn(BRIGHTNESS_RAMP_RATE_FAST_DECREASE);
         when(displayDeviceConfigMock.getBrightnessRampFastIncrease())
@@ -1327,6 +1433,15 @@
                 .thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE);
         when(displayDeviceConfigMock.getBrightnessRampSlowIncreaseIdle())
                 .thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE);
+
+        when(displayDeviceConfigMock.getBrightnessRampIncreaseMaxMillis())
+                .thenReturn(BRIGHTNESS_RAMP_INCREASE_MAX);
+        when(displayDeviceConfigMock.getBrightnessRampDecreaseMaxMillis())
+                .thenReturn(BRIGHTNESS_RAMP_DECREASE_MAX);
+        when(displayDeviceConfigMock.getBrightnessRampIncreaseMaxIdleMillis())
+                .thenReturn(BRIGHTNESS_RAMP_INCREASE_MAX_IDLE);
+        when(displayDeviceConfigMock.getBrightnessRampDecreaseMaxIdleMillis())
+                .thenReturn(BRIGHTNESS_RAMP_DECREASE_MAX_IDLE);
     }
 
     private DisplayPowerControllerHolder createDisplayPowerController(int displayId,
@@ -1358,7 +1473,6 @@
         final HighBrightnessModeMetadata hbmMetadata = mock(HighBrightnessModeMetadata.class);
         final BrightnessSetting brightnessSetting = mock(BrightnessSetting.class);
         final DisplayDeviceConfig config = mock(DisplayDeviceConfig.class);
-        final DisplayManagerFlags flags = mock(DisplayManagerFlags.class);
 
         setUpDisplay(displayId, uniqueId, display, device, config, isEnabled);
 
@@ -1366,11 +1480,11 @@
                 mContext, injector, mDisplayPowerCallbacksMock, mHandler,
                 mSensorManagerMock, mDisplayBlankerMock, display,
                 mBrightnessTrackerMock, brightnessSetting, () -> {},
-                hbmMetadata, /* bootCompleted= */ false, flags);
+                hbmMetadata, /* bootCompleted= */ false, mDisplayManagerFlagsMock);
 
         return new DisplayPowerControllerHolder(dpc, display, displayPowerState, brightnessSetting,
                 animator, automaticBrightnessController, screenOffBrightnessSensorController,
-                hbmController, hbmMetadata, brightnessMappingStrategy, injector);
+                hbmController, hbmMetadata, brightnessMappingStrategy, injector, config);
     }
 
     /**
@@ -1389,6 +1503,7 @@
         public final HighBrightnessModeMetadata hbmMetadata;
         public final BrightnessMappingStrategy brightnessMappingStrategy;
         public final DisplayPowerController.Injector injector;
+        public final DisplayDeviceConfig config;
 
         DisplayPowerControllerHolder(DisplayPowerController dpc, LogicalDisplay display,
                 DisplayPowerState displayPowerState, BrightnessSetting brightnessSetting,
@@ -1398,7 +1513,8 @@
                 HighBrightnessModeController hbmController,
                 HighBrightnessModeMetadata hbmMetadata,
                 BrightnessMappingStrategy brightnessMappingStrategy,
-                DisplayPowerController.Injector injector) {
+                DisplayPowerController.Injector injector,
+                DisplayDeviceConfig config) {
             this.dpc = dpc;
             this.display = display;
             this.displayPowerState = displayPowerState;
@@ -1410,6 +1526,7 @@
             this.hbmMetadata = hbmMetadata;
             this.brightnessMappingStrategy = brightnessMappingStrategy;
             this.injector = injector;
+            this.config = config;
         }
     }
 
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerStateTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerStateTest.java
deleted file mode 100644
index 167a412..0000000
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerStateTest.java
+++ /dev/null
@@ -1,64 +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.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.display;
-
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
-
-import static org.mockito.Mockito.times;
-
-import android.os.Handler;
-import android.os.test.TestLooper;
-import android.view.Display;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-
-
-@SmallTest
-public class DisplayPowerStateTest {
-    private static final int DISPLAY_ID = 123;
-
-    private DisplayPowerState mDisplayPowerState;
-    private TestLooper mTestLooper;
-    @Mock
-    private DisplayBlanker mDisplayBlankerMock;
-    @Mock
-    private ColorFade mColorFadeMock;
-
-    @Rule
-    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
-
-    @Before
-    public void setUp() {
-        mTestLooper = new TestLooper();
-        mDisplayPowerState = new DisplayPowerState(
-                mDisplayBlankerMock, mColorFadeMock, DISPLAY_ID, Display.STATE_ON,
-                new Handler(mTestLooper.getLooper()));
-    }
-
-    @Test
-    public void testColorFadeStopsOnDpsStop() {
-        mDisplayPowerState.stop();
-        verify(mColorFadeMock, times(1)).stop();
-    }
-}
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 c0128ae..1c43418 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.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 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 @@
 
     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 @@
         // 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 @@
         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);
     }
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 0ebe46a..37d966d 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 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.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 
+import java.util.Map;
+
 @SmallTest
 public class HdrClamperTest {
 
@@ -108,10 +111,13 @@
     }
 
     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);
     }
 }
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 8e17b3a..dcd5317 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,33 @@
 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;
+import java.io.FileWriter;
 
 public class BackupManagerMonitorDumpsysUtilsTest {
-    private File mTempFile;
+    private long mRetentionPeriod;
+    private File mTempBMMEventsFile;
+    private File mTempSetUpDateFile;
+
+    private long mSizeLimit;
     private TestBackupManagerMonitorDumpsysUtils mBackupManagerMonitorDumpsysUtils;
     @Rule
     public TemporaryFolder tmp = new TemporaryFolder();
 
     @Before
     public void setUp() throws Exception {
-        mTempFile = tmp.newFile("testbmmevents.txt");
+        mRetentionPeriod = 30 * 60 * 1000;
+        mSizeLimit = 25 * 1024 * 1000;
+        mTempBMMEventsFile = tmp.newFile("testbmmevents.txt");
+        mTempSetUpDateFile = tmp.newFile("testSetUpDate.txt");
         mBackupManagerMonitorDumpsysUtils = new TestBackupManagerMonitorDumpsysUtils();
     }
 
@@ -46,7 +53,7 @@
             throws Exception {
         mBackupManagerMonitorDumpsysUtils.parseBackupManagerMonitorRestoreEventForDumpsys(null);
 
-        assertTrue(mTempFile.length() == 0);
+        assertTrue(mTempBMMEventsFile.length() == 0);
 
     }
 
@@ -57,7 +64,7 @@
         event.putInt(BackupManagerMonitor.EXTRA_LOG_EVENT_CATEGORY, 1);
         mBackupManagerMonitorDumpsysUtils.parseBackupManagerMonitorRestoreEventForDumpsys(event);
 
-        assertTrue(mTempFile.length() == 0);
+        assertTrue(mTempBMMEventsFile.length() == 0);
     }
 
     @Test
@@ -67,18 +74,236 @@
         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 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 {
+        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;
+        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() {
-            return mTempFile;
+            return mTempBMMEventsFile;
         }
+
+        @Override
+        File getSetUpDateFile() {
+            return mTempSetUpDateFile;
+        }
+
+        @Override
+        long getRetentionPeriodInMillisec() {
+            return testRetentionPeriod;
+        }
+
+        @Override
+        long getBMMEventsFileSizeLimit(){
+            return testSizeLimit;
+        }
+
+
     }
 }
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 3af2932..604a68d 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 @@
     @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 @@
 
     @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 @@
         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);
+    }
 }
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
index 552b59c..a250ac7 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
@@ -33,7 +33,6 @@
 import static com.android.server.job.JobSchedulerService.WORKING_INDEX;
 import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
 import static com.android.server.job.JobSchedulerService.sSystemClock;
-
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
@@ -75,11 +74,11 @@
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.SystemClock;
-import android.platform.test.annotations.LargeTest;
 import android.provider.DeviceConfig;
 import android.util.ArraySet;
 import android.util.SparseBooleanArray;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.util.ArrayUtils;
@@ -2597,7 +2596,9 @@
     @Test
     public void testIsWithinEJQuotaLocked_TempAllowlisting_Restricted() {
         setDischarging();
-        JobStatus js = createExpeditedJobStatus("testIsWithinEJQuotaLocked_TempAllowlisting_Restricted", 1);
+        JobStatus js =
+                createExpeditedJobStatus(
+                        "testIsWithinEJQuotaLocked_TempAllowlisting_Restricted", 1);
         setStandbyBucket(RESTRICTED_INDEX, js);
         setDeviceConfigLong(QcConstants.KEY_EJ_LIMIT_FREQUENT_MS, 10 * MINUTE_IN_MILLIS);
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
@@ -6088,7 +6089,8 @@
         Handler handler = mQuotaController.getHandler();
         spyOn(handler);
 
-        JobStatus job = createExpeditedJobStatus("testEJTimerTracking_TempAllowlisting_Restricted", 1);
+        JobStatus job =
+                createExpeditedJobStatus("testEJTimerTracking_TempAllowlisting_Restricted", 1);
         setStandbyBucket(RESTRICTED_INDEX, job);
         synchronized (mQuotaController.mLock) {
             mQuotaController.maybeStartTrackingJobLocked(job, null);
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 b97fd4b..eb50556 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 @@
     }
 
     @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 @@
     }
 
     @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,
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java
index 4a06611f..1cd61e9 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java
@@ -253,7 +253,8 @@
         goFromStateClearTo(STATE_TOUCH_EXPLORING_1FINGER);
         moveEachPointers(mLastEvent, p(10, 10));
         send(mLastEvent);
-
+        // Wait 10 ms to make sure that hover enter and exit are not scheduled for the same moment.
+        mHandler.fastForward(10);
         send(upEvent());
         // Wait for sending hover exit event to transit to clear state.
         mHandler.fastForward(USER_INTENT_TIMEOUT);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationThumbnailTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationThumbnailTest.java
index 8faddf8..fcfe48e 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationThumbnailTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationThumbnailTest.java
@@ -17,7 +17,6 @@
 package com.android.server.accessibility.magnification;
 
 import static com.google.common.truth.Truth.assertThat;
-
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
@@ -27,13 +26,13 @@
 
 import android.graphics.Rect;
 import android.os.Handler;
-import android.platform.test.annotations.LargeTest;
 import android.testing.TestableContext;
 import android.view.WindowInsets;
 import android.view.WindowManager;
 import android.view.WindowMetrics;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.LargeTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 
 import org.junit.Before;
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java
index c40ad28..1c48b8a 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java
@@ -88,7 +88,8 @@
                         /* secureWindowCallback= */ null,
                         /* intentListenerCallback= */ null,
                         /* displayCategories= */ new ArraySet<>(),
-                        /* showTasksInHostDeviceRecents= */ true);
+                        /* showTasksInHostDeviceRecents= */ true,
+                        /* customHomeComponent= */ null);
     }
 
 
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 8f88ba6..7d73563 100644
--- a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
@@ -30,7 +30,6 @@
 import static org.testng.Assert.assertNull;
 import static org.testng.Assert.assertThrows;
 
-import android.app.ActivityManager;
 import android.hardware.devicestate.DeviceStateInfo;
 import android.hardware.devicestate.DeviceStateRequest;
 import android.hardware.devicestate.IDeviceStateManagerCallback;
@@ -582,10 +581,10 @@
                 // When the app is foreground, the state should not change
                 () -> {
                     int pid = Binder.getCallingPid();
-                    when(mWindowProcessController.getPid()).thenReturn(pid);
+                    int uid = Binder.getCallingUid();
                     try {
-                        mService.mOverrideRequestTaskStackListener.onTaskMovedToFront(
-                                new ActivityManager.RunningTaskInfo());
+                        mService.mProcessObserver.onForegroundActivitiesChanged(pid, uid,
+                                true /* foregroundActivities */);
                     } catch (RemoteException e) {
                         throw new RuntimeException(e);
                     }
@@ -594,8 +593,11 @@
                 () -> {
                     when(mWindowProcessController.getPid()).thenReturn(FAKE_PROCESS_ID);
                     try {
-                        mService.mOverrideRequestTaskStackListener.onTaskMovedToFront(
-                                new ActivityManager.RunningTaskInfo());
+                        int pid = Binder.getCallingPid();
+                        int uid = Binder.getCallingUid();
+                        mService.mProcessObserver.onForegroundActivitiesChanged(pid, uid,
+                                false /* foregroundActivities */);
+
                     } catch (RemoteException e) {
                         throw new RuntimeException(e);
                     }
diff --git a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateNotificationControllerTest.java b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateNotificationControllerTest.java
index 728606f..bb0de03 100644
--- a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateNotificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateNotificationControllerTest.java
@@ -33,6 +33,8 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
 import android.platform.test.annotations.Presubmit;
 import android.util.SparseArray;
 
@@ -89,11 +91,12 @@
     @Before
     public void setup() throws Exception {
         Context context = InstrumentationRegistry.getInstrumentation().getContext();
-        Handler handler = mock(Handler.class);
         PackageManager packageManager = mock(PackageManager.class);
         Runnable cancelStateRunnable = mock(Runnable.class);
         ApplicationInfo applicationInfo = mock(ApplicationInfo.class);
 
+        Handler handler = new DeviceStateNotificationControllerTestHandler(Looper.getMainLooper());
+
         final SparseArray<DeviceStateNotificationController.NotificationInfo> notificationInfos =
                 new SparseArray<>();
         notificationInfos.put(STATE_WITH_ACTIVE_NOTIFICATION,
@@ -259,4 +262,16 @@
         assertEquals(Locale.ITALY, mNotificationInfoProvider.getCachedLocale());
         clearInvocations(mNotificationInfoProvider);
     }
+
+    private static class DeviceStateNotificationControllerTestHandler extends Handler {
+        DeviceStateNotificationControllerTestHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
+            msg.getCallback().run();
+            return true;
+        }
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
index 0d172fdb..708ee35 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
@@ -21,8 +21,15 @@
 
 import static com.android.server.SystemService.PHASE_BOOT_COMPLETED;
 import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
+import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM;
+import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1;
+import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_2;
+import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_3;
 import static com.android.server.hdmi.HdmiControlService.DEVICE_CLEANUP_TIMEOUT;
 import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
+import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_HOTPLUG;
+import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_SCREEN_ON;
+import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_SOUNDBAR_MODE;
 import static com.android.server.hdmi.HdmiControlService.WAKE_UP_SCREEN_ON;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -51,6 +58,7 @@
 import android.hardware.hdmi.IHdmiCecVolumeControlFeatureListener;
 import android.hardware.hdmi.IHdmiControlStatusChangeListener;
 import android.hardware.hdmi.IHdmiVendorCommandListener;
+import android.hardware.tv.cec.V1_0.SendMessageResult;
 import android.os.Binder;
 import android.os.Looper;
 import android.os.RemoteException;
@@ -71,6 +79,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Optional;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Tests for {@link HdmiControlService} class.
@@ -137,7 +146,7 @@
 
         mLocalDevices.add(mAudioSystemDeviceSpy);
         mLocalDevices.add(mPlaybackDeviceSpy);
-        mHdmiPortInfo = new HdmiPortInfo[4];
+        mHdmiPortInfo = new HdmiPortInfo[5];
         mHdmiPortInfo[0] =
                 new HdmiPortInfo.Builder(1, HdmiPortInfo.PORT_INPUT, 0x2100)
                         .setCecSupported(true)
@@ -166,6 +175,13 @@
                         .setArcSupported(false)
                         .setEarcSupported(false)
                         .build();
+        mHdmiPortInfo[4] =
+                new HdmiPortInfo.Builder(4, HdmiPortInfo.PORT_OUTPUT, 0x3000)
+                        .setCecSupported(true)
+                        .setMhlSupported(false)
+                        .setArcSupported(false)
+                        .setEarcSupported(false)
+                        .build();
         mNativeWrapper.setPortInfo(mHdmiPortInfo);
         mHdmiControlServiceSpy.initService();
         mWakeLockSpy = spy(new FakePowerManagerWrapper.FakeWakeLockWrapper());
@@ -1396,6 +1412,207 @@
     }
 
     @Test
+    public void triggerMultipleAddressAllocations_uniqueLocalDevicePerDeviceType() {
+        long allocationDelay = TimeUnit.SECONDS.toMillis(60);
+        mHdmiCecController.setLogicalAddressAllocationDelay(allocationDelay);
+        mTestLooper.dispatchAll();
+        Mockito.clearInvocations(mHdmiControlServiceSpy);
+
+        // Wake up process that will trigger the address allocation to start.
+        mHdmiControlServiceSpy.onWakeUp(HdmiControlService.WAKE_UP_SCREEN_ON);
+        verify(mHdmiControlServiceSpy, times(1))
+                .allocateLogicalAddress(any(), eq(INITIATED_BY_SCREEN_ON));
+        Mockito.clearInvocations(mHdmiControlServiceSpy);
+        mTestLooper.dispatchAll();
+
+        mTestLooper.moveTimeForward(allocationDelay / 2);
+        mTestLooper.dispatchAll();
+        // Hotplug In will trigger the address allocation to start.
+        mHdmiControlServiceSpy.onHotplug(4, true);
+        verify(mHdmiControlServiceSpy, times(1))
+                .allocateLogicalAddress(any(), eq(INITIATED_BY_HOTPLUG));
+        Mockito.clearInvocations(mHdmiControlServiceSpy);
+
+        mTestLooper.moveTimeForward(allocationDelay / 2);
+        mTestLooper.dispatchAll();
+        // The first allocation finished. The second allocation is still in progress.
+        HdmiCecLocalDevicePlayback firstAllocatedPlayback = mHdmiControlServiceSpy.playback();
+        verify(mHdmiControlServiceSpy, times(1))
+                .notifyAddressAllocated(any(), eq(INITIATED_BY_SCREEN_ON));
+        Mockito.clearInvocations(mHdmiControlServiceSpy);
+
+        mTestLooper.moveTimeForward(allocationDelay / 2);
+        mTestLooper.dispatchAll();
+        // The second allocation finished.
+        HdmiCecLocalDevicePlayback secondAllocatedPlayback = mHdmiControlServiceSpy.playback();
+        verify(mHdmiControlServiceSpy, times(1))
+                .notifyAddressAllocated(any(), eq(INITIATED_BY_HOTPLUG));
+        // Local devices have the same identity.
+        assertTrue(firstAllocatedPlayback == secondAllocatedPlayback);
+    }
+
+    @Test
+    public void triggerMultipleAddressAllocations_keepLastAllocatedAddress() {
+        // First logical address for playback is free.
+        mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_1, SendMessageResult.NACK);
+        mTestLooper.dispatchAll();
+
+        long allocationDelay = TimeUnit.SECONDS.toMillis(60);
+        mHdmiCecController.setLogicalAddressAllocationDelay(allocationDelay);
+        mTestLooper.dispatchAll();
+        Mockito.clearInvocations(mHdmiControlServiceSpy);
+
+        // Wake up process that will trigger the address allocation to start.
+        mHdmiControlServiceSpy.onWakeUp(HdmiControlService.WAKE_UP_SCREEN_ON);
+        verify(mHdmiControlServiceSpy, times(1))
+                .allocateLogicalAddress(any(), eq(INITIATED_BY_SCREEN_ON));
+        Mockito.clearInvocations(mHdmiControlServiceSpy);
+        mTestLooper.dispatchAll();
+
+        mTestLooper.moveTimeForward(allocationDelay / 2);
+        mTestLooper.dispatchAll();
+
+        // First logical address for playback is busy.
+        mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_1, SendMessageResult.SUCCESS);
+        mTestLooper.dispatchAll();
+
+        mHdmiControlServiceSpy.onWakeUp(HdmiControlService.WAKE_UP_SCREEN_ON);
+        verify(mHdmiControlServiceSpy, times(1))
+                .allocateLogicalAddress(any(), eq(INITIATED_BY_SCREEN_ON));
+        Mockito.clearInvocations(mHdmiControlServiceSpy);
+        mTestLooper.dispatchAll();
+
+        mTestLooper.moveTimeForward(allocationDelay / 2);
+        mTestLooper.dispatchAll();
+        // The first allocation finished. The second allocation is still in progress.
+        verify(mHdmiControlServiceSpy, times(1))
+                .notifyAddressAllocated(any(), eq(INITIATED_BY_SCREEN_ON));
+        Mockito.clearInvocations(mHdmiControlServiceSpy);
+
+        mTestLooper.moveTimeForward(allocationDelay / 2);
+        mTestLooper.dispatchAll();
+        // The second allocation finished. Second logical address for playback is used.
+        HdmiCecLocalDevicePlayback allocatedPlayback = mHdmiControlServiceSpy.playback();
+        verify(mHdmiControlServiceSpy, times(1))
+                .notifyAddressAllocated(any(), eq(INITIATED_BY_SCREEN_ON));
+        assertThat(allocatedPlayback.getDeviceInfo().getLogicalAddress())
+                .isEqualTo(ADDR_PLAYBACK_2);
+    }
+
+    @Test
+    public void triggerMultipleAddressAllocations_toggleSoundbarMode_addThenRemoveAudioSystem() {
+        mHdmiControlServiceSpy.setPowerStatus(HdmiControlManager.POWER_STATUS_ON);
+        long allocationDelay = TimeUnit.SECONDS.toMillis(60);
+        mHdmiCecController.setLogicalAddressAllocationDelay(allocationDelay);
+        mTestLooper.dispatchAll();
+        Mockito.clearInvocations(mHdmiControlServiceSpy);
+
+        // Enabling Dynamic soundbar mode will trigger address allocation.
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
+                HdmiControlManager.CEC_SETTING_NAME_SOUNDBAR_MODE,
+                HdmiControlManager.SOUNDBAR_MODE_ENABLED);
+        mTestLooper.dispatchAll();
+        verify(mHdmiControlServiceSpy, times(1))
+                .allocateLogicalAddress(any(), eq(INITIATED_BY_SOUNDBAR_MODE));
+        Mockito.clearInvocations(mHdmiControlServiceSpy);
+
+        mTestLooper.moveTimeForward(allocationDelay / 2);
+        mTestLooper.dispatchAll();
+        // Disabling Dynamic soundbar mode will trigger another address allocation.
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
+                HdmiControlManager.CEC_SETTING_NAME_SOUNDBAR_MODE,
+                HdmiControlManager.SOUNDBAR_MODE_DISABLED);
+        mTestLooper.dispatchAll();
+        verify(mHdmiControlServiceSpy, times(1))
+                .allocateLogicalAddress(any(), eq(INITIATED_BY_SOUNDBAR_MODE));
+        Mockito.clearInvocations(mHdmiControlServiceSpy);
+
+        mTestLooper.moveTimeForward(allocationDelay / 2);
+        mTestLooper.dispatchAll();
+        // The first allocation finished. The second allocation is still in progress.
+        // The audio system is present in the network.
+        verify(mHdmiControlServiceSpy, times(1))
+                .notifyAddressAllocated(any(), eq(INITIATED_BY_SOUNDBAR_MODE));
+        assertThat(mHdmiControlServiceSpy.audioSystem()).isNotNull();
+        Mockito.clearInvocations(mHdmiControlServiceSpy);
+
+        mTestLooper.moveTimeForward(allocationDelay / 2);
+        mTestLooper.dispatchAll();
+        // The second allocation finished. The audio system is not present in the network.
+        verify(mHdmiControlServiceSpy, times(1))
+                .notifyAddressAllocated(any(), eq(INITIATED_BY_SOUNDBAR_MODE));
+        assertThat(mHdmiControlServiceSpy.audioSystem()).isNull();
+    }
+
+    @Test
+    public void triggerMultipleAddressAllocations_toggleSoundbarMode_removeThenAddAudioSystem() {
+        mHdmiControlServiceSpy.setPowerStatus(HdmiControlManager.POWER_STATUS_ON);
+        // Enable the setting and check if the audio system local device is found in the network.
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
+                HdmiControlManager.CEC_SETTING_NAME_SOUNDBAR_MODE,
+                HdmiControlManager.SOUNDBAR_MODE_ENABLED);
+        mTestLooper.dispatchAll();
+        assertThat(mHdmiControlServiceSpy.audioSystem()).isNotNull();
+
+        long allocationDelay = TimeUnit.SECONDS.toMillis(60);
+        mHdmiCecController.setLogicalAddressAllocationDelay(allocationDelay);
+        mTestLooper.dispatchAll();
+        Mockito.clearInvocations(mHdmiControlServiceSpy);
+
+        // Disabling Dynamic soundbar mode will trigger address allocation.
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
+                HdmiControlManager.CEC_SETTING_NAME_SOUNDBAR_MODE,
+                HdmiControlManager.SOUNDBAR_MODE_DISABLED);
+        mTestLooper.dispatchAll();
+        verify(mHdmiControlServiceSpy, times(1))
+                .allocateLogicalAddress(any(), eq(INITIATED_BY_SOUNDBAR_MODE));
+        Mockito.clearInvocations(mHdmiControlServiceSpy);
+
+        mTestLooper.moveTimeForward(allocationDelay / 2);
+        mTestLooper.dispatchAll();
+        // Enabling Dynamic soundbar mode will trigger another address allocation.
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
+                HdmiControlManager.CEC_SETTING_NAME_SOUNDBAR_MODE,
+                HdmiControlManager.SOUNDBAR_MODE_ENABLED);
+        mTestLooper.dispatchAll();
+        verify(mHdmiControlServiceSpy, times(1))
+                .allocateLogicalAddress(any(), eq(INITIATED_BY_SOUNDBAR_MODE));
+        Mockito.clearInvocations(mHdmiControlServiceSpy);
+
+        mTestLooper.moveTimeForward(allocationDelay / 2);
+        mTestLooper.dispatchAll();
+        // The first allocation finished. The second allocation is still in progress.
+        // The audio system is not present in the network.
+        verify(mHdmiControlServiceSpy, times(1))
+                .notifyAddressAllocated(any(), eq(INITIATED_BY_SOUNDBAR_MODE));
+        assertThat(mHdmiControlServiceSpy.audioSystem()).isNull();
+        Mockito.clearInvocations(mHdmiControlServiceSpy);
+
+        mTestLooper.moveTimeForward(allocationDelay / 2);
+        mTestLooper.dispatchAll();
+        // The second allocation finished. The audio system is present in the network.
+        verify(mHdmiControlServiceSpy, times(1))
+                .notifyAddressAllocated(any(), eq(INITIATED_BY_SOUNDBAR_MODE));
+        assertThat(mHdmiControlServiceSpy.audioSystem()).isNotNull();
+    }
+
+    @Test
+    public void failedAddressAllocation_noLocalDevice() {
+        mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_1, SendMessageResult.SUCCESS);
+        mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_2, SendMessageResult.SUCCESS);
+        mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_3, SendMessageResult.SUCCESS);
+        mNativeWrapper.setPollAddressResponse(ADDR_AUDIO_SYSTEM, SendMessageResult.SUCCESS);
+        mTestLooper.dispatchAll();
+
+        mHdmiControlServiceSpy.clearCecLocalDevices();
+        mHdmiControlServiceSpy.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+        mTestLooper.dispatchAll();
+
+        assertThat(mHdmiControlServiceSpy.playback()).isNull();
+        assertThat(mHdmiControlServiceSpy.audioSystem()).isNull();
+    }
+
+    @Test
     public void earcIdle_blocksArcConnection() {
         mHdmiControlServiceSpy.clearEarcLocalDevice();
         HdmiEarcLocalDeviceTx localDeviceTx = new HdmiEarcLocalDeviceTx(mHdmiControlServiceSpy);
diff --git a/services/tests/servicestests/src/com/android/server/job/PendingJobQueueTest.java b/services/tests/servicestests/src/com/android/server/job/PendingJobQueueTest.java
index be13753..213e05e 100644
--- a/services/tests/servicestests/src/com/android/server/job/PendingJobQueueTest.java
+++ b/services/tests/servicestests/src/com/android/server/job/PendingJobQueueTest.java
@@ -18,7 +18,6 @@
 
 import static android.app.job.JobInfo.NETWORK_TYPE_ANY;
 import static android.app.job.JobInfo.NETWORK_TYPE_NONE;
-
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -28,13 +27,14 @@
 
 import android.app.job.JobInfo;
 import android.content.ComponentName;
-import android.platform.test.annotations.LargeTest;
 import android.util.ArraySet;
 import android.util.Log;
 import android.util.SparseArrayMap;
 import android.util.SparseBooleanArray;
 import android.util.SparseLongArray;
 
+import androidx.test.filters.LargeTest;
+
 import com.android.server.job.controllers.JobStatus;
 
 import org.junit.Test;
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 0000000..81867df
--- /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 4576e9b..9543a2d 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.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 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.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 @@
     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 @@
 
         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 @@
                     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 @@
                     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 @@
 
         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 @@
         // 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);
@@ -1653,6 +1669,23 @@
     }
 
     @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";
         Notification original = new Notification.Builder(mContext,
@@ -9015,6 +9048,24 @@
     }
 
     @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()
                 ? UserHandle.getUserId(UID_HEADLESS)
diff --git a/services/tests/wmtests/src/com/android/server/policy/ShortcutKeyTestBase.java b/services/tests/wmtests/src/com/android/server/policy/ShortcutKeyTestBase.java
index 8db09f9..61c4d06 100644
--- a/services/tests/wmtests/src/com/android/server/policy/ShortcutKeyTestBase.java
+++ b/services/tests/wmtests/src/com/android/server/policy/ShortcutKeyTestBase.java
@@ -46,7 +46,6 @@
 import static java.util.Collections.unmodifiableMap;
 
 import android.content.Context;
-import android.os.Looper;
 import android.os.SystemClock;
 import android.util.ArrayMap;
 import android.view.InputDevice;
@@ -99,10 +98,6 @@
      *      settings values.
      */
     protected final void setUpPhoneWindowManager(boolean supportSettingsUpdate) {
-        if (Looper.myLooper() == null) {
-            Looper.prepare();
-        }
-
         doReturn(mSettingsProviderRule.mockContentResolver(mContext))
                 .when(mContext).getContentResolver();
         mPhoneWindowManager = new TestPhoneWindowManager(mContext, supportSettingsUpdate);
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 ef28ffa..6e2c4bd 100644
--- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
+++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
@@ -70,7 +70,6 @@
 import android.hardware.input.InputManager;
 import android.media.AudioManagerInternal;
 import android.os.Handler;
-import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.PowerManager;
 import android.os.PowerManagerInternal;
@@ -78,6 +77,7 @@
 import android.os.UserHandle;
 import android.os.Vibrator;
 import android.os.VibratorInfo;
+import android.os.test.TestLooper;
 import android.service.dreams.DreamManagerInternal;
 import android.telecom.TelecomManager;
 import android.util.FeatureFlagUtils;
@@ -160,8 +160,8 @@
     @Mock private KeyguardServiceDelegate mKeyguardServiceDelegate;
 
     private StaticMockitoSession mMockitoSession;
-    private HandlerThread mHandlerThread;
     private Handler mHandler;
+    private TestLooper mTestLooper;
 
     private class TestInjector extends PhoneWindowManager.Injector {
         TestInjector(Context context, WindowManagerPolicy.WindowManagerFuncs funcs) {
@@ -184,12 +184,11 @@
 
     TestPhoneWindowManager(Context context, boolean supportSettingsUpdate) {
         MockitoAnnotations.initMocks(this);
-        mHandlerThread = new HandlerThread("fake window manager");
-        mHandlerThread.start();
-        mHandler = new Handler(mHandlerThread.getLooper());
+        mTestLooper = new TestLooper();
+        mHandler = new Handler(mTestLooper.getLooper());
         mContext = mockingDetails(context).isSpy() ? context : spy(context);
-        mHandler.runWithScissors(() -> setUp(supportSettingsUpdate),  0 /* timeout */);
-        waitForIdle();
+        mHandler.post(() -> setUp(supportSettingsUpdate));
+        mTestLooper.dispatchAll();
     }
 
     private void setUp(boolean supportSettingsUpdate) {
@@ -301,7 +300,6 @@
     }
 
     void tearDown() {
-        mHandlerThread.quitSafely();
         LocalServices.removeServiceForTest(InputMethodManagerInternal.class);
         Mockito.reset(mPhoneWindowManager);
         mMockitoSession.finishMocking();
@@ -328,7 +326,7 @@
     }
 
     void waitForIdle() {
-        mHandler.runWithScissors(() -> { }, 0 /* timeout */);
+        mTestLooper.dispatchAll();
     }
 
     /**
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 3d3531e..d2eb1cc 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.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.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 @@
     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 @@
         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();
@@ -184,24 +164,6 @@
     }
 
     @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;
         session.setVirtualDisplayId(mDisplaySession.getVirtualDisplayId());
@@ -703,13 +665,4 @@
                 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();
-            }
-        }
-    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java
index 30a8941..cf620fe 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java
@@ -275,5 +275,10 @@
         public boolean isEnteringPipAllowed(int uid) {
             return true;
         }
+
+        @Override
+        public ComponentName getCustomHomeComponent() {
+            return null;
+        }
     }
 }
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 7db32a9..f93c703 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.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 @@
 
             // 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 @@
             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 @@
                 mHandler.sendEmptyMessageDelayed(MSG_FLUSH_TO_DISK, FLUSH_INTERVAL);
             }
         }
+        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
     }
 
     /**
@@ -1944,17 +1954,23 @@
                 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 @@
                     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 7d2e1a4..b5d8096 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 @@
         }
     }
 
-    private static String eventToString(int eventType) {
+    static String eventToString(int eventType) {
         switch (eventType) {
             case Event.NONE:
                 return "NONE";
diff --git a/tests/CtsSurfaceControlTestsStaging/Android.bp b/tests/CtsSurfaceControlTestsStaging/Android.bp
index 3272cef..6809521 100644
--- a/tests/CtsSurfaceControlTestsStaging/Android.bp
+++ b/tests/CtsSurfaceControlTestsStaging/Android.bp
@@ -36,6 +36,7 @@
         "androidx.test.rules",
         "compatibility-device-util-axt",
         "com.google.android.material_material",
+        "SurfaceFlingerProperties",
         "truth-prebuilt",
     ],
     resource_dirs: ["src/main/res"],
diff --git a/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/GraphicsActivity.java b/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/GraphicsActivity.java
index 4b12053..79348d1 100644
--- a/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/GraphicsActivity.java
+++ b/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/GraphicsActivity.java
@@ -30,6 +30,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
+import android.sysprop.SurfaceFlingerProperties;
 import android.util.Log;
 import android.view.Display;
 import android.view.Surface;
@@ -45,6 +46,7 @@
 import java.util.Comparator;
 import java.util.List;
 import java.util.Optional;
+import java.util.stream.Collectors;
 
 /**
  * An Activity to help with frame rate testing.
@@ -217,6 +219,27 @@
             postBuffer();
         }
 
+        Surface getSurface() {
+            return mSurface;
+        }
+
+        SurfaceControl getSurfaceControl() {
+            return mSurfaceControl;
+        }
+
+        public int setFrameRate(float frameRate) {
+            Log.i(TAG,
+                    String.format("Setting frame rate for %s: frameRate=%.2f", mName, frameRate));
+
+            int rc = 0;
+            try (SurfaceControl.Transaction transaction = new SurfaceControl.Transaction()) {
+                transaction.setFrameRate(
+                        mSurfaceControl, frameRate, Surface.FRAME_RATE_COMPATIBILITY_DEFAULT);
+                transaction.apply();
+            }
+            return rc;
+        }
+
         public int setFrameRateCategory(int category) {
             Log.i(TAG,
                     String.format(
@@ -230,6 +253,19 @@
             return rc;
         }
 
+        public int setFrameRateSelectionStrategy(int strategy) {
+            Log.i(TAG,
+                    String.format("Setting frame rate selection strategy for %s: strategy=%d",
+                            mName, strategy));
+
+            int rc = 0;
+            try (SurfaceControl.Transaction transaction = new SurfaceControl.Transaction()) {
+                transaction.setFrameRateSelectionStrategy(mSurfaceControl, strategy);
+                transaction.apply();
+            }
+            return rc;
+        }
+
         public void setVisibility(boolean visible) {
             Log.i(TAG,
                     String.format("Setting visibility for %s: %s", mName,
@@ -342,6 +378,11 @@
                 uniqueFrameRates.add(frameRate);
             }
         }
+        Log.i(TAG,
+                "**** Available display refresh rates: "
+                        + uniqueFrameRates.stream()
+                                  .map(Object::toString)
+                                  .collect(Collectors.joining(", ")));
         return uniqueFrameRates;
     }
 
@@ -358,6 +399,10 @@
                 <= FRAME_RATE_TOLERANCE;
     }
 
+    private boolean frameRateEquals(float frameRate1, float frameRate2) {
+        return Math.abs(frameRate1 - frameRate2) <= FRAME_RATE_TOLERANCE;
+    }
+
     // Waits until our SurfaceHolder has a surface and the activity is resumed.
     private void waitForPreconditions() throws InterruptedException {
         assertNotSame(
@@ -447,9 +492,22 @@
         verifyCompatibleAndStableFrameRate(0, surfaces);
     }
 
-    // Set expectedFrameRate to 0.0 to verify only stable frame rate.
+    private void verifyExactAndStableFrameRate(
+            float expectedFrameRate,
+            TestSurface... surfaces) throws InterruptedException {
+        verifyFrameRate(expectedFrameRate, false, surfaces);
+    }
+
     private void verifyCompatibleAndStableFrameRate(
-            float expectedFrameRate, TestSurface... surfaces) throws InterruptedException {
+            float expectedFrameRate,
+            TestSurface... surfaces) throws InterruptedException {
+        verifyFrameRate(expectedFrameRate, true, surfaces);
+    }
+
+    // Set expectedFrameRate to 0.0 to verify only stable frame rate.
+    private void verifyFrameRate(
+            float expectedFrameRate, boolean multiplesAllowed,
+            TestSurface... surfaces) throws InterruptedException {
         Log.i(TAG, "Verifying compatible and stable frame rate");
         long nowNanos = System.nanoTime();
         long gracePeriodEndTimeNanos =
@@ -457,9 +515,19 @@
         while (true) {
             if (expectedFrameRate > FRAME_RATE_TOLERANCE) { // expectedFrameRate > 0
                 // Wait until we switch to a compatible frame rate.
-                while (!isFrameRateMultiple(mDeviceFrameRate, expectedFrameRate)
-                        && !waitForEvents(gracePeriodEndTimeNanos, surfaces)) {
-                    // Empty
+                Log.i(TAG,
+                        "Verifying expected frame rate: actual (device)=" + mDeviceFrameRate
+                                + " expected=" + expectedFrameRate);
+                if (multiplesAllowed) {
+                    while (!isFrameRateMultiple(mDeviceFrameRate, expectedFrameRate)
+                            && !waitForEvents(gracePeriodEndTimeNanos, surfaces)) {
+                        // Empty
+                    }
+                } else {
+                    while (!frameRateEquals(mDeviceFrameRate, expectedFrameRate)
+                            && !waitForEvents(gracePeriodEndTimeNanos, surfaces)) {
+                        // Empty
+                    }
                 }
                 nowNanos = System.nanoTime();
                 if (nowNanos >= gracePeriodEndTimeNanos) {
@@ -604,12 +672,65 @@
                 "frame rate category=" + category);
     }
 
+    private void testSurfaceControlFrameRateSelectionStrategyInternal(int parentStrategy)
+            throws InterruptedException {
+        Log.i(TAG,
+                "**** Running testSurfaceControlFrameRateSelectionStrategy for strategy "
+                        + parentStrategy);
+        TestSurface parent = null;
+        TestSurface child = null;
+        try {
+            parent = new TestSurface(mSurfaceView.getSurfaceControl(), mSurface,
+                    "testSurfaceParent", mSurfaceView.getHolder().getSurfaceFrame(),
+                    /*visible=*/true, Color.RED);
+            child = new TestSurface(parent.getSurfaceControl(), parent.getSurface(),
+                    "testSurfaceChild", mSurfaceView.getHolder().getSurfaceFrame(),
+                    /*visible=*/true, Color.BLUE);
+
+            // Test
+            Display display = getDisplay();
+            List<Float> frameRates = getRefreshRates(display.getMode(), display);
+            assumeTrue("**** SKIPPED due to frame rate override disabled",
+                    SurfaceFlingerProperties.enable_frame_rate_override().orElse(true));
+            float childFrameRate = Collections.max(frameRates);
+            float parentFrameRate = childFrameRate / 2;
+            int initialNumEvents = mModeChangedEvents.size();
+            parent.setFrameRate(parentFrameRate);
+            parent.setFrameRateSelectionStrategy(parentStrategy);
+            child.setFrameRate(childFrameRate);
+
+            // Verify
+            float expectedFrameRate =
+                    parentStrategy == SurfaceControl.FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN
+                    ? parentFrameRate
+                    : childFrameRate;
+            verifyExactAndStableFrameRate(expectedFrameRate, parent, child);
+            verifyModeSwitchesDontChangeResolution(initialNumEvents, mModeChangedEvents.size());
+        } finally {
+            if (parent != null) {
+                parent.release();
+            }
+            if (child != null) {
+                child.release();
+            }
+        }
+    }
+
+    public void testSurfaceControlFrameRateSelectionStrategy(int parentStrategy)
+            throws InterruptedException {
+        runTestsWithPreconditions(
+                () -> testSurfaceControlFrameRateSelectionStrategyInternal(parentStrategy),
+                "frame rate strategy=" + parentStrategy);
+    }
+
     private float getExpectedFrameRate(int category) {
         Display display = getDisplay();
         List<Float> frameRates = getRefreshRates(display.getMode(), display);
 
-        if (category == Surface.FRAME_RATE_CATEGORY_DEFAULT
-                || category == Surface.FRAME_RATE_CATEGORY_NO_PREFERENCE) {
+        if (category == Surface.FRAME_RATE_CATEGORY_DEFAULT) {
+            // Max due to default vote and no other frame rate specifications.
+            return Collections.max(frameRates);
+        } else if (category == Surface.FRAME_RATE_CATEGORY_NO_PREFERENCE) {
             return Collections.min(frameRates);
         }
 
diff --git a/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/SurfaceControlTest.java b/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/SurfaceControlTest.java
index ccbda7f..bed9cff 100644
--- a/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/SurfaceControlTest.java
+++ b/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/SurfaceControlTest.java
@@ -23,11 +23,14 @@
 import android.os.SystemProperties;
 import android.support.test.uiautomator.UiDevice;
 import android.view.Surface;
+import android.view.SurfaceControl;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.platform.app.InstrumentationRegistry;
 import androidx.test.rule.ActivityTestRule;
 
+import com.android.compatibility.common.util.DisplayUtil;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
@@ -59,19 +62,15 @@
         uiDevice.executeShellCommand("wm dismiss-keyguard");
 
         InstrumentationRegistry.getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
-                Manifest.permission.LOG_COMPAT_CHANGE,
-                Manifest.permission.READ_COMPAT_CHANGE_CONFIG,
                 Manifest.permission.MODIFY_REFRESH_RATE_SWITCHING_TYPE,
-                Manifest.permission.OVERRIDE_DISPLAY_MODE_REQUESTS,
-                Manifest.permission.MANAGE_GAME_MODE);
+                Manifest.permission.OVERRIDE_DISPLAY_MODE_REQUESTS);
 
         // Prevent DisplayManager from limiting the allowed refresh rate range based on
         // non-app policies (e.g. low battery, user settings, etc).
         mDisplayManager = activity.getSystemService(DisplayManager.class);
         mDisplayManager.setShouldAlwaysRespectAppRequestedMode(true);
 
-        mInitialRefreshRateSwitchingType =
-                toSwitchingType(mDisplayManager.getMatchContentFrameRateUserPreference());
+        mInitialRefreshRateSwitchingType = DisplayUtil.getRefreshRateSwitchingType(mDisplayManager);
         mDisplayManager.setRefreshRateSwitchingType(
                 DisplayManager.SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS);
     }
@@ -118,16 +117,18 @@
         activity.testSurfaceControlFrameRateCategory(Surface.FRAME_RATE_CATEGORY_DEFAULT);
     }
 
-    private int toSwitchingType(int matchContentFrameRateUserPreference) {
-        switch (matchContentFrameRateUserPreference) {
-            case DisplayManager.MATCH_CONTENT_FRAMERATE_NEVER:
-                return DisplayManager.SWITCHING_TYPE_NONE;
-            case DisplayManager.MATCH_CONTENT_FRAMERATE_SEAMLESSS_ONLY:
-                return DisplayManager.SWITCHING_TYPE_WITHIN_GROUPS;
-            case DisplayManager.MATCH_CONTENT_FRAMERATE_ALWAYS:
-                return DisplayManager.SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS;
-            default:
-                return -1;
-        }
+    @Test
+    public void testSurfaceControlFrameRateSelectionStrategySelf() throws InterruptedException {
+        GraphicsActivity activity = mActivityRule.getActivity();
+        activity.testSurfaceControlFrameRateSelectionStrategy(
+                SurfaceControl.FRAME_RATE_SELECTION_STRATEGY_SELF);
+    }
+
+    @Test
+    public void testSurfaceControlFrameRateSelectionStrategyOverrideChildren()
+            throws InterruptedException {
+        GraphicsActivity activity = mActivityRule.getActivity();
+        activity.testSurfaceControlFrameRateSelectionStrategy(
+                SurfaceControl.FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN);
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppBackButton3ButtonLandscape.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppBackButton3ButtonLandscape.kt
index 030b292..b3c9c96 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppBackButton3ButtonLandscape.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppBackButton3ButtonLandscape.kt
@@ -31,7 +31,8 @@
 @RunWith(FlickerServiceJUnit4ClassRunner::class)
 class CloseAppBackButton3ButtonLandscape :
     CloseAppBackButton(NavBar.MODE_3BUTTON, Rotation.ROTATION_90) {
-    @ExpectedScenarios(["APP_CLOSE_TO_HOME"])
+    // TODO: Missing CUJ (b/300078127)
+    @ExpectedScenarios(["ENTIRE_TRACE"])
     @Test
     override fun closeAppBackButtonTest() = super.closeAppBackButtonTest()
 
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppBackButton3ButtonPortrait.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppBackButton3ButtonPortrait.kt
index 770da143..29c11a4 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppBackButton3ButtonPortrait.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppBackButton3ButtonPortrait.kt
@@ -31,7 +31,8 @@
 @RunWith(FlickerServiceJUnit4ClassRunner::class)
 class CloseAppBackButton3ButtonPortrait :
     CloseAppBackButton(NavBar.MODE_3BUTTON, Rotation.ROTATION_0) {
-    @ExpectedScenarios(["APP_CLOSE_TO_HOME"])
+    // TODO: Missing CUJ (b/300078127)
+    @ExpectedScenarios(["ENTIRE_TRACE"])
     @Test
     override fun closeAppBackButtonTest() = super.closeAppBackButtonTest()
 
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppBackButtonGesturalNavLandscape.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppBackButtonGesturalNavLandscape.kt
index 4b2206d7..1bb4a25 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppBackButtonGesturalNavLandscape.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppBackButtonGesturalNavLandscape.kt
@@ -31,7 +31,8 @@
 @RunWith(FlickerServiceJUnit4ClassRunner::class)
 class CloseAppBackButtonGesturalNavLandscape :
     CloseAppBackButton(NavBar.MODE_GESTURAL, Rotation.ROTATION_90) {
-    @ExpectedScenarios(["APP_CLOSE_TO_HOME"])
+    // TODO: Missing CUJ (b/300078127)
+    @ExpectedScenarios(["ENTIRE_TRACE"])
     @Test
     override fun closeAppBackButtonTest() = super.closeAppBackButtonTest()
 
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppBackButtonGesturalNavPortrait.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppBackButtonGesturalNavPortrait.kt
index 54b471e..17cb6e1 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppBackButtonGesturalNavPortrait.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/close/flicker/CloseAppBackButtonGesturalNavPortrait.kt
@@ -31,7 +31,8 @@
 @RunWith(FlickerServiceJUnit4ClassRunner::class)
 class CloseAppBackButtonGesturalNavPortrait :
     CloseAppBackButton(NavBar.MODE_GESTURAL, Rotation.ROTATION_0) {
-    @ExpectedScenarios(["APP_CLOSE_TO_HOME"])
+    // TODO: Missing CUJ (b/300078127)
+    @ExpectedScenarios(["ENTIRE_TRACE"])
     @Test
     override fun closeAppBackButtonTest() = super.closeAppBackButtonTest()
 
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/scenarios/QuickSwitchBetweenTwoAppsBack.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/scenarios/QuickSwitchBetweenTwoAppsBack.kt
index 93130c4..a1708fe 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/scenarios/QuickSwitchBetweenTwoAppsBack.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/scenarios/QuickSwitchBetweenTwoAppsBack.kt
@@ -19,6 +19,7 @@
 import android.app.Instrumentation
 import android.tools.common.NavBar
 import android.tools.common.Rotation
+import android.tools.device.flicker.rules.ChangeDisplayOrientationRule
 import android.tools.device.traces.parsers.WindowManagerStateHelper
 import androidx.test.platform.app.InstrumentationRegistry
 import com.android.launcher3.tapl.LauncherInstrumentation
@@ -46,7 +47,9 @@
         tapl.setExpectedRotation(rotation.value)
         tapl.setIgnoreTaskbarVisibility(true)
         testApp1.launchViaIntent(wmHelper)
+        ChangeDisplayOrientationRule.setRotation(rotation)
         testApp2.launchViaIntent(wmHelper)
+        ChangeDisplayOrientationRule.setRotation(rotation)
     }
 
     @Test
diff --git a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
index f867c98..9198ae1 100644
--- a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
@@ -102,6 +102,20 @@
                 <category android:name="android.intent.category.LAUNCHER"/>
             </intent-filter>
         </activity>
+        <activity android:name=".PortraitImmersiveActivity"
+                  android:taskAffinity="com.android.server.wm.flicker.testapp.PortraitImmersiveActivity"
+                  android:immersive="true"
+                  android:resizeableActivity="true"
+                  android:screenOrientation="portrait"
+                  android:theme="@android:style/Theme.NoTitleBar"
+                  android:configChanges="screenSize"
+                  android:label="PortraitImmersiveActivity"
+                  android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
         <activity android:name=".LaunchTransparentActivity"
                   android:resizeableActivity="false"
                   android:screenOrientation="portrait"
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java
index 7c5e9a3..8b334c0 100644
--- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java
@@ -73,6 +73,12 @@
                 FLICKER_APP_PACKAGE + ".NonResizeablePortraitActivity");
     }
 
+    public static class PortraitImmersiveActivity {
+        public static final String LABEL = "PortraitImmersiveActivity";
+        public static final ComponentName COMPONENT = new ComponentName(FLICKER_APP_PACKAGE,
+                FLICKER_APP_PACKAGE + ".PortraitImmersiveActivity");
+    }
+
     public static class TransparentActivity {
         public static final String LABEL = "TransparentActivity";
         public static final ComponentName COMPONENT = new ComponentName(FLICKER_APP_PACKAGE,
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/PortraitImmersiveActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/PortraitImmersiveActivity.java
new file mode 100644
index 0000000..0a7f81c
--- /dev/null
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/PortraitImmersiveActivity.java
@@ -0,0 +1,20 @@
+/*
+ * 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.wm.flicker.testapp;
+
+public class PortraitImmersiveActivity extends GameActivity {
+}
diff --git a/tests/NetworkSecurityConfigTest/res/raw/ca_certs_der.der b/tests/NetworkSecurityConfigTest/res/raw/ca_certs_der.der
index 235bd47..fd888ec 100644
--- a/tests/NetworkSecurityConfigTest/res/raw/ca_certs_der.der
+++ b/tests/NetworkSecurityConfigTest/res/raw/ca_certs_der.der
Binary files differ
diff --git a/tests/NetworkSecurityConfigTest/res/raw/ca_certs_pem.pem b/tests/NetworkSecurityConfigTest/res/raw/ca_certs_pem.pem
index 413e3c0..66f7bfd 100644
--- a/tests/NetworkSecurityConfigTest/res/raw/ca_certs_pem.pem
+++ b/tests/NetworkSecurityConfigTest/res/raw/ca_certs_pem.pem
@@ -1,35 +1,31 @@
 -----BEGIN CERTIFICATE-----
-MIIDfTCCAuagAwIBAgIDErvmMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT
-MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0
-aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDIwNTIxMDQwMDAwWhcNMTgwODIxMDQwMDAw
-WjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UE
-AxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
-CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9m
-OSm9BXiLnTjoBbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIu
-T8rxh0PBFpVXLVDviS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6c
-JmTM386DGXHKTubU1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmR
-Cw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5asz
-PeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo4HwMIHtMB8GA1UdIwQYMBaAFEjm
-aPkr0rKV10fYIyAQTzOYkJ/UMB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrM
-TjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjA6BgNVHR8EMzAxMC+g
-LaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9jcmxzL3NlY3VyZWNhLmNybDBO
-BgNVHSAERzBFMEMGBFUdIAAwOzA5BggrBgEFBQcCARYtaHR0cHM6Ly93d3cuZ2Vv
-dHJ1c3QuY29tL3Jlc291cmNlcy9yZXBvc2l0b3J5MA0GCSqGSIb3DQEBBQUAA4GB
-AHbhEm5OSxYShjAGsoEIz/AIx8dxfmbuwu3UOx//8PDITtZDOLC5MH0Y0FWDomrL
-NhGc6Ehmo21/uBPUR/6LWlxz/K7ZGzIZOKuXNBSqltLroxwUCEm2u+WR74M26x1W
-b8ravHNjkOR/ez4iyz0H7V84dJzjA1BOoa+Y7mHyhD8S
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIICPDCCAaUCEDyRMcsf9tAbDpq40ES/Er4wDQYJKoZIhvcNAQEFBQAwXzELMAkG
-A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
-cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
-MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
-BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt
-YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
-ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE
-BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is
-I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G
-CSqGSIb3DQEBBQUAA4GBABByUqkFFBkyCEHwxWsKzH4PIRnN5GfcX6kb5sroc50i
-2JhucwNhkcV8sEVAbkSdjbCxlnRhLQ2pRdKkkirWmnWXbj9T/UWZYB2oK0z5XqcJ
-2HUw19JlYD1n1khVdWk/kfVIC0dpImmClr7JyDiGSnoscxlIaU5rfGW/D/xwzoiQ
+MIIFYjCCBEqgAwIBAgIQd70NbNs2+RrqIQ/E8FjTDTANBgkqhkiG9w0BAQsFADBX
+MQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTEQMA4GA1UE
+CxMHUm9vdCBDQTEbMBkGA1UEAxMSR2xvYmFsU2lnbiBSb290IENBMB4XDTIwMDYx
+OTAwMDA0MloXDTI4MDEyODAwMDA0MlowRzELMAkGA1UEBhMCVVMxIjAgBgNVBAoT
+GUdvb2dsZSBUcnVzdCBTZXJ2aWNlcyBMTEMxFDASBgNVBAMTC0dUUyBSb290IFIx
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAthECix7joXebO9y/lD63
+ladAPKH9gvl9MgaCcfb2jH/76Nu8ai6Xl6OMS/kr9rH5zoQdsfnFl97vufKj6bwS
+iV6nqlKr+CMny6SxnGPb15l+8Ape62im9MZaRw1NEDPjTrETo8gYbEvs/AmQ351k
+KSUjB6G00j0uYODP0gmHu81I8E3CwnqIiru6z1kZ1q+PsAewnjHxgsHA3y6mbWwZ
+DrXYfiYaRQM9sHmklCitD38m5agI/pboPGiUU+6DOogrFZYJsuB6jC511pzrp1Zk
+j5ZPaK49l8KEj8C8QMALXL32h7M1bKwYUH+E4EzNktMg6TO8UpmvMrUpsyUqtEj5
+cuHKZPfmghCN6J3Cioj6OGaK/GP5Afl4/Xtcd/p2h/rs37EOeZVXtL0m79YB0esW
+CruOC7XFxYpVq9Os6pFLKcwZpDIlTirxZUTQAs6qzkm06p98g7BAe+dDq6dso499
+iYH6TKX/1Y7DzkvgtdizjkXPdsDtQCv9Uw+wp9U7DbGKogPeMa3Md+pvez7W35Ei
+Eua++tgy/BBjFFFy3l3WFpO9KWgz7zpm7AeKJt8T11dleCfeXkkUAKIAf5qoIbap
+sZWwpbkNFhHax2xIPEDgfg1azVY80ZcFuctL7TlLnMQ/0lUTbiSw1nH69MG6zO0b
+9f6BQdgAmD06yK56mDcYBZUCAwEAAaOCATgwggE0MA4GA1UdDwEB/wQEAwIBhjAP
+BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTkrysmcRorSCeFL1JmLO/wiRNxPjAf
+BgNVHSMEGDAWgBRge2YaRQ2XyolQL30EzTSo//z9SzBgBggrBgEFBQcBAQRUMFIw
+JQYIKwYBBQUHMAGGGWh0dHA6Ly9vY3NwLnBraS5nb29nL2dzcjEwKQYIKwYBBQUH
+MAKGHWh0dHA6Ly9wa2kuZ29vZy9nc3IxL2dzcjEuY3J0MDIGA1UdHwQrMCkwJ6Al
+oCOGIWh0dHA6Ly9jcmwucGtpLmdvb2cvZ3NyMS9nc3IxLmNybDA7BgNVHSAENDAy
+MAgGBmeBDAECATAIBgZngQwBAgIwDQYLKwYBBAHWeQIFAwIwDQYLKwYBBAHWeQIF
+AwMwDQYJKoZIhvcNAQELBQADggEBADSkHrEoo9C0dhemMXoh6dFSPsjbdBZBiLg9
+NR3t5P+T4Vxfq7vqfM/b5A3Ri1fyJm9bvhdGaJQ3b2t6yMAYN/olUazsaL+yyEn9
+WprKASOshIArAoyZl+tJaox118fessmXn1hIVw41oeQa1v1vg4Fv74zPl6/AhSrw
+9U5pCZEt4Wi4wStz6dTZ/CLANx8LZh1J7QJVj2fhMtfTJr9w4z30Z209fOU0iOMy
++qduBmpvvYuR7hZL6Dupszfnw0Skfths18dG9ZKb59UhvmaSGZRVbNQpsg3BZlvi
+d0lIKO2d1xozclOzgjXPYovJJIultzkMu34qQb9Sz/yilrbCgj8=
 -----END CERTIFICATE-----
diff --git a/tests/NetworkSecurityConfigTest/res/xml/domain_whitespace.xml b/tests/NetworkSecurityConfigTest/res/xml/domain_whitespace.xml
index 5d23d36e..99106ad 100644
--- a/tests/NetworkSecurityConfigTest/res/xml/domain_whitespace.xml
+++ b/tests/NetworkSecurityConfigTest/res/xml/domain_whitespace.xml
@@ -5,7 +5,7 @@
     </domain>
     <domain>   developer.android.com    </domain>
     <pin-set>
-      <pin digest="SHA-256">  7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=  </pin>
+      <pin digest="SHA-256">  zCTnfLwLKbS9S2sbp+uFz4KZOocFvXxkV06Ce9O5M2w=  </pin>
     </pin-set>
   </domain-config>
 </network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/res/xml/nested_domains.xml b/tests/NetworkSecurityConfigTest/res/xml/nested_domains.xml
index d45fd77..232f88f 100644
--- a/tests/NetworkSecurityConfigTest/res/xml/nested_domains.xml
+++ b/tests/NetworkSecurityConfigTest/res/xml/nested_domains.xml
@@ -9,7 +9,7 @@
       <domain-config>
           <domain>developer.android.com</domain>
           <pin-set>
-              <pin digest="SHA-256">7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin>
+              <pin digest="SHA-256">zCTnfLwLKbS9S2sbp+uFz4KZOocFvXxkV06Ce9O5M2w=</pin>
           </pin-set>
       </domain-config>
     </domain-config>
diff --git a/tests/NetworkSecurityConfigTest/res/xml/pins1.xml b/tests/NetworkSecurityConfigTest/res/xml/pins1.xml
index 1773d280..7cc81b0 100644
--- a/tests/NetworkSecurityConfigTest/res/xml/pins1.xml
+++ b/tests/NetworkSecurityConfigTest/res/xml/pins1.xml
@@ -3,7 +3,7 @@
   <domain-config>
     <domain>android.com</domain>
     <pin-set>
-      <pin digest="SHA-256">7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin>
+      <pin digest="SHA-256">zCTnfLwLKbS9S2sbp+uFz4KZOocFvXxkV06Ce9O5M2w=</pin>
     </pin-set>
   </domain-config>
 </network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/src/android/security/net/config/NetworkSecurityConfigTests.java b/tests/NetworkSecurityConfigTest/src/android/security/net/config/NetworkSecurityConfigTests.java
index 047be16..0494f17 100644
--- a/tests/NetworkSecurityConfigTest/src/android/security/net/config/NetworkSecurityConfigTests.java
+++ b/tests/NetworkSecurityConfigTest/src/android/security/net/config/NetworkSecurityConfigTests.java
@@ -22,23 +22,17 @@
 import android.test.ActivityUnitTestCase;
 import android.util.ArraySet;
 import android.util.Pair;
+
+import com.android.org.conscrypt.TrustedCertificateStore;
+
 import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.net.Socket;
-import java.net.URL;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLHandshakeException;
-import javax.net.ssl.TrustManager;
 
-import com.android.org.conscrypt.TrustedCertificateStore;
+import javax.net.ssl.SSLContext;
 
 public class NetworkSecurityConfigTests extends ActivityUnitTestCase<Activity> {
 
@@ -46,9 +40,9 @@
         super(Activity.class);
     }
 
-    // SHA-256 of the G2 intermediate CA for android.com (as of 10/2015).
-    private static final byte[] G2_SPKI_SHA256
-            = hexToBytes("ec722969cb64200ab6638f68ac538e40abab5b19a6485661042a1061c4612776");
+    // SHA-256 of the GTS intermediate CA (CN = GTS CA 1C3) for android.com (as of 09/2023).
+    private static final byte[] GTS_INTERMEDIATE_SPKI_SHA256 =
+        hexToBytes("cc24e77cbc0b29b4bd4b6b1ba7eb85cf82993a8705bd7c64574e827bd3b9336c");
 
     private static final byte[] TEST_CA_BYTES
             = hexToBytes(
@@ -161,7 +155,7 @@
 
     public void testGoodPin() throws Exception {
         ArraySet<Pin> pins = new ArraySet<Pin>();
-        pins.add(new Pin("SHA-256", G2_SPKI_SHA256));
+        pins.add(new Pin("SHA-256", GTS_INTERMEDIATE_SPKI_SHA256));
         NetworkSecurityConfig domain = new NetworkSecurityConfig.Builder()
                 .setPinSet(new PinSet(pins, Long.MAX_VALUE))
                 .addCertificatesEntryRef(
@@ -247,7 +241,7 @@
 
     public void testWithUrlConnection() throws Exception {
         ArraySet<Pin> pins = new ArraySet<Pin>();
-        pins.add(new Pin("SHA-256", G2_SPKI_SHA256));
+        pins.add(new Pin("SHA-256", GTS_INTERMEDIATE_SPKI_SHA256));
         NetworkSecurityConfig domain = new NetworkSecurityConfig.Builder()
                 .setPinSet(new PinSet(pins, Long.MAX_VALUE))
                 .addCertificatesEntryRef(
@@ -304,7 +298,7 @@
         } finally {
             // Delete the user added CA. We don't know the alias so just delete them all.
             for (String alias : store.aliases()) {
-                if (store.isUser(alias)) {
+                if (TrustedCertificateStore.isUser(alias)) {
                     try {
                         store.deleteCertificateEntry(alias);
                     } catch (Exception ignored) {
diff --git a/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestUtils.java b/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestUtils.java
index 9dec21b..39b5cb4c 100644
--- a/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestUtils.java
+++ b/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestUtils.java
@@ -16,19 +16,20 @@
 
 package android.security.net.config;
 
+import static org.junit.Assert.fail;
+
 import android.content.pm.ApplicationInfo;
 import android.os.Build;
-import java.net.Socket;
+
 import java.net.URL;
+
 import javax.net.ssl.HttpsURLConnection;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLHandshakeException;
-import javax.net.ssl.TrustManager;
+import javax.net.ssl.SSLSocket;
 import javax.net.ssl.TrustManagerFactory;
 
-import junit.framework.Assert;
-
-public final class TestUtils extends Assert {
+public final class TestUtils {
 
     private TestUtils() {
     }
@@ -36,8 +37,8 @@
     public static void assertConnectionFails(SSLContext context, String host, int port)
             throws Exception {
         try {
-            Socket s = context.getSocketFactory().createSocket(host, port);
-            s.getInputStream();
+            SSLSocket s = (SSLSocket) context.getSocketFactory().createSocket(host, port);
+            s.startHandshake();
             fail("Expected connection to " + host + ":" + port + " to fail.");
         } catch (SSLHandshakeException expected) {
         }
@@ -45,7 +46,8 @@
 
     public static void assertConnectionSucceeds(SSLContext context, String host, int port)
             throws Exception {
-        Socket s = context.getSocketFactory().createSocket(host, port);
+        SSLSocket s = (SSLSocket) context.getSocketFactory().createSocket(host, port);
+        s.startHandshake();
         s.getInputStream();
     }
 
diff --git a/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java b/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java
index 4b7a014..81e05c1 100644
--- a/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java
+++ b/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java
@@ -16,26 +16,18 @@
 
 package android.security.net.config;
 
-import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.test.AndroidTestCase;
 import android.test.MoreAsserts;
-import android.util.ArraySet;
-import android.util.Pair;
+
 import java.io.IOException;
 import java.net.InetAddress;
-import java.net.Socket;
-import java.net.URL;
 import java.security.KeyStore;
 import java.security.Provider;
-import java.security.Security;
 import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Set;
-import javax.net.ssl.HttpsURLConnection;
+
 import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLHandshakeException;
 import javax.net.ssl.SSLSocket;
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.TrustManagerFactory;
@@ -52,7 +44,7 @@
         NetworkSecurityConfig config = appConfig.getConfigForHostname("");
         assertNotNull(config);
         // Check defaults.
-        assertTrue(config.isCleartextTrafficPermitted());
+        assertFalse(config.isCleartextTrafficPermitted());
         assertFalse(config.isHstsEnforced());
         assertFalse(config.getTrustAnchors().isEmpty());
         PinSet pinSet = config.getPins();
@@ -72,7 +64,7 @@
         NetworkSecurityConfig config = appConfig.getConfigForHostname("");
         assertNotNull(config);
         // Check defaults.
-        assertTrue(config.isCleartextTrafficPermitted());
+        assertFalse(config.isCleartextTrafficPermitted());
         assertFalse(config.isHstsEnforced());
         assertTrue(config.getTrustAnchors().isEmpty());
         PinSet pinSet = config.getPins();
@@ -91,14 +83,14 @@
         NetworkSecurityConfig config = appConfig.getConfigForHostname("");
         assertNotNull(config);
         // Check defaults.
-        assertTrue(config.isCleartextTrafficPermitted());
+        assertFalse(config.isCleartextTrafficPermitted());
         assertFalse(config.isHstsEnforced());
         assertTrue(config.getTrustAnchors().isEmpty());
         PinSet pinSet = config.getPins();
         assertTrue(pinSet.pins.isEmpty());
         // Check android.com.
         config = appConfig.getConfigForHostname("android.com");
-        assertTrue(config.isCleartextTrafficPermitted());
+        assertFalse(config.isCleartextTrafficPermitted());
         assertFalse(config.isHstsEnforced());
         assertFalse(config.getTrustAnchors().isEmpty());
         pinSet = config.getPins();
@@ -188,7 +180,7 @@
         ApplicationConfig appConfig = new ApplicationConfig(source);
         assertTrue(appConfig.hasPerDomainConfigs());
         NetworkSecurityConfig config = appConfig.getConfigForHostname("android.com");
-        assertTrue(config.isCleartextTrafficPermitted());
+        assertFalse(config.isCleartextTrafficPermitted());
         assertFalse(config.isHstsEnforced());
         assertFalse(config.getTrustAnchors().isEmpty());
         PinSet pinSet = config.getPins();
@@ -250,9 +242,9 @@
         ApplicationConfig appConfig = new ApplicationConfig(source);
         // Check android.com.
         NetworkSecurityConfig config = appConfig.getConfigForHostname("android.com");
-        assertTrue(config.isCleartextTrafficPermitted());
+        assertFalse(config.isCleartextTrafficPermitted());
         assertFalse(config.isHstsEnforced());
-        assertEquals(2, config.getTrustAnchors().size());
+        assertEquals(1, config.getTrustAnchors().size());
         // Try connections.
         SSLContext context = TestUtils.getSSLContext(source);
         TestUtils.assertConnectionSucceeds(context, "android.com", 443);
@@ -267,9 +259,9 @@
         ApplicationConfig appConfig = new ApplicationConfig(source);
         // Check android.com.
         NetworkSecurityConfig config = appConfig.getConfigForHostname("android.com");
-        assertTrue(config.isCleartextTrafficPermitted());
+        assertFalse(config.isCleartextTrafficPermitted());
         assertFalse(config.isHstsEnforced());
-        assertEquals(2, config.getTrustAnchors().size());
+        assertEquals(1, config.getTrustAnchors().size());
         // Try connections.
         SSLContext context = TestUtils.getSSLContext(source);
         TestUtils.assertConnectionSucceeds(context, "android.com", 443);
diff --git a/tests/utils/testutils/TEST_MAPPING b/tests/utils/testutils/TEST_MAPPING
index d9eb44f..6468d8c 100644
--- a/tests/utils/testutils/TEST_MAPPING
+++ b/tests/utils/testutils/TEST_MAPPING
@@ -4,7 +4,7 @@
       "name": "frameworks-base-testutils-tests",
       "options": [
         {
-          "exclude-annotation": "android.platform.test.annotations.LargeTest"
+          "exclude-annotation": "androidx.test.filters.LargeTest"
         },
         {
           "exclude-annotation": "android.platform.test.annotations.FlakyTest"
diff --git a/tools/lint/fix/Android.bp b/tools/lint/fix/Android.bp
index 43f2122..ddacf57 100644
--- a/tools/lint/fix/Android.bp
+++ b/tools/lint/fix/Android.bp
@@ -25,6 +25,11 @@
     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 b42f9ee..4a2e37e 100644
--- a/tools/lint/fix/soong_lint_fix.py
+++ b/tools/lint/fix/soong_lint_fix.py
@@ -213,5 +213,5 @@
 
 if __name__ == "__main__":
     opts = SoongLintFixOptions()
-    opts.parse_args(sys.argv)
+    opts.parse_args()
     SoongLintFix(opts).run()
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 bc41829..71ac94b 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 @@
         if (mServiceConnection != null) {
             mContext.unbindService(mServiceConnection);
             mServiceConnection = null;
+            mService = null;
         }
     }